在浏览了一本关于 ML 的书后,我正在浏览 scikit-learn learn 的官方文档,并遇到了以下事情:
在文档中给出了它,sklearn.preprocessing.OrdinalEncoder()
而在书中给出了它sklearn.preprocessing.LabelEncoder()
,当我检查它们的功能时,它对我来说看起来是一样的。有人可以告诉我两者之间的区别吗?
在浏览了一本关于 ML 的书后,我正在浏览 scikit-learn learn 的官方文档,并遇到了以下事情:
在文档中给出了它,sklearn.preprocessing.OrdinalEncoder()
而在书中给出了它sklearn.preprocessing.LabelEncoder()
,当我检查它们的功能时,它对我来说看起来是一样的。有人可以告诉我两者之间的区别吗?
Afaik,两者都具有相同的功能。背后的想法有点不同。OrdinalEncoder
用于转换特征,而LabelEncoder
用于转换目标变量。
这就是为什么OrdinalEncoder
可以拟合形状为(n_samples, n_features)
while的LabelEncoder
数据只能拟合形状为(n_samples,)
LabelEncoder
OrdinalEncoder
至于差异OrdinalEncoder
和LabelEncoder
实现,接受的答案提到了数据的形状:
OrdinalEncoder
用于形状为 2D 的数据 (n_samples, n_features)
LabelEncoder
用于形状为 1D 的数据(n_samples,)
)也许这就是为什么投票最多的答案 OrdinalEncoder
是针对“特征”(通常是二维数组),而LabelEncoder
针对“目标变量”(通常是一维数组)。
这就是为什么OrdinalEncoder
如果尝试拟合一维数据会出错:OrdinalEncoder().fit(['a','b'])
ValueError: Expected 2D array, got 1D array instead:
编码器之间的另一个区别是它们学习参数的名称;
LabelEncoder
学习 classes_
OrdinalEncoder
学习 categories_
注意拟合 LabelEncoder
vs的差异,以及学习参数OrdinalEncoder
值的差异。
LabelEncoder.fit(...)
接受一维数组;LabelEncoder.classes_
是一维的OrdinalEncoder.fit(...)
接受二维数组;OrdinalEncoder.categories_
是二维的。 LabelEncoder().fit(['a','b']).classes_
# >>> array(['a', 'b'], dtype='<U1')
OrdinalEncoder().fit([['a'], ['b']]).categories_
# >>> [array(['a', 'b'], dtype=object)]
这与以下想法一致
OrdinalEncoder
适用于您X
的输入功能(2D)LabelEncoder
是为了你y
的目标变量(1D)(这里也提到):
LabelEncoder
应该用于编码目标值,即 y,而不是输入 X。
其他在 2D 中工作的编码器,包括OneHotEncoder
,也使用该属性categories_
有关dtype 的更多信息<U1
(little-endian,Unicode,1 字节;即长度为 1 的字符串)
编辑
在对我的回答的评论中,Piotr 不同意我的回答;但 Piotr 更普遍地指出了序数编码和标签编码之间的区别(相对于它们的实现差异)。Piotr 关于一般定义/用法的权利:
cold
, warm
, hot
);blonde
, brunette
)这是一个很好的观点,但是这个问题询问了sklearn
classes/ implementation。但是,如果您想要像 Piotr 描述的那样的序数编码(即保留顺序的位置);您必须自己进行序数编码(既OrdinalEncoder
不能也LabelEncoder
不能推断顺序!请参阅OrdinalEncoder
调用的构造函数参数categories
)。
至于实现,就所选整数而言,它似乎LabelEncoder
并且OrdinalEncoder
具有一致的行为。他们都根据字母顺序分配整数。例如:
OrdinalEncoder().fit_transform([['cold'],['warm'],['hot']]).reshape((1,3))
# >>> array([[0., 2., 1.]])
LabelEncoder().fit_transform(['cold','warm','hot'])
# >>> array([0, 2, 1], dtype=int64)
请注意两个编码器是如何按字母顺序“c”<'h'<'w'分配整数的。
但这部分很重要:注意两个编码器如何正确地得到“真实”顺序(即真实顺序应该反映温度,其中顺序是“冷”<“暖”<“热”;0<1<2)。如果编码器使用“真实”顺序,则该值'warm'
将被分配整数 1(而不是整数 2)
在 Piotr 引用的博文中,作者甚至没有使用OrdinalEncoder()
. 为了实现序数编码,作者手动进行:将每个温度映射到“真实”顺序整数,使用如下字典{'cold':0, 'warm':1, 'hot':2}
:
使用 Pandas 参考此代码,首先我们需要通过字典分配变量的实际顺序......虽然它非常简单,但它需要编码来告诉序数值以及从文本到整数的实际映射是什么命令。
换句话说,如果您想知道是否使用OrdinalEncoder
,请注意OrdinalEncoder
实际上可能并没有按照您期望的方式提供“序数编码”!
编辑
@Magnus Persson 指出OrdinalEncoder
该类接受一个名为 的参数categories
,您可以使用它来
确定/分配结果 order。
OrdinalEncoder(categories=[['cold','warm','hot']])
.fit_transform([['hot'],['warm'],['warm'],['cold']])
.reshape((1,-1))[0]
# Output is:
# >>> array([[2., 1., 1., 0.]])
编辑
@lbcommer 指出有一个 Python 库category_encoders
,它有一个OrdinalEncoder
类。请注意,即使该类构造函数也有一个mapping
参数,所以您可以选择结果顺序:
'mapping' 的值应该是 'original_label' 到 'encoded_label' 的字典......示例映射:
{‘col’: ‘col1’, ‘mapping’: {None: 0, ‘a’: 1, ‘b’: 2}}, {‘col’: ‘col2’, ‘mapping’: {None: 0, ‘x’: 1, ‘y’: 2}}
您使用序数编码来保留分类数据的顺序,即冷、暖、热;低中高。您对分类数据使用标签编码或一种热门编码,其中数据中没有顺序,即狗、猫、鲸鱼。在媒体上查看这篇文章。它很好地解释了这些概念。