【问题标题】:Understanding Ridge Linear Regression in sci-kit learn了解 scikit learn 中的岭线性回归
【发布时间】:2017-03-26 06:00:10
【问题描述】:

我正在尝试了解 Ridge 回归是如何在 scikit-learn Ridge 中实现的@

岭回归具有最小化 (y - Xw)^2 + \alpha * |w|^2 的闭式解,即 (X'*X + \alpha * I)^{-1} X'y

拟合模型的截距和系数似乎与封闭形式的解决方案不同。任何想法如何在 scikit-learn 中实现岭回归?

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

# prepare dataset
boston = datasets.load_boston()
X = boston.data
y = boston.target
# add the w_0 intercept where the corresponding x_0 = 1
Xp = np.concatenate([np.ones((X.shape[0], 1)), X], axis=1)

alpha = 0.5
ridge = Ridge(fit_intercept=True, alpha=alpha)
ridge.fit(X, y)

# 1. intercept and coef of the fit model
print np.array([ridge.intercept_] + list(ridge.coef_))
# output:
# array([  3.34288615e+01,  -1.04941233e-01,   4.70136803e-02,
     2.52527006e-03,   2.61395134e+00,  -1.34372897e+01,
     3.83587282e+00,  -3.09303986e-03,  -1.41150803e+00,
     2.95533512e-01,  -1.26816221e-02,  -9.05375752e-01,
     9.61814775e-03,  -5.30553855e-01])

# 2. the closed form solution
print np.linalg.inv(Xp.T.dot(Xp) + alpha * np.eye(Xp.shape[1])).dot(Xp.T).dot(y)
# output:
# array([  2.17772079e+01,  -1.00258044e-01,   4.76559911e-02,
    -6.63573226e-04,   2.68040479e+00,  -9.55123875e+00,
     4.55214996e+00,  -4.67446118e-03,  -1.25507957e+00,
     2.52066137e-01,  -1.15766049e-02,  -7.26125030e-01,
     1.14804636e-02,  -4.92130481e-01])

【问题讨论】:

  • 作为 lejlot 答案的补充:有多个求解器可用。 solver='cholesky' 正是使用这种封闭形式的解决方案,如 here 所示。 (如答案中所述:差异隐藏在其他地方)

标签: machine-learning scikit-learn linear-regression


【解决方案1】:

解析解是正确的

(X' X + α I)-1 X'y,

但问题是 Xy 是什么。其实有两种不同的解释:

  1. 在您的分析计算中,您实际上使用的是 Xp,其中在 X 前添加了一列 1(用于拦截),并使用原始的 y。这就是您要输入上述等式的内容。

  2. 在 sklearn 中,解释是不同的。首先 yn 通过减去其均值(即截距)进行归一化。然后,对Xyn进行计算。

很清楚为什么您认为您的解释是正确的,因为在 OLS 中没有区别。但是,当您添加岭惩罚时,您的解释也会惩罚第一列的系数,这没有多大意义。

如果您执行以下操作

alpha = 0.5
ridge = Ridge(fit_intercept=True, alpha=alpha)
ridge.fit(X, y - np.mean(y))
# 1. intercept and coef of the fit model
print np.array([ridge.intercept_] + list(ridge.coef_))


Xp = Xp - np.mean(Xp, axis=0)
# 2. the closed form solution
print np.linalg.inv(Xp.T.dot(Xp) + alpha * np.eye(Xp.shape[1])).dot(Xp.T).dot(y)

那么你会看到同样的结果。

【讨论】:

    【解决方案2】:

    棘手的一点是拦截。您拥有的封闭形式解决方案是缺少截距,当您将一列 1 附加到数据中时,您还会在截距项上添加 L2 惩罚。 Scikit-learn 岭回归没有。

    如果你想对偏差进行 L2 惩罚,那么只需在 Xp 上调用 ridge (并在构造函数中关闭拟合偏差),你会得到:

    >>> ridge = Ridge(fit_intercept=False, alpha=alpha)
    >>> ridge.fit(Xp, y)
    >>> print np.array(list(ridge.coef_))
    [  2.17772079e+01  -1.00258044e-01   4.76559911e-02  -6.63573226e-04
       2.68040479e+00  -9.55123875e+00   4.55214996e+00  -4.67446118e-03
      -1.25507957e+00   2.52066137e-01  -1.15766049e-02  -7.26125030e-01
       1.14804636e-02  -4.92130481e-01]
    

    【讨论】:

    • 很抱歉回答了同样的问题,基本上 - 在您回答之前开始回答,但在您回答之后完成。很好的答案。
    • @lejlot 谢谢你的回答,但是否有一个表达式产生与 "ridge = Ridge(fit_intercept=True, alpha=alpha); ridge.fit(X, y)" 相同的结果?
    • w=(X'X + aI)^(-1)X'(y-avg y), intercept=avg y 应该产生同样的结果
    猜你喜欢
    • 2014-06-17
    • 2019-05-14
    • 2017-12-25
    • 2017-06-21
    • 2013-07-10
    • 2018-07-31
    • 2016-05-10
    • 2021-04-01
    • 2018-10-12
    相关资源
    最近更新 更多