字符串作为决策树/随机森林中的特征

数据挖掘 机器学习 Python scikit-学习 随机森林 决策树
2021-09-23 19:46:53

我在决策树/随机森林的应用上做一些问题。我正在尝试解决具有数字和字符串(例如国家名称)作为特征的问题。现在库scikit-learn只接受数字作为参数,但我想注入字符串以及它们携带大量知识。

我该如何处理这种情况?

我可以通过某种机制(例如 Python 中的哈希)将字符串转换为数字。但我想知道在决策树问题中如何处理字符串的最佳实践。

4个回答

在大多数成熟的机器学习系统中,分类变量是自然处理的。例如,在 R 中您将使用因子,在 WEKA 中您将使用名义变量。在 scikit-learn 中并非如此。scikit-learn 中实现的决策树仅使用数字特征,这些特征总是被解释为连续的数字变量

因此,应避免简单地用哈希码替换字符串,因为被视为连续数字特征,您将使用的任何编码都会导致数据中根本不存在的顺序。

一个例子是用 [1,2,3] 编码 ['red','green','blue'],会产生奇怪的东西,比如 'red' 低于 'blue',如果你平均一个 'red'和一个'蓝色'你会得到一个'绿色'。当您使用 [1,2,3] 编码 ['low', 'medium', 'high'] 时,可能会发生另一个更微妙的示例。在后一种情况下,它可能碰巧有一个有意义的排序,但是,当“中”不在“低”和“高”的中间时,可能会发生一些微妙的不一致。

最后,您问题的答案在于将分类特征编码为多个二元特征例如,您可以将 ['red','green','blue'] 编码为 3 列,每个类别一列,类别匹配时为 1,否则为 0。这称为one-hot-encoding、二进制编码、one-of-k-encoding 或其他。您可以在此处查看文档以了解编码分类特征特征提取 - 散列和 dicts显然,单热编码会扩大您的空间需求,有时还会损害性能。

您需要将字符串编码为 sci-kit 可用于 ML 算法的数字特征。此功能在预处理模块中处理(例如,参见sklearn.preprocessing.LabelEncoder示例)。

您通常应该对 scikit-learn 模型(包括随机森林)的分类变量进行一次性编码。随机森林在没有 one-hot 编码的情况下通常可以正常工作,但如果你进行 one-hot 编码,通常表现更好。在这种情况下,单热编码和“虚拟”变量的含义相同。Scikit-learn 有sklearn.preprocessing.OneHotEncoder和 Pandas 有pandas.get_dummies来完成这个。

但是,还有其他选择。KDnuggets上的“Beyond One-Hot”一文很好地解释了为什么需要对分类变量进行编码以及 one-hot 编码的替代方案。

有一些随机森林的替代实现不需要单热编码,例如 R 或 H2O。R 中的实现在计算上很昂贵如果您的特征有很多类别,则将无法工作H2O 将适用于大量类别。Continuum在 Anaconda Python 中提供了 H2O。

正在努力使 scikit-learn 直接处理分类特征

本文解释了 H2O 中使用的算法。它引用了学术论文A Streaming Parallel Decision Tree Algorithm和同一论文的更长版本

2018更新!

您可以为分类变量创建嵌入(密集向量)空间。你们中的许多人都熟悉 word2vec 和 fastext,它们将单词嵌入到有意义的密集向量空间中。这里的想法相同——您的分类变量将映射到具有某种含义的向量。

来自郭/伯克汉论文

与 one-hot 编码相比,实体嵌入不仅减少了内存使用并加速了神经网络,更重要的是,通过在嵌入空间中映射相似的值彼此接近,它揭示了分类变量的内在属性。我们在最近的一次 Kaggle 比赛中成功应用了它,并且能够以相对简单的特征达到第三名。

作者发现,以这种方式表示分类变量提高了所有测试机器学习算法的有效性,包括随机森林。

最好的例子可能是Pinterest 应用该技术对相关 Pin 图进行分组:

在此处输入图像描述

fastai 的人已经实现了分类嵌入,并创建了一篇非常不错的博客文章以及配套的演示笔记本

其他详细信息和说明

神经网络用于创建嵌入,即为每个分类值分配一个向量。一旦你有了向量,你就可以在任何接受数值的模型中使用它们。向量的每个分量都成为一个输入变量。例如,如果您使用 3-D 向量来嵌入颜色的分类列表,您可能会得到类似:red=(0, 1.5, -2.3), blue=(1, 1, 0) 等。您将使用三个随机森林中对应于三个组件的输入变量。对于红色的东西,c1=0,c2=1.5,c3=-2.3。对于蓝色的东西,c1=1、c2=1 和 c3=0。

您实际上不需要使用神经网络来创建嵌入(尽管我不建议回避该技术)。如果可能,您可以通过手动或其他方式自由地创建自己的嵌入。一些例子:

  1. 将颜色映射到 RGB 向量。
  2. 将位置映射到纬度/经度向量。
  3. 在美国政治模型中,将城市映射到一些代表左/右对齐、税收负担等的向量分量。