特征是不是必须是浮点数才能通过决策树进行多类分类?

Posted

技术标签:

【中文标题】特征是不是必须是浮点数才能通过决策树进行多类分类?【英文标题】:Do features have to be float numbers for multiclass-classification by Decision Tree?特征是否必须是浮点数才能通过决策树进行多类分类? 【发布时间】:2021-04-06 21:41:18 【问题描述】:
X_train

------------------------------------------------------------------------------------------
   | bias | word.lower | word[-3:] | word.isupper | word.isdigit |  POS  |  BOS  |  EOS  |
------------------------------------------------------------------------------------------
0  |  1.0 | headache,  |      HE,  |         True |        False |   NNP |  True | False |
1  |  1.0 |    mostly  |      tly  |        False |        False |   NNP | False | False |
2  |  1.0 |       but  |      BUT  |         True |        False |   NNP | False | False |
...
...
...

y_train

------------
   |  OBI  |
------------
0  | B-ADR |
1  | O     |
2  | O     |
...
...
...

我正在尝试使用 决策树 进行名称实体识别 (NER)。我的特征数据框和标签数据框如下所示。当我运行以下代码时,它返回ValueError: could not convert string to float: 'headache,'。我的数据格式是否正确(我正在关注this tutorial)?特征是否必须是浮点数才能通过决策树进行多类分类?如果是这样,鉴于大多数令牌特征(如果不是全部)都是字符串或布尔值,我应该如何进行 OBI 标记?

import pandas as pd
from sklearn.tree import DecisionTreeClassifier

DT = DecisionTreeClassifier()
DT.fit(X_train, y_train)

---------------------------------------------------------------------------
ValueError                                Traceback (most recent call last)
<ipython-input-15-aa02be64ac27> in <module>
      1 DT = DecisionTreeClassifier()
----> 2 DT.fit(X_train, y_train)

d:\python\lib\site-packages\sklearn\tree\_classes.py in fit(self, X, y, sample_weight, check_input, X_idx_sorted)
    888         """
    889 
--> 890         super().fit(
    891             X, y,
    892             sample_weight=sample_weight,

d:\python\lib\site-packages\sklearn\tree\_classes.py in fit(self, X, y, sample_weight, check_input, X_idx_sorted)
    154             check_X_params = dict(dtype=DTYPE, accept_sparse="csc")
    155             check_y_params = dict(ensure_2d=False, dtype=None)
--> 156             X, y = self._validate_data(X, y,
    157                                        validate_separately=(check_X_params,
    158                                                             check_y_params))

d:\python\lib\site-packages\sklearn\base.py in _validate_data(self, X, y, reset, validate_separately, **check_params)
    427                 # :(
    428                 check_X_params, check_y_params = validate_separately
--> 429                 X = check_array(X, **check_X_params)
    430                 y = check_array(y, **check_y_params)
    431             else:

d:\python\lib\site-packages\sklearn\utils\validation.py in inner_f(*args, **kwargs)
     70                           FutureWarning)
     71         kwargs.update(k: arg for k, arg in zip(sig.parameters, args))
---> 72         return f(**kwargs)
     73     return inner_f
     74 

d:\python\lib\site-packages\sklearn\utils\validation.py in check_array(array, accept_sparse, accept_large_sparse, dtype, order, copy, force_all_finite, ensure_2d, allow_nd, ensure_min_samples, ensure_min_features, estimator)
    596                     array = array.astype(dtype, casting="unsafe", copy=False)
    597                 else:
--> 598                     array = np.asarray(array, order=order, dtype=dtype)
    599             except ComplexWarning:
    600                 raise ValueError("Complex data not supported\n"

d:\python\lib\site-packages\numpy\core\_asarray.py in asarray(a, dtype, order)
     83 
     84     """
---> 85     return array(a, dtype, copy=False, order=order)
     86 
     87 

ValueError: could not convert string to float: 'headache,'

【问题讨论】:

【参考方案1】:

是的,它们必须是数字(不一定是浮动的)。因此,如果您在一列中有 4 个不同的文本标签,那么您需要将其转换为 4 个数字。为此,请使用 sklearn 的 labelencoder。如果您的数据位于 pandas 数据框 df

from sklearn import preprocessing
from collections import defaultdict

# select text columns
cat_cols = df.select_dtypes(include='object').columns

# this is a way to apply label_encoder to all category cols at once, returning a label encoder per categorical column, in a dict d 
d = defaultdict(preprocessing.LabelEncoder)

 # transform all text columns to numbers
df[cat_cols] = df[cat_cols].apply(lambda x: d[x.name].fit_transform(x.astype(str)))

将所有列转换为数字后,您可能还希望对"one-hot" 进行编码。对分类列和布尔列执行此操作(这里我只为您的分类列显示)。

# you should probably also one-hot the categorical columns
df = pd.get_dummies(df, columns=cat_cols)

之后您可以使用标签编码器的字典d 从标签编码器中检索值的名称。

d[col_name].inverse_transform(value)

This tutorial 对于理解这些概念特别有用。

【讨论】:

谢谢!我加了from collections import defaultdict,效果很好! 哎呀!我已经添加了这个。

以上是关于特征是不是必须是浮点数才能通过决策树进行多类分类?的主要内容,如果未能解决你的问题,请参考以下文章

scikit-learn 决策树是不是支持无序(“枚举”)多类特征?

Spark Random Forest classifier 随机森林分类

决策树算法实例讲解

使用 Apache Spark 决策树分类器进行多类分类时出错

多类 SVM。二元决策树。 LIBSVM 的问题

决策树基本原理