首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >状态模型与滑雪板岭回归的失配

状态模型与滑雪板岭回归的失配
EN

Stack Overflow用户
提问于 2022-05-16 14:25:45
回答 1查看 220关注 0票数 1

我在探索山脊回归。在比较statsmodelssklearn时,我发现这两个库产生了不同的岭回归输出。下面是区别的一个简单例子

代码语言:javascript
复制
import numpy as np
import pandas as pd 
import statsmodels.api as sm
from sklearn.linear_model import Lasso, Ridge

np.random.seed(142131)

n = 500
d = pd.DataFrame()
d['A'] = np.random.normal(size=n)
d['B'] = d['A'] + np.random.normal(scale=0.25, size=n)
d['C'] = np.random.normal(size=n)
d['D'] = np.random.normal(size=n)
d['intercept'] = 1
d['Y'] = 5 - 2*d['A'] + 1*d['D'] + np.random.normal(size=n)

y = np.asarray(d['Y'])
X = np.asarray(d[['intercept', 'A', 'B', 'C', 'D']])

首先,使用sklearnRidge

代码语言:javascript
复制
ridge = Ridge(alpha=1, fit_intercept=True)
ridge.fit(X=np.asarray(d[['A', 'B', 'C', 'D', 'E', 'F', 'G', 'H']]), y=y)
ridge.intercept_, ridge.coef_

输出4.99721, -2.00968, 0.03363, -0.02145, 1.02895]

接下来,statsmodelsOLS.fit_regularized

代码语言:javascript
复制
penalty = np.array([0, 1., 1., 1., 1.])
ols = sm.OLS(y, X).fit_regularized(L1_wt=0., alpha=penalty)
ols.params

输出[5.01623, -0.69164, -0.63901, 0.00156, 0.55158]。然而,由于这两者都在实施岭回归,我希望它们是一样的。

请注意,这两种方法都不能惩罚拦截术语(已经检查过了,因为这是一个可能的潜在差异)。我也不认为这是我的错误。具体来说,我发现这两种实现为LASSO提供了相同的输出。下面是前面数据的演示

代码语言:javascript
复制
# sklearn LASSO
lasso = Lasso(alpha=0.5, fit_intercept=True)
lasso.fit(X=np.asarray(d[['A', 'B', 'C', 'D']]), y=y)
lasso.intercept_, lasso.coef_

# statsmodels LASSO
penalty = np.array([0, 0.5, 0.5, 0.5, 0.5])
ols = sm.OLS(y, X).fit_regularized(L1_wt=1., alpha=penalty)
ols.params

两者都输出[5.01465, -1.51832, 0., 0., 0.57799]

因此,我的问题是为什么岭回归的估计系数在sklearnstatsmodels的实现中有所不同?

EN

回答 1

Stack Overflow用户

回答已采纳

发布于 2022-05-16 14:25:45

在仔细研究了一下之后,我发现了为什么他们会有不同的答案。不同之处在于,sklearnRidge将惩罚项定级为alpha / n,其中n是观察的数量。statsmodels不适用这种调优参数的缩放。如果您重新调整statsmodels的惩罚级别,则可以使岭实现匹配。

使用我发布的示例,下面是如何在这两者之间进行输出匹配:

代码语言:javascript
复制
# sklearn 
# NOTE: there is no difference from above
ridge = Ridge(alpha=1, fit_intercept=True)
ridge.fit(X=np.asarray(d[['A', 'B', 'C', 'D']]), y=y)
ridge.intercept_, ridge.coef_

# statsmodels
# NOTE: going to re-scale the penalties based on n observations
n = X.shape[0]
penalty = np.array([0, 1., 1., 1., 1.]) / n  # scaling penalties
ols = sm.OLS(y, X).fit_regularized(L1_wt=0., alpha=penalty)
ols.params

现在,两者都输出[ 4.99721, -2.00968, 0.03363, -0.02145, 1.02895]

我发布了这篇文章,所以如果其他人在我的情况下发现了他们,他们可以更容易地找到答案(因为我以前从未见过任何关于这种差异的讨论)。我不确定重新调整的理由。同样奇怪的是,Ridge重新调整了调优参数,但Lasso没有。看起来是很重要的行为。阅读sklearn 山脊套索的文档后,我没有看到讨论过的Ridge的重新缩放行为有什么不同。

票数 1
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/72260808

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档