为什么 OneHotEncoder 最多只适用于 5 个不同的分类变量值?

Why does OneHotEncoder only work for up to 5 different categorical variable values?

我注意到当分类变量列有 6 个或更多类别时,OneHotEncoder 会失败。 例如,我有一个包含两列的 TestData.csv 文件:Geography 和 Continent。 地理的不同值是法国、西班牙、肯尼亚、博茨瓦纳和尼日利亚,而大陆的不同值是欧洲和非洲。 我的目标是使用 OneHotEncoder 对地理列进行编码。我执行以下代码来执行此操作:

import numpy as np
import pandas as pd

#Importing the dataset
dataset = pd.read_csv('TestData.csv')
X = dataset.iloc[:,:].values #X is hence a 2-dimensional numpy.ndarray

#Encoding categorical column Geography
from sklearn.preprocessing import OneHotEncoder 
from sklearn.compose import ColumnTransformer
ct = ColumnTransformer(transformers=[('encoder', OneHotEncoder(), [0])], remainder='passthrough') #the 0 is the column index for the categorical column we want to encode, in this case Geography
X = np.array(ct.fit_transform(X))

然后我 print(X) 以确保我得到预期的输出,它看起来像这样 (还要注意 X 的大小)

但是,如果我向 TestData 文件添加一个新国家/地区,假设是比利时。我们现在有 6 个不同的国家。现在 运行 完全相同的代码产生以下内容:

在第

行失败
X = np.array(ct.fit_transform(X))

如您所见,X 没有改变,也没有完成编码。我已经多次测试过这个。所以看起来 OneHotEncoder 最多只能处理 5 个不同的类别值。 是否有我可以更改的参数或我可以执行的其他方法来对具有 5 个以上值的分类变量进行编码?

PS - 我知道在编码后删除虚拟变量 ;)

我是运行Python3.7.7

谢谢!

我认为问题出在 ColumnTransformer 中的“sparse_threshold”参数。尝试将其设置为 0,以便所有输出 numpy 数组都是密集的。您的输出密度低于 0.3(默认值),这会提示它尝试切换到稀疏数组,但它仍然包含字符串列 Continent 并且稀疏数组不能包含字符串。

我注意到您已经在使用 pandas。那么还有一种方法就是使用one-hot encoding。 是您问题的更好答案。我的回答更像是一个扩展评论。

正在准备类似于您的示例数据。

import numpy as np
import pandas as pd

a = np.random.choice(['afr','deu','swe','fi','rus','eng','wu'], 40)
b = np.random.choice(['eu','as'], 40)

df = pd.DataFrame({'a':a, 'b':b})
df.head()

输出

     a   b
0  rus  as
1  eng  as
2   fi  eu
3  swe  eu
4  eng  eu

您可以使用 get_dummies 进行单热编码

pd.get_dummies(df, columns=['a'])

输出(剪裁)

     b  a_afr  a_deu  a_eng  a_fi  a_rus  a_swe  a_wu
0   eu      0      0      0     1      0      0     0
1   eu      0      0      0     0      1      0     0
2   as      0      0      0     0      1      0     0
3   eu      0      0      0     1      0      0     0
4   eu      0      0      0     0      0      0     1
5   as      0      0      0     0      0      1     0
...