二进制特征应该是one-hot编码吗?

Jur*_*rgy 10 python machine-learning scikit-learn

我正在处理由几十个关于人的二进制特征组成的数据,这些特征基本上归结为“人具有特征 x”[真/假]。

从我可以找到的在线分类数据来看,应该是单热编码,而不是为每个类别分配任意值,因为您不能说“类别 1 小于类别 2”。所以解决方案是为每个类别创建一个虚拟变量:

Cat || dummy 1 | dummy 2 | dummy 3
____||_________|_________|________
 1  ||   1     |   0     |   0
 2  ||   0     |   1     |   0
 3  ||   0     |   0     |   1
Run Code Online (Sandbox Code Playgroud)

现在对于二元特征,可以选择直接使用变量(1 表示真,0 表示假)或使用两个虚拟变量((1, 0) 表示真,(0, 1) 表示假。)。但我找不到任何显示/解释最佳方法的来源。

我自己很矛盾,因为一方面,虚拟变量降低了每个单独变量的重要性,并且表明至少在某些情况下模型的准确性会受到影响,来源。但另一方面,这也可以编码丢失的数据(以 (0, 0) 的形式)。此外,是否可以说“假小于真”?

我实际上在 python 中使用了随机森林,我知道基于树的分类器(如随机森林)支持分类数据,但 Sklearn 包尚未实现这一点。

我在 Sklearn 数字数据集上写了一个小测试。该数据集有多个 8 x 8 的数字图像 (0-9),每个像素的值在 0 到 16 之间,一个简单的模型可以使用它来学习识别数字。

对于我的测试,我将 > 8 的值更改为 True,将 <= 8 的值更改为 False。与原始数据相比,准确性当然会受到影响,但是当我实现单热编码时,因此将 True 更改为 (1, 0) 并将 False 更改为 (0, 1) 与二进制编码相比,我找不到显着差异.

对推荐方法的解释将不胜感激!

Yah*_*hya 5

将取 [0, 1] 值的二进制变量转换为 [(0, 1), (1, 0)] 的单热编码是多余的,不建议这样做,原因如下(其中一些已经提到在上面的评论中,但只是为了扩展这一点):

  1. 它是多余的,因为二进制变量已经是一种类似于 one-hot 编码的形式,其中最后一列被删除,因为它有或没有它没有任何区别,因为它可以从第一个给定的列中推断出来:如果我给你[(0, ), (1,)],你可以知道补列[(, 1), (, 0)]。

  2. 假设您有多个二元变量,例如 4。如果将它们转换为one-hot编码形式,维数将从4增加到8,不推荐使用后者,原因如下:

    • 维度诅咒:高维数据可能很麻烦。这是因为很多算法(例如聚类算法)使用欧几里得距离,由于平方项,它对噪声很敏感。事实上,随着维度的增加,数据点散布得太细,使得数据变得非常嘈杂。此外,邻域的概念变得毫无意义,基于寻找数据点距离之间的相对对比度的方法变得不可靠。

    • 时间和内存复杂度:很直观,增加特征数量将花费算法更多的执行时间和内存空间要求。仅举几例,在计算中使用协方差矩阵的算法将受到影响。多项式算法最终会得到太多项……等等。一般来说,学习通常更快,特征更少,特别是如果额外的特征是多余的。

    • 多重共线性:由于二进制变量的one-hot编码形式的最后一列是冗余的,并且与第一列100%相关,这会给基于线性回归的算法带来麻烦。例如,由于普通最小二乘估计涉及对矩阵求逆,如果许多特征相关,计算机算法可能无法成功获得近似逆,因此逆可能在数值上不准确。此外,线性模型通过观察因变量y的变化而工作,在将所有其他自变量保持为常数后,一个自变量的单位变化,但如果自变量高度相关,后者失败(多重共线性还有更多其他后果)(尽管其他一些算法可能对此不那么敏感,如决策树)。

    • 容易过度拟合:通常,太多的特征(无论它们是否相关)可能会过度拟合您的模型并且无法推广到新示例,因为您的数据集中的每个数据点都将被给定的特征完全识别(搜索 Andrew NG讲座,他详细解释了

概括

简而言之,将二进制变量转换为单热编码的变量是多余的,可能会导致不必要和不请自来的麻烦。尽管相关特征可能并不总是会使您的模型恶化,但它们也不总是会改善它。