问题引入

  • 线性模型:minwXwy22\mathop{min}_{w} {\Vert X w-y \Vert_2}^2
  • 岭回归: minwXwy22+αw22\mathop{min}_{w} {\Vert X w - y \Vert _2}^2 + {\alpha \Vert w \Vert_2}^2
  • lasso:minwXwy22+αw1\mathop{min}_{w} {\Vert X w - y \Vert _2}^2 + {\alpha \Vert w \Vert_1}

在线性回归中,对于普通最小二乘的系数估计问题,其依赖于模型各项的相互独立性。当各项是相关的,且设计矩阵 X 的各列近似线性相关,那么,设计矩阵会趋向于奇异矩阵,这会导致最小二乘估计对于随机误差非常敏感,产生很大的方差。例如,在没有实验设计的情况下收集到的数据,这种多重共线性(multicollinearity) 的情况可能真的会出现。因此,是否可以删除掉一些相关性较强的变量呢?如果p个变量之间具有较强的相关性,那么又应当删除哪几个是比较好的呢?

岭回归

思想

岭回归通过对系数的大小施加惩罚来解决普通最小二乘法的一些问题。 岭系数最小化一个带罚项的残差平方和,

minwXwy22+αw22\mathop{min}_{w} {\Vert X w - y \Vert _2}^2 + {\alpha \Vert w \Vert_2}^2

其中, α0\alpha \geq 0 是控制收缩量复杂性的参数: α\alpha的值越大,收缩量越大,因此系数对共线性变得更加鲁棒。

在不断增大惩罚函数系数α\alpha的过程中,画下估计参数(α\alpha)的变化情况,即为岭迹。通过岭迹的形状来判断我们是否要剔除掉该参数(例如:岭迹波动很大,说明该变量参数有共线性)。

步骤

  1. 对数据做标准化,从而方便以后对(α\alpha)的岭迹的比较,否则不同变量的参数大小没有比较性。
  2. 构建惩罚函数,对不同的 α\alpha ,画出岭迹图。
  3. 根据岭迹图,选择剔除掉哪些变量。

公式

目标函数

L=minwXwy22+αw22L = \mathop{min}_{w} {\Vert X w - y \Vert _2}^2 + {\alpha \Vert w \Vert_2}^2

L=(XwY)T(XwY)+αwTwL = {( X w - Y )^T(X w - Y) } + {\alpha w^T w}

ww 求导:

Lw=2XT(XwY)+2αw=0\frac{\partial L}{\partial w} = 2X^T(X w - Y) + 2\alpha w = 0

得到:

w=(XTX+αI)1XTYw = (X^TX + \alpha I)^{-1}X^TY

Plot Ridge coefficients as a function of the regularization

import numpy as np
import matplotlib.pyplot as plt
from sklearn.linear_model import Ridge

# X is the 10x10 Hilbert matrix
X = 1. / (np.arange(1, 11) + np.arange(0, 10)[:, np.newaxis])
y = np.ones(10)

# #############################################################################
# Compute paths

n_alphas = 200
alphas = np.logspace(-10, -2, n_alphas)

coefs = []
for a in alphas:
ridge = Ridge(alpha=a, fit_intercept=False)
ridge.fit(X, y)
coefs.append(ridge.coef_)

# #############################################################################
# Display results

ax = plt.gca()

ax.plot(alphas, coefs)
ax.set_xscale('log')
ax.set_xlim(ax.get_xlim()[::-1]) # reverse axis
plt.xlabel('alpha')
plt.ylabel('weights')
plt.title('Ridge coefficients as a function of the regularization')
plt.axis('tight')
plt.show()

result