- 机器学习
- 深度学习
- 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.
导读
gainslift_bins是 H2O-3 平台中控制二分类模型Gains/Lift 表(提升度/增益表)分箱数量的核心参数。它直接决定了模型评估输出中每个分组的预测分数阈值划分方式,并深刻影响基于分组统计的Kolmogorov-Smirnov (KS) 指标的精度与稳定性。本文将以 H2O-3 官方参数文档 gainslift_bins.rst 为骨架,结合 h2o-core 源码中 GainsLift.java 的实现逻辑,为你讲透该参数的语义、取值规则、底层计算原理,并给出 R 与 Python 双语言的可运行示例与实测验证方法。
参数概览:适用算法与基本语义
适用算法范围
根据官方文档,gainslift_bins可用于以下 H2O 算法:
- Deeplearning(深度学习)
- DRF(分布式随机森林)
- GAM(广义可加模型)
- GBM(梯度提升机)
- GLM(广义线性模型)
- Naïve-Bayes(朴素贝叶斯)
- Stacked Ensemble(集成模型)
- XGBoost
该参数属于模型超参数(Hyperparameter),但官方文档明确标注为Hyperparameter: no,即不可用于网格搜索(Grid Search)调优。这一点在 Python 客户端 GBM 估计器的实现中也有对应体现(见 gbm.py 第 2177-2197 行,属性通过_parms字典直接读写,无 gridable 标记)。
基本语义
gainslift_bins指定 Gains/Lift 表的分箱(bin)数量:
- 默认值为
-1:表示自动分箱(automatic binning); - 设置为
0:表示完全禁用 Gains/Lift 表计算; - 设置为正整数(如
20):表示将预测分数按该数量分成指定数目的组。
为什么需要关注分箱:KS 指标与 Gains/Lift 表的关系
官方文档明确指出,Kolmogorov-Smirnov (KS) 指标表示二分类模型中正例(positive)与负例(negative)分布函数之间的分离程度,而每个分组的详细指标可以在 Gains/Lift 表中找到。两者是同一套统计计算的一体两面:
- Gains/Lift 表:将全部样本按预测概率从高到低排序后等分为若干组,逐组统计事件数、观测数、响应率、提升度(Lift)、增益(Gain)、捕获率(Capture Rate)等指标;
- KS 指标:正是由 Gains/Lift 表中每个分组的累计正例比例与累计负例比例之差(
cum_event - cum_non_event)取最大值得到的。
在 GainsLift.java 的createTwoDimTable()方法中,可以看到这张表共包含 14 列:Group、Cumulative Data Fraction、Lower Threshold、Lift、Cumulative Lift、Response Rate、Score、Cumulative Response Rate、Cumulative Score、Capture Rate、Cumulative Capture Rate、Gain、Cumulative Gain、Kolmogorov Smirnov。
其中:
Lift = p_i / P(分组响应率 ÷ 总体平均响应率);Gain = 100 × (Lift - 1);Kolmogorov Smirnov = cum_event - cum_non_event。
当P == 0(即总体无正例)时 Lift 为NaN,源码中对此有专门处理(第 168-169 行)。
取值规则与底层校验
在 Model.java 第 550-553 行,参数被定义在基类Parameters中:
/** * Bins for Gains/Lift table, if applicable. Ignored if G/L are not calculated. */ public int _gainslift_bins = -1;而真正决定该参数行为的逻辑位于 ModelMetricsBinomial.java 第 310-321 行的calculateGainsLift()方法:
private Optional<GainsLift> calculateGainsLift(Model m, Frame preds, Vec resp, Vec weights) { final GainsLift gl = new GainsLift(preds.lastVec(), resp, weights); if (m != null && m._parms._gainslift_bins < -1) { throw new IllegalArgumentException("Number of G/L bins must be greater or equal than -1."); } else if (m != null && (m._parms._gainslift_bins > 0 || m._parms._gainslift_bins == -1)) { gl._groups = m._parms._gainslift_bins; } else if (m != null && m._parms._gainslift_bins == 0){ return Optional.empty(); } gl.exec(m != null ? m._output._job : null); return Optional.of(gl); }由此可以总结出三条明确的取值规则:
| 取值 | 行为 | 说明 |
|---|---|---|
-1(默认) | 自动分箱 | 采用默认概率分位点集合进行分箱 |
0 | 禁用 | 不计算 Gains/Lift 表,Optional.empty()直接返回 |
> 0(正整数) | 固定分组数 | 将样本等分为 N 组(如 20 组) |
< -1 | 抛异常 | IllegalArgumentException: Number of G/L bins must be greater or equal than -1. |
自动分箱(-1)与固定分箱(N)的区别
在GainsLift.exec()内部,分箱分位点的计算方式截然不同(见 GainsLift.java 第 95-102 行):
- 固定分组(
_groups > 0):概率分位点由公式probs[i] = (_groups - i - 1.0) / _groups计算,即0.9, 0.8, 0.7, ... , 0.1, 0(以 10 组为例),样本被严格等分为 N 组; - 自动分箱(
_groups == -1):使用默认概率分位点集合{0.99, 0.98, 0.97, 0.96, 0.95, 0.9, 0.85, 0.8, 0.7, 0.6, 0.5, 0.4, 0.3, 0.2, 0.1, 0},即最多可产生 16 个非均匀分组(去重后实际组数取决于数据分布)。
分位点的计算借助 H2O 的Quantile(分位数)模型完成,支持权重列(_weights_column),并且会通过TreeSet对计算出的分位点去重(第 106-111 行),保证每个分组的阈值严格递减且互不重复。
实操示例:R 与 Python 完整代码
R 语言示例
以下示例来自官方文档,完整演示了从导入数据到打印 Gains/Lift 表的全过程:
library(h2o) h2o.init() # import the airlines dataset: airlines <- h2o.importFile("https://s3.amazonaws.com/h2o-public-test-data/smalldata/testng/airlines_train.csv") # build and train the model: model <- h2o.gbm(x = c("Origin", "Distance"), y = "IsDepDelayed", training_frame = airlines, ntrees = 1, gainslift_bins = 20) # print the Gains/Lift table for the model: print(h2o.gainsLift(model))在 R 客户端中,h2o.gainsLift()是提取 Gains/Lift 表的统一入口(见 models.R 第 4730-4768 行),它支持:
h2o.gainsLift(model) ## 提取训练指标 h2o.gainsLift(model, valid = TRUE) ## 提取验证集指标 h2o.gainsLift(model, xval = TRUE) ## 提取交叉验证指标 h2o.gainsLift(model, newdata = prostate) ## 在新数据上评分 h2o.gainsLift(perf) ## 从已有 metrics 对象提取同时,R 客户端还提供了h2o.kolmogorov_smirnov()方法,直接从 Gains/Lift 表中取kolmogorov_smirnov列的最大值作为 KS 指标(第 4795-4821 行)。
Python 示例
Python 侧同样沿用官方文档的示例(使用H2OGradientBoostingEstimator):
import h2o from h2o.estimators import H2OGradientBoostingEstimator h2o.init() # import the airlines dataset: airlines = h2o.import_file("https://s3.amazonaws.com/h2o-public-test-data/smalldata/testng/airlines_train.csv") # build and train the model: model = H2OGradientBoostingEstimator(ntrees=1, gainslift_bins=20) model.train(x=["Origin", "Distance"], y="IsDepDelayed", training_frame=airlines) # print the Gains/Lift table for the model: print(model.gains_lift())在 Python 客户端中:
model.gains_lift()返回模型指标中的gains_lift_table(见 binomial.py 第 877-899 行);model.gains_lift_plot()可绘制 Gains/Lift 曲线,支持type="both"、"gains"、"lift"三种模式(第 901-919 行);- 通过
model.model_performance(data).gains_lift()可以在任意新数据上重新计算 Gains/Lift 表。
Python 估计器类中,gainslift_bins作为构造参数接受None或int类型(如 gbm.py 第 2177-2197 行),设置后会写入_parms["gainslift_bins"]并随训练请求发送到服务端。
源码级验证:分箱对 KS 精度的影响
仓库中的测试 pyunit_gainslift_bins.py 用一套非常直观的方法验证了分箱数量与 KS 指标精度的关系:
mod_default = fast_estimator(Estimator) mod_default.train(y=y, training_frame=df) assert_not_eq(get_ks(mod_default, df), ks_score(mod_default, df, y)) # 默认直方图不够精确 mod_glbins = fast_estimator(Estimator, gainslift_bins=df.nrow) mod_glbins.train(y=y, training_frame=df) assert_eq(get_ks(mod_glbins, df), ks_score(mod_glbins, df, y)) # 应该得到精确统计量测试的结论极具实战价值:
- 默认自动分箱(-1)时,基于直方图(最多 16 组)计算出的 KS 值与
scipy.stats.ks_2samp直接计算的结果存在偏差(assert_not_eq通过); - 将
gainslift_bins设置为样本行数(df.nrow)时,即“每组一行”的极限分箱,KS 值与ks_2samp的结果完全一致(assert_eq通过)。
该测试覆盖了 Deeplearning、DRF、GAM、GBM、GLM、XGBoost 以及 Stacked Ensemble 全部七种适用算法(见第 80-129 行),为参数行为的正确性提供了系统性保障。
底层计算层面,GainsLift.java 中的GainsLiftBuilder是一个基于MRTask的分布式 map-reduce 任务(第 199-277 行),逐行将样本按预测概率落入对应分箱,并累加_events、_observations、_avg_scores等统计量,最终在postGlobal()阶段计算各组的响应率与平均分数。这意味着分箱逻辑天然支持大规模分布式计算。
此外,GainsLiftTest.java 中还包含对常数预测、良好排序、错误排序、随机预测、平局/NA 预测、不平衡数据、罕见事件、权重列以及标签基数校验(仅接受二分类标签)等 12 个场景的单元测试,可用于深入理解边界行为。
边界情况与使用建议
需要留意的边界条件
- 仅适用于二分类(binomial)模型:底层
GainsLiftBuilder在map()阶段对标签值进行硬校验,非 0/1 值直接抛出IllegalArgumentException(见 GainsLift.java 第 234 行);init()阶段也要求标签列为整数且基数为 2(第 52-53 行); - 不可用于网格搜索:
gainslift_bins不是 hyperparameter,不能放进search_criteria进行调参; - NA 处理:标签或预测概率为 NA 的样本行会在统计时被跳过(第 232、235 行),权重为 0 的样本同样不计入(
perRow中if (w==0) return;); - 分组数与数据量的匹配:当分组数大于样本数时,部分分箱可能为空,响应率按 0 处理,KS 计算的精度提升也随之饱和(这正是测试中直接取
df.nrow即可对齐 scipy 结果的原因)。
实战选型建议
- 快速评估 / 默认场景:保持
gainslift_bins = -1,自动分箱开销小、结果稳定,适合模型对比与初步筛选; - 精细化 KS 分析:若需要精确的 KS 值或细粒度分组洞察(如营销响应建模中的 Top-decile Lift),建议设置
gainslift_bins = 20甚至更高(如 100),并结合h2o.gainsLift(model)/model.gains_lift()查看逐组Lift、Gain、Capture Rate; - 完全关闭:当不需要 Gains/Lift 评估且希望节省指标计算开销时,显式设置
gainslift_bins = 0。
总结
gainslift_bins虽是一个不起眼的“次级参数”(API level 为 secondary),却直接决定了 H2O-3 二分类模型 Gains/Lift 表与 KS 指标的粒度和精度:
-1自动分箱,适合默认使用;0完全禁用;- 正整数自定义分组数,可在精度与开销之间自由权衡,极限情况下可对齐
scipy.stats.ks_2samp的精确结果。
其核心实现在 GainsLift.java(分箱统计)、ModelMetricsBinomial.java(参数分发与校验)以及 Model.java(参数定义)三处,配合 pyunit_gainslift_bins.py 与 GainsLiftTest.java 的测试体系,构成了从参数到指标、从单机到分布式集群的完整闭环。理解并善用这一参数,将帮助你在营销响应、信用评分、风险预警等二分类业务场景中获得更可靠、更细粒度的模型评估视图。
- 机器学习
- 深度学习
- 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.
相关推荐
QOwnNotes 命令行参数完全指南:从启动控制到加密笔记解密
QOwnNotes 命令行参数完全指南:从启动控制到加密笔记解密 QOwnNotes 是支持 Markdown 与 Nextcloud / ownCloud 同
桌面应用VLC鼠标控制播放插件完全指南:从安装到精通
VLC鼠标控制播放插件完全指南:从安装到精通 一、认识这款神奇的VLC插件 🖱️▶️ 想象一下:看电影时伸手去够键盘的播放键,结果打翻了桌上的咖啡;想暂停视频
音视频插件系统如何快速上手SAM3D?从安装到首次3D分割的完整指南
如何快速上手SAM3D?从安装到首次3D分割的完整指南 SAM3D(Segment Anything in 3D Scenes)是一款强大的3D场景分割工具,能
创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考