Py学习  »  机器学习算法

为什么说:学界使用为主的机器学习,mlr3verse比sklearn是更佳选择

R语言与数学建模 • 10 月前 • 187 次点击  

说到机器学习,很多人首先想到的是Python sklearn,实际上如果是学界使用为主的话,R语言的mlr3verse 才是更优解。

一、先看一下 mlr3verse 的生态

mlr3verse
mlr3verse

除了常规的回归、分类、聚类之外,还包含其它的学术方向:时空、函数型、空间、时间序列、生存。

mlr3verse 是现代化、面向对象的机器学习生态系统,它提供了一套统一、模块化、可扩展的接口设计。无论是线性回归、支持向量机、随机森林,还是梯度提升树,所有算法都遵循一致的流程方法,极大降低了学习和使用成本。

常规机器学习流程我就不展示了,下文将展示两个对于 sklearn 来说非常棘手、繁琐的案例。

二、mlr3verse在学界中的独特价值

mlr3verse不仅致力于“让建模更高效”,更强调“让研究更严谨”。它为科研人员提供了一套符合统计学规范、支持发表级分析的完整工具链,以下特性尤为突出:

1.嵌套重抽样:确保无偏性能估计

在模型开发中,超参数调优常在验证集上进行。然而,如果在同一验证集上同时进行调参和性能评估,会引入乐观偏差,导致报告的性能指标高估模型的真实泛化能力。

mlr3verse通过嵌套重抽样原生解决这一问题:

  • 外层循环用于性能评估(如4折交叉验证);
  • 内层循环用于超参数优化(如在每折训练集中再进行5折交叉验证)。

这一设计确保模型性能的无偏估计,满足学术研究对方法严谨性的高要求。相比之下,许多其他工具要么缺乏此功能,要么需手动实现,易出错且效率低下。

2. 统计推断:从描述性能到检验差异

在算法比较研究中,仅仅报告“模型A的AUC为0.85”远远不够,科研人员更关心“模型A是否显著优于模型B”。mlr3verse通过基准测试(或mlr3batchmark包)和mlr3inferr包(泛化误差统计推断)提供强大支持:

  • 在单个或多个数据集上公平无偏地比较不同算法的性能;
  • 通过多种重抽样方法生成泛化误差的置信区间;
  • mlr3batchmark 支持将 mlr3 基准实验分布式运行于高性能计算环境,并提供统计显著性检验功能。

这种“从描述到推断”的能力,使mlr3verse成为方法论研究、仿真实验和论文复现的理想平台,特别适合需要高可信度和严谨性的场景。

  1. 科研导向的设计哲学 mlr3verse的架构围绕科研需求设计,强调:
  • 可复现的实验流程:通过确定性种子控制与完整流程封装,确保结果可精确复现,满足学术发表的严谨性要求;
  • 可审计的建模路径与可比较的预处理策略:图学习器不仅记录完整操作链,还支持构建分支管道,系统评估不同预处理方案与模型组合的性能差异;
  • 可发表的分析输出:结构化结果对象配合 mlr3viz::autoplot() 快速生成高质量图形,经 ggplot2 进一步润色后可直接用于论文与报告。

这些特性使mlr3verse不仅适用于教学和科研,也成为系统性机器学习实验(如算法基准测试、特征工程影响分析、模型鲁棒性评估)的首选工具。

三、如何选择算法?让实验设计驱动决策

机器学习实践一个非常常见的场景:(1) 选择哪个算法

很显然,应该选择的是:(2) 哪个带超参数调优的算法

再提升一下,应该选择的是:(3) 哪个特征工程分支+带超参数调优的算法(完整方案)

而 (3) 在 mlr3verse 下非常容易实现,因为有图学习器基准测试,让你能轻松使用嵌套重抽样无偏估计哪个完整方案更好。

案例1

以 Sonar 数据集为例,基准测试对比

  • 对  cost, gamma 做超参数调优的SVM
  • 对 num.trees, mtry, min.node.size 做超参数调优的随机森林

的无偏性能表现(嵌套重抽样:外层5折交叉验证,内存4折交叉验证)

library(mlr3verse)
task = tsk("sonar")
lrn_svm = lrn("classif.svm", type = "C-classification", kernel = "radial", predict_type = "prob")
ps_svm = ps(cost = p_dbl(1, 1e5, logscale = TRUE), gamma = p_dbl(1e-5, 1))
at_svm = auto_tuner(
  tuner = tnr("random_search"),
  learner = lrn_svm,
  search_space = ps_svm,
  resampling = rsmp("cv", folds = 4),
  measure = msr("classif.auc"),
  term_evals = 10)
lrn_rf = lrn("classif.ranger", predict_type = "prob")
ps_rf = ps(num.trees = p_int(2, 10, trafo = \(x) 5 * x),
           mtry = p_int(3, 20), min.node.size = p_int(2, 10))
at_rf = auto_tuner(
  tuner = tnr("random_search"),
  learner = lrn_rf,
  search_space = ps_rf,
  resampling = rsmp("cv", folds = 4),
  measure = msr("classif.auc"),
  term_evals = 10)
set.seed(123)
design = benchmark_grid(tasks = task, learners = list(at_svm, at_rf),
                        resamplings = rsmp("cv", folds = 5))
bmr = benchmark(design)
bmr$aggregate(msr("classif.auc"))                     # 平均性能
image
image
autoplot(bmr, measure = msr("classif.auc"))           # 默认箱线图(外层迭代5次性能)
image
image

