在数据准备阶段如果含有类别变量,可以对它进行 one-hot 编译,将它转换成数值再进行后续分析考虑放入模型等.
举个例子,假如 Rank 包含A,B,C三个值:
Rank
A
B
C
A
A
B
解决的办法就是向数据集中再加入三个属性,在此命名为Rank_A,Rank_B,Rank_C,如果Rank的值为A,那么这三个属性依次为(1,0,0),Rank值为B,则为(0,1,0),C为(0,0,1).每个属性都为Boolean,1代表是,0代表否.
输出结果:
Rank_A Rank_B Rank_C
0 1 0 0
1 0 1 0
2 0 0 1
3 1 0 0
4 1 0 0
5 0 1 0
Python代码:
import pandas as pd
df=pd.read_csv(r'...\dummy_test.txt')#读入文件
#Rank是特征名称
#drop_first是函数参数,是否保存原来的列,就是没有进行独热编译的原始列,默认是False
dummies_df = pd.get_dummies(df.Rank,drop_first=True)
dummies_df = dummies_df.rename(columns=lambda x:'Rank_'+str(x))
df = pd.concat([df,dummies_df],axis=1)
print(dummies_df)
Sklearn里面有专门的OneHotEncoder,跟Pandas的get_dummies实现的效果完全一致:
from sklearn.preprocessing import OneHotEncoder
除了one-hot 编译之外,另外一种方式即 label encoding,它的效果如下图所示:
但是 label encoding 有个问题,它会给每一个类别随机指定一个数字代码,并且不能反映这个类别固有的本质.
当我重新进行 label encoding 时,这些数字代码会发生改变(因为每次都是随机指定).
以下代码是当类别变量中有不超过2个类别时,对其进行 label encoding 并对训练集和测试集进行转换的过程,供参考:
from sklearn.preprocessing import LabelEncoder
le = LabelEncoder()
le_count = 0
for col in data:
if data[col].dtype == 'object':
if len(list(data[col].unique())) <= 2:
le.fit(data[col])
data_train[col] = le.transform(data_train[col])
data_test[col] = le.transform(data_test[col])
le_count += 1
print('%d columns were label encoded.' % le_count)