OrdinalEncoder 和 LabelEncoder 的区别

数据挖掘 机器学习 Python scikit-学习 预处理 编码
2021-10-12 21:00:39

在浏览了一本关于 ML 的书后,我正在浏览 scikit-learn learn 的官方文档,并遇到了以下事情:

在文档中给出了它,sklearn.preprocessing.OrdinalEncoder()而在书中给出了它sklearn.preprocessing.LabelEncoder(),当我检查它们的功能时,它对我来说看起来是一样的。有人可以告诉我两者之间的区别吗?

3个回答

Afaik,两者都具有相同的功能。背后的想法有点不同。OrdinalEncoder用于转换特征,而LabelEncoder用于转换目标变量。

就是为什么OrdinalEncoder可以拟合形状为(n_samples, n_features)whileLabelEncoder数据只能拟合形状(n_samples,)LabelEncoderOrdinalEncoder

至于差异OrdinalEncoderLabelEncoder 实现,接受的答案提到了数据的形状:

  • 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_

注意拟合 LabelEncodervs的差异,以及学习参数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)]

这与以下想法一致

LabelEncoder 应该用于编码目标值,即 y,而不是输入 X。

其他在 2D 中工作的编码器,包括OneHotEncoder,也使用该属性categories_

有关dtype 的更多信息<U1(little-endian,Unicode,1 字节;即长度为 1 的字符串)

编辑

对我的回答的评论中,Piotr 不同意我的回答但 Piotr 更普遍地指出了序数编码和标签编码之间的区别(相对于它们的实现差异)。Piotr 关于一般定义/用法的权利:

  • 序数编码应该用于序数变量(顺序很重要,如cold, warm, hot);
  • vs标签编码应该用于非序数(又名标称)变量(顺序无关紧要,例如blonde, brunette

这是一个很好的观点,但是这个问题询问了sklearnclasses/ 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}}

您使用序数编码来保留分类数据的顺序,即冷、暖、热;低中高。您对分类数据使用标签编码或一种热门编码,其中数据中没有顺序,即狗、猫、鲸鱼。在媒体上查看这篇文章。它很好地解释了这些概念。