imd 统计教程 · 预测模型与机器学习
← 教程首页 返回本模块

一键批量预测模型机器学习,自动图表集成学习∶ e2e包深度测评

聂志强实战医学统计2025-10-16 21:50:30江西


Med Research杂志,大家可以关注一下,里面发表的R包和R代码质量颇高。最近MR发表了几篇非常好的R包,做限制性立方样条rcssci一键table2森林图,我已经用的飞起,无敌好用啊。

今天给大家测评第三个R包,一键机器学习e2e包, https://onlinelibrary.wiley.com/doi/10.1002/mdr2.70030。作者解释E2E构建了一个综合性的集成学习框架,并且内置多种诊断和预后的基本算法,能够帮助用户快速实现集成学习,也提供了可视化分析和可解释分析选项。

简单来说就是17种机器学习模型自动运行调参自动出图

一、mlr3局限性

tidymodels 或者 mlr3,虽然支持高度灵活的模型选择,但是其并未完全实现集成式算法框架,使得其在处理不平衡或者大数据集时有很大的困难。而目前能用的集成学习算法诸如 ipred 和 SuperLearner,大多只能实现一种集成学习算法,而且对于基模型的选择缺乏灵活性。

E2E参考了 sklearn 和 imblanced-learn 等 python 库,实现 bagging、stacking、voting 等算法并且能够灵活选择或添加基模型来进行二分类(诊断)和预后。这里需要注意,缺失值问题是前置条件,E2E不包括处理missing问题。

二、E2E模型

包括12 种诊断模型:随机森林、极端梯度提升(XGBoost)、支持向量机、多层感知器、L1 正则化逻辑回归(lasso)、弹性网、L2 正则化逻辑回归(ridge)、线性判别分析、二次判别分析、朴素贝叶斯、决策树、梯度提升机。6 种time相关预后模型:lasso Cox 回归、弹性网 Cox 回归、ridge Cox 回归、逐步 Cox 回归、梯度提升机、随机生存森林。此外,用户可根据需要添加模型。我们建议简化每个基模型以避免计算冗余和过拟合,同时保留交叉验证和超参数调优功能。

2.1批量机器R包

批量机器学习的R包最早要追溯到NC2022的文章是鼻祖,提供了基代码。后续2025biol等杂志陆续发表101法批量代码和R包。Mime1也是优秀的生信ML的批量产品。这些R包在面对临床表型数据和多组学数据时,未考虑临床真实数据的复杂性,无论从超参数自动化、不平衡性问题上均没有考量。这也是一直以来的症结所在。所以长期我都比较关注一键输出机器学习方案,第一眼看到e2e介绍,解决了不平衡问题和超参数问题,也是本文测评的最主要原因。

2.2 baging boosting stacking

测评前,我们一起回顾下我在A款智荟机器学习中总结的方法学对比,如下。Bagging是并行、boosting是串行,stacking是合集。

三、实战案例

源代码来自https://xiaojie0519.github.io/E2E/articles/diagnostic-workflow.html。不过原文代码45步骤错误,修正如下。



#本代码由实战医学统计整理测评
#------一、诊断模型初始化 -----------
#train_dia, test_dia, train_pro, test_pro是四个 E2E 自带的数据集
library(E2E)
#用于诊断模型
initialize_modeling_system_dia()

#-----1 类别不平衡案例------- 
set.seed(42)              
n_obs <- 100              
n_minority <- 10     
# 少数类样本数(正类=1),这里做成 1:9 比例的不平衡

#   Feat1:  连续特征1(正态分布)
#   Feat2:  连续特征2(均匀分布)
data_imbalanced_toy <- data.frame(
  ID     = paste0("Sample", 1:n_obs),
  Status = c(rep(1, n_minority), rep(0, n_obs - n_minority)),
  Feat1  = rnorm(n_obs),
  Feat2  = runif(n_obs)
)

#运行 EasyEnsemble(多次欠采样 + 基学习器训练 + 融合)
#   imbalance_dia() 的核心思想:
#   - 从多数类(0)反复“随机欠采样”,每次与全部少数类(1)合并成一个“近似平衡”的子集
#   - 在每个子集上训练一个“基学习器”(这里用 xgboost)
#   - 对多个子模型的预测做融合(平均/投票),得到最终模型
 
easyensemble_results <- imbalance_dia(
  data              = data_imbalanced_toy,
  base_model_name   = "xb",       # xgboost 作为基模型
  n_estimators      = 3,          # 欠采样次数 / 子模型数(演示取小值)
  threshold_choices = "f1"        # 用 F1 最大的阈值作为最终分类阈值
  #常见还包括 "0.5"(固定0.5)、"youden"(约登指数最大)、"best_acc"(准确率最大)等
)

# 4) 打印/汇总模型结果
#   - 函数通常会输出:最佳阈值、各类评估指标(Accuracy/Precision/Recall/F1/ROC-AUC/PR-AUC 等)
#   - 以及可视化(如 ROC/PR 曲线、混淆矩阵)、分层评估、变量重要性等(视包内实现而定)
print_model_summary_dia("EasyEnsemble (XGBoost)", easyensemble_results)



#----2 models_dia 诊断 ----
train_dia <- train_dia
#---?? 不平衡数据
# results_imbalance_dia <- imbalance_dia(train_dia, base_model_name = "xb", n_estimators = 5, seed = 123)

