在 XGboost 中呈现数字分类数据(特别是一天中的小时)变量的正确方法是啥?

Posted

技术标签:

【中文标题】在 XGboost 中呈现数字分类数据(特别是一天中的小时)变量的正确方法是啥?【英文标题】:What's the proper way to present numerical categorical data (specifically hour of day) variable in XGboost?在 XGboost 中呈现数字分类数据(特别是一天中的小时)变量的正确方法是什么? 【发布时间】:2020-03-15 02:44:37 【问题描述】:

一个热编码更好还是只保留一个数字变量更好? 我在网上看到混合的结论:

“避免 OneHot 用于高基数列和基于决策树的算法。” https://towardsdatascience.com/smarter-ways-to-encode-categorical-data-for-machine-learning-part-1-of-3-6dca2f71b159

相对于

"(onehotencoded) 这是 xgboost 或任何其他机器学习工具的分类变量的正确表示。" XGBoost Categorical Variables: Dummification vs encoding

【问题讨论】:

“小时”有 24 个可能的类别级别,这可能还不是“高基数”领域吗? HoD 的确切操作类型(连续、分类或有序)也取决于数据集。 我喜欢保持较少的特征数量以减少过度拟合的可能性,添加 23 个特征对我来说感觉很多。一种热编码通常不会针对序数变量进行,即如果您进行一种热编码,您将丢失例如下午 2 点非常接近下午 3 点的信息。我想你肯定会从尝试两者中学到一些东西! 感谢 cmets,但我正在寻找更通用的答案。从我发布的链接看来,似乎有两种思想流派相互对立。 【参考方案1】:

有两种以上的思想流派:)。在实践中,每件事都有利有弊,最佳方法将取决于您的数据。因此,通常的前进道路是尝试所有可行的选项并选择最适合您的用例的选项(不仅在指标方面,而且在 CPU/RAM 方面,如果数据不是很小)

例如,OHE 会添加多个列,这在长表的情况下会导致较大的内存占用。同时 OHE 丢失了序数信息(如果特征是序数的)。但这可能不是问题,因为树通常会在运行时勾选目标的相关依赖项。另一方面,小时的简单有序数字表示保持低内存并保持有序的值序列。但问题是它会在 24 小时后丢失大约 1 小时的信息,它将与 xgboost 中的树助推器一起使用,但不适用于 xgboost 中的线性助推器或 xgboost 之外的其他模型系列(线性、支持向量机等),并且它对于非序数特征在理论上并不合理(您的问题似乎很笼统)。

让我添加适用于这种特殊情况的第三种思想流派:您可以对具有重复周期(一年中的月份、一天中的小时等)的特征使用循环编码。 )。其概念是使用 sincos 函数以固定周期(在一天中的小时为 24)对每个值进行编码。这允许保持边缘的连续性并控制内存(只有 2 个特征而不是原始的数字有序表示),并且编码特征的数量不依赖于基数。有很多讨论可以在谷歌上找到,例如,这个问题:https://datascience.stackexchange.com/q/5990/53060。而且我确信网络上有很多它的实现,我个人在python中使用这个:https://github.com/MaxHalford/xam/blob/master/docs/feature-extraction.md#cyclic-features。当然,这不适用于一般的数字分类数据,而是具体适用于一天中的小时。

但正如开头所说,我个人会尝试所有这些,看看哪个最适合手头的问题。循环编码在概念上最适合一天中的某个小时,但可能比其他方法执行得更差,并且对于 “年龄组” 之类的功能毫无意义。

【讨论】:

以上是关于在 XGboost 中呈现数字分类数据(特别是一天中的小时)变量的正确方法是啥?的主要内容,如果未能解决你的问题,请参考以下文章

技术分享 | 机器学习-浅谈XGBoost算法

Xgboost 处理不平衡的分类数据

2万字阐述-Python 用 XGBoost 进行梯度提升的数据准备(收藏)

在分类列上训练 xgboost 时遇到问题

100天搞定机器学习|Day60 遇事不决,XGBoost

XGBoost 用于多标签分类?