何时使用 One Hot Encoding、LabelEncoder 和 DictVectorizo​​r?

数据挖掘 scikit-学习 分类数据 特征工程
2021-09-15 19:25:01

我用分类数据构建模型已经有一段时间了,在这种情况下,我基本上默认使用 scikit-learn 的 LabelEncoder 函数在构建模型之前转换这些数据。

我了解它们之间的区别OHELabelEncoder以及DictVectorizor它们对数据所做的事情,但我不清楚的是何时您可能会选择使用一种技术而不是另一种技术。

是否有某些算法或情况相对于其他算法或情况具有优势/劣势?

4个回答

在某些情况下LabelEncoderDictVectorizor有用的情况下,但由于顺序性,我认为这些情况非常有限。

LabelEncoder可以[dog,cat,dog,mouse,cat]变成[1,2,1,3,2],但是强加的序数意味着狗和老鼠的平均值是猫。仍然有诸如决策树和随机森林之类的算法可以很好地处理分类变量,并且LabelEncoder可以使用更少的磁盘空间来存储值。

One-Hot-Encoding 的优点是结果是二进制而不是序数,并且所有内容都位于正交向量空间中。缺点是对于高基数,特征空间真的会很快爆炸,你开始与维度的诅咒作斗争。在这些情况下,我通常使用 one-hot-encoding 和 PCA 进行降维。我发现 one-hot 加 PCA 的明智组合很少能被其他编码方案击败。PCA 发现线性重叠,因此自然会倾向于将相似的特征分组为相同的特征。

虽然AN6U5给出了非常好的答案,但我想补充几点以供将来参考。在考虑One Hot Encoding (OHE) 和Label Encoding时,我们必须尝试并了解您要构建的模型。即我们将考虑的两类模型是:

  1. 基于树的模型:梯度提升决策树和随机森林。
  2. 基于非树的模型:基于线性、kNN 或神经网络。

让我们考虑在构建基于树的模型时何时应用 OHE 以及何时应用标签编码。

我们在以下情况下应用 OHE:

  1. 当标签编码中彼此接近的值对应于不接近的目标值时(非线性数据)。
  2. 当分类特征不是序数时(狗、猫、老鼠)。

我们在以下情况下应用标签编码:

  1. 分类特征是有序的(Jr. kg、Sr. kg、小学、高中等)。
  2. 当我们可以提出一个标签编码器,将接近的标签分配给相似的类别时:这会减少树的分裂,从而减少执行时间。
  3. 当数据集中的分类特征数量巨大时:One-hot 编码具有大量值的分类特征会导致 (1) 高内存消耗和 (2) 模型很少使用非分类特征的情况。如果您使用稀疏矩阵,则可以处理第一种情况。如果您仅使用特征子集构建树,则可能会出现第二种情况。例如,如果您有 9 个数字特征和 1 个具有 100 个唯一值的分类特征,并且您对该分类特征进行一次热编码,您将获得 109 个特征。如果只使用特征子集构建树,则很少使用最初的 9 个数字特征。在这种情况下,您可以增加该子集的参数控制大小。在 xgboost 中,它在 sklearn 的随机森林 max_features 中称为 colsample_bytree。

如果您想按照@AN6U5 的建议继续使用 OHE,您可能希望将 PCA 与 OHE 结合使用。

让我们考虑在构建非基于树的模型时何时应用 OHE 和标签编码。

要应用标签编码,特​​征和目标之间的依赖关系必须是线性的,才能有效地利用标签编码。

同样,如果依赖性是非线性的,您可能希望使用 OHE。

注意:部分解释参考了 Coursera的 How to Win a Data Science Competition

LabelEncoder用于序数数据,而 OHE 用于名义数据。

您还可以使用频率编码,在其中将值映射到它们的频率

示例取自如何从 Coursera 赢得数据科学竞赛,例如。对于泰坦尼克数据集:

   encoding = titanic.groupby('Embarked').size()
   encoding = encoding/len(titanic)   // calculates frequency
   titanic['enc'] = titanic.embarked.map('Encoding')

这将保留有关值分布的信息,并将有助于线性和基于树的模型。确保您没有多个具有相同频率的类别,您可以使用排名操作或任何其他相关操作。