
XGBoost 是梯度提升的一种实现,用于赢得机器学习竞赛。
它功能强大,但可能很难开始。学习本文需要已经熟悉 scikit-learn 和 SciPy 生态系统的 Python 机器学习从业者设计。
在我们开始之前,让我们确保您在正确的地方。下面的列表提供了一些关于本课程的设计对象的一般指南。
如果您不完全匹配这些点,请不要惊慌,您可能只需要在一个或另一个区域刷一遍以跟上。
把你从一个对 Python 了解一点机器学习的开发人员转变为一个能够获得结果并将 XGBoost 的强大功能带入你自己的项目的开发人员。
梯度提升简介梯度提升是构建预测模型最强大的技术之一。
boosting 的想法来自于是否可以修改弱学习器以变得更好的想法。在应用中取得巨大成功的第一个 Boosting 实现是 Adaptive Boosting 或简称 AdaBoost。AdaBoost 中的弱学习器是具有单个分裂的决策树,由于它们的短小,称为决策树桩。
AdaBoost 和相关算法在统计框架中被重新定义,并被称为梯度提升机。统计框架将 boosting 视为数值优化问题,其目标是通过使用类似梯度下降的过程添加弱学习器来最小化模型的损失,因此得名。
Gradient Boosting算法涉及三个要素:
新的弱学习器被添加到模型中,以纠正所有先前树的残差。结果是一个强大的预测建模算法,可能比随机森林更强大。
XGBoost 简介XGBoost 是为速度和性能而设计的梯度提升决策树的实现。
XGBoost 代表 e X treme G radient Boosting。
它由 Tianqi Chen 开发,专注于计算速度和模型性能,因此几乎没有多余的装饰。
除了支持该技术的所有关键变体之外,真正令人感兴趣的是实施的精心设计所提供的速度,包括:
传统上,梯度提升的实现速度很慢,因为必须构建每棵树并将其添加到模型中的顺序性。
XGBoost 开发过程中的高性能产生了最好的预测建模算法之一,它现在可以利用您的硬件平台或您可能在云中租用的超大型计算机的全部功能。
因此,XGBoost 一直是竞争性机器学习的基石,是用于获胜和被获胜者推荐的技术。例如,以下是一些最近的 Kaggle 比赛获胜者所说的话:
开发第一个 XGBoost 模型As the winner of an increasing amount of Kaggle competitions, XGBoost showed us again to be a great all-round algorithm worth having in your toolbox.
作为越来越多的 Kaggle 比赛的获胜者,XGBoost 再次向我们展示了它是一种值得在您的工具箱中使用的出色的全能算法。
假设您有一个可用的 SciPy 环境,可以使用 pip 轻松安装 XGBoost。
pip install xgboost
您可以在XGBoost 安装说明 中了解有关在您的平台上安装和构建 XGBoost 的更多信息。
XGBoost 模型可以使用包装类直接在 scikit-learn 框架中使用
这是在 Python 中使用 XGBoost 的推荐方法。
下载 Pima Indians 糖尿病发病数据集。
这是一个很好的二元分类测试数据集,因为所有输入变量都是数字,这意味着可以直接对问题进行建模而无需准备数据。
我们可以通过构建 XGBoost 模型并调用model.fit()函数来训练它进行分类:
model = XGBClassifier() model.fit(X_train, y_train)
然后可以通过对新数据调用model.predict()函数来使用该模型进行预测。
y_pred = model.predict(X_test)
我们可以将这一切联系在一起,如下所示:
from numpy import loadtxt
from xgboost import XGBClassifier
from sklearn.model_selection import train_test_split
from sklearn.metrics import accuracy_score
# 加载数据
dataset = loadtxt('pima-indians-diabetes.csv', delimiter=",")
# 拆分数据中的自变量和因变量
X = dataset[:,0:8]
Y = dataset[:,8]
seed = 7
test_size = 0.33
X_train, X_test, y_train, y_test = train_test_split(X, Y, test_size=test_size, random_state=seed)
# 在训练集上拟合模型数据
model = XGBClassifier()
model.fit(X_train, y_train)
# 预测数据结果
y_pred = model.predict(X_test)
predictions = [round(value) for value in y_pred]
# 验证结果
accuracy = accuracy_score(y_test, predictions)
print("Accuracy: %.2f%%" % (accuracy * 100.0))
在下一课中,我们将研究如何使用提前停止来限制过度拟合。
监控性能和提前停止XGBoost 模型可以在训练期间评估和报告模型在测试集上的性能。
它通过在训练模型和指定详细输出 ( verbose=True )时在调用model.fit()时指定测试数据集和评估指标来支持此功能。
例如,我们可以在训练 XGBoost 模型时报告独立测试集 ( eval_set )上的二进制分类错误率 ( error ) ,如下所示:
eval_set = [(X_test, y_test)] model.fit(X_train, y_train, eval_metric="error", eval_set=eval_set, verbose=True)
使用此配置运行模型将在添加每棵树后报告模型的性能。例如:
... [89] validation_0-error:0.204724 [90] validation_0-error:0.208661
一旦模型没有进一步改进,我们就可以使用这个评估来停止训练。
我们可以通过在调用model.fit()时将 early_stopping_rounds 参数设置为在训练停止之前在验证数据集上没有看到任何改进的迭代次数来做到这一点。
下面提供了使用 Pima Indians onset of Diabetes 数据集的完整示例。
# exmaple of early stopping
from numpy import loadtxt
from xgboost import XGBClassifier
from sklearn.model_selection import train_test_split
from sklearn.metrics import accuracy_score
# 加载数据
dataset = loadtxt('pima-indians-diabetes.csv', delimiter=",")
# 拆分数据中的自变量和因变量
X = dataset[:,0:8]
Y = dataset[:,8]
seed = 7
test_size = 0.33
X_train, X_test, y_train, y_test = train_test_split(X, Y, test_size=test_size, random_state=seed)
# 在训练集上拟合模型数据
model = XGBClassifier()
eval_set = [(X_test, y_test)]
model.fit(X_train, y_train, early_stopping_rounds=10, eval_metric="logloss", eval_set=eval_set, verbose=True)
# 预测数据结果
y_pred = model.predict(X_test)
predictions = [round(value) for value in y_pred]
# 验证结果
accuracy = accuracy_score(y_test, predictions)
print("Accuracy: %.2f%%" % (accuracy * 100.0))
XGBoost 的特征重要性
使用诸如梯度提升之类的决策树方法集成的一个好处是,它们可以从训练有素的预测模型中自动提供特征重要性的估计。
经过训练的 XGBoost 模型会自动计算预测建模问题的特征重要性。
这些重要性分数在训练模型的feature_importances_成员变量中可用。例如,它们可以直接打印如下:
print(model.feature_importances_)
XGBoost 库提供了一个内置函数来绘制按重要性排序的特征。
该函数称为plot_importance()并且可以按如下方式使用:
plot_importance(model) pyplot.show()
这些重要性分数可以帮助您决定保留或丢弃哪些输入变量。它们也可以用作自动特征选择技术的基础。
下面提供了使用 Pima Indians onset of Diabetes 数据集绘制特征重要性分数的完整示例。
from numpy import loadtxt
from xgboost import XGBClassifier
from xgboost import plot_importance
from matplotlib import pyplot
# 加载数据
dataset = loadtxt('pima-indians-diabetes.csv', delimiter=",")
# 拆分数据中的自变量和因变量
X = dataset[:,0:8]
y = dataset[:,8]
# 在训练集上拟合模型数据
model = XGBClassifier()
model.fit(X, y)
# 显示得分模型特征得分
plot_importance(model)
pyplot.show()
如何配置梯度提升
梯度提升是应用机器学习中最强大的技术之一,因此正迅速成为最受欢迎的技术之一。
但是您如何针对您的问题配置梯度提升?
在最初的梯度提升论文中发表了许多配置启发式方法。它们可以概括为:
一个好的通用配置策略如下:
Owen Zhang 曾是 Kaggle 排名第一的竞争对手,现在是 Data Robot 的 CTO,他提出了一个有趣的配置 XGBoost 的策略。
他建议将树的数量设置为目标值,例如 100 或 1000,然后调整学习率以找到最佳模型。这是快速找到好的模型的有效策略。
XGBoost 超参数调优scikit-learn 框架提供了搜索参数组合的能力。
此功能在GridSearchCV类中提供,可用于发现配置模型以在您的问题上获得最佳性能的最佳方法。
例如,我们可以定义一个包含树数量 ( n_estimators ) 和树大小 ( max_depth ) 的网格,通过将网格定义为:
n_estimators = [50, 100, 150, 200] max_depth = [2, 4, 6, 8] param_grid = dict(max_depth=max_depth, n_estimators=n_estimators)
然后使用 10 折交叉验证评估每个参数组合:
kfold = StratifiedKFold(n_splits=10, shuffle=True, random_state=7) grid_search = GridSearchCV(model, param_grid, scoring="neg_log_loss", n_jobs=-1, cv=kfold, verbose=1) result = grid_search.fit(X, label_encoded_y)
然后,我们可以查看结果以确定最佳组合和参数组合变化的总体趋势。
这是将 XGBoost 应用于您自己的问题时的最佳实践。要考虑调整的参数是:
下面是在 Pima Indians onset of Diabetes 数据集上调整learning_rate的完整示例。
from numpy import loadtxt
from xgboost import XGBClassifier
from sklearn.model_selection import GridSearchCV
from sklearn.model_selection import StratifiedKFold
# 加载数据
dataset = loadtxt('pima-indians-diabetes.csv', delimiter=",")
# 拆分数据中的自变量和因变量
X = dataset[:,0:8]
Y = dataset[:,8]
# 网格搜索
model = XGBClassifier()
learning_rate = [0.0001, 0.001, 0.01, 0.1, 0.2, 0.3]
param_grid = dict(learning_rate=learning_rate)
kfold = StratifiedKFold(n_splits=10, shuffle=True, random_state=7)
grid_search = GridSearchCV(model, param_grid, scoring="neg_log_loss", n_jobs=-1, cv=kfold)
grid_result = grid_search.fit(X, Y)
# 汇总结果
print("Best: %f using %s" % (grid_result.best_score_, grid_result.best_params_))
means = grid_result.cv_results_['mean_test_score']
stds = grid_result.cv_results_['std_test_score']
params = grid_result.cv_results_['params']
for mean, stdev, param in zip(means, stds, params):
print("%f (%f) with: %r" % (mean, stdev, param))
XGBoost 学习回顾
花点时间回顾一下你走了多远:
不要轻视这一点,你在很短的时间内已经走了很长一段路。这只是您在 Python 中使用 XGBoost 的旅程的开始。继续练习和发展你的技能。