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 小时前
《XGBoost算法的原理推导》12-14决策树复杂度的正则化项 公式解析
人工智能·决策树·机器学习·集成学习·boosting·xgboost
浮生如梦_10 小时前
Halcon基于laws纹理特征的SVM分类
图像处理·人工智能·算法·支持向量机·计算机视觉·分类·视觉检测
m0_7434148521 小时前
【天线&其他】大疆无人机热成像人员目标检测系统源码&数据集全套:改进yolo11-bifpn-SDI
分类
spssau1 天前
多分类logistic回归分析案例教程
分类·数据挖掘·数据分析·回归·回归分析·logistic回归·spssau
快乐点吧1 天前
BERT 模型在句子分类任务中的作用分析笔记
笔记·分类·bert
亿牛云爬虫专家1 天前
用Puppeteer点击与数据爬取:实现动态网页交互
javascript·爬虫·爬虫代理·puppeteer·数据·代理ip·16yun
Yeats_Liao1 天前
昇思大模型平台打卡体验活动:基于MindSpore实现GPT1影评分类
gpt·分类·数据挖掘
战国2 天前
卫星授时服务器,单北斗授时服务器,北斗卫星时钟服务器
服务器·网络·测试工具·分类
卡洛驰2 天前
交叉熵损失函数详解
人工智能·深度学习·算法·机器学习·ai·分类·概率论
C_Ryson2 天前
【机器学习】k最近邻分类
人工智能·python·机器学习·分类