Python 字符串分类特征的一种热编码
我正在尝试对一个微不足道的数据集执行一次热编码Python 字符串分类特征的一种热编码,python,encoding,scikit-learn,one-hot-encoding,Python,Encoding,Scikit Learn,One Hot Encoding,我正在尝试对一个微不足道的数据集执行一次热编码 data = [['a', 'dog', 'red'] ['b', 'cat', 'green']] 使用Scikit Learn预处理这些数据的最佳方法是什么 本能地,你会看向Scikit的Learn。但是one hot编码器不支持字符串作为特性;它只离散整数 然后,您将使用,它将字符串编码为整数。但是,您必须将标签编码器应用到每个列中,并存储每个标签编码器(以及应用它们的列)。这感觉非常笨重 那么,在Scikit Learn中
data = [['a', 'dog', 'red']
['b', 'cat', 'green']]
使用Scikit Learn预处理这些数据的最佳方法是什么
本能地,你会看向Scikit的Learn。但是one hot编码器不支持字符串作为特性;它只离散整数
然后,您将使用,它将字符串编码为整数。但是,您必须将标签编码器应用到每个列中,并存储每个标签编码器(以及应用它们的列)。这感觉非常笨重
那么,在Scikit Learn中,最好的方法是什么
请不要建议。这就是我现在常用的一种热编码。然而,它的局限性在于您不能单独编码您的训练/测试集。这是一个很好的问题
然而,在某种意义上,这是一个私人案例(至少对我来说)经常出现-给定sklearn
阶段适用于X
矩阵的子集,我想应用(可能几个)给定整个矩阵。例如,在这里,您有一个知道在单个列上运行的stage,您希望应用它三次—每列一次
这是使用的经典案例
下面是一个可重用阶段的(草图),它接受一个字典,将列索引映射到要应用于它的转换中:
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页的书中找到了解决方案: 我们可以应用这两种转换(从文本类别到整数类别,然后从整数类别) 使用LabelBinarizer类一次性将类别设置为一个热向量: 示例代码如下:
from sklearn.preprocessing import LabelBinarizer
encoder = LabelBinarizer()
housing_cat_1hot = encoder.fit_transform(data)
housing_cat_1hot
因此:
请注意,默认情况下,这将返回密集的NumPy数组。您可以通过传递来获得稀疏矩阵
稀疏_输出=LabelBinarizer构造函数的True
如果您使用的是sklearn>0.20.dev0,您可以在sklearn官方文档中找到关于LabelBinarizer的更多信息
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.]])
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.]])
如果您在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.]])
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_编码器
以下是一个例子:
% 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]])
老实说,我以前也创造过类似的东西。而且感觉很笨重。Scikit Learn应该有一个在幕后对其进行抽象的类,因为这是一种常见的设计模式。如果没有,那么我认为这方面的PR是合适的。你的解决方案给出了这个数据的问题:X=np.数组([['cat'],['dog'],'cat'],['pet'],'man'],['cat']])y=[1,2,3,4]我通常也做类似的事情,但是一个已知的缺点是
LabelEncoder#transform
在看到训练中没有出现的字符串时崩溃。难道fit#u transform
不应该纠正这个问题吗?这在Windows 10上的Python 3.6中失败了。>>外壳\u cat\u 1hot=encoder.fit\u transform(数据)-----回溯(最近一次调用):文件“”,第1行,在,,,,,,,这不是一个热编码,而是虚拟编码。此外,pandas.get_虚拟二进制编码被决策树分类器视为连续编码,因此不适用于该场景。CategorialEncoder已与OneHotEncoder合并,因此该功能包含在当前版本的sklearn==0.20.dev0中