为何用parsnip构建的Lasso逻辑回归模型输出全重复?
问题排查与解决思路
核心原因推测:Lasso惩罚系数过高
你设置的penalty = 1可能远大于最优值,导致Lasso正则化将所有特征的系数压缩至0,此时模型仅保留截距项,对所有样本输出相同的预测概率(该概率等于训练集中正类的样本比例,和你输出的0.462匹配)。
验证方法
先检查拟合后模型的系数,确认是否所有特征系数被归零:
# 提取glmnet模型在penalty=1时的系数 coef(lr_fit$fit, s = 1)
如果输出结果中,除了(Intercept)外,所有特征对应的系数均为0,即可验证此问题。
解决步骤
1. 降低惩罚系数或自动选择最优值
- 先尝试更小的penalty值(如0.01、0.1)测试:
lr_noReg_mod1 <- logistic_reg(mode = 'classification', engine = 'glmnet', penalty = 0.1) # 调整为更小的惩罚系数 lr_fit <- fit(lr_noReg_mod1, outcome_rip ~ ., data = data_lr_train)
- 更严谨的方式是用交叉验证自动选择最优penalty:
# 加载tune包 library(tune) # 定义带可调penalty的模型 lr_tune_mod <- logistic_reg(mode = 'classification', engine = 'glmnet', penalty = tune()) # 设置penalty的候选范围(用对数尺度更合理) penalty_grid <- grid_regular(penalty(range = c(-4, 1)), levels = 20) # 用交叉验证训练并选择最优penalty lr_res <- tune_grid( lr_tune_mod, outcome_rip ~ ., resamples = data_folds, grid = penalty_grid, metrics = metric_set(roc_auc) ) # 提取最优penalty值 best_penalty <- select_best(lr_res, metric = "roc_auc")$penalty # 用最优penalty重新拟合模型 lr_final_mod <- logistic_reg(mode = 'classification', engine = 'glmnet', penalty = best_penalty) lr_final_fit <- fit(lr_final_mod, outcome_rip ~ ., data = data_lr_train)
2. 统一预处理流程,避免手动操作误差
你当前手动mutate转换因子的方式容易导致训练/测试集处理不一致,建议将所有预处理步骤整合到recipe中:
# 基于原始训练数据初始化recipe(用交叉验证前的原始数据) lr_rec <- recipe(outcome_rip ~ ., data = original_train_data) %>% step_impute_bag(all_predictors()) %>% # 批量转换分类变量为因子 step_mutate_at(vars(gender_m, starts_with("ards_type")), factor) %>% prep() # 处理训练集(第1折) data_lr_train <- data_folds$splits[[1]] %>% analysis() %>% bake(lr_rec, new_data = .) # 处理测试集(第1折) data_lr_test <- data_folds$splits[[1]] %>% assessment() %>% bake(lr_rec, new_data = .)
3. 验证测试集特征的有效性
如果调整penalty后仍有问题,检查测试集特征是否存在异常(如所有样本特征值完全相同):
# 查看测试集特征的统计分布 summary(data_lr_test %>% select(-outcome_rip)) # 检查特征变异系数,确认是否有特征无变异 apply(data_lr_test %>% select(-outcome_rip), 2, function(x) sd(x)/mean(x, na.rm = TRUE))
内容的提问来源于stack exchange,提问作者for_the_love_of_cod
相关产品推荐
相关产品推荐

