- 机器学习
- 深度学习
- AutoML
- 大数据
- 后端
【免费下载链接】h2o-3
H2O is an Open Source, Distributed, Fast & Scalable Machine Learning Platform: Deep Learning, Gradient Boosting (GBM) & XGBoost, Random Forest, Generalized Linear Modeling (GLM with Elastic Net), K-Means, PCA, Generalized Additive Models (GAM), RuleFit, Support Vector Machine (SVM), Stacked Ensembles, Automatic Machine Learning (AutoML), etc.
导读
stopping_metric是 H2O-3 机器学习平台中控制"早停(early stopping)"所依据的评估指标参数,它决定模型在训练过程中观察哪一项指标来判断是否已经收敛。本文以官方参数文档为主体,结合h2o-core中的ScoreKeeper.StoppingMetric枚举、ModelBuilder参数校验逻辑与 Python 客户端实现,系统梳理该参数的全部可用取值、与stopping_rounds/stopping_tolerance的协同机制、底层收敛判定算法,并提供 GBM 分类与自定义指标(custom metric)两套可直接运行的 Python / R 实战示例。读完本文,你将能够为不同任务类型(分类、回归、异常检测、增量学习 Uplift)正确选配早停指标,并理解其背后的移动平均收敛判据。
一、stopping_metric 是什么:早停的"观察窗口"
在 H2O-3 中,stopping_metric用于指定当启用早停时(即stopping_rounds> 0)所依据的指标。它的作用不是改变模型结构,而是控制训练何时停止——模型会持续打分(scoring),如果该指标在连续若干次打分事件中不再提升到指定程度,训练即提前终止,从而通过限制实际构建的模型数量来提升训练效率。
该参数在官方文档中标注为:
- 可用算法:GBM、DRF、Deep Learning、GLM、GAM、AutoML、XGBoost、Isolation Forest、UpliftDRF
- 属于超参数(Hyperparameter: yes)
从源码看,该参数定义于通用模型参数基类 hex/Model.java,是几乎所有监督式算法共享的早停三元组之一:
public int _stopping_rounds = 0; // 默认 0(关闭) public ScoreKeeper.StoppingMetric _stopping_metric = ScoreKeeper.StoppingMetric.AUTO; // 默认 AUTO public double _stopping_tolerance = defaultStoppingTolerance(); // 默认 1e-3其中defaultStoppingTolerance()的默认实现即返回1e-3(见 hex/Model.java)。
三个参数如何协同工作
官方文档用一个典型组合说明三者配合方式:
stopping_rounds=3stopping_metric=misclassificationstopping_tolerance=1e-3
此时模型会在连续 3 次打分事件中,误分类率(misclassification)相对提升未达到 1e-3时停止训练。也就是说:
stopping_metric决定"看哪个指标";stopping_rounds决定"连续看几轮"(等价于移动平均窗口 k);stopping_tolerance决定"相对提升达到多少才算有改进"。
关键约束:stopping_rounds必须被启用(> 0),stopping_metric与stopping_tolerance才会生效;否则即使设置了这两个参数也会被忽略。
二、底层原理:移动平均收敛判据
在 hex/ScoreKeeper.java 的stopEarly方法中,早停逻辑基于**简单移动平均(SMA)**实现。官方文档对stopping_rounds/stopping_tolerance页的说明与此完全对应:
当
stopping_rounds=3时,会计算最近 4 轮打分的移动平均值(第一个移动平均值作为参考基准,供其余 3 个比较)。若"最优移动平均值 / 参考移动平均值"的比值满足停止条件,则提前终止——对"越小越好"的指标(如 misclassification),比值需 ≥1 - 1e-3;对"越大越好"的指标(如 AUC),比值需 ≤1 + 1e-3。
对应源码中的收敛策略ConvergenceStrategy(hex/ScoreKeeper.java):
| 策略 | 方向 | 停止条件(ratio 表示极值点与参考移动平均之比) |
|---|---|---|
LESS_IS_BETTER | 越小越好(direction=-1) | ratio >= 1 - rel_improvement |
MORE_IS_BETTER | 越大越好(direction=+1) | ratio <= 1 + rel_improvement |
NON_DIRECTIONAL | 无方向(仅 anomaly_score) | 1 - rel_change <= ratio <= 1 + rel_change |
此外还有两个细节值得注意:
- 每个指标还带有
isLowerBoundBy0标志:若指标存在 0 下界(如 logloss、MSE、misclassification)且参考移动平均已收敛到 0,会直接判定收敛停止(hex/ScoreKeeper.java)。 - 移动平均窗口存在符号翻转(zero-crossing)时会返回"未收敛",避免除零或产生无意义的相对提升计算(hex/ScoreKeeper.java)。
- 早停至少需要
2k次完整打分事件才有足够的数据计算窗口(len < 2*k时直接返回不停止,见 hex/ScoreKeeper.java)。
三、全部可用取值与适用场景
官方文档列出的stopping_metric可用选项如下。下表在文档基础上补充了每个指标的收敛方向(来源于 hex/ScoreKeeper.java 枚举定义):
| 取值 | 含义 | 收敛方向 | 备注 |
|---|---|---|---|
AUTO | 自动选择 | 依任务而定 | 分类默认logloss,回归默认deviance,Isolation Forest 默认anomaly_score |
anomaly_score | 异常评分 | 无方向(NON_DIRECTIONAL) | 仅 Isolation Forest 使用 |
deviance | 平均残差偏差(mean residual deviance) | 越小越好 | 回归任务 AUTO 默认值;分类中仅 GLM 允许使用 |
logloss | 对数损失 | 越小越好(有 0 下界) | 仅分类 |
MSE | 均方误差 | 越小越好(有 0 下界) | 回归 / 自编码器(autoencoder) |
RMSE | 均方根误差 | 越小越好(有 0 下界) | 回归 |
MAE | 平均绝对误差 | 越小越好(有 0 下界) | 回归 |
RMSLE | 均方根对数误差 | 越小越好(有 0 下界) | 回归 |
AUC | ROC 曲线下面积 | 越大越好 | 仅分类,二分类常用 |
AUCPR | Precision-Recall 曲线下面积 | 越大越好 | 仅分类,类别不平衡场景适用 |
lift_top_group | 分组提升度 | 越大越好 | 仅分类 |
misclassification | 误分类率 | 越小越好(有 0 下界) | 仅分类 |
mean_per_class_error | 各类平均错误率 | 越小越好(有 0 下界) | 仅分类 |
AUUC | 提升曲线下面积 | 越大越好 | 仅 UpliftDRF |
qini | Qini AUUC 与随机提升曲线下面积之差 | 越大越好 | 仅 UpliftDRF |
ATE | 平均处理效应(Average Treatment Effect) | 越大越好 | 仅 UpliftDRF |
ATT | 处理组平均处理效应 | 越大越好 | 仅 UpliftDRF |
ATC | 对照组平均处理效应 | 越大越好 | 仅 UpliftDRF |
custom | 自定义指标(越小越好,期望下界为 0) | 越小越好 | 目前仅 Python 客户端 + GBM / DRF |
custom_increasing | 自定义指标(越大越好) | 越大越好 | 目前仅 Python 客户端 + GBM / DRF |
AUTO 的默认值如何确定
AUTO并非随机选择,而是由任务类型(ProblemType)决定。源码中 hex/ScoreKeeper.java 明确定义:
public enum ProblemType { regression(StoppingMetric.deviance), // 回归 → deviance classification(StoppingMetric.logloss), // 分类 → logloss anomaly_detection(StoppingMetric.anomaly_score), // 异常检测 → anomaly_score autoencoder(StoppingMetric.MSE), // 自编码器 → MSE uplift(StoppingMetric.AUUC); // 增量学习 → AUUC }而在stopEarly中,AUTO会被替换为当前任务类型的默认指标(见 hex/ScoreKeeper.java)。这解释了官方文档中"AUTO 对分类默认 logloss、对回归默认 deviance、对 Isolation Forest 默认 anomaly_score"的出处,同时补充了自编码器与 Uplift 场景的默认值。
四、参数校验规则:什么组合会被拒绝
不是任意组合都能通过校验。在 hex/ModelBuilder.java 中,H2O 会在训练前对早停参数执行以下校验:
stopping_tolerance必须在[0, 1)区间:小于 0 报错,≥ 1 报错;stopping_rounds=0(未启用早停)时,若同时设置了stopping_metric或自定义的stopping_tolerance,会产生警告("ignored"),而不会报错;stopping_rounds < 0直接报错;- 分类任务:
deviance不能用作早停指标(除 GLM 外); - 回归任务:标记为
isClassificationOnly的指标(logloss、AUC、AUCPR、lift_top_group、misclassification、mean_per_class_error)会被拒绝; - 选择
custom或custom_increasing时,必须同时提供custom_metric_func,否则报错(见 hex/ModelBuilder.java)。
这些规则保证早停指标与任务类型、评估口径一致,避免出现"用 AUC 监控回归模型"这类无意义配置。
五、网格搜索中的定位:固定值而非搜索维度
官方文档特别指出:stopping_metric控制的是早停行为而非模型结构,因此在网格搜索中通常将其固定,而不是作为变化维度参与搜索。该说明在 grid-search.rst 的 "Stopping and Runtime Controls" 一节有完整阐述:
以下参数适用于所有监督式算法,均标注
Hyperparameter: yes,但它们控制的是早停与总运行时长而非模型结构,因此应在整个网格中固定一次,而不是在不同模型间变化:max_runtime_secs、stopping_metric、stopping_rounds、stopping_tolerance。可通过search_criteria或在每个模型的参数中设置它们,以限制总运行时长或让单个模型提前停止。
同理,stopping_rounds与stopping_tolerance的官方文档页面(stopping_rounds.rst、stopping_tolerance.rst)也给出了各自的默认值与补充说明,与stopping_metric共同构成完整的早停参数体系:
stopping_rounds默认值因算法而异:GBM / DRF / XGBoost 默认 0(关闭);Deep Learning 默认 5;AutoML 默认 3。设为 0 即关闭早停(此时指标在验证集上计算,未提供验证集则用训练集)。stopping_tolerance除 AutoML 与 Isolation Forest 外默认0.001;AutoML 在数据至少 100 万行时默认0.001,否则按数据集规模与非缺失率取更大值;Isolation Forest 默认0.01。stopping_rounds指的是打分事件(scoring events)的数量而非 epoch 数。- 使用 Deep Learning 时可配合
overwrite_with_best_model,启用后最终模型为指定stopping_metric下的最佳模型。
六、实战示例:用 AUC 早停训练 GBM 分类模型
官方文档提供了基于航空公司航班延误数据(IsDepDelayed 二分类)的完整示例。以下示例完整保留文档逻辑,并补充了可运行性说明:数据从 H2O 公共测试数据源(S3)导入,按 8:2 划分训练/验证集,使用AUC作为早停指标、stopping_rounds=3、stopping_tolerance=1e-2。
Python
import h2o from h2o.estimators.gbm import H2OGradientBoostingEstimator h2o.init() h2o.cluster().show_status() # 导入航空公司数据集(用于判断航班是否延误 "YES"/"NO") airlines = h2o.import_file("https://s3.amazonaws.com/h2o-public-test-data/smalldata/airlines/allyears2k_headers.zip") # 将类别列转为因子 airlines["Year"] = airlines["Year"].asfactor() airlines["Month"] = airlines["Month"].asfactor() airlines["DayOfWeek"] = airlines["DayOfWeek"].asfactor() airlines["Cancelled"] = airlines["Cancelled"].asfactor() airlines['FlightNum'] = airlines['FlightNum'].asfactor() # 指定预测变量与响应列 predictors = ["Origin", "Dest", "Year", "UniqueCarrier", "DayOfWeek", "Month", "Distance", "FlightNum"] response = "IsDepDelayed" # 划分训练集与验证集 train, valid = airlines.split_frame(ratios=[.8], seed=1234) # 使用 stopping_metric 早停: # 分类问题看 AUC,也可选 logloss、misclassification 等 airlines_gbm = H2OGradientBoostingEstimator(stopping_metric="auc", stopping_rounds=3, stopping_tolerance=1e-2, seed=1234) airlines_gbm.train(x=predictors, y=response, training_frame=train, validation_frame=valid) # 打印验证集 AUC airlines_gbm.auc(valid=True)R
library(h2o) h2o.init() # 导入航空公司数据集(用于判断航班是否延误 "YES"/"NO") airlines <- h2o.importFile("http://s3.amazonaws.com/h2o-public-test-data/smalldata/airlines/allyears2k_headers.zip") # 将类别列转为因子 airlines["Year"] <- as.factor(airlines["Year"]) airlines["Month"] <- as.factor(airlines["Month"]) airlines["DayOfWeek"] <- as.factor(airlines["DayOfWeek"]) airlines["Cancelled"] <- as.factor(airlines["Cancelled"]) airlines['FlightNum'] <- as.factor(airlines['FlightNum']) # 指定预测变量与响应列 predictors <- c("Origin", "Dest", "Year", "UniqueCarrier", "DayOfWeek", "Month", "Distance", "FlightNum") response <- "IsDepDelayed" # 划分训练集与验证集 airlines_splits <- h2o.splitFrame(data = airlines, ratios = 0.8, seed = 1234) train <- airlines_splits[[1]] valid <- airlines_splits[[2]] # 使用 AUC 作为早停指标,配合 stopping_rounds 与 stopping_tolerance airlines_gbm <- h2o.gbm(x = predictors, y = response, training_frame = train, validation_frame = valid, stopping_metric = "AUC", stopping_rounds = 3, stopping_tolerance = 1e-2, seed = 1234) # 打印验证集 AUC print(h2o.auc(airlines_gbm, valid = TRUE))七、进阶:custom 与 custom_increasing 自定义早停指标
当内置指标无法满足业务需求时,可使用custom(越小越好)或custom_increasing(越大越好)接入自定义评估函数。目前该能力仅在 Python 客户端中,且仅 GBM 与 DRF 支持(见 Python 估算器签名 estimators/gbm.py)。
自定义指标本质是一个提供map/reduce/metric三个方法的类,分别对应分布式计算中的逐行映射、结果合并与最终指标计算(详见 custom_functions.md)。官方文档给出的自定义 RMSE 指标示例完整复现如下:
# 创建自定义 RMSE 模型指标并保存为 mm_rmse.py # 注意:其中引用了 Java 类 java.lang.Math class CustomRmseFunc: def map(self, pred, act, w, o, model): idx = int(act[0]) err = 1 - pred[idx + 1] if idx + 1 < len(pred) else 1 return [err * err, 1] def reduce(self, l, r): return [l[0] + r[0], l[1] + r[1]] def metric(self, l): # 直接调用 Java API import java.lang.Math as math return math.sqrt(l[0] / l[1]) # 将自定义指标上传到 H2O 集群 custom_mm_func = h2o.upload_custom_metric(CustomRmseFunc, func_name="rmse", func_file="mm_rmse.py") # 训练时指定 custom_metric_func 与 stopping_metric="custom" model = H2OGradientBoostingEstimator(ntrees=3, max_depth=5, score_each_iteration=True, custom_metric_func=custom_mm_func, stopping_metric="custom", stopping_tolerance=0.1, stopping_rounds=3) model.train(x=predictors, y=response, training_frame=train, validation_frame=valid)实现原理上,upload_custom_metric会把类源码保存为文件、打成 zip 归档并存入 H2O 的 K/V 存储;返回的引用形如python:rmse=mm_rmse.CustomRmseFuncWrapper。custom_metric_func参数接受该引用,训练过程中通过专用类加载器在分布式环境下动态加载并执行(custom_functions.md)。注意func_name与func_file对每个自定义指标必须唯一。
八、选型建议与注意事项
- 分类任务优先考虑 logloss 或 AUC:两者均带 0 下界或明确方向,收敛判定稳定;类别不平衡时可考虑
AUCPR。 - 回归任务用 deviance、MSE 或 RMSE:AUTO 默认 deviance,但业务口径上 MSE/RMSE 更直观。
- 异常检测用 anomaly_score:它是唯一"无方向"指标,采用双侧区间判据,不要在回归/分类任务中使用。
- UpliftDRF 场景:只能使用
AUUC、qini、ATE、ATT、ATC中的指标,AUTO 会落到AUUC。 - 必须配合
stopping_rounds使用,否则stopping_metric与stopping_tolerance会被忽略(仅产生警告,不会报错,容易踩坑)。 - 网格搜索时固定这三个参数,作为运行控制而非超参数维度(grid-search.rst)。
- 校验失败信息均来自 hex/ModelBuilder.java:例如回归模型使用
misclassification、非 GLM 分类模型使用deviance、custom未定义custom_metric_func都会在训练前被明确拒绝。
综上,stopping_metric是 H2O-3 早停机制的核心选参,理解其枚举取值、AUTO 默认映射与移动平均收敛判据,是高效调优 GBM、XGBoost、Deep Learning 等模型训练时长的关键一步。相关源码与文档可进一步查阅 ScoreKeeper.java、Model.java、ModelBuilder.java 及配套参数文档 stopping_rounds.rst、stopping_tolerance.rst。
- 机器学习
- 深度学习
- AutoML
- 大数据
- 后端
【免费下载链接】h2o-3
H2O is an Open Source, Distributed, Fast & Scalable Machine Learning Platform: Deep Learning, Gradient Boosting (GBM) & XGBoost, Random Forest, Generalized Linear Modeling (GLM with Elastic Net), K-Means, PCA, Generalized Additive Models (GAM), RuleFit, Support Vector Machine (SVM), Stacked Ensembles, Automatic Machine Learning (AutoML), etc.
相关推荐
NNI Assessor 早停机制详解:Median Stop 与 Curve Fitting 的原理、配置与实战
NNI Assessor 早停机制详解:Median Stop 与 Curve Fitting 的原理、配置与实战 在超参数调优(HPO)场景中,并非所有超参数
人工智能AutoML机器学习深度学习模型压缩特征工程H2O-3 GBM learn_rate 参数详解:学习率原理、取值范围与实战调优
H2O 3 GBM learn_rate 参数详解:学习率原理、取值范围与实战调优 learn_rate (学习率)是 H2O 3 中 GBM、XGBoost
机器学习深度学习AutoML大数据后端H2O-3 CoxPH 的 stop_column 参数:生存分析中的事件停止时间列配置与实现原理
H2O 3 CoxPH 的 stop_column 参数:生存分析中的事件停止时间列配置与实现原理 本文围绕 H2O 3 分布式机器学习平台中 CoxPH(Co
机器学习深度学习AutoML大数据后端
创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考