1. 过拟合问题
在前一篇文章(《再读线性回归》)中,我回顾了线性回归的问题和基本的解决思路。线性回归主要通过构建含参数的多项式方程 f θ ( x ) f_{\theta}(x) fθ(x) 来对新的样本进行预测。 为了构建这样的方程,线性回归算法中利用梯度下降更新参数组合 θ \theta θ来不断减少代价函数 J ( θ ) J(\theta) J(θ) 的值,直至达到最优。
不可否认的是,虽然线性回归模型在很多领域的应用都很强势,但是它也有一些自身固有的缺点,如参数初始化问题,参数项过多问题,过拟合问题等,科学家们也在原有的线性回归模型上做了一些改进,这里主要讨论一下过拟合问题(Overfiting)。
过拟合的一般理解是在训练集上拟合的很好,但是在测试集上预测结果很差。总的来讲,过拟合问题反映出模型的泛化能力的不足。这个泛化能力对机器学习模型来讲可是很要命的,要知道机器学习就是让机器去自助探测未知世界的,泛化能力的强弱决定了模型的取舍。换句话说,我们更希望提升出来的模型在测试集上的性能(泛化能力),而不是一味的拟合现有的训练集。
一般来讲,模型过拟合的本质原因可以归咎为模型过于复杂,如上图所示,(a) 表示了一个正常的线性模型(可能是简单的
y
=
θ
0
+
θ
1
x
y=\theta_0+\theta_1x
y=θ0+θ1x),(b) 表示了一个复杂的过拟合模型
y
=
θ
0
+
θ
1
x
+
θ
2
x
2
+
.
.
.
+
θ
n
x
n
y=\theta_0 + \theta_1x+\theta_2x^2+...+\theta_nx^n
y=θ0+θ1x+θ2x2+...+θnxn。直观的来讲,当新的点加进来时,我们利用 (a) 中的模型预测其
y
y
y 值会更加的准确。而使用过拟合预测的趋势明显不对,其效果甚至还不如 c) 中欠拟合的参数模型。
2. 正则化
正则化(Regularization) 是缓解过拟合现象的通用解决方案。它的做法就是在正常代价函数 J ( θ ) J(\theta) J(θ) 的后方添加一个关于参数 θ \theta θ 的惩罚项。简单的来讲,正则化之后的代价函数可以写成,
J ( θ ) = 1 2 m [ ∑ i = 1 m ( f θ ( x ( i ) ) − y ( i ) ) 2 + λ ∑ j = 1 n ( θ j ) 2 ] J(\theta) = \frac{1}{2m} [\sum_{i=1}^{m}(f_{\theta}(x^{(i)})-y^{(i)})^2 + \lambda \sum_{j=1}^{n}(\theta_j)^2] J(θ)=2m1[i=1∑m(fθ(x(i))−y(i))2+λj=1∑n(θj)2]
这与我们之前的代价函数仅仅多了一个末尾的一个 λ ∑ j = 1 n ( θ j ) 2 \lambda \sum_{j=1}^{n}(\theta_j)^2 λ∑j=1n(θj)2,这个多出来的乘法项就是用来缓解过拟合现象的。试想一下前面的正则化参数 λ \lambda λ 取值非常大,如100,1000,那么更新参数的结果往往会导致较小的 θ j \theta_j θj 的取值,这样较小的 θ j \theta_j θj 值就会让该参数项对整体的回归函数的影响变得微弱。一个极端的例子,当除 θ 0 \theta_0 θ0 以外的参数全都为 0 后,我们的回归函数就变成了 f θ ( x ) = θ f_{\theta}(x)=\theta fθ(x)=θ。这就是一条直线。
总而言之,正则化通过添加额外惩罚项的方式使参数的分布变得稀疏(更接近于零),进而促使模型变得更加简单。正则化就是用这种方法来缓解过拟合带来的危害。针对于正则化的代价函数,我们按如下方式更新参数向量 θ \theta θ,
θ j = θ j − α m [ ∑ i = 1 m ( f θ ( x ( i ) ) − y ( i ) ) x j ( i ) + λ θ j ] , j ∈ [ 1 , n ] \theta_j = \theta_j - \frac{\alpha}{m}[\sum_{i=1}^{m}(f_{\theta}(x^{(i)})-y^{(i)})x^{(i)}_j + \lambda\theta_j],j\in [1,n] θj=θj−mα[i=1∑m(fθ(x(i))−y(i))xj(i)+λθj],j∈[1,n]
我们化简一下,得到如下的式子,
θ j = ( 1 − α m ) θ j − α m ∑ i = 1 m ( f θ ( x ( i ) ) − y ( i ) ) x j ( i ) , j ∈ [ 1 , n ] \theta_j= (1-\frac{\alpha}{m})\theta_j - \frac{\alpha}{m}\sum_{i=1}^{m}(f_{\theta}(x^{(i)})-y^{(i)})x^{(i)}_j,j\in [1,n] θj=(1−mα)θj−mαi=1∑m(fθ(x(i))−y(i))xj(i),j∈[1,n]
根据最小二乘法,让所有的偏导数均等于零。我们可以直接求出最终参数向量为:
θ = ( X T X + λ ( 0 1 1 . . . 1 ) ) − 1 X T Y \theta = (X^TX+\lambda \begin{pmatrix} 0 \\ & 1 \\ & & 1 \\ & & & ...\\ & & & & 1\\ \end{pmatrix} )^{-1}X^TY θ=(XTX+λ⎝⎜⎜⎜⎜⎛011...1⎠⎟⎟⎟⎟⎞)−1XTY
注意,上式中的的 X X X 和 Y Y Y 分别表示特征矩阵( m × n m\times n m×n 维)和标签矩阵( m × 1 m \times 1 m×1 维),这个可能与有些文章讲解的公式不一样,这是因为我们没有对 θ 0 \theta_0 θ0 进行正则化。如果对 θ 0 \theta_0 θ0 也正则化,那么相应的 θ \theta θ 可写成,
θ = ( X T X + λ I ) − 1 X T Y \theta = (X^TX+\lambda I)^{-1}X^TY θ=(XTX+λI)−1XTY
这里的 I I I 表示 ( n + 1 ) (n+1) (n+1) 的单位矩阵。
3. 几种正则化方法
目前为止,提到的比较多的正则方法就是 L 1 L1 L1 和 L 2 L2 L2 正则化了,使用这两种正则化的回归方法分别称为 套索回归(Lasso Regression) 和 岭回归(Ridge Regression)。他们的代价函数分别为,
L 1 正 则 化 : J ( θ ) = 1 2 m ∑ i = 1 m ( f θ ( x ( i ) ) − y ( i ) ) 2 + λ ∣ ∣ θ ∣ ∣ 1 L1正则化:J(\theta) = \frac{1}{2m} \sum_{i=1}^{m}(f_{\theta}(x^{(i)})-y^{(i)})^2 + \lambda ||\theta||_1 L1正则化:J(θ)=2m1i=1∑m(fθ(x(i))−y(i))2+λ∣∣θ∣∣1
L 2 正 则 化 : J ( θ ) = 1 2 m ∑ i = 1 m ( f θ ( x ( i ) ) − y ( i ) ) 2 + λ ∣ ∣ θ ∣ ∣ 2 2 L2正则化:J(\theta) = \frac{1}{2m} \sum_{i=1}^{m}(f_{\theta}(x^{(i)})-y^{(i)})^2 + \lambda ||\theta||_2^2 L2正则化:J(θ)=2m1i=1∑m(fθ(x(i))−y(i))2+λ∣∣θ∣∣22
上式中的 ∣ ∣ θ ∣ ∣ 1 ||\theta||_1 ∣∣θ∣∣1 和 ∣ ∣ θ ∣ ∣ 2 2 ||\theta||_2^2 ∣∣θ∣∣22 表示参数向量的一维范式和二维范式,直观的理解就是一维范式就是 θ \theta θ 中项的绝对值相加,二维范式就是 θ \theta θ 中项的平方和相加。类推到 p p p 维范式有,
∣ ∣ θ ∣ ∣ p p = 1 p × ( ∑ i = 0 m ∣ θ ∣ p ) , p = 1 , 2 , . . . ||\theta||_p^p = \frac{1}{p} \times (\sum_{i=0}^{m} |\theta|^p),p=1,2,... ∣∣θ∣∣pp=p1×(i=0∑m∣θ∣p),p=1,2,...
一般来讲, L 1 L1 L1 正则化要比 L 2 L2 L2正则化更能得到一个稀疏的参数解(即参数为极小值且均接近于0)。下面两幅图展示了等高线图中两种正则化的过程。由图可知, L 1 L1 L1 正则化找到的最优解往往是坐标轴上的点,这样 θ 0 \theta_0 θ0 就很有可能等于 0。 L 2 L2 L2 正则化找到的最优解往往是切点, θ 0 \theta_0 θ0 和 θ 1 \theta_1 θ1 更难等于0。这个只是一个简单的演示。
因此,记住 L 1 L1 L1 正则化要比 L 2 L2 L2正则化更能得到一个稀疏的参数解 就对了。
有的人甚至提出了 L 1 L1 L1 和 L 2 L2 L2 的综合正则化方法(用这种综合的正则化方法构建的线性回归模型我们称之为 弹性网络(Elastic Net))。简单的说,综合的正则化方法在计算代价的时候添加了 L 1 L1 L1 和 L 2 L2 L2 的两个惩罚项,如下所示,
J ( θ ) = 1 2 m ∑ i = 1 m ( f θ ( x ( i ) ) − y ( i ) ) 2 + λ ( L 1 r a t i o ∣ ∣ θ ∣ ∣ 1 + ( 1 − L 1 r a t i o ) ∣ ∣ θ ∣ ∣ 2 2 ) J(\theta) = \frac{1}{2m} \sum_{i=1}^{m}(f_{\theta}(x^{(i)})-y^{(i)})^2 + \lambda ( L1_{ratio} ||\theta||_1 + (1 - L1_{ratio}) ||\theta||_2^2) J(θ)=2m1i=1∑m(fθ(x(i))−y(i))2+λ(L1ratio∣∣θ∣∣1+(1−L1ratio)∣∣θ∣∣22)
上式中的 L 1 r a t i o L1_{ratio} L1ratio 参数表示使用 L 1 L1 L1 进行正则化的惩罚项所占的比例。同理, ( 1 − L 1 r a t i o ) (1-L1_{ratio}) (1−L1ratio) 表示使用 L 2 L2 L2 进行正则化的惩罚项所占的比例。可以想见,这个比例 L 1 r a t i o L1_{ratio} L1ratio 会极大的影响着回归结果。
4. 总结
需要说明的是,即使使用了不同的正则化方法,过拟合现象只是比之前稍稍 缓解 了,并没有被完全解除。另外,线性回归的另一个问题就是参数项过多,当特征数量巨大时,训练一个线性回归模型耗费巨大。
在图像识别中,一张 500 × 500 500 \times 500 500×500 像素的图片,构造出来的线性回归模型会有有 750,000 个参数项(即 500 × 500 × 3 500\times500\times3 500×500×3),这个计算量将十分巨大(特别涉及到矩阵计算时)。
f θ ( x ) = θ 0 + θ 1 x 1 + θ 2 x 2 + . . . + θ 750 , 000 x 750 , 000 f_{\theta}(x) = \theta_0 + \theta_1x_1 + \theta_2x_2 + ... + \theta_{750,000}x_{750,000} fθ(x)=θ0+θ1x1+θ2x2+...+θ750,000x750,000
并且,一旦我们的训练样本个数 m < 750 , 000 m<750,000 m<750,000 时,极有可能产生过拟合。这么一来,处理起来更加的不方便。我们需要一种新的算法来解决图像的问题,这就是 神经网络(Neural Network)。随着硬件技术的发展,神经网络逐渐发挥出自己的优势,在图形图像处理,自然语言处理领域大放异彩,我后续会继续介绍。
附: 用 sk-learn 包实现不同的线性回归模型
在 sk-learn 包里1,也提供了正则化的接口,相关使用代码为,
from sklearn.linear_model import Ridge
from sklearn.linear_model import Lasso
from sklearn.linear_model import ElasticNet
def test_norm(train_x, train_y):
# 使用 L1 正则化建立线性回归模型
reg_l1 = Lasso(alpha=1.0) # 正则化参数为 1.0
reg_l1.fit(train_x, train_y)
# 使用 L2 正则化建立线性回归模型
reg_l2 = Ridge(aplha=2.5) # 正则化参数为 2.5
reg_l2.fit(train_x, train_y)
# 同时使用 L1 和 L2 正则化建立线性回归模型
reg_l2 = ElasticNet(aplha=1.0, l1_ratio=0.5) # 正则化参数为 1.0,正则化比例为 1:1
reg_l2.fit(train_x, train_y)
...