为何glmnet在某数据集出现Fortran错误,其他数据集正常?
glmnet模型训练报错的原因排查与解决方法
使用的R代码
Res_F <- K1Z1vK2K3ROI1_Spec set.seed(10) index <- createDataPartition(y=Res_F$Var,p=0.5,list=FALSE) train2 <- dplyr::select(Res_F, corr, rdist, CCF2,Wcorr, Wcorr2, Wcorr3, Var) train <- train2[index,] test <- train2[-index,] MySummary <- function(data, lev = NULL, model = NULL){ a1 <- defaultSummary(data, lev, model) b1 <- twoClassSummary(data, lev, model) c1 <- prSummary(data, lev, model) out <- c(a1, b1, c1) out} classCtrl <- trainControl(method = "repeatedcv", number=10,repeats=5,classProbs = TRUE,summaryFunction = MySummary,savePredictions = "final") set.seed(355) model <- train(Var~., train, method= "glmnet", metric= "Spec", trControl=classCtrl)
报错信息
Error in loop$lambda[loop$alpha == alph[i]] <- np[which.max(np)] : replacement has length zero In addition: Warning message: from glmnet Fortran code (error code -2); Convergence for 2th lambda value not reached after maxit=100000 iterations; solutions for larger lambdas returned
数据集背景
- 研究中有数十个同类处理流程的数据集,仅
K1Z1vK2K3ROI1_Spec出现该错误,其余数据集(如K2Z1vK1K3ROI1_Spec)可正常运行。 - 两个数据集均为包含645条观测、11个变量的数据框。
错误原因分析
- 收敛失败引发连锁错误:警告提示glmnet在第2个lambda值处未收敛,导致自动生成的lambda序列异常,进而触发
replacement has length zero的赋值错误。 - 数据集特性异常:
- 特征共线性极强:部分特征间相关性过高,导致正则化优化过程难以收敛。
- 交叉验证折的类别分布异常:部分交叉验证折中某类样本量为0,破坏模型训练逻辑。
- 特征方差极低:存在接近常数的特征,引发数值不稳定问题。
解决步骤
步骤1:检查并预处理数据集
- 检查训练集类别分布及交叉验证折的类别覆盖情况:
# 查看训练集类别分布 table(train$Var) # 模拟交叉验证折,检查每个折的类别情况 folds <- createFolds(train$Var, k=10) lapply(folds, function(x) table(train$Var[x])) - 检查特征方差与共线性:
# 计算特征方差 apply(dplyr::select(train, -Var), 2, var) # 计算VIF值(需加载car包) library(car) vif(lm(Var~., data=train)) - 移除方差接近0或VIF>10的高共线性特征。
步骤2:调整glmnet训练参数
- 增加最大迭代次数解决收敛问题:
model <- train(Var~., train, method= "glmnet", metric= "Spec", trControl=classCtrl, control = list(maxit = 200000)) - 手动指定lambda与alpha候选序列,避免自动生成的序列异常:
model <- train(Var~., train, method= "glmnet", metric= "Spec", trControl=classCtrl, tuneGrid = expand.grid(alpha=seq(0,1,0.1), lambda=10^seq(-3,3,1)))
步骤3:调整交叉验证策略
若存在类别分布失衡问题,可在trainControl中启用分层交叉验证,或设置sampling参数处理类别不平衡:
classCtrl <- trainControl(method = "repeatedcv", number=10,repeats=5, classProbs = TRUE,summaryFunction = MySummary, savePredictions = "final", sampling = "up") # 上采样处理类别不平衡
内容的提问来源于stack exchange,提问作者Jean-Alexandre Patteet
相关产品推荐
相关产品推荐

