前面我们介绍的线性回归、岭回归、Lasso都是线性回归模型,但有些场景下,数据分布并不是简单的线性模型,比如Sklearn中的圆形数据、月亮型数据等。现实中也有例子,比如用房屋的长和宽,去拟合价格效果并不好,但如果将长和宽相乘得到面积,再去拟合价格就能有非常好的效果。解决类似这类问题,就要用到线性回归里一个非常重要的改进方法:多项式回归

当然,对于回归问题,数据若分布为一条直线,则是线性的,对于分类问题,数据分布若能用一条直线来划分类别,则是线性可分的。多项式回归,会拓展出原特征的高次项甚至交叉项,并不属于线性回归的范畴,只是帮助线性回归解决非线性问题的一种手段。

代码示例

1、生成数据集

import numpy as np
import matplotlib.pyplot as plt

rnd = np.random.RandomState(24)
x = rnd.uniform(-3, 3, size=100)
y = np.sin(x) + rnd.normal(size=len(x)) / 3

# plt.scatter(x, y)
# plt.show()

# sklearn只接受二维数据,先转化
x = x.reshape(-1, 1)

2、使用原始数据

from sklearn.linear_model import LinearRegression

linear = LinearRegression()
linear.fit(x, y)
print(linear.score(x, y))  #0.500

# 创建连续变量进行预测
line = np.linspace(-3, 3, 100).reshape(-1,1)
line_pred = linear.predict(line)

# plt.plot(line, line_pred, c='red')
# plt.scatter(x, y)
# plt.show()

R2分数0.5,拟合的是一条直线,看不出sin函数的变化趋势,效果很差。 

3、多项式回归

from sklearn.preprocessing import PolynomialFeatures

# 创建3次项,保留交叉项(两个以上的特征时才有意义),不要截距项(线性回归模型中会添加)
poly = PolynomialFeatures(degree=3, interaction_only=False, include_bias=False)
x_ = poly.fit_transform(x)

# 再做线性拟合
linear = LinearRegression()
linear.fit(x_, y)
print(linear.score(x_, y))

# 创建连续变量
line = np.linspace(-3, 3, 100).reshape(-1, 1)
line_ = poly.fit_transform(line)
y_pred_ = linear.predict(line_)

plt.scatter(x, y)
plt.plot(line, y_pred_, c='red')
plt.show()

由图可见,将特征扩展到三次项后,基本能完全拟合出sin曲线了。

本文为 陈华 原创,欢迎转载,但请注明出处:http://www.ichenhua.cn/read/295