文章目录
- 前言
- PolynomialFeatures详细探讨
- 如何实现多项式回归
- 代码实现:
- 正规方程验证
前言
在机器学习入门(六)中,已经通过pipeline快速实现了多项式回归。代码如下:
PolyRegr = Pipeline([
('poly',PolynomialFeatures(degree=2)),
('clf',LinearRegression())
])
PolyRegr.fit(X, y)
这个方式省略了很多步骤,并且也无法得知PolynomialFeatures是如何运作的。
PolynomialFeatures详细探讨
现在有(a,b)两个特征,使用degree=2的二次多项式则为(1,a, a^2, ab, b ,b^2)。
PolynomialFeatures主要有以下几个参数:
degree:度数,决定多项式的次数
interaction_only: 默认为False,字面意思就是只能交叉相乘,不能有a^2这种.
include_bias: 默认为True, 这个bias指的是多项式会自动包含1,设为False就没这个1了.
order:有"C" 和"F" 两个选项。官方写的是在密集情况(dense case)下的输出array的顺序,F可以加快操作但可能使得subsequent estimators变慢。
利用代码试验一下:
from sklearn.preprocessing import PolynomialFeatures
a=[[2,3]]
pf=PolynomialFeatures(degree=2)
print(pf.fit_transform(a))
pf=PolynomialFeatures(degree=2,include_bias=False)
print(pf.fit_transform(a))
pf=PolynomialFeatures(degree=2,interaction_only=True)
print(pf.fit_transform(a))
得到结果如下:
如果是c=[[a],[b]]这种形式,生成的多项式就没有ab交叉项了,只有[[1,a,a^2], [1,b,b^2]] 。
c=[[2],[3]]
print(pf.fit_transform(c))
如何实现多项式回归
多项式回归是多元线性回归的一个特例
所以其本质是一个求解多元线性方程组的问题:
或者:
这里无论是还是,其实本质都一样.
把b处理一下写成的形式带入,以矩阵的形式更容易理解:
左边是关于x的矩阵,右边是关于w系数的矩阵,每一个系数w都对应x中的一列。而PolynomialFeatures就是用来生成关于x的矩阵的。
然后再用LinearRegression学习,获得相应的w。
说的再简单一点,比如现在有横坐标[[a], [b], [c]], 纵坐标[[x], [y], [z]],通过PolynomialFeatures(degree=2)即生成二次多项式矩阵,degree是多少,就是几次。
其中每一列都会对应生成一个系数,很直观的理解,如果是一维的,LinearRegression就会学得一次项系数,二维的就会学得二次项系数,一次类推。所以最后LinearRegression模型中的coef_参数返回的是一个关于系数的list。
代码实现:
首先创建数据并且添加噪音:
import numpy as np
import matplotlib.pyplot as plt
from sklearn.preprocessing import PolynomialFeatures
from sklearn.linear_model import LinearRegression
X = np.sort(3 * np.random.rand(40, 1), axis=0)
y = np.sin(X).ravel()
# 噪音
y[::5] += 2.5 * (0.5 - np.random.rand(8))
plt.plot(X,y,'b^')
plt.show()
生成这样的数据:
然后实现多项式矩阵,并且训练模型,查看训练出来的系数w和截距b:
lr = LinearRegression()
pf=PolynomialFeatures(degree=2)
lr.fit(pf.fit_transform(X), y)
print(lr.coef_)
print(lr.intercept_)
结果如下:
正好三个系数,分别对应常数项,一次项,二次项。
然后绘制图像:
xx = np.linspace(0, 5, 100) #生成密集点
xx2 = pf.transform(xx[:, np.newaxis]) #转换格式
yy2 = lr.predict(xx2)
plt.plot(xx ,yy2,c='r')
生成图像,由于二次项系数为负,所以这个二次函数先增后减。:
正规方程验证
其实,想要获得w系数,更直接的方式是利用正规方程:
想要得到这个公式也非常简单, 已知我们要求解,两边同时乘上得:
将左边的除到右边即可
python代码验证:
w=np.linalg.inv(X.T@X)@X.T@y
print(w)
这里X是经过PolynomialFeatures处理之后的矩阵,对应之前代码中的XX2。
np.linalg.inv()表示逆矩阵,X.T就是转置,@等价于.dot()操作,可以获得结果如下:
和之前求的w和b一模一样,说明结果完全正确!