多数据集迭代LASSO代码从lars转cv.lars后返回NULL的问题排查
问题:使用cv.lars提取LASSO选中变量返回NULL的修复方法
我正在为统计学习论文运行LASSO基准模型,针对N个随机生成的合成数据集迭代拟合模型——LASSO是选定的3种基准变量选择算法之一,用于对比我们提出的新算法。原代码使用固定s=0.1的predict函数能正常输出选中变量,但改用cv.lars通过k折交叉验证选择最优正则化参数后,提取的系数全为NULL,得到空的变量列表。
原可正常运行的代码
# 拟合所有LASSO模型 set.seed(11) # 保证可复现性 system.time(LASSO.Lars.fits <- lapply(X = datasets, function(i) lars(x = as.matrix(select(i, starts_with("X"))), y = i$Y, type = "lasso", normalize = FALSE))) # 提取选中变量对应的系数 set.seed(11) # 保证可复现性 system.time(LASSO.Lars.Coeffs <- lapply(LASSO.Lars.fits, function(i) predict(i, x = as.matrix(dplyr::select(i, starts_with("X"))), s = 0.1, mode = "fraction", type = "coefficients")[["coefficients"]])) # 筛选选中/未选中的变量 IVs.Selected.by.Lars <- lapply(LASSO.Lars.Coeffs, function(i) names(i[i > 0])) IVs.Not.Selected.by.Lars <- lapply(LASSO.Lars.Coeffs, function(j) names(j[j == 0]))
出错的cv.lars代码及现象
改用cv.lars的代码如下,但LASSO.Lars.Coeffs返回全为NULL:
# 使用cv.lars拟合模型 set.seed(11) # 保证可复现性 system.time(LASSO.Lars.fits <- lapply(X = datasets, function(i) cv.lars(x = as.matrix(select(i, starts_with("X"))), y = i$Y, type = "lasso", normalize = FALSE, trace = TRUE))) print(LASSO.Lars.fits) # 尝试提取最优误差对应的系数 LASSO.Lars.Coeffs <- lapply(LASSO.Lars.fits, function(i) i$beta[, which.min(i$cv.error)]) # 提取非零系数变量名 IVs.Selected.by.Lars <- lapply(LASSO.Lars.Coeffs, function(i) names(i[i != 0]))
输出示例:
[[671]] NULL [[672]] NULL [[673]] NULL
错误原因
cv.lars返回的对象中没有直接存储名为beta的系数矩阵,它的核心输出是交叉验证误差、最优正则化参数的索引等信息。你需要从cv.lars对象的fit字段中取出完整的lars拟合模型,再基于交叉验证得到的最优参数提取系数。
修复代码
修改后的代码通过获取cv.lars中的原始lars模型,结合最优正则化比例来提取系数:
set.seed(11) # 保证可复现性 system.time(LASSO.Lars.cvfits <- lapply(X = datasets, function(i) { # 运行k折交叉验证 cv_fit <- cv.lars(x = as.matrix(select(i, starts_with("X"))), y = i$Y, type = "lasso", normalize = FALSE, trace = FALSE) # 返回交叉验证结果+原始数据集(方便后续预测) list(cv_fit = cv_fit, data = i) })) # 提取最优正则化比例对应的系数 LASSO.Lars.Coeffs <- lapply(LASSO.Lars.cvfits, function(item) { cv_fit <- item$cv_fit data <- item$data # 找到对应最小CV误差的正则化比例 opt_fraction <- cv_fit$fraction[which.min(cv_fit$cv.error)] # 从原始lars模型中预测系数 predict(cv_fit$fit, x = as.matrix(select(data, starts_with("X"))), s = opt_fraction, mode = "fraction", type = "coefficients")$coefficients }) # 筛选选中的变量 IVs.Selected.by.Lars <- lapply(LASSO.Lars.Coeffs, function(i) names(i[i != 0]))
关键说明
cv_fit$fit存储的是完整的lars拟合模型,这才是用于提取系数的核心对象cv_fit$fraction对应LASSO路径上的正则化比例,用which.min(cv_fit$cv.error)可定位到交叉验证最优的比例值- 显式传入原始数据集是为了确保
predict时使用正确的特征矩阵,避免索引混乱
内容的提问来源于stack exchange,提问作者Marlen
相关产品推荐
相关产品推荐

