使用 glmnet 进行正则化回归:组间没有差异?

Regularized regression using glmnet: No difference between groups?

我正在对 select 几种最能区分健康状况(二元:疾病或无疾病)的蛋白质进行正则化回归。使用它的目的是减少维度(变量 selection),这样我们就可以拥有更小的一组蛋白质,从而最好地区分两组。

使用 R 中的 cv.glmnet 函数适当地选择了调整参数(我相信...)。 (具体来说,alpha是根据预测率来选择的,我用的是lambda.1se,因为alpha选择的是0.5,所以我其实用的是elastic net regression。)

因此,16 种蛋白质(近 500 种蛋白质中的)具有非零系数,我认为这些是最能“区分”两种情况的蛋白质:疾病或非疾病。为了可视化,我使用这些 selected 蛋白质制作了箱线图。

然而,我注意到一种蛋白质(TRAP1;图中底部)在两组之间没有显示任何明显的平均差异或分散。

我开始想知道为什么正则化回归预测它可能是最能区分两种健康状况的蛋白质之一?

有人能帮帮我吗?

非常感谢!!

Lasso 不保证您的预测器在您测试时会显示统计显着性。大多数时候,如果有预测能力,您会看到套索 selected 变量与因变量之间的相关性。

当你设置 alpha=0.5 时,它会施加 L1 惩罚(最小化你的系数的大小)和 L2 惩罚(select使用 0/1 的变量),所以看看你的分布变量,其中大部分为零,因此将其降低到较低的值应该可以使其“逃脱” L2 惩罚。

如果套索的目的是 select 变量,我会建议两件事 1,删除大部分为零或低方差的特征,如上面显示的特征,以及 2。 运行 alpha = 1 的完整套索。比较你的预测的准确性。

我没有你的数据,但我可以用一个数据集 mtcars 来说明,我在其中引入了一个无意义的预测变量,并首先计算预测变量的 p 值:

set.seed(111)
dat = iris
dat$Species = ifelse(dat$Species=="versicolor",1,0)
noise_var = data.frame(matrix(runif(750),nrow=150))
colnames(noise_var) = paste0("noise",1:ncol(noise_var))
dat  = cbind(noise_var,dat)

p = sapply(dat[,-ncol(dat)],function(i)cor.test(i,dat$Species)$p.value)

使用全套索拟合:

set.seed(222)
fit_lasso = cv.glmnet(x = as.matrix(dat[,-ncol(dat)]),y=dat[,ncol(dat)],alpha=1)
cbind(coef(fit_lasso,lambda="1se")[-1],p)

                                   p
noise1        0.0000000 5.089346e-01
noise2        0.0000000 2.722532e-01
noise3        0.0000000 9.564023e-02
noise4        0.0000000 7.743330e-01
noise5        0.0000000 7.324517e-02
Sepal.Length  0.0000000 3.341524e-01
Sepal.Width  -0.3073508 1.595624e-09
Petal.Length  0.0000000 1.329302e-02
Petal.Width   0.0000000 1.507473e-01

你可以看到非零系数是显着的,而其他一些显着的系数没有包括在内,这是由于相关性。

现在拟合弹性网,可以看到包含了低系数的噪声变量:

set.seed(222)
fit_enet = cv.glmnet(x = as.matrix(dat[,-ncol(dat)]),y=dat[,ncol(dat)],alpha=0.5)
cbind(coef(fit_enet,lambda="1se")[-1],p)

                                    p
noise1        0.00000000 5.089346e-01
noise2        0.00000000 2.722532e-01
noise3        0.00000000 9.564023e-02
noise4        0.00000000 7.743330e-01
noise5       -0.04636756 7.324517e-02
Sepal.Length  0.00000000 3.341524e-01
Sepal.Width  -0.31452496 1.595624e-09
Petal.Length  0.00000000 1.329302e-02
Petal.Width   0.00000000 1.507473e-01

还要记住溶液或select离子不稳定,参见this post,如果你运行它在不同的种子下,你会得到不同的结果:

set.seed(333)
fit_enet = cv.glmnet(x = as.matrix(dat[,-ncol(dat)]),y=dat[,ncol(dat)],alpha=0.5)
cbind(coef(fit_enet,lambda="1se")[-1],p)

                                   p
noise1        0.0000000 5.089346e-01
noise2        0.0000000 2.722532e-01
noise3        0.0000000 9.564023e-02
noise4        0.0000000 7.743330e-01
noise5        0.0000000 7.324517e-02
Sepal.Length  0.0000000 3.341524e-01
Sepal.Width  -0.2393709 1.595624e-09
Petal.Length  0.0000000 1.329302e-02
Petal.Width   0.0000000 1.507473e-01

你当然可以 运行 通过几个种子来查看系数的 select 离子有多稳定,但请记住,当相关性很大时,这很复杂