四、易错场景:不平衡处理+超参数调优

处理不平衡数据时需遵循一个基本原则:不平衡处理只能应用于训练集,绝不能影响验证集或测试集。

当模型训练涉及超参数调优时,这一原则的实现变得更加复杂。此时数据应按以下方式划分与使用:

  • (外)训练集:用于训练最终模型,在调参阶段需进一步划分为(内)训练集和验证集;
  • 测试集:仅用于最终性能评估,全程不可参与模型训练或调参。

那么,如何确保不平衡处理不违反上述原则?以下是一些常见的误区:

(1) 对整个(外)训练集提前进行不平衡处理

错误。这会导致内层交叉验证中的“验证集”也被间接影响,破坏了评估的独立性。

(2) 仅对(内)训练集处理,但验证集未处理

表面上看似合理,但若在调参后直接用处理过的(内)训练集与未处理的验证集合并训练最终模型,会导致数据分布不一致。

(3) 训练集经采样后样本量变化,如何评估原始数据上的性能?

若直接在采样后的数据上评估,无法反映模型在真实分布下的表现。

正确做法是:分阶段独立处理。其实原理并不复杂,关键在于将调参阶段与训练最终模型阶段的不平衡处理分开:

  • 调参阶段:每次内层 CV 训练时,仅对(内)训练集进行不平衡处理,验证集保持原始分布;
  • 训练最终模型阶段:使用最优超参数,对整个(外)训练集重新进行不平衡处理并训练最终模型;
  • 预测阶段:模型在原始的训练集和测试集上分别进行预测,从而公平比较其在真实数据分布下的性能。

这一流程虽然逻辑严谨,但手动实现较为繁琐。mlr3verse 框架通过图学习器将预处理与模型打包,自动实现了上述复杂逻辑,极大简化了操作。

案例2

SMOTE + 决策树调参的完整示例,展示如何在 mlr3 中正确执行结合不平衡处理的超参数调优。

task = tsk("spam")                         # 垃圾邮件分类
## 划分(外)训练集、测试集
set.seed(123)
split = partition(task, ratio = 0.8)
## 图学习器, 打包SMOTE和决策树学习器
glrn = po("smote", dup_size = 1) %>>%      # 少数类增加1倍
  lrn("classif.rpart")
## 超参数调优: 剪枝复杂度
at = auto_tuner(
  tuner = tnr("random_search"),
  learner = glrn,
  resampling = rsmp("cv", folds = 5),
  measure = msr("classif.ce"),
  search_space = ps(classif.rpart.cp = p_dbl(0, 0.1)),
  term_evals = 10)
at$train(task, row_ids = split$train)
at$tuning_result
image
image
## 最终模型在原始测试集上做预测
pred_test = at$predict(task, row_ids = split$test)

五、学机器学习需不需要先补充数学知识?

机器学习的确以数学为基础,但学习它的路径并非“先啃完高等数学、线性代数、概率论,再去写代码”。相反,最有效的策略是“边学边补、以用促学”——在建模实践中遇到数学概念时,再针对性地补充相关知识。这种方式不仅效率更高,还能让你保持学习的动力和热情。

那么,哪些数学知识对机器学习最关键?如何高效地掌握它们?

1. 核心数学领域

以下是机器学习中最重要的数学领域,助你有的放矢:

  • 高等数学:导数、梯度、链式法则——帮助你理解优化过程(如梯度下降)以及损失函数的动态变化。
  • 线性代数 :矩阵运算、向量空间、特征值与特征向量——这些概念帮助你理解数据表示、降维技术(如PCA)以及模型参数的结构。
  • 概率与统计:条件概率、期望、方差、常见概率分布、假设检验——这些是理解模型输出、评估指标和泛化误差的基础。
  • 优化理论基础:目标函数、正则化、局部最优——这些知识对超参数调优和模型复杂度控制至关重要。

2. 学习策略:按需补数学,而非系统学数学

错误路径:试图在开始建模前“系统学完”所有数学知识。这种方式不仅耗时漫长,还因数学的抽象性容易让人望而却步,甚至中途放弃。

正确路径:从实践出发,以问题驱动学习。例如,在使用mlr3实现Logistic回归时,理解“对数几率”的含义;在探索神经网络时,补习“复合函数求导”的原理。通过这种方式,数学不再是枯燥的理论,而是解决具体问题的工具,自然更容易内化。

本书在讲解每个算法时,都会以直观的语言剖析其数学直觉,让你在无需深陷复杂公式推导的情况下,快速抓住模型的核心逻辑。

3. 重要提醒:理解重于推导,直觉胜于证明

学习机器学习的数学,不需要你手推SVM的对偶问题,也无需死记硬背贝叶斯公式。你真正需要的是:

  • 理解“这个公式为何适用?”
  • 明白“这个参数如何影响模型?”
  • 洞悉“这个指标反映了什么?”

机器学习不是数学竞赛,而是工程实践。通过mlr3快速构建一个可运行的模型,远比推导上百个公式更能让你建立信心、积累能力。随着实践的深入,你的数学理解会像种子一样生根发芽,逐渐成长为系统化的知识体系。




以上内容,节选自我即将在机械工业出版社出版的新书:《R机器学习:基于mlr3verse》,敬请期待!


Python社区是高质量的Python/Django开发社区
本文地址:http://www.python88.com/topic/187406