如果您的数据点显然不适合线性回归(穿过数据点之间的直线),那么多项式回归可能是理想的选择。它的出现就是为了弥补线性回归。
像线性回归一样,多项式回归使用变量 x 和 y 之间的关系来找到绘制数据点线的最佳方法。
文章目录
一、案例(numpy实现)
1.1 搭建模型
- 一、案例(numpy实现)
- 1.1 搭建模型
- 1.2 评估回归
- 1.3 预测未来值
- 二、案例(sklearn实现)
在下面的例子中,我们注册了 18 辆经过特定收费站的汽车。我们已经记录了汽车的速度和通过时间(小时)。x 轴表示一天中的小时,y 轴表示速度:
import matplotlib.pyplot as plt
x = [1,2,3,5,6,7,8,9,10,12,13,14,15,16,18,19,21,22]
y = [100,90,80,60,60,55,60,65,70,70,75,76,78,79,90,99,99,100]
plt.scatter(x, y)
plt.show()
绘制如图: 明显这不是线性了。
导入 numpy 和 matplotlib,然后画出多项式回归线:
import numpy
import matplotlib.pyplot as plt
x = [1,2,3,5,6,7,8,9,10,12,13,14,15,16,18,19,21,22]
y = [100,90,80,60,60,55,60,65,70,70,75,76,78,79,90,99,99,100]
mymodel = numpy.poly1d(numpy.polyfit(x, y, 3)) # 三阶
myline = numpy.linspace(1, 22, 100) # 产生1到22的100个点
plt.scatter(x, y)
plt.plot(myline, mymodel(myline))
plt.show()
绘制如图:
重要的是要知道 x 轴和 y 轴的值之间的关系有多好,如果没有关系,则多项式回归不能用于预测任何东西:
import numpy
from sklearn.metrics import r2_score
x = [1,2,3,5,6,7,8,9,10,12,13,14,15,16,18,19,21,22]
y = [100,90,80,60,60,55,60,65,70,70,75,76,78,79,90,99,99,100]
mymodel = numpy.poly1d(numpy.polyfit(x, y, 3))
print(r2_score(y, mymodel(x)))
结果 0.94 表明存在很好的关系,我们可以在将来的预测中使用多项式回归。
1.3 预测未来值预测下午 17 点过车的速度:
speed = mymodel(17)
print(speed)
该例预测速度为 88.87。
二、案例(sklearn实现)语法:
sklearn.preprocessing.PolynomialFeatures(degree=2,
interaction_only=False,include_bias=True)
- degree :多项式中的次数,默认为2
- interaction_only:布尔值是否只产生交互项,默认为False
- include_bias:布尔值,是否产出与截距项相乘的 ,默认True
对数据先处理:
import numpy as np
import matplotlib.pyplot as plt
x = np.random.uniform(-3, 3, size=100)
X = x.reshape(-1, 1)
y = 0.5 + x**2 + x + 2 + np.random.normal(0, 1, size=100)
# 多项式回归其实对数据进行预处理,给数据添加新的特征,所以调用的库在preprocessing中
from sklearn.preprocessing import PolynomialFeatures
# 这个degree表示我们使用多少次幂的多项式
poly = PolynomialFeatures(degree=3)
poly.fit(X)
X2 = poly.transform(X)
X2.shape
输出结果:(100, 3)。 第一列常数项,第二列一次项系数,第三列二次项系数,第三列三次项系数。接下来查看一下前五列
X2[:5, :]
如下:
array([[ 1. , 1.9088657 , 3.64376826, 6.95546424],
[ 1. , 2.19759619, 4.829429 , 10.61313477],
[ 1. , -0.34147544, 0.11660547, -0.0398179 ],
[ 1. , -2.06594379, 4.26812376, -8.8177038 ],
[ 1. , 0.61105841, 0.37339238, 0.22816456]])
再来用模型:
from sklearn.linear_model import LinearRegression
reg = LinearRegression()
reg.fit(X2, y)
y_predict = reg.predict(X2)
plt.scatter(x, y)
plt.plot(np.sort(x), y_predict[np.argsort(x)], color='r')
plt.show()
如下: 查看系数:
reg.coef_
输出:
array([ 0. , 1.09334334, 0.96869916, -0.006003 ])
查看截距:
reg.intercept_
如下:
2.6598901195165805