为什么onehotencoding会将二进制数据转换成2个互斥的特征?
Why does onehotencoding convert binary data into 2 mutually exclusive features?
考虑以下来自 scikitlearn 网站的代码,
from sklearn.preprocessing import OneHotEncoder
enc = OneHotEncoder(handle_unknown='ignore')
X = [['Male', 1], ['Female', 3], ['Female', 2]]
enc.fit(X)
这将允许我将分类信息表示为二进制输入。代码的输出:
enc.get_feature_names()
是
array(['x0_Female', 'x0_Male', 'x1_1', 'x1_2','x1_3'],dtype=object)
显示转换后的新特征 space。但是,为什么要分别代表女性和男性呢?这是相互排斥的信息,应该能够表示为单个特征,例如 0 -> 'female' 和 1 -> 'male'。 运行 代码,
enc.transform([['Female', 1], ['Male', 2]]).toarray()
输出是
array([[1., 0., 1., 0., 0.],
[0., 1., 0., 1., 0.]])
由于该类别只有两个可能的输入,因此每行的前两个元素要么是 0-1 代表男性,要么 1-0 代表女性。它们之间的相关性将为-1。这些信息可以表示为一个单一的特征,为什么做成2?
OneHotEncoder
不知道你想要什么,需要什么。但在任何情况下,对于包含 2 个和 100 个类别的特征,它的行为都不应该有所不同。
假设您在一个地图项中有 5 个或 100 个类别。也许它会偶然删除与目标有很强相关性的类别 X
。那么你的 ML 算法将很难很好地泛化(例如,基于树的算法需要将拆分设置为所有其余 4 或 99 个二进制列都等于 0,这会导致许多拆分)
不过确实是信息冗余。 OneHotEncoder
不允许配置转换以删除其中一个类别(例如,这可能对线性模型有益)。如果您确实需要该功能,可以改用 pandas.get_dummies。它有 drop_first
参数,默认情况下它只转换分类特征而不是所有特征。
如果你有二元特征(比如你提到的男性和女性),你可以使用(我相信你应该使用)OrdinalEncoder 而不是 OneHotEncoder。所以它会将这两个类别隐藏到0和1的一列。实际上它等于one-hot编码删除了两列之一。
考虑以下来自 scikitlearn 网站的代码,
from sklearn.preprocessing import OneHotEncoder
enc = OneHotEncoder(handle_unknown='ignore')
X = [['Male', 1], ['Female', 3], ['Female', 2]]
enc.fit(X)
这将允许我将分类信息表示为二进制输入。代码的输出:
enc.get_feature_names()
是
array(['x0_Female', 'x0_Male', 'x1_1', 'x1_2','x1_3'],dtype=object)
显示转换后的新特征 space。但是,为什么要分别代表女性和男性呢?这是相互排斥的信息,应该能够表示为单个特征,例如 0 -> 'female' 和 1 -> 'male'。 运行 代码,
enc.transform([['Female', 1], ['Male', 2]]).toarray()
输出是
array([[1., 0., 1., 0., 0.],
[0., 1., 0., 1., 0.]])
由于该类别只有两个可能的输入,因此每行的前两个元素要么是 0-1 代表男性,要么 1-0 代表女性。它们之间的相关性将为-1。这些信息可以表示为一个单一的特征,为什么做成2?
OneHotEncoder
不知道你想要什么,需要什么。但在任何情况下,对于包含 2 个和 100 个类别的特征,它的行为都不应该有所不同。
假设您在一个地图项中有 5 个或 100 个类别。也许它会偶然删除与目标有很强相关性的类别 X
。那么你的 ML 算法将很难很好地泛化(例如,基于树的算法需要将拆分设置为所有其余 4 或 99 个二进制列都等于 0,这会导致许多拆分)
不过确实是信息冗余。 OneHotEncoder
不允许配置转换以删除其中一个类别(例如,这可能对线性模型有益)。如果您确实需要该功能,可以改用 pandas.get_dummies。它有 drop_first
参数,默认情况下它只转换分类特征而不是所有特征。
如果你有二元特征(比如你提到的男性和女性),你可以使用(我相信你应该使用)OrdinalEncoder 而不是 OneHotEncoder。所以它会将这两个类别隐藏到0和1的一列。实际上它等于one-hot编码删除了两列之一。