python - 岭回归 : Scikit-learn vs. 直接计算与 alpha > 0 不匹配

标签 python scikit-learn linear-regression

在 Ridge 回归中,我们使用 L2 正则化解决 Ax=b。直接计算由下式给出:

x = (ATA + alpha * I)-1ATb

我查看了 scikit-learn 代码,它们确实实现了相同的计算。但是,我似乎无法为 alpha > 0

获得相同的结果

重现这一点的最少代码。

import numpy as np
A = np.asmatrix(np.c_[np.ones((10,1)),np.random.rand(10,3)])
b = np.asmatrix(np.random.rand(10,1))
I = np.identity(A.shape[1])
alpha = 1
x = np.linalg.inv(A.T*A + alpha * I)*A.T*b
print(x.T)
>>> [[ 0.37371021  0.19558433  0.06065241  0.17030177]]

from sklearn.linear_model import Ridge
model = Ridge(alpha = alpha).fit(A[:,1:],b)
print(np.c_[model.intercept_, model.coef_])
>>> [[ 0.61241566  0.02727579 -0.06363385  0.05303027]]

关于我可以做些什么来解决这个差异有什么建议吗?

最佳答案

此修改似乎对直接版本和 numpy 版本产生相同的结果:

import numpy as np
A = np.asmatrix(np.random.rand(10,3))
b = np.asmatrix(np.random.rand(10,1))
I = np.identity(A.shape[1])
alpha = 1
x = np.linalg.inv(A.T*A + alpha * I)*A.T*b
print (x.T)


from sklearn.linear_model import Ridge
model = Ridge(alpha = alpha, tol=0.1, fit_intercept=False).fit(A ,b)

print model.coef_
print model.intercept_

看起来差异的主要原因是 Ridge 类具有参数 fit_intercept=True(继承自 _BaseRidge 类)( source )

这是在将矩阵传递给 _solve_cholesky 函数之前应用数据居中过程。

这是 ridge.py 中执行此操作的行

        X, y, X_mean, y_mean, X_std = self._center_data(
        X, y, self.fit_intercept, self.normalize, self.copy_X,
        sample_weight=sample_weight)

此外,您似乎试图通过添加 1 的列来隐式说明截距。如您所见,如果您指定 fit_intercept=False

,则没有必要这样做

附录:Ridge 类是否实际实现了直接公式?

这取决于求解器参数的选择。

实际上,如果您没有在 Ridge 中指定 solver 参数,它默认采用 solver='auto'(内部求助到 solver='cholesky')。这应该等同于直接计算。

严格来说,_solve_cholesky 使用 numpy.linalg.solve 而不是 numpy.inv。但是可以很容易地检查出

np.linalg.solve(A.T*A + alpha * I, A.T*b)

产量与

相同
np.linalg.inv(A.T*A + alpha * I)*A.T*b

关于python - 岭回归 : Scikit-learn vs. 直接计算与 alpha > 0 不匹配,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/38562701/

相关文章:

python - sklearn 中给定折叠分割的交叉验证

python - 在 python 中从 cURL GET 请求保存 .zip 文件

python - 名称错误 : name 'List' is not defined

python - 在朴素贝叶斯中获取特征重要性

python - 从最佳拟合线找出斜率趋势

scipy - 我可以使用什么算法来识别此散点图中的线?

python - Python 中使用随机梯度下降的岭回归

python - 如何优雅地检查对象/实例/变量的存在,如果它存在于python中,同时将其分配给变量?

python - scikit-learn:转换器按名称选择列

python - 手动PCA逆变换