如何从BoostedTrees估计器迁移到TensorFlow决策森林

128 阅读6分钟

Mathieu Guillame-BertJosh Gordon为TensorFlow团队发布

随机森林梯度提升树这样的决策森林模型通常是处理表格数据的最有效工具。与神经网络相比,它们有很多优势,包括更容易配置,更快训练。使用树可以大大减少准备数据集所需的代码量,因为它们可以自然地处理数字、分类和缺失特征。而且,它们通常能提供开箱即用的良好结果,并具有可解释的属性。

虽然我们通常认为TensorFlow是一个训练神经网络的库,但在谷歌,一个流行的用例是使用TensorFlow来创建决策森林。

一个决策树分类数据的动画。

如果你之前使用2019年推出的 tf.estimator.BoostedTrees创建基于树的模型,本文提供了一个迁移指南。Estimator API处理了在生产中使用模型的大部分复杂性,包括分布式训练和序列化。然而,它不再被推荐用于新代码。

如果你开始一个新的项目,我们建议你使用TensorFlow Decision Forests(TF-DF)。这个库为训练、服务和解释决策森林模型提供了最先进的算法,与以前的方法相比有很多好处,特别是在质量、速度和易用性方面。

首先,这里是使用Estimator API和TF-DF创建一个提升树模型的等效例子。

以前,你是这样用tf.estimator.BoostedTrees训练梯度提升树模型的(不再推荐)。

pythonimport tensorflow as tf# Dataset generatorsdef make_dataset_fn(dataset_path):    def make_dataset():        data = ... # read dataset        return tf.data.Dataset.from_tensor_slices(...data...).repeat(10).batch(64)    return make_dataset# List the possible values for the feature "f_2".f_2_dictionary = ["NA", "red", "blue", "green"]# The feature columns define the input features of the model.feature_columns = [    tf.feature_column.numeric_column("f_1"),    tf.feature_column.indicator_column(       tf.feature_column.categorical_column_with_vocabulary_list("f_2",         f_2_dictionary,         # A special value "missing" is used to represent missing values.         default_value=0)       ),    ]# Configure the estimatorestimator = boosted_trees.BoostedTreesClassifier(          n_trees=1000,          feature_columns=feature_columns,          n_classes=3,          # Rule of thumb proposed in the BoostedTreesClassifier documentation.          n_batches_per_layer=max(2, int(len(train_df) / 2 / FLAGS.batch_size)),      )# Stop the training is the validation loss stop decreasing.early_stopping_hook = early_stopping.stop_if_no_decrease_hook(      estimator,      metric_name="loss",      max_steps_without_decrease=100,      min_steps=50)tf.estimator.train_and_evaluate(      estimator,      train_spec=tf.estimator.TrainSpec(          make_dataset_fn(train_path),          hooks=[              # Early stopping needs a CheckpointSaverHook.              tf.train.CheckpointSaverHook(                  checkpoint_dir=input_config.raw.temp_dir, save_steps=500),              early_stopping_hook,          ]),      eval_spec=tf.estimator.EvalSpec(make_dataset_fn(valid_path)))

如何使用TensorFlow决策森林来训练相同的模型

pythonimport tensorflow_decision_forests as tfdf# Load the datasets# This code is similar to the estimator.def make_dataset(dataset_path):    data = ... # read dataset    return tf.data.Dataset.from_tensor_slices(...data...).batch(64)train_dataset = make_dataset(train_path)valid_dataset = make_dataset(valid_path)# List the input features of the model.features = [  tfdf.keras.FeatureUsage("f_1", keras.FeatureSemantic.NUMERICAL),  tfdf.keras.FeatureUsage("f_2", keras.FeatureSemantic.CATEGORICAL),]model = tfdf.keras.GradientBoostedTreesModel(  task = tfdf.keras.Task.CLASSIFICATION,  num_trees=1000,  features=features,  exclude_non_specified_features=True)model.fit(train_dataset, valid_dataset)# Export the model to a SavedModel.model.save("project/model")

