Python 基于直方图的梯度提升集成方法

Python中文社区

共 9627字,需浏览 20分钟

 ·

2021-01-12 03:44

梯度提升是决策树算法的集合。鉴于它在实践中在各种数据集上表现出色,它可能是针对结构化(表格)分类和回归预测建模问题的最受欢迎的技术之一。梯度提升的主要问题是训练模型的速度较慢。在具有成千上万个示例(行)的大型数据集上使用模型时,这尤其是一个问题。通过将连续输入变量离散化(合并)为数百个唯一值,可以大大加快对添加到集合中的树的训练。实现此技术并在此变换下围绕输入变量定制训练算法的梯度增强合奏称为基于直方图的梯度增强合奏。
在本教程中,您将发现如何开发基于直方图的梯度增强树集成体。完成本教程后,您将知道:
  • 基于直方图的梯度增强是一种用于训练梯度增强集成中使用的更快决策树的技术。
  • 如何在scikit-learn库中使用基于直方图的梯度增强的实验实现。
  • 如何将基于直方图的梯度增强与XGBoostLightGBM第三方库结合使用。
教程概述
本教程分为四个部分。他们是:
  • 直方图梯度提升
  • Scikit-Learn直方图梯度增强
  • XGBoost直方图梯度增强
  • LightGBM的直方图梯度增强
