Scikit-learn的LabelBinarizer vs. OneHotEncoder

67

这两种方法有什么不同?它们似乎都会创建新的列,其数量等于特征中唯一类别的数量。然后根据数据点所在的类别分配0和1。


3
何时使用One Hot编码,LabelEncoder和DictVectorizer?在机器学习中,当我们需要将分类数据转换为数字格式时,可以使用不同的编码技术,包括One Hot编码、LabelEncoder和DictVectorizer。One Hot编码适用于分类变量具有无序性质的情况,LabelEncoder适用于分类变量具有内在顺序的情况,并且DictVectorizer适用于分类变量具有复合结构的情况。选择哪种编码方法取决于分类变量的性质以及如何使用它们来训练模型。 - pault
这是否与一对多编码有关,而不是一对K编码?在编码标签时,每个类必须存在。在编码变量时,最后一个变量不应进行编码,因为它依赖于其他变量,并且大多数模型需要独立变量。尽管如此,在具有大量维度的情况下,这可能并不重要。 - Andrew Lavers
1
即使在对变量进行编码时,如果您期望该变量的新分类值出现在验证集/测试集/生产环境中,您也应该对所有变量进行编码。否则,“最后一个值”和新的词汇外值之间就没有区别了。@AndrewLavers - Elisio Quintino
5个回答

44

下面展示了使用LabelEncoder、OneHotEncoder、LabelBinarizer对数组进行编码的简单示例。

我注意到,OneHotEncoder需要先将数据转换为整数编码形式,然后才能将其转换为相应的编码形式,而在LabelBinarizer的情况下不需要。

from numpy import array
from sklearn.preprocessing import LabelEncoder
from sklearn.preprocessing import OneHotEncoder
from sklearn.preprocessing import LabelBinarizer

# define example
data = ['cold', 'cold', 'warm', 'cold', 'hot', 'hot', 'warm', 'cold', 
'warm', 'hot']
values = array(data)
print "Data: ", values
# integer encode
label_encoder = LabelEncoder()
integer_encoded = label_encoder.fit_transform(values)
print "Label Encoder:" ,integer_encoded

# onehot encode
onehot_encoder = OneHotEncoder(sparse=False)
integer_encoded = integer_encoded.reshape(len(integer_encoded), 1)
onehot_encoded = onehot_encoder.fit_transform(integer_encoded)
print "OneHot Encoder:", onehot_encoded

#Binary encode
lb = LabelBinarizer()
print "Label Binarizer:", lb.fit_transform(values)

在此输入图像描述

另一个很好的链接,可以解释OneHotEncoder:使用Python解释OneHotEncoder

也许还有其他合理的差异,专家们可能会解释。


24
你的言论中有小错误: 根据文档(https://scikit-learn.org/stable/modules/generated/sklearn.preprocessing.OneHotEncoder.html#sklearn.preprocessing.OneHotEncoder),OneHotEncoder并不需要整数编码数据来生成其稀疏矩阵。进一步研究后发现,区别在于OneHotEncoder默认生成SciPy稀疏矩阵,而LabelBinarizer默认生成密集的NumPy数组。 - stephenjfox
@stevethecoder,“密集的Numpy数组”基本上是开箱即用的数组类型吗? - F.S.
5
如果需要使用LabelBinarizer,在什么情况下应该使用它呢? - Supratim Haldar
1
我认为LabelBinarizer应该用于编码一维标签向量,而不是多列(二维)数据。对于这种情况,您应该使用OneHotEncoder - Soren

30

不同之处在于,对于多列数据,您可以使用OneHotEncoder,而无法使用LabelBinarizerLabelEncoder

from sklearn.preprocessing import LabelBinarizer, LabelEncoder, OneHotEncoder

X = [["US", "M"], ["UK", "M"], ["FR", "F"]]
OneHotEncoder().fit_transform(X).toarray()

# array([[0., 0., 1., 0., 1.],
#        [0., 1., 0., 0., 1.],
#        [1., 0., 0., 1., 0.]])
LabelBinarizer().fit_transform(X)
# ValueError: Multioutput target data is not supported with label binarization

LabelEncoder().fit_transform(X)
# ValueError: bad input shape (3, 2)

17

Scikitlearn建议使用OneHotEncoder对X矩阵进行编码,即你将要用于模型的特征,并使用LabelBinarizer来处理y标签。

它们非常相似,唯一的区别在于OneHotEncoder可能会返回一个稀疏矩阵,可以节省很多内存,在y标签中实际上并不需要这个。

即使你有一个多标签多类问题,你也可以使用MultiLabelBinarizer来处理y标签,而不是切换到OneHotEncoder进行多热编码。

https://scikit-learn.org/stable/modules/generated/sklearn.preprocessing.OneHotEncoder.html


11
OneHotEncoder() 和 LabelBinarizer() 的结果几乎相似 [默认输出类型可能有所不同]。
然而,据我所知,LabelBinarizer() 应该理想地用于响应变量,而 OneHotEncoder() 应该用于特征变量。
尽管目前我不确定为什么我们需要不同的编码器来完成类似的任务。任何指向这个方向的指针都将不胜感激。
快速总结:
LabelEncoder - 用于标签(响应变量)编码1,2,3... [意味着顺序]
OrdinalEncoder - 用于特征编码1,2,3... [意味着顺序]
Label Binarizer - 用于响应变量,编码0和1 [创建多个虚拟列]
OneHotEncoder - 用于特征变量,编码0和1 [创建多个虚拟列]
可以在此处找到一个快速示例。

1

关于此的另一个注意事项...

如果输入数据只有两个类别,则 LabelBinarizer 的输出只有一列,因为这已足以进行二进制表示:

> data = np.array([['b'], ['a']])

array([[0., 1.],
       [1., 0.]])

> LabelBinarizer().fit_transform(data)
 
array([[1],
       [0]])

与之比较:

> data = np.array([['b'], ['a'], ['c']])

array([[0., 1., 0.],
       [1., 0., 0.],
       [0., 0., 1.]])

> LabelBinarizer().fit_transform(data)

array([[0, 1, 0],
       [1, 0, 0],
       [0, 0, 1]])

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接