使用 Scikit-Learn 估计器接口
目录
概述
除了原生接口外,XGBoost 还提供了一个符合 sklearn 估计器指南 的 sklearn 估计器接口。它支持回归、分类和学习排序。sklearn 估计器接口的生存训练仍在进行中。
你可以在 使用 sklearn 接口的示例集合 找到一些快速开始的示例。使用 sklearn 接口的主要优势是它与 sklearn 提供的多数实用工具兼容,例如 sklearn.model_selection.cross_validate()
。此外,由于其流行性,许多其他库也识别 sklearn 估计器接口。
通过 sklearn 估计器接口,我们只需几行 Python 代码就可以训练一个分类模型。以下是一个训练分类模型的示例:
from sklearn.datasets import load_breast_cancer
from sklearn.model_selection import train_test_split
import xgboost as xgb
X, y = load_breast_cancer(return_X_y=True)
X_train, X_test, y_train, y_test = train_test_split(X, y, stratify=y, random_state=94)
# Use "hist" for constructing the trees, with early stopping enabled.
clf = xgb.XGBClassifier(tree_method="hist", early_stopping_rounds=2)
# Fit the model, test sets are used for early stopping.
clf.fit(X_train, y_train, eval_set=[(X_test, y_test)])
# Save model into JSON format.
clf.save_model("clf.json")
tree_method
参数指定用于构建树的方法,而 early_stopping_rounds 参数启用提前停止。提前停止可以帮助防止过拟合并节省训练时间。
早停
如前例所示,可以通过参数 early_stopping_rounds
启用提前停止。或者,可以使用回调函数 xgboost.callback.EarlyStopping
来指定提前停止行为的更多细节,包括 XGBoost 是否应返回最佳模型而不是完整的树堆栈:
early_stop = xgb.callback.EarlyStopping(
rounds=2, metric_name='logloss', data_name='validation_0', save_best=True
)
clf = xgb.XGBClassifier(tree_method="hist", callbacks=[early_stop])
clf.fit(X_train, y_train, eval_set=[(X_test, y_test)])
目前,XGBoost 在估计器内部没有实现数据分割逻辑,而是依赖于 xgboost.XGBModel.fit()
方法的 eval_set
参数。如果你想使用早停来防止过拟合,你需要使用 sklearn 库中的 sklearn.model_selection.train_test_split()
函数手动将数据分割为训练集和测试集。其他一些机器学习算法,如 sklearn 中的算法,将早停作为估计器的一部分,并且可能与交叉验证一起工作。然而,在交叉验证期间使用早停可能不是一个完美的方法,因为它会改变每个验证折叠的模型树的数量,导致不同的模型。更好的方法是,在交叉验证后使用最佳超参数和早停重新训练模型。如果你想尝试使用早停进行交叉验证的想法,这里有一个代码片段可以开始:
from sklearn.base import clone
from sklearn.datasets import load_breast_cancer
from sklearn.model_selection import StratifiedKFold, cross_validate
import xgboost as xgb
X, y = load_breast_cancer(return_X_y=True)
def fit_and_score(estimator, X_train, X_test, y_train, y_test):
"""Fit the estimator on the train set and score it on both sets"""
estimator.fit(X_train, y_train, eval_set=[(X_test, y_test)])
train_score = estimator.score(X_train, y_train)
test_score = estimator.score(X_test, y_test)
return estimator, train_score, test_score
cv = StratifiedKFold(n_splits=5, shuffle=True, random_state=94)
clf = xgb.XGBClassifier(tree_method="hist", early_stopping_rounds=3)
results = {}
for train, test in cv.split(X, y):
X_train = X[train]
X_test = X[test]
y_train = y[train]
y_test = y[test]
est, train_score, test_score = fit_and_score(
clone(clf), X_train, X_test, y_train, y_test
)
results[est] = (train_score, test_score)
获取原生助推器对象
sklearn 估计器接口主要便于训练,并没有实现 XGBoost 中的所有功能。例如,为了获得缓存的预测,需要使用 xgboost.DMatrix
与 xgboost.Booster.predict()
。可以通过 xgboost.XGBModel.get_booster()
从 sklearn 接口获取 booster 对象。
booster = clf.get_booster()
print(booster.num_boosted_rounds())
预测
当启用早停时,包括 xgboost.XGBModel.predict()
、xgboost.XGBModel.score()
和 xgboost.XGBModel.apply()
方法在内的预测函数将自动使用最佳模型。这意味着 xgboost.XGBModel.best_iteration
用于指定预测中使用的树的范围。
要为增量预测获取缓存结果,请使用 xgboost.Booster.predict()
方法。
并行线程数
在使用 XGBoost 和其他 sklearn 工具时,你可以通过使用 n_jobs
参数来指定要使用的线程数。默认情况下,XGBoost 会使用计算机上所有可用的线程,这在与 sklearn.model_selection.cross_validate()
等其他 sklearn 函数结合使用时,可能会导致一些有趣的后果。如果 XGBoost 和 sklearn 都设置为使用所有线程,你的计算机可能会由于所谓的“线程抖动”而显著变慢。为了避免这种情况,你可以简单地将 XGBoost 的 n_jobs
参数设置为 None`(使用所有线程),并将 sklearn 的 ``n_jobs` 参数设置为 1。这样,两个程序将能够顺利协同工作,而不会造成不必要的计算机负担。