直方图梯度提升
梯度提升是一种集成的机器学习算法。Boosting是一类集成学习算法,可将树模型顺序添加到集成中。添加到集合中的每个树模型都尝试纠正由集合中已经存在的树模型造成的预测误差。
梯度增强是将AdaBoost等增强算法推广到一个统计框架,该统计框架将训练过程视为累加模型,并允许使用任意损失函数,从而极大地提高了该技术的能力。因此,对于大多数结构化(例如表格数据)预测建模任务而言,梯度增强合奏是必不可少的技术。尽管梯度提升在实践中表现非常出色,但是模型的训练速度可能很慢。这是因为树必须按顺序创建和添加,这与其他集成模型(如随机森林)不同,在随机森林中,可以利用多个CPU内核并行训练集成成员。这样,已经投入了很多努力来提高梯度增强训练算法的效率。包含许多用于训练梯度增强算法的许多现代效率技术的著名库包括“极端梯度增强(XGBoost)”和“光梯度增强机(LightGBM)”。可以加速的训练算法的一个方面是每个决策树的构造,其速度受训练数据集中的示例数(行)和特征数(列)的限制。大型数据集成千上万个示例甚至更多,可能会导致树木的构建速度非常慢,因为每个值的分割点都必须建立,因为在构建树时必须考虑每个要素。
通过减少连续输入要素的值数量,可以显着加快决策树的构建。这可以通过将值离散化或将值合并到固定数量的存储桶中来实现。这样可以将每个功能的唯一值数量从数万个减少到几百个。这允许决策树对序数存储桶(整数)进行操作,而不是对训练数据集中的特定值进行操作。输入数据的这种粗略近似通常对模型技能几乎没有影响,即使不能提高模型技能,也可以极大地加快决策树的构建。另外,有效的数据结构可用于表示输入数据的合并;例如,例如,可以使用直方图,并且可以进一步调整树构造算法,以在每棵树的构造中有效使用直方图。这些技术最初是在1990年代后期开发的,用于在大型数据集上高效开发单个决策树,但可用于决策树的集成,例如梯度提升。因此,通常将支持现代机器学习库中“直方图”的梯度提升算法称为基于直方图的梯度提升。
现在,我们已经熟悉了在梯度增强中将直方图添加到决策树中的想法,现在让我们回顾一下可以在预测建模项目中使用的一些常见实现。有三种支持该技术的主要库;它们是Scikit-Learn,XGBoost和LightGBM。让我们依次仔细研究一下。注意:我们不是在争夺算法;相反,我们只是在演示如何配置每个实现以使用直方图方法并使所有其他不相关的超参数保持其默认值不变。
Scikit-Learn直方图梯度增强
scikit-learn机器学习库提供了支持直方图技术的梯度提升的实验实现。具体来说,这在HistGradientBoostingClassifier(https://scikit-learn.org/stable/modules/generated/sklearn.ensemble.HistGradientBoostingClassifier.html)和HistGradientBoostingRegressor(https://scikit-learn.org/stable/modules/generated/sklearn.ensemble.HistGradientBoostingRegressor.html)类中提供。为了使用这些类,必须在项目中添加额外的一行,以表明您很高兴使用这些实验技术,并且它们的行为可能随库的后续发行版而改变。
# explicitly require this experimental feature
from sklearn.experimental import enable_hist_gradient_boosting
scikit-learn文档声称,这些基于直方图的梯度增强实现比库提供的默认梯度增强实现快几个数量级。
这些类可以像其他任何scikit-learn模型一样使用。默认情况下,集成为每个连续输入要素使用255个bin,可以通过“ max_bins”参数进行设置。将此值设置为较小的值(例如50或100)可能会进一步提高效率,尽管可能会牺牲一些模型技能。可以通过“ max_iter”参数设置树的数量,默认为100。
# define the model
model = HistGradientBoostingClassifier(max_bins=255, max_iter=100)
以下示例显示了如何在具有10,000个示例和100个特征的综合分类数据集上评估直方图梯度增强算法。使用重复分层k折交叉验证对模型进行评估,并报告所有折叠和重复的平均准确性。
# evaluate sklearn histogram gradient boosting algorithm for classification
from numpy import mean
from numpy import std
from sklearn.datasets import make_classification
from sklearn.model_selection import cross_val_score
from sklearn.model_selection import RepeatedStratifiedKFold
from sklearn.experimental import enable_hist_gradient_boosting
from sklearn.ensemble import HistGradientBoostingClassifier
# define dataset
X, y = make_classification(n_samples=10000, n_features=100, n_informative=50, n_redundant=50, random_state=1)
# define the model
model = HistGradientBoostingClassifier(max_bins=255, max_iter=100)
# define the evaluation procedure
cv = RepeatedStratifiedKFold(n_splits=10, n_repeats=3, random_state=1)
# evaluate the model and collect the scores
n_scores = cross_val_score(model, X, y, scoring='accuracy', cv=cv, n_jobs=-1)
# report performance
print('Accuracy: %.3f (%.3f)' % (mean(n_scores), std(n_scores)))
运行示例将评估综合数据集上的模型性能,并报告均值和标准差分类准确性。注意:由于算法或评估程序的随机性,或者数值精度不同,您的结果可能会有所不同。考虑运行该示例几次并比较平均结果。在这种情况下,我们可以看到scikit-learn直方图梯度提升算法在合成数据集上实现了约94.3%的平均准确度。
Accuracy: 0.943 (0.007)
我们还可以探索垃圾箱数量对模型性能的影响。下面的示例使用50到(大约)250的每个连续输入要素,以不同数量的仓来评估模型的性能。下面列出了完整的示例。
# compare number of bins for sklearn histogram gradient boosting
from numpy import mean
from numpy import std
from sklearn.datasets import make_classification
from sklearn.model_selection import cross_val_score
from sklearn.model_selection import RepeatedStratifiedKFold
from sklearn.experimental import enable_hist_gradient_boosting
from sklearn.ensemble import HistGradientBoostingClassifier
from matplotlib import pyplot
 
# get the dataset
def get_dataset():
 X, y = make_classification(n_samples=10000, n_features=100, n_informative=50, n_redundant=50, random_state=1)
 return X, y
 
# get a list of models to evaluate
def get_models():
 models = dict()
 for i in [1050100150200255]:
  models[str(i)] = HistGradientBoostingClassifier(max_bins=i, max_iter=100)
 return models
 
# evaluate a give model using cross-validation
def evaluate_model(model, X, y):
 # define the evaluation procedure
 cv = RepeatedStratifiedKFold(n_splits=10, n_repeats=3, random_state=1)
 # evaluate the model and collect the scores
 scores = cross_val_score(model, X, y, scoring='accuracy', cv=cv, n_jobs=-1)
 return scores
 
# define dataset
X, y = get_dataset()
# get the models to evaluate
models = get_models()
# evaluate the models and store results
results, names = list(), list()
for name, model in models.items():
 # evaluate the model and collect the scores
 scores = evaluate_model(model, X, y)
 # stores the results
 results.append(scores)
 names.append(name)
 # report performance along the way
 print('>%s %.3f (%.3f)' % (name, mean(scores), std(scores)))
# plot model performance for comparison
pyplot.boxplot(results, labels=names, showmeans=True)
pyplot.show()
通过运行示例评估每种配置,并在此过程中报告均值和标准差分类的准确性,最后创建分数分布图。
注意:由于算法或评估程序的随机性,或者数值精度不同,您的结果可能会有所不同。考虑运行该示例几次并比较平均结果。在这种情况下,我们可以看到增加箱数可能会降低该数据集上模型的平均准确性。我们可能希望增加箱数还可能需要增加树数(max_iter),以确保模型可以有效地探索和利用其他分割点。重要的是,在树中每个变量使用10或50个bin的地方集成一个集合要比每个输入变量255 bin快得多。
>10 0.945 (0.009)
>50 0.944 (0.007)
>100 0.944 (0.008)
>150 0.944 (0.008)
>200 0.944 (0.007)
>255 0.943 (0.007)
创建一个图形,使用箱形图和晶须图比较每个配置的准确性分数分布。
在这种情况下,我们可以看到增加直方图中的bin数量似乎会减少分布的散布,尽管这可能会降低模型的平均性能。

XGBoost直方图梯度增强
Extreme Gradient Boosting,简称XGBoost,是一个提供高度优化的梯度增强实现的库。库中实现的技术之一是对连续输入变量使用直方图。可以使用您喜欢的Python包管理器(例如Pip)安装XGBoost库。例如:
pip install xgboost
我们可以通过XGBClassifier和XGBRegressor类开发用于scikit-learn库的XGBoost模型。
通过将“ tree_method”参数设置为“ approx”,可以将训练算法配置为使用直方图方法,并且可以通过“ max_bin”参数设置箱数。
# define the model
model = XGBClassifier(tree_method='approx', max_bin=255, n_estimators=100)
下面的示例演示了如何评估XGBoost模型,该模型配置为使用直方图或近似技术来构建每个连续输入要素具有255个bin的树,并且该模型中有100棵树。
# evaluate xgboost histogram gradient boosting algorithm for classification
from numpy import mean
from numpy import std
from sklearn.datasets import make_classification
from sklearn.model_selection import cross_val_score
from sklearn.model_selection import RepeatedStratifiedKFold
from xgboost import XGBClassifier
# define dataset
X, y = make_classification(n_samples=10000, n_features=100, n_informative=50, n_redundant=50, random_state=1)
# define the model
model = XGBClassifier(tree_method='approx', max_bin=255, n_estimators=100)
# define the evaluation procedure
cv = RepeatedStratifiedKFold(n_splits=10, n_repeats=3, random_state=1)
# evaluate the model and collect the scores
n_scores = cross_val_score(model, X, y, scoring='accuracy', cv=cv, n_jobs=-1)
# report performance
print('Accuracy: %.3f (%.3f)' % (mean(n_scores), std(n_scores)))
运行示例将评估综合数据集上的模型性能,并报告均值和标准差分类准确性。
注意:由于算法或评估程序的随机性,或者数值精度不同,您的结果可能会有所不同。考虑运行该示例几次并比较平均结果。在这种情况下,我们可以看到XGBoost直方图梯度提升算法在合成数据集上实现了约95.7%的平均准确度。
Accuracy: 0.957 (0.007)
LightGBM的直方图梯度增强
Light Gradient Boosting Machine或简称LightGBM是另一个类似XGBoost的第三方库,它提供了高度优化的梯度增强实现。它可能在XGBoost之前实现了直方图技术,但是XGBoost后来又实现了相同的技术,突出了梯度提升库之间的“梯度提升效率”竞争。可以使用您喜欢的Python软件包管理器(例如Pip)安装LightGBM库。例如:
pip install lightgbm
我们可以通过LGBMClassifier和LGBMRegressor类开发与scikit-learn库一起使用的LightGBM模型。训练算法默认情况下使用直方图。可以通过“ max_bin”参数设置每个连续输入变量的最大仓位。
# define the model
model = LGBMClassifier(max_bin=255, n_estimators=100)
下面的示例演示如何评估LightGBM模型,该模型配置为使用直方图或近似技术来构建每个连续输入要素有255个bin的树,模型中有100棵树。
# evaluate lightgbm histogram gradient boosting algorithm for classification
from numpy import mean
from numpy import std
from sklearn.datasets import make_classification
from sklearn.model_selection import cross_val_score
from sklearn.model_selection import RepeatedStratifiedKFold
from lightgbm import LGBMClassifier
# define dataset
X, y = make_classification(n_samples=10000, n_features=100, n_informative=50, n_redundant=50, random_state=1)
# define the model
model = LGBMClassifier(max_bin=255, n_estimators=100)
# define the evaluation procedure
cv = RepeatedStratifiedKFold(n_splits=10, n_repeats=3, random_state=1)
# evaluate the model and collect the scores
n_scores = cross_val_score(model, X, y, scoring='accuracy', cv=cv, n_jobs=-1)
# report performance
print('Accuracy: %.3f (%.3f)' % (mean(n_scores), std(n_scores)))
运行示例将评估综合数据集上的模型性能,并报告均值和标准差分类准确性。
注意:由于算法或评估程序的随机性,或者数值精度不同,您的结果可能会有所不同。考虑运行该示例几次并比较平均结果。在这种情况下,我们可以看到,LightGBM直方图梯度提升算法在合成数据集上实现了约94.2%的平均准确度。
Accuracy: 0.942 (0.006)
下面给出来一些相关的教程链接和文档接口说明。
接口
  • sklearn.ensemble.HistGradientBoostingClassifier API.
https://scikit-learn.org/stable/modules/generated/sklearn.ensemble.HistGradientBoostingClassifier.html
  • sklearn.ensemble.HistGradientBoostingRegressor API.
https://scikit-learn.org/stable/modules/generated/sklearn.ensemble.HistGradientBoostingRegressor.html
  • XGBoost, Fast Histogram Optimized Grower, 8x to 10x Speedup
https://github.com/dmlc/xgboost/issues/1950
  • xgboost.XGBClassifier API.
https://xgboost.readthedocs.io/en/latest/python/python_api.html#xgboost.XGBClassifier
  • xgboost.XGBRegressor API.
https://xgboost.readthedocs.io/en/latest/python/python_api.html#xgboost.XGBRegressor
  • lightgbm.LGBMClassifier API.
https://lightgbm.readthedocs.io/en/latest/pythonapi/lightgbm.LGBMClassifier.html
  • lightgbm.LGBMRegressor API.
https://lightgbm.readthedocs.io/en/latest/pythonapi/lightgbm.LGBMRegressor.html


作者:沂水寒城,CSDN博客专家,个人研究方向:机器学习、深度学习、NLP、CV

Blog: http://yishuihancheng.blog.csdn.net


赞 赏 作 者



更多阅读



2020 年最佳流行 Python 库 Top 10


2020 Python中文社区热门文章 Top 10


Top 10 沙雕又有趣的 GitHub 程序

特别推荐




点击下方阅读原文加入社区会员

浏览 41
点赞
评论
收藏
分享

手机扫一扫分享

举报
评论
图片
表情
推荐
点赞
评论
收藏
分享

手机扫一扫分享

举报