在數據準備階段如果含有類別變量,可以對它進行 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)