在機器學習中,大多數算法,譬如邏輯回歸,支援向量機SVM,k近鄰算法等都隻能夠處理數值型資料,不能處理文字,在sklearn當中,除了專用來處理文字的算法,其他算法在fit的時候全部要求輸入數組或矩陣,也不能夠導入文字型資料(其實手寫決策樹和普斯貝葉斯可以處理文字,但是sklearn中規定必須導入數值型)。
然而在現實中,許多标簽和特征在資料收集完畢的時候,都不是以數字來表現的。比如說,學曆的取值可以是["國小",“國中”,“高中”,"大學"],付費方式可能包含["支付寶",“現金”,“微信”]等等。在這種情況下,為了讓資料适應算法和庫,我們必須将資料進行編碼,即是說,将文字型資料轉換為數值型。
preprocessing.LabelEncoder
preprocessing.LabelEncoder:标簽專用,能夠将分類轉換為分類數值
preprocessing.OrdinalEncoder
preprocessing.OrdinalEncoder:特征專用,能夠将分類特征轉換為分類數值

>>[array(['female', 'male'], dtype=object), array(['C', 'Q', 'S'], dtype=object)]
preprocessing.OneHotEncoder
preprocessing.OneHotEncoder:獨熱編碼,建立啞變量
我們剛才已經用OrdinalEncoder把分類變量Sex和Embarked都轉換成數字對應的類别了。在艙門Embarked這一列中,我們使用[0,1,2]代表了三個不同的艙門,然而這種轉換是正确的嗎?
我們來思考三種不同性質的分類資料:
1) 艙門(S,C,Q)三種取值S,C,Q是互相獨立的,彼此之間完全沒有聯系,表達的是S≠C≠Q的概念。這是名義變量。2) 學曆(國小,國中,高中)三種取值不是完全獨立的,我們可以明顯看出,在性質上可以有高中>國中>國小這樣的聯系,學曆有高低,但是學 曆取值之間卻不是可以計算的,我們不能說國小 + 某個取值 = 國中。 這是有序變量。3) 體重(>45kg,>90kg,>135kg)各個取值之間有聯系,且是可以互相計算的,比如120kg - 45kg = 90kg,分類之間可以通過數學計算互相轉換。這 是有距變量。
然而在對特征進行編碼的時候,這三種分類資料都會被我們轉換為[0,1,2],這三個數字在算法看來,是連續且可以計算的,這三個數字互相不等,有大小,并且有着可以相加相乘的聯系。是以算法會把艙門,學曆這樣的分類特征,都誤會成是體重這樣的分類特征。這是說,我們把分類轉換成數字的時候,忽略了數字中自帶的數學性質,是以給算法傳達了一些不準确的資訊,而這會影響我們的模組化。
類别OrdinalEncoder可以用來處理有序變量,但對于名義變量,我們隻有使用啞變量的方式來處理,才能夠盡量向算法傳達最準确的資訊:
這樣的變化,讓算法能夠徹底領悟,原來三個取值是沒有可計算性質的,是“有你就沒有我”的不等概念。在我們的資料中,性别和艙門,都是這樣的名義變量。是以我們需要使用獨熱編碼,将兩個特征都轉換為啞變量。
data.head()
from sklearn.preprocessing import OneHotEncoder
X = data.iloc[:,1:-1]
enc = OneHotEncoder(categories='auto').fit(X)
result = enc.transform(X).toarray()
result
#依然可以直接一步到位,但為了給大家展示模型屬性,是以還是寫成了三步
OneHotEncoder(categories='auto').fit_transform(X).toarray()
#依然可以還原
pd.DataFrame(enc.inverse_transform(result))
enc.get_feature_names()#傳回每一個經過啞變量後生成稀疏矩陣列的名字
result
result.shape
#axis=1,表示跨行進行合并,也就是将兩表左右相連,如果是axis=0,就是将量表上下相連
newdata = pd.concat([data,pd.DataFrame(result)],axis=1)
newdata.head()
newdata.drop(["Sex","Embarked"],axis=1,inplace=True)
newdata.columns = ["Age","Survived","Female","Male","Embarked_C","Embarked_Q","Embarked_S"]
newdata.head()
特征可以做啞變量,标簽也可以嗎?可以,使用類sklearn.preprocessing.LabelBinarizer可以對做啞變量,許多算法都可以處理多标簽問題(比如說決策樹),但是這樣的做法在現實中不常見,是以我們在這裡就不贅述了。
歡迎轉發分享、點贊評論