onehotencoder 的 sklearn 掩码不起作用

Posted

技术标签:

【中文标题】onehotencoder 的 sklearn 掩码不起作用【英文标题】:sklearn mask for onehotencoder does not work 【发布时间】:2016-03-09 11:28:48 【问题描述】:

考虑如下数据:

from sklearn.preprocessing import OneHotEncoder
import numpy as np
dt = 'object, i4, i4'
d = np.array([('aaa', 1, 1), ('bbb', 2, 2)], dtype=dt)  

我想使用 OHE 功能排除文本列。

为什么以下不起作用?

ohe = OneHotEncoder(categorical_features=np.array([False,True,True], dtype=bool))       
ohe.fit(d)
ValueError: could not convert string to float: 'bbb'

上面写着documentation:

categorical_features: “all” or array of indices or mask :
  Specify what features are treated as categorical.
   ‘all’ (default): All features are treated as categorical.
   array of indices: Array of categorical feature indices.
   mask: Array of length n_features and with dtype=bool.

我正在使用掩码,但它仍在尝试转换为浮点数。

即使使用

ohe = OneHotEncoder(categorical_features=np.array([False,True,True], dtype=bool), 
                    dtype=dt)        
ohe.fit(d)

同样的错误。

在“索引数组”的情况下:

ohe = OneHotEncoder(categorical_features=np.array([1, 2]), dtype=dt)        
ohe.fit(d)

【问题讨论】:

【参考方案1】:

我遇到了同样的行为,觉得很沮丧。正如其他人指出的那样,Scikit-Learn 在考虑选择categorical_features 参数中提供的列之前要求所有数据都是数字的。

具体来说,列选择由/sklearn/preprocessing/data.py 中的_transform_selected() 方法处理,该方法的第一行是

X = check_array(X, accept_sparse='csc', copy=copy, dtype=FLOAT_DTYPES).

如果提供的数据框X 中的任何 数据无法成功转换为浮点数,则此检查失败。

我同意sklearn.preprocessing.OneHotEncoder 的文档在这方面颇具误导性。

【讨论】:

【参考方案2】:

您应该了解,Scikit-Learn 中的所有估算器都是为数字输入而设计的。因此,从这个角度来看,以这种形式留下文本列是没有意义的。您必须将该文本列转换为数字形式,或者将其删除。

如果您从 Pandas DataFrame 获得数据集 - 您可以查看这个小型包装器:https://github.com/paulgb/sklearn-pandas。它将帮助您同时转换所有需要的列(或以数字形式保留一些行)

import pandas as pd
import numpy as np
from sklearn_pandas import DataFrameMapper
from sklearn.preprocessing import OneHotEncoder

data = pd.DataFrame('text':['aaa', 'bbb'], 'number_1':[1, 1], 'number_2':[2, 2])

#    number_1  number_2 text
# 0         1         2  aaa
# 1         1         2  bbb

# SomeEncoder here must be any encoder which will help you to get
# numerical representation from text column
mapper = DataFrameMapper([
    ('text', SomeEncoder),
    (['number_1', 'number_2'], OneHotEncoder())
])
mapper.fit_transform(data)

【讨论】:

如果您使用的是 pandas 数据框,则使用 df[column].astype('category') 设置类型并使用 get_dummies 方法也会为您对文本列进行一次性编码。 @hume,是的,但是如果您获得相同结构的其他数据帧 - 您应该能够使用您在训练集中使用的相同编码对其进行编码。 是的,同意!如果您需要在这些文本值可能不同的数据集中进行一致的转换,最好使用具有 fittransform 方法的 sklearn 编码器。【参考方案3】:

我认为这里有些混乱。您仍然需要输入数值,但在 encoder 中您可以指定哪些值是分类值,哪些不是。

这个转换器的输入应该是一个整数矩阵,表示 分类(离散)特征所采用的值。

所以在下面的示例中,我将aaa 更改为5,将bbb 更改为6。这样它将与12 数值区分开来:

d = np.array([[5, 1, 1], [6, 2, 2]])
ohe = OneHotEncoder(categorical_features=np.array([True,False,False], dtype=bool))
ohe.fit(d)

现在您可以检查您的功能类别:

ohe.active_features_
Out[22]: array([5, 6], dtype=int64)

【讨论】:

请注意,我不想使用这些字母。我不指出不好,但我想忽略文本列(因为 OHE 只接受整数,我只想删除这个文本)。 AFAIK 在将它们送入编码器之前,您需要先放下它们。你不能那样做吗?在哪里d = d[:,1:] 如果你想让它自动化的话,真的不行。再一次看一下 OH​​E 的参数categorical_features:这似乎准确地描述了我希望它做的事情。文档进一步指出:“非分类特征总是堆叠在矩阵的右侧。” @PascalvKooten,Leb 是对的,您传递给 OHE 的每个特征都应该是数字的,无论您是否选择其中一些。那就是执行问题。因此,您可以更轻松地在致电 OHE 之前删除未选择的功能。

以上是关于onehotencoder 的 sklearn 掩码不起作用的主要内容,如果未能解决你的问题,请参考以下文章

如何在 sklearn 中使用 OneHotEncoder 的输出?

sklearn中的LabelEncoder和OneHotEncoder的区别

sklearn:无法使 OneHotEncoder 与 Pipeline 一起使用

onehotencoder 的 sklearn 掩码不起作用

在 sklearn 0.14 中使用 OneHotEncoder 指定要分类的选择特征

为啥我在 Sklearn 管道中的 OneHotEncoding 后得到的列比预期的多?