glmnet包Lasso回归相同lambda值结果不同的原因及解决方法
glmnet同一lambda值回归结果不一致的原因与解决办法
在使用R语言的glmnet::glmnet()时,会出现一种情况:即使目标lambda值相同,只要它所在的lambda序列不同,最终得到的回归系数会有细微差异,示例代码如下:
# 生成随机小数据集 set.seed(123) X = matrix(runif(12), ncol = 3) y = runif(nrow(X)) # 第一次生成lambda序列并拟合模型 lda = sort(c((runif(1) + 1) * 0.001, 0.001, 0.001 * (1 - runif(1))), decreasing = T) theModel = glmnet::glmnet(X, y, lambda = lda, intercept = T, standardize = T) coef(theModel)[, 2] # 查看lambda=0.001对应的系数 # (Intercept) V1 V2 V3 # 0.8794007 1.6709897 -0.9141978 -1.5334346 # 第二次生成不同的lambda序列并拟合模型 lda = sort(c((runif(1) + 1) * 0.001, 0.001, 0.001 * (1 - runif(1))), decreasing = T) theModel = glmnet::glmnet(X, y, lambda = lda, intercept = T, standardize = T) coef(theModel)[, 2] # 再次查看lambda=0.001对应的系数 # (Intercept) V1 V2 V3 # 0.8793756 1.6708981 -0.9141037 -1.5333721
原因分析
glmnet采用路径式迭代求解:它会从序列中最大的lambda值开始,逐步求解到最小的lambda,每一步的解都会作为下一个lambda值求解的初始值。当你传入的lambda序列不同(哪怕包含同一个目标lambda),序列中目标lambda之前的那些值不一样,会导致求解到目标lambda时的初始迭代状态不同,再加上迭代收敛的精度限制,最终得到的系数就会出现细微差异。示例中每次生成的lambda序列前后值都是随机的,这就放大了这种差异。
解决办法
- 单独指定目标lambda:如果只需要某个特定lambda的结果,直接把lambda参数设为单个值,不要传入序列。这样glmnet会直接针对该lambda求解,不依赖路径迭代的初始值,结果稳定。
theModel = glmnet::glmnet(X, y, lambda = 0.001, intercept = T, standardize = T) coef(theModel) - 固定lambda序列:如果必须使用序列,不要随机生成,固定整个序列的取值,这样每次求解的路径完全一致,同一lambda的结果就会相同。
- 提高收敛精度:调整
thresh参数(默认是1e-7),设置更小的值(比如1e-10),让迭代更精确,减少差异,但会增加计算时间。theModel = glmnet::glmnet(X, y, lambda = lda, intercept = T, standardize = T, thresh = 1e-10)
内容的提问来源于stack exchange,提问作者user2961927
相关产品推荐
相关产品推荐

