字符串分类特征的一种热编码



我正在尝试对一个琐碎的数据集执行一个热编码。

data = [['a', 'dog', 'red']
        ['b', 'cat', 'green']]

使用Scikit-Learn预处理这些数据的最佳方法是什么?

第一直觉,你会看向Scikit-Learn的OneHotEncoder。但是一个热编码器不支持字符串作为功能;它只离散整数。

因此,您将使用LabelEncoder,它将字符串编码为整数。但是,您必须将标签编码器应用于每个列,并存储这些标签编码器中的每一个(以及应用它们的列)。这感觉非常笨拙。

那么,在Scikit-Learn中做到这一点的最佳方法是什么?

请不要建议pandas.get_dummies。这就是我现在通常用于一个热编码的。但是,它的限制在于您无法单独对训练/测试集进行编码。

如果你在sklearn>0.20.dev0

In [11]: from sklearn.preprocessing import OneHotEncoder
    ...: cat = OneHotEncoder()
    ...: X = np.array([['a', 'b', 'a', 'c'], [0, 1, 0, 1]], dtype=object).T
    ...: cat.fit_transform(X).toarray()
    ...: 
Out[11]: array([[1., 0., 0., 1., 0.],
           [0., 1., 0., 0., 1.],
           [1., 0., 0., 1., 0.],
           [0., 0., 1., 0., 1.]])

如果你在sklearn==0.20.dev0

In [30]: cat = CategoricalEncoder()
In [31]: X = np.array([['a', 'b', 'a', 'c'], [0, 1, 0, 1]], dtype=object).T
In [32]: cat.fit_transform(X).toarray()
Out[32]:
array([[ 1.,  0., 0.,  1.,  0.],
       [ 0.,  1.,  0.,  0.,  1.],
       [ 1.,  0.,  0.,  1.,  0.],
       [ 0.,  0.,  1.,  0.,  1.]])

另一种方法是使用category_encoders。

下面是一个示例:

% pip install category_encoders
import category_encoders as ce
le =  ce.OneHotEncoder(return_df=False, impute_missing=False, handle_unknown="ignore")
X = np.array([['a', 'dog', 'red'], ['b', 'cat', 'green']])
le.fit_transform(X)
array([[1, 0, 1, 0, 1, 0],
       [0, 1, 0, 1, 0, 1]])

非常好的问题。

然而,从某种意义上说,这是一个经常出现(至少对我来说)的私人情况——鉴于适用于X矩阵子集的sklearn阶段,我想应用(可能是几个)给定整个矩阵。例如,在这里,您有一个知道在单个列上运行的阶段,并且您希望应用它三次 - 每列一次。

这是使用复合设计模式的经典案例。

下面是一个(草图)可重用阶段,它接受将列索引映射到转换以应用于它的字典:

class ColumnApplier(object):
    def __init__(self, column_stages):
        self._column_stages = column_stages
    def fit(self, X, y):
        for i, k in self._column_stages.items():
            k.fit(X[:, i])
        return self
    def transform(self, X):
        X = X.copy()
        for i, k in self._column_stages.items():
            X[:, i] = k.transform(X[:, i])
        return X

现在,在此上下文中使用它,从

X = np.array([['a', 'dog', 'red'], ['b', 'cat', 'green']])
y = np.array([1, 2])
X

您只需使用它来将每个列索引映射到所需的转换:

multi_encoder = 
    ColumnApplier(dict([(i, preprocessing.LabelEncoder()) for i in range(3)]))
multi_encoder.fit(X, None).transform(X)

一旦你开发了这样一个阶段(我不能发布我使用的那个),你可以一遍又一遍地使用它来进行各种设置。

我多次遇到这个问题,我在这本书的第 100 页找到了解决方案:

我们可以应用这两种转换(从文本类别到整数类别,然后从整数 类别到一热矢量)使用标签二叙述器类一次性拍摄:

示例代码在这里:

from sklearn.preprocessing import LabelBinarizer
encoder = LabelBinarizer()
housing_cat_1hot = encoder.fit_transform(data)
housing_cat_1hot

结果:请注意,默认情况下,这将返回一个密集的 NumPy 数组。你可以通过传递来获取稀疏矩阵sparse_output=True to the LabelBinarizer 构造函数。

你可以在sklearn官方文档中找到更多关于LabelBinarizer的信息。

相关内容

  • 没有找到相关文章