为什么在省略截距项时 cv.glmnet 返回荒谬的系数?

机器算法验证 r 岭回归 网络
2022-03-19 11:59:38

x是一个数值矩阵并且y是一个数值向量:

x = structure(c(53, 36, 51, 51, 54, 35, 56, 60, 60, 60, 35, 59, 62, 
36, 38, 61, 64, 60, 92, 92, 62, 42, 65, 89, 62, 61, 62, 62, 62, 
35, 35, 37, 3.32, 3.1, 3.18, 3.39, 3.2, 3.03, 4.78, 4.72, 4.6, 
4.53, 2.9, 4.4, 4.31, 4.27, 4.41, 4.39, 7.32, 7.32, 7.45, 7.27, 
3.91, 3.75, 6.48, 6.7, 4.3, 4.02, 4.02, 3.98, 4.39, 2.75, 2.59, 
2.73, 3.42, 3.26, 3.18, 3.08, 3.41, 3.03, 4.57, 4.72, 4.41, 4.53, 
2.95, 4.36, 4.42, 3.94, 3.49, 4.39, 6.7, 7.2, 7.45, 7.26, 4.08, 
3.45, 5.8, 6.6, 4.3, 4.1, 3.89, 4.02, 4.53, 2.64, 2.59, 2.59), .Dim = c(32L, 
3L), .Dimnames = list(NULL, c("PT", "ITP", "PP")))

y = c(29, 24, 26, 22, 27, 21, 33, 34, 32, 34, 20, 36, 34, 23, 24, 
32, 40, 46, 55, 52, 29, 22, 31, 45, 37, 37, 33, 27, 34, 19, 16, 
22)

无拦截

代码:

fit.ridge = glmnet(x, y, alpha = 0, intercept = FALSE)
plot(fit.ridge, xvar = "lambda", label = TRUE)
cv.ridge = cv.glmnet(x, y, alpha = 0, intercept = FALSE)
plot(cv.ridge)
coef(cv.ridge)

#4 x 1 sparse Matrix of class "dgCMatrix"
#                       1
#(Intercept) .           
#PT          7.877576e-36
#ITP         7.371832e-35
#PP          7.871337e-35

带拦截

代码:

fit.ridge = glmnet(x, y, alpha = 0, intercept = TRUE)
plot(fit.ridge, xvar = "lambda", label = TRUE)
cv.ridge = cv.glmnet(x, y, alpha = 0, intercept = TRUE)
plot(cv.ridge)
coef(cv.ridge)

#4 x 1 sparse Matrix of class "dgCMatrix"
#                   1
#(Intercept) 5.821492
#PT          0.194511
#ITP         1.420347
#PP          1.884496

为什么我会得到这些荒谬的系数?

2个回答

我可以解释你所看到的,但不一定是为什么会这样。glmnet以比有截距解决方案高得多的初始正则化惩罚 \lambda_{max} 开始无截距解决,然后在路径中提前停止,然后才能探索更好的解决方案。λmax

如何选择λmax

对于被选为仍然产生一个非零系数的的最大值(截距除外,它没有被正则化)。Ridge 将系数渐近地推向零,而 LASSO 可以将系数完全归零。时,LASSO 贡献减少,导致恰好一个非零系数的值变得越来越高。0<α1λmaxλα0λ

对于或 L2 正则化,系数永远不会被正则化到零,即使是如何在这里选择很难从源代码或论文中收集到,但它似乎将设置为一个非常小的正数并以常规方式的值相同α=0λglmnetλmaxαλmaxα=0λmax120,761.2α=0.001

如何选择完整的向量λ

通常最小 lambda被选为之间搜索 100 个均匀分布的对数尺度点由于某种原因,无截距模型仅在 31 个值后停止。我不知道为什么会这样。如果最近拟合的没有显着改善训练偏差,将尽早停止搜索源代码是一个完整的黑盒。谁知道发生了什么。λmin0.001λmaxλminλmaxglmnetλλ

为什么无截距有更高的λmax

由于截距是无正则化的,因此模型拟合数据是一种免费的方式。截距使系数要做的工作更少,因为与没有截距相比,无系数模型的误差要低得多。要低得多,在. 它一直在寻找并找到好的解决方案。无截距模型从到搜索,几乎没有掠过带截距模型的路径的顶部。λmax8496.60.8497120761.27409.8λ

如何获得更好的解决方案

如果你只是将 with-intercept路径移植到 no-intercept 模型中,你会得到更好的解决方案。λ

cv.ridge.wi = cv.glmnet(x, y, alpha = 0, intercept = TRUE)
cv.ridge.ni = cv.glmnet(x, y, alpha = 0, intercept = FALSE, lambda = cv.ridge.wi$lambda)
plot(cv.ridge.ni)

为什么coef(cv.ridge)返回非常小的数字

coefcv.glmnet默认情况下,目标是s = "lambda.1se"启发式,在文档中描述。由于无截距模型搜索 31并且它们的误差非常平坦,你可以从. with-intercept 模型的要低得多,系数也更发达。λλ1seλmaxplot(cv.ridge)λ1se

稍后将在一些图像中进行编辑。

我首先要说明这不是这个问题的答案,但是我遇到了类似的问题并且已经确定了我的情况的原因,如果他们碰巧犯了和我一样的错误,这可能会帮助将来看到这里的人。

我正在将 LASSO 拟合到一个相当大的训练集(p = 20,n = 100000),并且知道大多数特征与响应之间存在某种程度的共线性关系。lambda.1se 选择的最佳拟合系数全部为零,考虑到我对游戏中关系的了解,这似乎很奇怪。

LASSO 模型使用 alpha = 1 的 cv.glmnet 进行拟合。

使用 plot(fit_object) 绘制 MSE 显示 lambda.min 是最小的 lamdbda,而 lambda.1se 是最大的,所有其他值都介于两者之间,每个点的误差线都很大。

  • 使用lambda.min的模型除了 3 和截距外,所有系数都为零
  • 使用lambda.1se的模型除截距外所有系数都为零

由于在我的初始清理中错过了一步,我的响应变量中有一些巨大的异常值。这导致所有 lambda 值的 MSE 之间的差异非常小,而 MSE 的总体水平很大。异常值高出许多数量级,但价值很少。