如何改进模型?¶
本文提供有关如何改进 YDF 模型的质量、速度和大小的建议。改进的程度将取决于数据集。在某些情况下,变化会很小,而在其他情况下,可能会很大。无法预先知道给定更改会产生多少改进。
本指南分为两章:优化模型质量和优化模型速度。在大多数情况下,提高模型质量也会使其更大更慢,反之亦然。换句话说,模型的预测质量通常与其大小相关联。
对决策森林的工作原理有一个基本的了解有助于对其进行优化。欲了解更多信息,请参阅Google 的决策森林课程。
超参数页面列出了并解释了可用的超参数。
随机森林还是梯度提升树?¶
随机森林 (RF) 和 梯度提升树 (GBT) 是用于训练决策森林的两种不同算法。每种算法都有其优点和缺点。总的来说,RF 比 GBT 更不容易过拟合,是小型数据集和具有大量输入特征的数据集的良好选择。另一方面,GBT 比 RF 学习效率更高。此外,GBT 模型通常比可比的 RF 模型小得多,推理速度也更快。
优化速度时,请使用 GBT。优化质量时,应同时测试两种算法。
警告:两种算法都有共同的超参数,例如树的数量和最大树深度。但是,这些超参数在每种算法中扮演着不同的角色,应相应地进行调优。例如,GBT 的最大树深度通常在 3 到 8 之间,而 RF 中很少小于 16。
优化模型质量¶
自动化超参数调优¶
自动化超参数调优是一种简单但昂贵的解决方案,可以提高模型质量。当完全超参数调优过于昂贵时,结合超参数调优和手动调优是一个很好的解决方案。
详细信息请参阅调优笔记本。
超参数模板¶
YDF 学习器的默认超参数设置为重现最初发布的算法,新方法默认禁用。
因此,默认参数并未针对性能进行优化,这可能会导致合理但不理想的结果。为了在不理解这些超参数且无需运行超参数调优的情况下从最新的 YDF 算法中受益,YDF 提供了预配置的超参数模板。
通过在学习器上调用hyperparameter_templates可以使用超参数模板。
# List the available templates for the GBT learner.
templates = ydf.GradientBoostedTreesLearner.hyperparameter_templates()
print(templates)
# Use the "better_defaultv1" template:
learner = ydf.GradientBoostedTreesLearner(**templates["better_defaultv1"], ...)
超参数模板也可在超参数页面上找到。请注意,不同的学习器有不同的模板。
增加树的数量¶
参数 num_trees
控制模型中的树数量。增加树的数量通常可以提高模型质量。默认情况下,YDF 训练 300 棵树的模型。对于高质量模型,使用 1000 棵或更多树有时很有价值。
注意:使用提前停止(默认行为)训练梯度提升树模型时,提前停止可能会将模型中的树数量减少到小于“num_trees”的值。
使用斜树¶
默认情况下,树是“正交”或“轴对齐”的,也就是说,每个切分/条件只测试一个特征。与此相反,斜树中的条件可以使用多个特征。斜切分通常可以提高性能,但训练速度较慢。
斜树训练成本更高。参数 num_projections_exponent
在训练时间和最终模型质量中起着重要作用(1 便宜,2 更好但更贵)。有关详细信息,请参阅DecisionTreeTrainingConfig 中的 SparseObliqueSplit
。
learner = ydf.RandomForestLearner(
split_axis="SPARSE_OBLIQUE",
sparse_oblique_normalization="MIN_MAX",
sparse_oblique_num_projections_exponent=1.0,
...)
随机分类切分 (GBT 和 RF)¶
默认情况下,分类切分使用 CART 分类算法学习。随机分类算法是另一种解决方案,可以提高模型性能,但会牺牲模型大小。
减少收缩率 [仅限 GBT]¶
“收缩率”,有时称为“学习率”,决定了 GBT 模型学习的速度。学习慢可以提高模型质量。shrinkage
默认值为 0.1。您可以尝试 0.05 或 0.02。
GBT 的其他有影响力的超参数¶
虽然所有超参数都可以提高模型质量,但某些超参数的影响比其他超参数更大。除了上述参数之外,以下是 GBT 最重要的参数:
use_hessian_gain
(默认False
)。例如,尝试use_hessian_gain=True
。max_depth
(默认6
)。例如,尝试max_depth=5
。num_candidate_attributes_ratio
(默认1
)。例如,尝试num_candidate_attributes_ratio=0.9
。min_examples
(默认5
)。例如,尝试min_examples=10
。growing_strategy
(默认"LOCAL"
)。例如,尝试growing_strategy="BEST_FIRST_GLOBAL"
。
注意:当使用 growing_strategy=LOCAL
(默认)训练模型时,调优 max_depth
参数(默认 6)通常是有益的。当使用 growing_strategy=BEST_FIRST_GLOBAL
训练模型时,最好不要限制 max_depth
(默认 -1),而是调优 max_num_nodes
参数。
禁用验证数据集 (仅限 GBT)¶
默认情况下,如果未提供验证数据集,梯度提升树学习器会从训练数据集中提取 10% 的数据来构建验证数据集,以控制提前停止(即当模型开始过拟合时停止训练)。
对于小型数据集和大型数据集,最好使用所有数据进行训练(因此禁用提前停止)。在这种情况下,应调优 num_trees
参数。
警告:禁用提前停止可能会导致模型过拟合。为避免这种情况,首先启用提前停止运行训练,以确定最佳树数量。例如,如果提前停止在训练结束前从未触发,您可能可以禁用它(并使用额外的数据进行训练)。如果提前停止总是在给定树数量附近触发,您也可以这样做。请记住,更改任何其他超参数都需要重新测试提前停止的行为。
优化模型速度(和大小)¶
模型的速度和大小受到输入特征数量、树数量和平均树深度的限制。
您可以使用 benchmark 方法测量模型的推理速度。
结果示例
Inference time per example and per cpu core: 0.702 us (microseconds)
Estimated over 441 runs over 3.026 seconds.
* Measured with the C++ serving API. Check model.to_cpp() for details.
从随机森林切换到梯度提升树¶
随机森林模型比梯度提升树模型大得多且慢得多。当速度很重要时,请使用梯度提升树模型。
# Before
learner = ydf.RandomForestLearner(...)
# After
learner = ydf.GradientBoostedTreesLearner(...)
减少树的数量¶
参数 num_trees
控制模型中的树数量。减少此参数会减小模型大小,但会牺牲模型质量。
注意:使用提前停止(默认行为)训练梯度提升树模型时,提前停止可能会将模型中的树数量减少到小于“num_trees”的值。
当使用 growing_strategy="BEST_FIRST_GLOBAL"
进行训练时,最好不要限制最大树数量,而是优化 max_num_nodes
。
移除模型调试数据¶
YDF 模型包含用于模型解释和调试的元数据。此元数据不用于模型推理,可以丢弃以减小模型大小。移除此数据通常会使模型大小减少约 50%。移除此数据不会提高模型的速度。
要训练不含元数据的模型,请将学习器构造函数参数 pure_serving_model
设置为 True
。
如果使用 CLI API,可以使用 edit_model
CLI 工具移除元数据
# Remove the meta-data from the model
./edit_model --input=/tmp/model_with_metadata --output=/tmp/model_without_metadata --pure_serving=true
# Look at the size of the model
du -h /tmp/model_with_metadata
du -h /tmp/model_without_metadata
在随机森林中设置 winner_take_all_inference=False¶
随机森林学习器的 winner_take_all_inference
参数默认设置为 True。这确保了默认情况下,YDF 随机森林等同于 Breiman 最初的随机森林。
但是,在许多情况下,winner_take_all=False
可以减小随机森林模型的大小并提高其质量。
设置 maximum_model_size_in_memory_in_bytes=...
¶
参数 maximum_model_size_in_memory_in_bytes
控制模型在 RAM 中的最大大小。通过设置此值,您可以控制模型的最终大小。
模型在 RAM 中的大小可能大于模型在磁盘上的大小。加载模型时使用的 RAM 对应于模型在 RAM 中的大小。运行模型推理之前,模型会被编译成一种通常更小的格式。
# Model limited to 10GB
learner = ydf.RandomForestLearner(maximum_model_size_in_memory_in_bytes=10e+9, ...)
不同的学习算法强制执行最大大小的方式不同。
增加收缩率 [仅限 GBT]¶
“收缩率”,有时称为“学习率”,决定了 GBT 模型学习的速度。学习过快通常会导致较差的结果,但会生成更小、训练更快、运行更快的模型。shrinkage
默认值为 0.1。您可以尝试 0.15 甚至 0.2。