二进制1 -hot(也称为1 -of- k)编码是为分类变量的每个不同值创建一个二进制列。例如,如果有一个颜色列(分类变量),它的值为'red', 'blue', 'yellow'和'unknown',那么二进制编码将用二进制列'color=red', 'color=blue'和'color=yellow'替换颜色列。我从熊猫数据框架中的数据开始,我想用这些数据来训练一个scikit-learn模型。我知道有两种方法可以进行二进制编码,但没有一种让我满意。
-
Pandas和get_dummies中的数据框架的分类列。只要原始数据帧包含所有可用的数据,这种方法似乎很好。也就是说,在将数据分成训练集、验证集和测试集之前,先进行一次编码。但是,如果数据已经被分割成不同的集合,这种方法就不能很好地工作。为什么?因为其中一个数据集(比如测试集)对于给定的变量可以包含更少的值。例如,可能会发生这样的情况:对于变量color,训练集包含红色、蓝色、黄色和未知的值,而测试集只包含红色和蓝色。所以测试集最终会比训练集拥有更少的列。(我也不知道新的列是如何排序的,如果有相同的列,这可能是在不同的顺序在每个集合)。
-
Sklearn和DictVectorizer这解决了前面的问题,因为我们可以确保我们对测试集应用了完全相同的转换。但是,转换的结果是numpy数组,而不是pandas数据帧。如果我们想要将输出恢复为pandas数据帧,我们需要(或者至少这是我的做法):1)pandas。DataFrame(data= DictVectorizer转换的结果,index=原始pandas数据框的索引,columns= DictVectorizer().get_features_names)和2)沿着索引将结果数据框与包含数字列的原始数据框连接起来。
如果我们在训练集和测试集中分割数据,是否有更好的方法在pandas数据帧中进行二进制one-hot编码?
如果列的顺序相同,则可以将dfs连接起来,使用get_dummies
,然后再将它们分开,例如
encoded = pd.get_dummies(pd.concat([train,test], axis=0))
train_rows = train.shape[0]
train_encoded = encoded.iloc[:train_rows, :]
test_encoded = encoded.iloc[train_rows:, :]
如果列的顺序不一致,那么无论您尝试什么方法,都将遇到挑战。
您可以将数据类型设置为categorical:
In [5]: df_train = pd.DataFrame({"car":Series(["seat","bmw"]).astype('category',categories=['seat','bmw','mercedes']),"color":["red","green"]})
In [6]: df_train
Out[6]:
car color
0 seat red
1 bmw green
In [7]: pd.get_dummies(df_train )
Out[7]:
car_seat car_bmw car_mercedes color_green color_red
0 1 0 0 0 1
1 0 1 0 1 0
见本期《熊猫》