我在决策树/随机森林的应用程序上遇到了一些问题。我正在尝试解决一个以数字和字符串(例如国家/地区名称)为特征的问题。现在的库scikit-learn仅将数字作为参数,但是我想注入字符串,因为它们具有大量的知识。
如何处理这种情况?
我可以通过某种机制将字符串转换为数字,例如Python中的哈希。但是我想知道有关如何在决策树问题中处理字符串的最佳实践。
我在决策树/随机森林的应用程序上遇到了一些问题。我正在尝试解决一个以数字和字符串(例如国家/地区名称)为特征的问题。现在的库scikit-learn仅将数字作为参数,但是我想注入字符串,因为它们具有大量的知识。
如何处理这种情况?
我可以通过某种机制将字符串转换为数字,例如Python中的哈希。但是我想知道有关如何在决策树问题中处理字符串的最佳实践。
Answers:
在大多数完善的机器学习系统中,分类变量是自然处理的。例如,在R中,您将使用因子,在WEKA中,您将使用名义变量。scikit-learn中不是这种情况。在scikit-learn中实现的决策树仅使用数字功能,并且这些功能始终被解释为连续的数字变量。
因此,应该避免用哈希码简单地替换字符串,因为将其视为连续的数字功能,您将使用的任何编码都将导致数据中根本不存在的顺序。
一个例子是用[1,2,3]编码['red','green','blue'],会产生诸如'red'低于'blue'的怪异事物,如果您平均使用'red'一个“蓝色”,您将得到一个“绿色”。当您用[1,2,3]编码['low','medium','high']时,可能会出现另一个更微妙的示例。在后一种情况下,它可能恰好具有合理的排序,但是,当“中”不在“低”和“高”中间时,可能会发生一些细微的不一致。
最后,问题的答案在于将分类特征编码为多个二进制特征。例如,您可以用3列编码['red','green','blue'],每个类别一个,类别匹配时为1,否则为0。这称为“ 一次热编码”,“二进制编码”,“千分之一编码”或其他。您可以在此处查看有关分类特征编码和特征提取(散列和字典)的文档。显然,一键编码会扩展您的空间要求,有时还会损害性能。
您需要将字符串编码为sci-kit可用于ML算法的数字功能。此功能在预处理模块中处理(例如,请参阅sklearn.preprocessing.LabelEncoder)。
通常,您应该对scikit-learn模型(包括随机森林)进行一键编码分类变量。随机森林通常无需使用一键编码就可以正常工作,但如果执行一键编码,通常效果会更好。在这种情况下,一键编码和“虚拟”变量含义相同。Scikit-learn具有sklearn.preprocessing.OneHotEncoder,Pandas具有pandas.get_dummies来完成此任务。
但是,还有其他选择。KDnuggets上的“超越一站式”文章很好地解释了为什么您需要编码分类变量和一键式编码的替代方法。
有一些随机森林的替代实现,它们不需要像R或H2O这样的一键编码。R中的实现在计算上是昂贵的,并且如果您的功能具有很多类别,则将无法使用。H2O将适用于大量类别。Continuum已在Anaconda Python中提供了H2O。
本文介绍了H2O中使用的算法。它引用了学术论文“流并行决策树算法”和该论文的较长版本。
2018更新!
您可以为分类变量创建一个嵌入(密集向量)空间。你们中的许多人都熟悉word2vec和fastext,它们将单词嵌入到有意义的密集向量空间中。同样的想法-您的分类变量将映射到具有某些含义的向量。
与单热编码相比,实体嵌入不仅减少了内存使用并加快了神经网络的速度,而且更重要的是,通过在嵌入空间中映射彼此接近的相似值,它揭示了分类变量的内在属性。我们在最近的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。
实际上,您不需要使用神经网络来创建嵌入(尽管我不建议您避开该技术)。在可能的情况下,您可以手动或其他方式自由创建自己的嵌入。一些例子:
(0, 1.5, -2.3)
,blue = (1, 1, 0)
等的信息。您将在随机森林中使用与三个分量相对应的三个输入变量。对于红色物体,c1 = 0,c2 = 1.5,c3 = -2.3。用于蓝色的东西,C1 = 1,C2 = 1,和c3 = 0
您可以在这种情况下使用伪变量。使用熊猫,panda.get_dummies
您可以为要放入决策树或随机森林的字符串创建虚拟变量。
例:
import pandas as pd
d = {'one' : pd.Series([1., 2., 3.,4.], index=['a', 'b', 'c','d']),'two' :pd.Series(['Paul', 'John', 'Micheal','George'], index=['a', 'b', 'c', 'd'])}
df = pd.DataFrame(d)
df_with_dummies= pd.get_dummies(df,columns=["two"],drop_first=False)
df_with_dummies
将它们转换为数字,例如,为每个唯一的国家/地区设置一个唯一的数字(例如1,2,3和...)
你也不要需要使用一热编码(又名虚拟变量)与随机森林工作时,因为树木并不像其他算法的工作(如线性/逻辑回归),他们不远处的工作(他们寻找适合您功能的最佳分割),因此无需一键编码