XGB-9: 分类数据

从1.5版本开始,XGBoost Python包为公共测试提供了对分类数据的实验性支持 。对于数值数据,切分条件被定义为 v a l u e < t h r e s h o l d value < threshold value<threshold ,而对于分类数据,切分的定义取决于是否使用分区或独热编码。对于基于分区的切分,切分被指定为 v a l u e ∈ c a t e g o r i e s value \in categories value∈categories,其中categories是一个特征中的类别集。如果使用独热编码,则切分定义为 v a l u e = = c a t e g o r y value == category value==category 。

使用 scikit-learn 进行训练

将分类数据传递给XGBoost的最简单方法是使用数据框和scikit-learn接口,如XGBClassifier。为了准备数据,用户需要将输入预测器的数据类型指定为category。对于pandas/cudf数据框,可以通过以下方式实现:

python 复制代码
X["cat_feature"].astype("category")

对于表示分类特征的所有列。之后,用户可以告诉XGBoost启用对分类数据的训练。假设正在使用XGBClassifier进行分类问题,指定参数enable_categorical

python 复制代码
# 支持的树方法有 `approx` 和 `hist`。
clf = xgb.XGBClassifier(tree_method="hist", enable_categorical=True, device="cuda")

# X 是前面代码片段中创建的数据框
clf.fit(X, y)

# 必须使用 JSON/UBJSON 进行序列化,否则信息将丢失。
clf.save_model("categorical-model.json")

训练完成后,大多数其他特征都可以利用该模型。例如,可以绘制模型并计算全局特征重要性:

python 复制代码
# 获取图形
graph = xgb.to_graphviz(clf, num_trees=1)

# 获取 matplotlib 轴
ax = xgb.plot_tree(clf, num_trees=1)

# 获取特征重要性
clf.feature_importances_

dask中的scikit-learn接口与单节点版本类似。基本思想是创建包含category特征类型的数据框,并通过设置enable_categorical参数告诉XGBoost使用它。有关在scikit-learn接口中使用带有独热编码的分类数据的实际示例,请参见使用cat_in_the_dat数据集进行分类数据的入门。可以在Train XGBoost with cat_in_the_dat dataset中找到使用独热编码数据和XGBoost分类数据支持的比较。

最佳分区Optimal Partitioning

最佳分区是一种用于每个节点拆分的分类预测变量的技术,首次由[1]引入并证明在数值输出方面是最优的。该算法用于决策树[2],后来LightGBM [3]将其引入到梯度提升树的上下文中 ,现在也作为XGBoost的可选功能用于处理分类拆分。具体而言,Fisher [1]的证明表明,当试图基于这些值的度量之间的距离将一组离散值分区为组时,只需要查看排序的分区而不是枚举所有可能的排列 。在决策树的上下文中,离散值是类别,度量是输出叶子值 。直观地说,希望将输出类似叶值的类别分组 。在查找拆分时,**首先对梯度直方图进行排序,以准备连续的分区,然后根据这些排序的值枚举拆分。**XGBoost的相关参数之一是max_cat_to_onehot,它控制每个特征是使用独热编码还是分区,详见分类特征的参数详情

使用原生接口Using native interface

scikit-learn接口对用户非常友好,但缺少仅在原生接口中提供的某些功能。例如,用户无法直接计算SHAP值。此外,原生接口支持更多的数据类型。要在具有分类数据的情况下使用原生接口,我们需要将类似的参数传递给DMatrixQuantileDMatrixtrain函数。对于数据框输入:

python 复制代码
# X is a dataframe we created in previous snippet
Xy = xgb.DMatrix(X, y, enable_categorical=True)
booster = xgb.train({"tree_method": "hist", "max_cat_to_onehot": 5}, Xy)

# Must use JSON for serialization, otherwise the information is lost
booster.save_model("categorical-model.json")

SHAP值计算:

python 复制代码
SHAP = booster.predict(Xy, pred_interactions=True)

# categorical features are listed as "c"
print(booster.feature_types)

对于其他类型的输入,例如numpy数组,可以通过在DMatrix中使用feature_types参数来告诉XGBoost有关特征类型:

python 复制代码
# "q" is numerical feature, while "c" is categorical feature
ft = ["q", "c", "c"]
X: np.ndarray = load_my_data()
assert X.shape[1] == 3
Xy = xgb.DMatrix(X, y, feature_types=ft, enable_categorical=True)

