我正在尝试执行一个简单数据集的热编码。
data = [['a', 'dog', 'red']
['b', 'cat', 'green']]
使用Scikit-Learn预处理此数据的最佳方法是什么?
首先,你会看到Scikit-Learn的OneHotEncoder。但是一个热门编码器不支持字符串作为功能;它只会使整数离散化。
那么你会使用LabelEncoder,它会将字符串编码为整数。但是,您必须将标签编码器应用到每个列中,并存储这些标签编码器中的每一个(以及它们所应用的列)。这感觉非常笨重。
那么,在Scikit-Learn中做到这一点的最佳方式是什么?
请不要建议pandas.get_dummies。这就是我现在通常使用的一种热编码方式。但是,由于您无法单独对训练/测试集进行编码,因此它受到限制。
答案 0 :(得分:7)
如果你在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]])
答案 1 :(得分:4)
非常好的问题。
然而,从某种意义上说,这是一个私人案例,它会出现(至少对我来说很常见) - 给定sklearn
阶段适用于X
矩阵的子集,I&#39 ; d喜欢在给定整个矩阵的情况下应用(可能是几个)。例如,在这里,您有一个知道要在单个列上运行的阶段,并且您希望将其应用三次 - 每列一次。
这是使用Composite Design Pattern的经典案例。
这是一个(草图)可重用阶段,它接受一个字典,将列索引映射到要应用的变换:
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)
一旦你开发了这样一个舞台(我无法发布我使用的舞台),你可以反复使用它进行各种设置。
答案 2 :(得分:3)
我多次遇到这个问题,我在他的第100页的this书中找到了解决方案:
我们可以应用两种转换(从文本类别到整数类别,然后从整数 使用LabelBinarizer类一次性对一个热矢量进行分类:
,示例代码在这里:
from sklearn.preprocessing import LabelBinarizer
encoder = LabelBinarizer()
housing_cat_1hot = encoder.fit_transform(data)
housing_cat_1hot
因此: 请注意,默认情况下,这会返回密集的NumPy数组。您可以通过传递获得稀疏矩阵 sparse_output = LabelBinarizer构造函数的True。
您可以在sklearn官方文档中找到有关LabelBinarizer的更多信息,here