机器学习系列笔记七:多项式回归[上]
文章目录
Intro
相比较线性回归所拟合的直线,多线性回归可以拟合的曲线更具有表达能力,能够有效提高模型的精度。区别如下图所示。
多项式回归在回归分析中很重要,因为任意一个函数至少在一个较小的范围内都可以用多项式任意逼近,因此在比较复杂的实际问题中,有时不问y与诸元素的确切关系如何,而用回归分析进行分析运算。
比如,对房屋成交信息建立多项式回归方程,并依据回归方程对房屋价格进行预测 。
多项式回归在机器学习算法上并没有什么新的地方,完全是使用线性回归的思路,它的关键在于:
-
为原来的数据样本添加合理的新的特征
-
这些新的特征是源于原有特征的
比如原有特征为X,则通过将 X 2 X^2 X2 作为新的特征
在PCA中是想办法将数据降维,而多项式回归则相反,是想办法将数据维度提升。在升维后,原始数据集具有了一下新的特征,可以使得线性回归算法可以更好的拟合这个高维度的数据。
简单实现
其实要理解多项式回归的思路还是得通过例子来。
首先我们模拟一个数据集
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)
plt.scatter(X,y)
plt.title("original data")
plt.show()
然后我们先使用线性回归模型来实现拟合
from sklearn.linear_model import LinearRegression
lin_reg = LinearRegression()
lin_reg.fit(X,y)
LinearRegression(copy_X=True, fit_intercept=True, n_jobs=None, normalize=False)
y_predict = lin_reg.predict(X)
plt.scatter(x,y)
plt.plot(X,y_predict,'r')
plt.show()
显然想过是不够好的,我们采用多项式回归的思路,人为的为该样本添加一个特征
(X**2).shape # 一个新的特征
(100, 1)
X_new = np.hstack([X,X**2]) # 将原来的样本横向展开,添加新的特征X**2
X_new.shape
(100, 2)
使用拓展了特征空间的新的数据集进行线性回归
lin_reg2 = LinearRegression()
lin_reg2.fit(X_new,y)
y_predict_new = lin_reg2.predict(X_new)
plt.scatter(x,y)
plt.plot(X,y_predict_new,'r')
plt.show()
可以看到生成了一大堆直线,很乱,这是因为我们的x不是顺序递增的,可能是3,2,6,1之类的顺序
我们可以通过对x进行排序来平滑曲线
plt.scatter(x,y)
plt.plot(np.sort(x),y_predict_new[np.argsort(x)],'r')
plt.show()
查看模型训练出的系数
lin_reg2.coef_
array([1.08034107, 0.4707525 ])
与之前生成的多项式中系数基本相似
lin_reg2.intercept_
2.1819245672677283
与之前生成的多项式截距基本相似
scikit-learn中的多项式回归和Pipeline
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)
scikit-leran将数据升维的过程封装到了preprocessing
包中的PolynomialFeatures
类中
from sklearn.preprocessing import PolynomialFeatures
在其构造函数中有一个重要参数degree
- 表示需要为原本的数据集添加相应的
degree次幂
相应的特征
poly = PolynomialFeatures(degree=2)
poly.fit(X)
X2 = poly.transform(X)
X2.shape
(100, 3)
X2[:5]
array([[ 1. , 1.52415023, 2.32303391],
[ 1. , 2.60525966, 6.7873779 ],
[ 1. , -2.58263766, 6.67001727],
[ 1. , -0.09536093, 0.00909371],
[ 1. , 2.20542548, 4.86390153]])
X[:5]
array([[ 1.52415023],
[ 2.60525966],
[-2.58263766],
[-0.09536093],
[ 2.20542548]])
可以看到X2的第一列表示X的特征的0次幂,第二列表示1次幂,第三列表示2次幂(degree=2)
from sklearn.linear_model import LinearRegression
lin_reg = LinearRegression()
lin_reg.fit(X2,y)
y_predict = lin_reg.predict(X2)
plt.scatter(x,y)
plt.plot(np.sort(x),y_predict[np.argsort(x)],'r')
plt.show()
关于PolynomialFeatures
我们尝试设置X具有两个特征
X = np