备注

  • 虽然在这个例子中没有明确说明,但早期停止是自动启用和配置的。
  • f_2 "特征的字典是自动建立和优化的(例如,稀有值被合并到一个词汇表外的项目中)。
  • 类的数量(在这个例子中是3)是由数据集自动决定的。
  • 批量大小(本例中为64)对模型训练没有影响。较大的值通常是最好的,因为它使读取数据集更有效率。

TF-DF是关于易用性的,前面的例子可以进一步简化和改进,如下所示。

如何训练TensorFlow Decision Forests(推荐方案)

import tensorflow_decision_forests as tfdfimport pandas as pd# Pandas dataset can be used easily with pd_dataframe_to_tf_dataset.train_df = pd.read_csv("project/train.csv")# Convert the Pandas dataframe into a TensorFlow dataset.train_ds = tfdf.keras.pd_dataframe_to_tf_dataset(train_df, label="my_label")model = tfdf.keras.GradientBoostedTreeModel(num_trees=1000)model.fit(train_dataset)

备注

  • 我们没有指定特征的语义(例如,数字,或分类)。在这种情况下,语义将被自动推断出来。
  • 我们也没有列出要使用哪些输入特征。在这种情况下,所有的列(除了标签)都将被使用。输入特征的列表和语义在训练日志中可以看到,或者用模型检查器的API也可以看到。
  • 我们没有指定任何验证数据集。每个算法都会选择性地从训练实例中提取一个验证数据集,这对算法来说是最好的。例如,如果没有提供验证数据集,GradientBoostedTreeModel默认使用10%的训练数据进行验证。

现在,让我们看看Estimator API和TF-DF之间的一些区别。

估算器API和TF-DF之间的区别

算法的类型

TF-DF是一个决策森林算法的集合。这包括(但不限于)Estimator API中的梯度提升树。值得注意的是,TF-DF还支持随机森林(非常适合多事的数据集)和一个CART%20and%20a-,CART,-implementation%20(great%20for)实现(非常适合模型解释)。

此外,对于这些算法中的每一种,TF-DF都包括了许多在文献中发现并在实验中验证的变化[1,2,3]。

精确与近似的拆分

TF1 GBT估算器是一种近似的树状学习算法。非正式地,估计器在每一步只考虑一个随机的例子子集和一个随机的条件子集来建立树。

默认情况下,TF-DF是一个精确的树训练算法。非正式地,TF-DF在每一步都考虑所有的训练例子和所有可能的分割。这是一个更常见的、通常性能更好的解决方案。

虽然有时在较大的数据集(>10B的例子x特征)上更快,但估计器的近似值往往不太准确(因为需要生长更多的树来达到相同的质量)。在一个小的数据集(<1亿个例子x特征)中,估计器中实现的近似训练形式甚至会比精确训练更慢。

TF-DF也支持各种类型的 "近似 "树训练。推荐的方法是使用精确训练,并选择在大数据集上测试近似训练。

推理

估算器使用自上而下的树形路由算法运行模型推理。TF-DF使用QuickScorer算法的一个扩展。

虽然这两种算法返回的结果完全相同,但自上而下的算法效率较低,因为超过了分支预测和高速缓存的错过。TF-DF推理在相同的模型上一般要快10倍。

对于延迟关键应用,TF-DF提供了一个C++ API。它提供的推理时间往往是~1µs/例子/核心。这通常比TF SavedModel推断的速度提高了50倍-1000倍(特别是在小批量上)。

多头模型

估算器支持多头模型(一个可以输出多个预测的模型)。TF-DF(目前)不直接支持多头模型,但是,使用Keras Functional API,多个并行训练的TF-DF模型可以组装成一个多头模型。

学习更多

你可以通过访问网站了解更多关于TensorFlow Decision Forests的信息。如果你是这个库的新手,初学者的例子是一个好的开始。有经验的TensorFlow用户可以访问本指南,了解在TensorFlow中使用决策森林和神经网络之间的重要细节,包括如何配置你的训练管道,以及数据集I/O的提示。你也可以看看从Estimator迁移到Keras APIs,了解更多关于从Estimator迁移到Keras的一般信息。