$\lambda = 0$ 和 OLS 的 LASSO 在 R glmnet 中产生不同的结果

Posted

技术标签:

【中文标题】$\\lambda = 0$ 和 OLS 的 LASSO 在 R glmnet 中产生不同的结果【英文标题】:LASSO with $\lambda = 0$ and OLS produce different results in R glmnet$\lambda = 0$ 和 OLS 的 LASSO 在 R glmnet 中产生不同的结果 【发布时间】:2016-11-17 14:26:50 【问题描述】:

我希望没有惩罚的 LASSO ($\lambda=0$) 产生与 OLS 拟合相同(或非常相似)的系数估计值。但是,我在 R 中得到不同的系数估计,将相同的数据 (x,y) 放入

glmnet(x, y , alpha=1, lambda=0) LASSO 适合没有惩罚和 lm(y ~ x) 适用于 OLS。

这是为什么呢?

【问题讨论】:

与其关注 R 中的特定功能,不如解释一下为什么您认为这两种拟合应该非常相似。例如。说没有惩罚的 LASSO 除了适合 OLS 之外什么都不应该,如果这就是你的意思的话。您还可以使用公式详细说明您为什么这么认为。 我认为没有惩罚的 LASSO 很明显,OLS 应该给出相同的结果。我想知道为什么两种算法给我不同的估计。 对你来说显而易见的事情可能对其他人来说并不明显,所以以防万一,最好尽可能明确和准确。 当然!我希望问题现在已经清楚了。 我确定是软件问题,如果您通过手动SVD解决问题,您将得到相同的结果。我尝试了同样的事情。 【参考方案1】:

您使用错误的功能。 x 应该是模型矩阵。不是原始预测值。当你这样做时,你会得到完全相同的结果:

x <- rnorm(500)
y <- rnorm(500)
mod1 <- lm(y ~ x) 

xmm <- model.matrix(mod1)
mod2 <- glmnet(xmm, y, alpha=1, lambda=0)

coef(mod1)
coef(mod2)

【讨论】:

但是glmnet默认有intercept=TRUE,所以它已经添加了一个intercept term,对吧?所以我不清楚为什么这应该是必要的,因为你 xmm 只是 cbind(1,x)....【参考方案2】:

我遇到了同样的问题,四处询问无济于事,然后我通过电子邮件向给出答案的包维护者 (Trevor Hastie) 发送了电子邮件。当系列高度相关时,就会出现问题。解决方案是降低glmnet() 函数调用中的阈值(而不是通过glmnet.control())。下面的代码使用内置数据集EuStockMarkets 并应用带有lambda=0 的VAR。对于XSMI,OLS系数在1以下,默认glmnet系数在1以上,相差约0.03,glmnet系数与thresh=1e-14非常接近OLS系数(相差1.8e-7 )。

# Use built-in panel data with integrated series
data("EuStockMarkets")
selected_market <- 2

# Take logs for good measure
EuStockMarkets <- log(EuStockMarkets)

# Get dimensions
num_entities <- dim(EuStockMarkets)[2]
num_observations <- dim(EuStockMarkets)[1]

# Build the response with the most recent observations at the top
Y <- as.matrix(EuStockMarkets[num_observations:2, selected_market])
X <- as.matrix(EuStockMarkets[(num_observations - 1):1, ])

# Run OLS, which adds an intercept by default
ols <- lm(Y ~ X)
ols_coef <- coef(ols)

# run glmnet with lambda = 0
fit <- glmnet(y = Y, x = X, lambda = 0)
lasso_coef <- coef(fit)

# run again, but with a stricter threshold
fit_threshold <- glmnet(y = Y, x = X, lambda = 0, thresh = 1e-14)
lasso_threshold_coef <- coef(fit_threshold)

# build a dataframe to compare the two approaches
comparison <- data.frame(ols = ols_coef,
                         lasso = lasso_coef[1:length(lasso_coef)],
                         lasso_threshold = lasso_threshold_coef[1:length(lasso_threshold_coef)]
)
comparison$difference <- comparison$ols - comparison$lasso
comparison$difference_threshold <- comparison$ols - comparison$lasso_threshold

# Show the two values for the autoregressive parameter and their difference
comparison[1 + selected_market, ]

R 返回:

           ols    lasso lasso_threshold  difference difference_threshold
XSMI 0.9951249 1.022945       0.9951248 -0.02782045         1.796699e-07

【讨论】:

我也遇到了同样的问题,设置较低的阈值并没有解决。 @bob 你使用了什么阈值?这些天我很少做 LASSO,所以我建议再次给包维护者发电子邮件,因为他非常敏感。【参考方案3】:

我已经用 Hastie 书中的“前列腺”示例数据集运行了下一个代码:

out.lin1 = lm( lpsa ~ . , data=yy ) 
out.lin1$coeff             
out.lin2 = glmnet( as.matrix(yy[ , -9]), yy$lpsa, family="gaussian", lambda=0, standardize=T  ) 
coefficients(out.lin2)

和系数的结果是相似的。当我们使用标准化选项时,glmnet() 返回的系数是输入变量的原始单位。 请检查您使用的是“高斯”系列

【讨论】:

添加 family = "gaussian" 并没有改变结果【参考方案4】:

来自 glmnet 帮助:另请注意,对于“高斯”,glmnet 在计算之前将 y 标准化为具有单位方差 它的 lambda 序列(然后对结果系数进行非标准化);如果你想复制 与其他软件推断/比较结果,最好提供标准化的 y。

【讨论】:

lm 和 glmnet 系数之间的差异变小,因为系数的绝对值越来越小。当我不标准化系数时,我仍然得到相同的差异。 帮助文件中还有一个Warning,特别是对lambda参数的描述,说如果只提供标量而不提供向量,算法可能会出现问题。我不确定这是否只会导致速度问题,或者实际上可能会使估计有偏差。

以上是关于$\lambda = 0$ 和 OLS 的 LASSO 在 R glmnet 中产生不同的结果的主要内容,如果未能解决你的问题,请参考以下文章

markdown Valida que todas las casillas visibles tengan capturadounnúmero市长0

题解Luogu P3584 LAS dp

R语言学习笔记:OLS回归

为啥 `sklearn` 和 `statsmodels` 的 OLS 回归实现给出不同的 R^2?

OLS 适合带有系数误差和转换目标的 python

我们如何计算 statsmodels OLS 中的截距和斜率?