对于数值数据,特征类型可以是"q""float",而对于分类特征,则指定为"c"。XGBoost中的Dask模块具有相同的接口,因此dask.Array也可以用于分类数据。最后,sklearn接口XGBRegressor也具有相同的参数。

数据一致性

XGBoost接受参数来指示哪个特征被视为分类特征,可以通过dataframedtypes或通过feature_types参数来指定。然而,XGBoost本身不存储关于类别如何编码的信息。例如,给定将音乐流派映射到整数代码的编码模式:

python 复制代码
{"acoustic": 0, "indie": 1, "blues": 2, "country": 3}

XGBoost不知道输入的映射,因此无法将其存储在模型中。映射通常在用户的数据工程管道中发生,使用像sklearn.preprocessing.OrdinalEncoder这样的列转换器。为了确保XGBoost的正确结果,用户需要保持在训练和测试数据上一致的数据转换管道。用户应该注意以下错误:

python 复制代码
X_train["genre"] = X_train["genre"].astype("category")
reg = xgb.XGBRegressor(enable_categorical=True).fit(X_train, y_train)

# invalid encoding
X_test["genre"] = X_test["genre"].astype("category")
reg.predict(X_test)

在上面的代码片段中,训练数据和测试数据被分别编码,导致两个不同的编码模式和无效的预测结果。有关使用序数编码器的示例,请参阅特征工程管道以获取分类数据

其他注意事项

默认情况下,XGBoost假设输入类别是从0到类别数 [ 0 , n _ c a t e g o r i e s ) [0, n\_categories) [0,n_categories)的整数。然而,由于训练数据集中的错误或缺失值,用户可能提供具有无效值的输入。这可能是负值、无法由32位浮点表示的整数值,或大于实际唯一类别数的值。在训练期间,需要进行验证,但对于预测而言,出于性能原因,它被视为未选择的类别。

参考

  • 1\] Walter D. Fisher. "[On Grouping for Maximum Homogeneity](https://www.tandfonline.com/doi/abs/10.1080/01621459.1958.10501479)". Journal of the American Statistical Association. Vol. 53, No. 284 (Dec., 1958), pp. 789-798.

  • 3\] Guolin Ke, Qi Meng, Thomas Finley, Taifeng Wang, Wei Chen, Weidong Ma, Qiwei Ye, Tie-Yan Liu. "[LightGBM: A Highly Efficient Gradient Boosting Decision Tree](https://papers.nips.cc/paper/6907-lightgbm-a-highly-efficient-gradient-boosting-decision-tree.pdf)." Advances in Neural Information Processing Systems 30 (NIPS 2017), pp. 3149-3157.

  • https://www.kaggle.com/code/shahules/an-overview-of-encoding-techniques/notebook

相关推荐
zeroporn34 分钟前
在Mac M1/M2上使用Hugging Face Transformers进行中文文本分类(完整指南)
macos·分类·数据挖掘·nlp·transformer·预训练模型·文本分类
BioRunYiXue12 小时前
一文了解氨基酸的分类、代谢和应用
人工智能·深度学习·算法·机器学习·分类·数据挖掘·代谢组学
白杆杆红伞伞19 小时前
02_线性模型(回归分类模型)
分类·数据挖掘·回归
地理探险家2 天前
各类有关NBA数据统计数据集大合集
数据库·数据集·数据·nba·赛季
yzx9910132 天前
支持向量机与逻辑回归的区别及 SVM 在图像分类中的应用
支持向量机·分类·逻辑回归
shadowtalon3 天前
基于CNN的猫狗图像分类系统
人工智能·深度学习·神经网络·机器学习·计算机视觉·分类·cnn
終不似少年遊*3 天前
MindSpore框架学习项目-ResNet药物分类-模型优化
人工智能·深度学习·机器学习·计算机视觉·分类·数据挖掘·华为云
蹦蹦跳跳真可爱5893 天前
Python----神经网络(基于AlexNet的猫狗分类项目)
人工智能·pytorch·python·深度学习·神经网络·分类
极客智谷4 天前
Spring AI 系列——使用大模型对文本内容分类归纳并标签化输出
人工智能·spring·分类
奋斗者1号4 天前
神经网络中之多类别分类:从基础到高级应用
大数据·神经网络·分类