#--1??诊断模型训练----
results_all_dia <- models_dia(train_dia, model = "all_dia")
#选任意几个
# results_all_dia <- models_dia(train_dia, model = c("rf", "lasso", "xb"))
#--?? 也可自定义模型, 调参种子,阈值依据!
results_dia_custom <- models_dia(
  data = train_dia,
  model = c("rf""lasso""xb"),
  tune = TRUE,
  seed = 123,
  threshold_choices = list(rf = "f1", lasso = 0.6, xb = "youden")
)

#后续stacking 全部模型作为基模型、lasso 作为meta模型的 stacking 框架
# model_object(每个模型的参数和细节)、sample_score(每个样本的评分和原始标签)、evaluation_metrics(模型评估指标)
#-----?? 集成-------
stacking_lasso_results <- stacking_dia(
  results_all_models = results_all_dia,
  data = train_dia,
  meta_model_name = "lasso")

voting_soft_results <- voting_dia(
  results_all_models = results_all_dia,
  data = train_dia,
  type = "soft")

#--??bagging格式不一样
bagging_xb_results <- bagging_dia(
  data= train_dia, 
  base_model_name = "xb"
  n_estimators = 5)


#---- 2?? 验证集预测----- 
#--test_dia 数据
#--仅测试Bagging model 
# 必须 model_object !
bagging_pred_new <- apply_dia(
  trained_model_object = bagging_xb_results$model_object,
  new_data = test_dia,
  label_col_name = "outcome"
)

# Evaluate these new predictions
eval_results_new <- evaluate_predictions_dia(
  prediction_df = bagging_pred_new,
  threshold_choices = "f1")

#-- ??没有evaluation_metrics
##print(eval_results_new$evaluation_metrics)



#---- 2?? 验证集预测----- 
#--test_dia 数据 仅测试Bagging model 
# 必须 model_object !
bagging_pred_new <- apply_dia(
  trained_model_object = bagging_xb_results$model_object,
  new_data = test_dia,
  label_col_name = "outcome"
)

# Evaluate these new predictions
eval_results_new <- evaluate_predictions_dia(
  prediction_df = bagging_pred_new,
  threshold_choices = "f1")

#-- ??没有evaluation_metrics
##print(eval_results_new$evaluation_metrics)


#------3 验证集性能可视化----------
external_eval_example_dia <- list(
  sample_score = data.frame(bagging_pred_new  ),
  evaluation_metrics = list( 
    Final_Threshold = eval_results_new$Threshold
  ))

#---3.1 训练ROC PR 混淆矩阵-----
p1 <- figure_dia(type = "roc", data = external_eval_example_dia)
plot(p1)

# Precision-Recall Curve
p2 <- figure_dia(type = "prc", data = external_eval_example_dia)
plot(p2)

# Confusion Matrix
p3 <- figure_dia(type = "matrix", data = external_eval_example_dia)
plot(p3)

#----3.2 shap图------
bagging_xb_results <- bagging_dia(test_dia, 
               base_model_name = "xb", n_estimators = 10, seed=123)
p6 <- figure_shap(
  data = bagging_xb_results,
  raw_data = test_dia,
  target_type = "diagnosis"
)
plot(p6)

四、发散思维

1、目前e2e适合迅速批量纯数值!的生信数据集成机器学习,模型经典没有前沿模型(需要手动添加自定义模型,https://xiaojie0519.github.io/E2E/articles/advanced-features.html)。实际上临床数据由于复杂性、哑变量等问题,比如LASSO分类问题入选机器学习形态,e2e和mime1等生信R包均没考虑。同理,分类x导致后续shapviz问题没有深入考量。

#----三、 自定义ML方法 ------  
# 定义 AdaBoost 模型(caret + ada),注册并调用
ab_dia <- function(X, y, tune = FALSE, cv_folds = 5) {
  if (!requireNamespace("caret", quietly = TRUE)) stop("需要安装 'caret' 包")
  ctrl <- caret::trainControl(method = "cv", number = cv_folds,
                              classProbs = TRUE, summaryFunction = caret::twoClassSummary)
  grid <- if (tune) {
    expand.grid(iter = c(50, 100), maxdepth = c(1, 2), nu = 0.1)
  } else {
    expand.grid(iter = 50, maxdepth = 1, nu = 0.1)
  }
  caret::train(x = X, y = y, method = "ada", metric = "ROC",
               trControl = ctrl, tuneGrid = grid)
}
register_model_dia("ab", ab_dia)
#---?? 批量调用
results_ab <- models_dia(train_dia, model = "ab")

2、不平衡数据很复杂,e2e内置了类似 EasyEnsemble 的欠采样方法。但是此方法学可能会被审稿人追溯,内嵌函数没找到提供smote等经典不平衡方法。

3、超参数默认范围组合少,很难说是全局最优超参数。不过貌似生信领域的R包都不看调参的,很奇怪,包括nc2022那篇,诸多101法等等都没有深入超参数的问题。真的很奇怪。

4、交叉验证似乎都只支持k折交叉验证,没有找到嵌套交叉等其他交叉方法。

 5、亮点:一键集成stacking、boosting、bagging集成过程。bagging_dia / stacking_dia / voting_dia属于“通用集成壳子”,适合任意基学习器 + 统一评估/阈值,非常棒!也是e2e的核心功能。

五、小结

e2e适合生信全为连续x的批量集成机器学习,boosting、bagging、stacking。 可批量简单自动超参数、性能图表roc、pr、混淆矩阵;可自定义模型。 支持12种诊断、6种预后预测模型,期待后续更新。 非常推荐!????????



本公众号建立了学术交流群(群7),仅供SCI学术交流,目前还有100人位置。入群请加笔者微信 popnie请备注说明:姓名-学校(单位)-专业