學習sklearn和kagggle時遇到的問題,什麼是獨熱編碼?爲何要用獨熱編碼?什麼狀況下能夠用獨熱編碼?以及和其餘幾種編碼方式的區別。html
首先了解機器學習中的特徵類別:連續型特徵和離散型特徵 算法
拿到獲取的原始特徵,必須對每一特徵分別進行歸一化,好比,特徵A的取值範圍是[-1000,1000],特徵B的取值範圍是[-1,1].若是使用logistic迴歸,w1*x1+w2*x2,由於x1的取值太大了,因此x2基本起不了做用。因此,必須進行特徵的歸一化,每一個特徵都單獨進行歸一化。框架
對於連續性特徵:機器學習
對於離散性特徵:函數
一. 什麼是獨熱編碼?post
獨熱碼,在英文文獻中稱作 one-hot code, 直觀來講就是有多少個狀態就有多少比特,並且只有一個比特爲1,其餘全爲0的一種碼制。舉例以下:學習
假若有三種顏色特徵:紅、黃、藍。 在利用機器學習的算法時通常須要進行向量化或者數字化。那麼你可能想令 紅=1,黃=2,藍=3. 那麼這樣其實實現了標籤編碼,即給不一樣類別以標籤。然而這意味着機器可能會學習到「紅<黃<藍」,但這並非咱們的讓機器學習的本意,只是想讓機器區分它們,並沒有大小比較之意。因此這時標籤編碼是不夠的,須要進一步轉換。由於有三種顏色狀態,因此就有3個比特。即紅色:1 0 0 ,黃色: 0 1 0,藍色:0 0 1 。如此一來每兩個向量之間的距離都是根號2,在向量空間距離都相等,因此這樣不會出現偏序性,基本不會影響基於向量空間度量算法的效果。ui
天然狀態碼爲:000,001,010,011,100,101this
獨熱編碼爲:000001,000010,000100,001000,010000,100000編碼
來一個sklearn的例子:
from sklearn import preprocessing enc = preprocessing.OneHotEncoder() enc.fit([[0, 0, 3], [1, 1, 0], [0, 2, 1], [1, 0, 2]]) # fit來學習編碼 enc.transform([[0, 1, 3]]).toarray() # 進行編碼
輸出:array([[ 1., 0., 0., 1., 0., 0., 0., 0., 1.]])
數據矩陣是4*3,即4個數據,3個特徵維度。
0 0 3 觀察左邊的數據矩陣,第一列爲第一個特徵維度,有兩種取值0\1. 因此對應編碼方式爲10 、01
1 1 0 同理,第二列爲第二個特徵維度,有三種取值0\1\2,因此對應編碼方式爲100、0十、001
0 2 1 同理,第三列爲第三個特徵維度,有四中取值0\1\2\3,因此對應編碼方式爲1000、0100、00十、0001
1 0 2
再來看要進行編碼的參數[0 , 1, 3], 0做爲第一個特徵編碼爲10, 1做爲第二個特徵編碼爲010, 3做爲第三個特徵編碼爲0001. 故此編碼結果爲 1 0 0 1 0 0 0 0 1
二. 爲何要獨熱編碼?
正如上文所言,獨熱編碼(啞變量 dummy variable)是由於大部分算法是基於向量空間中的度量來進行計算的,爲了使非偏序關係的變量取值不具備偏序性,而且到圓點是等距的。使用one-hot編碼,將離散特徵的取值擴展到了歐式空間,離散特徵的某個取值就對應歐式空間的某個點。將離散型特徵使用one-hot編碼,會讓特徵之間的距離計算更加合理。離散特徵進行one-hot編碼後,編碼後的特徵,其實每一維度的特徵均可以看作是連續的特徵。就能夠跟對連續型特徵的歸一化方法同樣,對每一維特徵進行歸一化。好比歸一化到[-1,1]或歸一化到均值爲0,方差爲1。
爲何特徵向量要映射到歐式空間?
將離散特徵經過one-hot編碼映射到歐式空間,是由於,在迴歸,分類,聚類等機器學習算法中,特徵之間距離的計算或類似度的計算是很是重要的,而咱們經常使用的距離或類似度的計算都是在歐式空間的類似度計算,計算餘弦類似性,基於的就是歐式空間。
三 .獨熱編碼優缺點
四. 什麼狀況下(不)用獨熱編碼?
總的來講,要是one hot encoding的類別數目不太多,建議優先考慮。
五. 什麼狀況下(不)須要歸一化?
六. 標籤編碼LabelEncoder
做用: 利用LabelEncoder() 將轉換成連續的數值型變量。便是對不連續的數字或者文本進行編號例如:
from sklearn.preprocessing import LabelEncoder le = LabelEncoder() le.fit([1,5,67,100]) le.transform([1,1,100,67,5])
輸出: array([0,0,3,2,1])
>>> le = preprocessing.LabelEncoder() >>> le.fit(["paris", "paris", "tokyo", "amsterdam"]) LabelEncoder() >>> list(le.classes_) ['amsterdam', 'paris', 'tokyo'] # 三個類別分別爲0 1 2 >>> le.transform(["tokyo", "tokyo", "paris"]) array([2, 2, 1]...) >>> list(le.inverse_transform([2, 2, 1])) # 逆過程 ['tokyo', 'tokyo', 'paris']
限制:上文顏色的例子已經提到標籤編碼了。Label encoding在某些狀況下頗有用,可是場景限制不少。再舉一例:好比有[dog,cat,dog,mouse,cat],咱們把其轉換爲[1,2,1,3,2]。這裏就產生了一個奇怪的現象:dog和mouse的平均值是cat。因此目前尚未發現標籤編碼的普遍使用。
附:基本的機器學習過程
參考:
Quora:What are good ways to handle discrete and continuous inputs together?