机器学习 | 目录
机器学习 | 回归评估指标
监督学习 | 线性回归 之多元线性回归原理及Sklearn实现
监督学习 | 线性回归 之正则线性模型原理及Sklearn实现
监督学习 | 线性分类 之Logistic回归原理及Sklearn实现
对于非线性数据,也可以用线性模型来拟合。一个简单的方法就是将每个特征的幂次方添加为一个新特征,然后在这个拓展多的特征集上训练线性模型。这种方法被称为多项式回归
。
回归模型
(1) y i = β 0 + β 1 x i + β 2 x i 2 + ε i y_i=\beta_0+\beta_1x_i+\beta_2x_i^2+\varepsilon_i \tag{1} yi=β0+β1xi+β2xi2+εi(1)
称为一元二阶
(或一元二次)多项式模型,其中, i = 1 , 2 , ⋯   , n i=1,2,\cdots,n i=1,2,⋯,n。
为了反应回归系数所对应的自变量次数,我们通常将多项式回归模型中的系数表示称下面模型中的情形:
(2) y i = β 0 + β 1 x i + β 11 x i 2 + ε i y_i=\beta_0+\beta_1x_i+\beta_{11}x_i^2+\varepsilon_i \tag{2} yi=β0+β1xi+β11xi2+εi(2)
模型式 (2) 的回归函数 y i = β 0 + β 1 x i + β 11 x i 2 y_i=\beta_0+\beta_1x_i+\beta_{11}x_i^2 yi=β0+β1xi+β11xi2 是一条抛物线,通常称称为二项式回归函数
。回归系数 β 1 \beta_1 β1 称为线性效应系数
, β 11 \beta_{11} β11 为二次效应系数
。
相应地,回归模型
(3) y i = β 0 + β 1 x i + β 11 x i 2 + β 111 ε i y_i=\beta_0+\beta_1x_i+\beta_{11}x_i^2+\beta_{111}\varepsilon_i \tag{3} yi=β0+β1xi+β11xi2+β111εi(3)
称为一元三次多项式模型
。[1]
对于非线性的数据,我们将利用 sklearn.preprocessing.PolynomialFeatures 将非线性数据通过多项式变换为线性数据,然后就可以重复 监督学习 | 线性回归 之多元线性回归原理及Sklearn实现 中的方法完成回归。
PolynomialFeatures(degree=2, interaction_only=False, include_bias=True, order=‘C’)
参数设置:
degree: integer
interaction_only: boolean, default = False
include_bias: boolean
order: str in {‘C’, ‘F’}, default ‘C’
方法:
powers_: array, shape (n_output_features, n_input_features)
n_input_features_: int
n_output_features_: int
首先基于二项式回归函数制造一些非线性数据(并添加随机噪声)。
import numpy as np
import numpy.random as rnd
import matplotlib.pyplot as plt
np.random.seed(42)
m = 100
X = 6 * np.random.rand(m, 1) - 3
y = 0.5 * X**2 + X + 2 + np.random.randn(m, 1)
plt.plot(X, y, "b.")
plt.xlabel("$x_1$", fontsize=18)
plt.ylabel("$y$", rotation=0, fontsize=18)
plt.axis([-3, 3, 0, 10])
plt.show()
显然,直线永远不可能拟合这个数据。所以我们使用 PolynomialFeatures 类来对训练数据进行转换,将每个特征的平方(二次多项式)作为新特征加入训练集(这个例子中只有一个特征):
from sklearn.preprocessing import PolynomialFeatures
poly_features = PolynomialFeatures(degree=2, include_bias=False)
X_poly = poly_features.fit_transform(X)
X[0]
array([-0.75275929])
X_poly[0]
array([-0.75275929, 0.56664654])
X_poly 现在包含原本的特征 X 和该特征的平方。现在对这个拓展后的特征集匹配一个 LinearRegression 模型。
from sklearn.linear_model import LinearRegression
lin_reg = LinearRegression()
lin_reg.fit(X_poly, y)
lin_reg.intercept_, lin_reg.coef_
(array([1.78134581]), array([[0.93366893, 0.56456263]]))
还不错,模型预估 y ^ = 0.56 x 1 2 + 0.93 x 1 1 + 1.78 \hat{y}=0.56x_1^2+0.93x_11+1.78 y^=0.56x12+0.93x11+1.78,而实际上原来的函数是 y = 0.5 x 1 2 + 1.0 x 1 + 2.0 + 高 斯 噪 声 y=0.5x_1^2+1.0x_1+2.0+高斯噪声 y=0.5x12+1.0x1+2.0+高斯噪声 。
注意,当存在多个特征时,多项式回归能够发现特征和特征之间的关系(纯线性回归模型做不到这一点)。这是因为 PolynomialFeatures 会在给定的多项式阶数下,添加所有特征组合。这是因为 PolynomialFeatures 会在给定的多项式阶数下,添加所有特征组合(interaction_only = False)。例如,有两个特征 a 和 b ,阶数 degree=3,PolynomialFeatures 不会只添加特征 a 2 , a 3 , b 2 和 b 3 a^2,a^3,b^2和b^3 a2,a3,b2和b3,还会添加组合 a b , a 2 b ab,a^2b ab,a2b 以及 a b 2 ab^2 ab2。[2]
X_new=np.linspace(-3, 3, 100).reshape(100, 1)
X_new_poly = poly_features.transform(X_new)
y_new = lin_reg.predict(X_new_poly)
plt.plot(X, y, "b.")
plt.plot(X_new, y_new, "r-", linewidth=2, label="Predictions")
plt.xlabel("$x_1$", fontsize=18)
plt.ylabel("$y$", rotation=0, fontsize=18)
plt.legend(loc="upper left", fontsize=14)
plt.axis([-3, 3, 0, 10])
plt.show()
PolynomialFeatures(degree=d) 可以将一个包含 n n n 个特征的数组为包含 n + d d ! n ! \frac{n+d}{d!n!} d!n!n+d 个特征的数组。
[1] 何晓群. 应用回归分析(R语言版)[M]. 北京: 电子工业出版社, 2018: 203-204.
[2] Aurelien Geron, 王静源, 贾玮, 边蕤, 邱俊涛. 机器学习实战:基于 Scikit-Learn 和 TensorFlow[M]. 北京: 机械工业出版社, 2018: 115-117.