Python 将分类数据传递给Sklearn决策树

Python 将分类数据传递给Sklearn决策树,python,scikit-learn,decision-tree,Python,Scikit Learn,Decision Tree,有几篇关于如何将分类数据编码到Sklearn决策树的文章,但是从Sklearn文档中,我们得到了这些 决策树的一些优点是: (……) 能够处理数字和分类数据。其他技术通常专门用于分析只有一种类型变量的数据集。有关更多信息,请参阅算法 但是运行下面的脚本 将熊猫作为pd导入 从sklearn.tree导入DecisionTreeClassifier data=pd.DataFrame() 数据['A']=['A','A','b','A'] 数据['B']=['B','B','a','B'] 数据[

有几篇关于如何将分类数据编码到Sklearn决策树的文章,但是从Sklearn文档中,我们得到了这些

决策树的一些优点是:

(……)

能够处理数字和分类数据。其他技术通常专门用于分析只有一种类型变量的数据集。有关更多信息,请参阅算法

但是运行下面的脚本

将熊猫作为pd导入
从sklearn.tree导入DecisionTreeClassifier
data=pd.DataFrame()
数据['A']=['A','A','b','A']
数据['B']=['B','B','a','B']
数据['C']=[0,0,1,0]
数据['Class']=['n','n','y','n']
tree=DecisionTreeClassifier()
fit(数据['A','B','C']],数据['Class']
输出以下错误:

Traceback (most recent call last):
  File "<stdin>", line 1, in <module>
  File "/usr/local/lib/python2.7/site-packages/sklearn/tree/tree.py", line 154, in fit
    X = check_array(X, dtype=DTYPE, accept_sparse="csc")
  File "/usr/local/lib/python2.7/site-packages/sklearn/utils/validation.py", line 377, in check_array
    array = np.array(array, dtype=dtype, order=order, copy=copy)
ValueError: could not convert string to float: b
回溯(最近一次呼叫最后一次):
文件“”,第1行,在
文件“/usr/local/lib/python2.7/site packages/sklearn/tree/tree.py”,第154行
X=检查数组(X,dtype=dtype,accept\u sparse=“csc”)
文件“/usr/local/lib/python2.7/site packages/sklearn/utils/validation.py”,第377行,在check_数组中
array=np.array(array,dtype=dtype,order=order,copy=copy)
ValueError:无法将字符串转换为浮点值:b

我知道在R中,可以通过Sklearn传递分类数据,是吗?

Sklearn决策树不处理分类字符串到数字的转换。我建议您在Sklearn(可能)中找到一个函数,或者手动编写一些代码,如:

def cat2int(column):
    vals = list(set(column))
    for i, string in enumerate(column):
        column[i] = vals.index(string)
    return column

与公认的答案相反,我更愿意使用Scikit Learn提供的工具来实现这一目的。这样做的主要原因是它们可以很容易地集成到一个系统中

Scikit Learn本身提供了非常好的类来处理分类数据。与其编写自定义函数,不如使用专门为此设计的函数

请参阅文档中的以下代码:

from sklearn import preprocessing
le = preprocessing.LabelEncoder()
le.fit(["paris", "paris", "tokyo", "amsterdam"])
le.transform(["tokyo", "tokyo", "paris"]) 
这会自动将它们编码为数字,用于机器学习算法。现在,它还支持从整数返回字符串。只需调用
逆变换
即可完成此操作,如下所示:

list(le.inverse_transform([2, 2, 1]))
这将返回
[“东京”、“东京”、“巴黎”]

还请注意,对于许多其他分类器,除了决策树(如逻辑回归或SVM)之外,您还希望使用。Scikit learn在课堂上也支持这一点

希望这有帮助

(……)

能够处理数字和分类数据

这只意味着您可以使用

  • 分类问题的DecisionTreeClassifier类
  • 用于回归的DecisionTreeGressor类
在任何情况下,在使用sklearn拟合树之前,都需要对分类变量进行热编码,如下所示:

import pandas as pd
from sklearn.tree import DecisionTreeClassifier

data = pd.DataFrame()
data['A'] = ['a','a','b','a']
data['B'] = ['b','b','a','b']
data['C'] = [0, 0, 1, 0]
data['Class'] = ['n','n','y','n']

tree = DecisionTreeClassifier()

one_hot_data = pd.get_dummies(data[['A','B','C']],drop_first=True)
tree.fit(one_hot_data, data['Class'])
(这只是从2016年开始的改革……它仍然适用。)

这个问题的公认答案是误导性的

目前,sklearn决策树不处理分类数据

建议使用标签编码的方法将转换为整数,
DecisionTreeClassifier()
视为数字。如果你的分类数据不是有序的,这是不好的-你将以没有意义的分割结束


使用
OneHotEncoder
是当前唯一有效的方法,允许任意拆分,不依赖于标签顺序,但计算成本较高。

对于标称分类变量,我不会使用
LabelEncoder
而是
sklearn.preprocessing.onehotcoder
pandas.get_dummies
,因为这些类型的变量通常没有顺序

截至,scikit支持在
HistGradientBoostingClassifier
HistGradientBoostingRegressionor
中使用分类功能

要启用分类支持,可以将布尔掩码传递给category_features参数,指示哪个功能是分类的。在下文中,第一个特征将被视为分类特征,第二个特征将被视为数字特征:

gbdt=HistGradientBoostingClassifier(分类特征=[True,False]) 同样,可以传递一个整数列表,指示分类特征的索引:

gbdt=HistGradientBoostingClassifier(分类功能=[0])
您仍然需要对字符串进行编码,否则将出现“无法将字符串转换为浮点”错误。有关使用
OrdinalEncoder
将字符串转换为整数的示例,请参见。

是的,通常是这样,但对于打印来说,这并不太好。如果您想从整数转换回字符串表示,请制作一个保存字符串和整数之间映射的字典,并使用它进行“解码”整数表示形式。该语句不准确。Scikit学习分类器不会隐式处理标签编码。然而,Scikit learn提供了很多类来处理这个问题。我建议使用scikit学习工具,因为它们也可以以最小的努力适应机器学习管道。-1这是误导。目前,sklearn决策树不处理分类数据。这种使用标签编码的方法将转换为整数,
DecisionTreeClassifier()
将其视为数字。如果你的分类数据不是有序的,这是不好的-你将以没有意义的分割结束。使用
OneHotEncoder
是当前唯一有效的方法,但计算成本很高。这是非常容易误导的。请不要将字符串转换为数字并在决策树中使用。在scikit learn中无法处理分类数据。一种选择是在Spark中使用决策树分类器,在该分类器中可以显式声明分类特征及其顺序性。参考这里了解更多细节,每个人都必须学习音阶