多项式回归
机器学习中一种常见的模式,是使用线性模型训练数据的非线性函数。这种方法保持了一般快速的线性方法的性能,同时允许它们适应更广泛的数据范围。
例如,可以通过构造系数的 polynomial features 来扩展一个简单的线性回归。在标准线性回归的情况下,你可能有一个类似于二维数据的模型:
如果我们想把抛物面拟合成数据而不是平面,我们可以结合二阶多项式的特征,使模型看起来像这样:
观察到这 还是一个线性模型 (这有时候是令人惊讶的): 看到这个,想象创造一个新的变量
有了这些重新标记的数据,我们可以将问题写成
我们看到,所得的 polynomial regression 与我们上文所述线性模型是同一类(即关于 w 是线性的),因此可以用同样的方法解决。通过用这些基函数建立的高维空间中的线性拟合,该模型具有灵活性,可以适应更广泛的数据范围。
这里是一个例子,使用不同程度的多项式特征将这个想法应用于一维数据:
../_images/sphx_glr_plot_polynomial_interpolation_0011.png
这个图是使用 PolynomialFeatures 预创建。该预处理器将输入数据矩阵转换为给定度的新数据矩阵。使用方法如下:
>>>
>>> from sklearn.preprocessing import PolynomialFeatures
>>> import numpy as np
>>> X = np.arange(6).reshape(3, 2)
>>> X
array([[0, 1],
[2, 3],
[4, 5]])
>>> poly = PolynomialFeatures(degree=2)
>>> poly.fit_transform(X)
array([[ 1., 0., 1., 0., 0., 1.],
[ 1., 2., 3., 4., 6., 9.],
[ 1., 4., 5., 16., 20., 25.]])
X 的特征已经从 [x_1, x_2] 转换到 [1, x_1, x_2, x_1^2, x_1 x_2, x_2^2], 并且现在可以用在任何线性模型。
这种预处理可以通过 Pipeline 工具进行简化。可以创建一个表示简单多项式回归的单个对象,使用方法如下所示:
>>> from sklearn.preprocessing import PolynomialFeatures
>>> from sklearn.linear_model import LinearRegression
>>> from sklearn.pipeline import Pipeline
>>> import numpy as np
>>> model = Pipeline([('poly', PolynomialFeatures(degree=3)),
... ('linear', LinearRegression(fit_intercept=False))])
>>> # fit to an order-3 polynomial data
>>> x = np.arange(5)
>>> y = 3 - 2 * x + x ** 2 - x ** 3
>>> model = model.fit(x[:, np.newaxis], y)
>>> model.named_steps['linear'].coef_
array([ 3., -2., 1., -1.])
利用多项式特征训练的线性模型能够准确地恢复输入多项式系数。
在某些情况下,没有必要包含任何单个特征的更高的幂,只需要相乘最多 d 个不同的特征即可,所谓 interaction features(交互特征) 。这些可通过设定 PolynomialFeatures 的 interaction_only=True 得到。
例如,当处理布尔属性,对于所有 n x_i^n = x_i ,因此是无用的;但 x_i x_j 代表两布尔结合。这样我们就可以用线性分类器解决异或问题:
>>>
>>> from sklearn.linear_model import Perceptron
>>> from sklearn.preprocessing import PolynomialFeatures
>>> import numpy as np
>>> X = np.array([[0, 0], [0, 1], [1, 0], [1, 1]])
>>> y = X[:, 0] ^ X[:, 1]
>>> y
array([0, 1, 1, 0])
>>> X = PolynomialFeatures(interaction_only=True).fit_transform(X).astype(int)
>>> X
array([[1, 0, 0, 0],
[1, 0, 1, 0],
[1, 1, 0, 0],
[1, 1, 1, 1]])
>>> clf = Perceptron(fit_intercept=False, max_iter=10, tol=None,
... shuffle=False).fit(X, y)
分类器的 “predictions” 是完美的:
>>>
>>> clf.predict(X)
array([0, 1, 1, 0])
>>> clf.score(X, y)
1.0