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

时间:2016-06-29 19:47:47

标签: python scikit-learn decision-tree

有几篇关于如何将分类数据编码为Sklearn Decission树的帖子,但是从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()
tree.fit(data[['A','B','C']], data['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

我知道在R中可以传递分类数据,Sklearn是否可能?

6 个答案:

答案 0 :(得分:10)

与接受的答案相反,我更倾向于使用Scikit-Learn提供的工具来实现此目的。这样做的主要原因是它们可以轻松集成到Pipeline

Scikit-Learn本身提供了非常好的类来处理分类数据。您应该使用专为此目的而设计的 <{strong> ,而不是编写自定义函数。

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

from sklearn import preprocessing
le = preprocessing.LabelEncoder()
le.fit(["paris", "paris", "tokyo", "amsterdam"])
le.transform(["tokyo", "tokyo", "paris"]) 

这会自动将它们编码为机器学习算法的数字。现在这也支持从整数返回字符串。您只需按以下方式调用inverse_transform即可完成此操作:

list(le.inverse_transform([2, 2, 1]))

这将返回['tokyo', 'tokyo', 'paris']

另请注意,对于许多其他分类器,除了逻辑回归或SVM等决策树之外,您还希望使用LabelEncoder对分类变量进行编码。 Scikit-learn也通过One-Hot encoding类支持这一点。

希望这有帮助!

答案 1 :(得分:4)

  

(..)

     

能够处理数字和分类数据。

这仅意味着您可以使用

  • 用于分类问题的DecisionTreeClassifier类
  • 用于回归的DecisionTreeRegressor类。

无论如何,在使用sklearn拟合树之前,您都需要对分类变量进行一次热编码,就像这样:

QDir::mkpath

答案 2 :(得分:3)

Sklearn Decision Trees不处理分类字符串到数字的转换。我建议你在Sklearn(也许是this)中找到一个函数,或者手动编写一些代码,如:

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

答案 3 :(得分:3)

该问题的公认答案具有误导性。

就目前而言,sklearn决策树无法处理分类数据-see issue #5442

推荐的使用标签编码的方法将转换为DecisionTreeClassifier()视为数字的整数。如果您的分类数据不是序数,那么这不好-您将得到没有意义的拆分。

使用OneHotEncoder是当前唯一有效的方法,它允许任意分割而不依赖于标签顺序,但计算量大。

答案 4 :(得分:1)

对于名义分类变量,我不会使用LabelEncoder,而是使用sklearn.preprocessing.OneHotEncoderpandas.get_dummies,因为这些类型的变量通常没有顺序。

答案 5 :(得分:0)

v0.24.0 起,scikit 支持在 HistGradientBoostingClassifierHistGradientBoostingRegressor natively 中使用分类特征!

<块引用>

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

>>> gbdt = HistGradientBoostingClassifier(categorical_features=[True, False])

等效地,可以传递一个整数列表,指示分类特征的索引:

>>> gbdt = HistGradientBoostingClassifier(categorical_features=[0])

您仍然需要对您的字符串进行编码,否则您将收到“无法将字符串转换为浮点数”的错误消息。有关使用 OrdinalEncoder 将字符串转换为整数的示例,请参阅 here