1. 程式人生 > >資料預處理:獨熱編碼(One-Hot Encoding)和 LabelEncoder標籤編碼

資料預處理:獨熱編碼(One-Hot Encoding)和 LabelEncoder標籤編碼

一、問題由來

在很多機器學習任務中,特徵並不總是連續值,而有可能是分類值。

離散特徵的編碼分為兩種情況:

  1、離散特徵的取值之間沒有大小的意義,比如color:[red,blue],那麼就使用one-hot編碼

  2、離散特徵的取值有大小的意義,比如size:[X,XL,XXL],那麼就使用數值的對映{X:1,XL:2,XXL:3}

使用pandas可以很方便的對離散型特徵進行one-hot編碼

複製程式碼

import pandas as pd
df = pd.DataFrame([
            ['green', 'M', 10.1, 'class1'], 
            ['red', 'L', 13.5, 'class2'], 
            ['blue', 'XL', 15.3, 'class1']])
 
df.columns = ['color', 'size', 'prize', 'class label']
 
size_mapping = {
           'XL': 3,
           'L': 2,
           'M': 1}
df['size'] = df['size'].map(size_mapping)
 
class_mapping = {label:idx for idx,label in enumerate(set(df['class label']))}
df['class label'] = df['class label'].map(class_mapping)

複製程式碼

例如,考慮一下的三個特徵:

["male", "female"]

["from Europe", "from US", "from Asia"]

["uses Firefox", "uses Chrome", "uses Safari", "uses Internet Explorer"]

如果將上述特徵用數字表示,效率會高很多。例如:

["male", "from US", "uses Internet Explorer"] 表示為[0, 1, 3]

["female", "from Asia", "uses Chrome"]表示為[1, 2, 1]

但是,即使轉化為數字表示後,上述資料也不能直接用在我們的分類器中。因為,分類器往往預設資料資料是連續的(可以計算距離?),並且是有序的(而上面這個0並不是說比1要高階)。但是,按照我們上述的表示,數字並不是有序的,而是隨機分配的。

獨熱編碼

為了解決上述問題,其中一種可能的解決方法是採用獨熱編碼(One-Hot Encoding)。獨熱編碼即 One-Hot 編碼,又稱一位有效編碼,其方法是使用N位狀態暫存器來對N個狀態進行編碼,每個狀態都由他獨立的暫存器位,並且在任意時候,其中只有一位有效。

例如:

自然狀態碼為:000,001,010,011,100,101

獨熱編碼為:000001,000010,000100,001000,010000,100000

可以這樣理解,對於每一個特徵,如果它有m個可能值,那麼經過獨熱編碼後,就變成了m個二元特徵(如成績這個特徵有好,中,差變成one-hot就是100, 010, 001)。並且,這些特徵互斥,每次只有一個啟用。因此,資料會變成稀疏的。

這樣做的好處主要有:

  1. 解決了分類器不好處理屬性資料的問題

  2. 在一定程度上也起到了擴充特徵的作用

  實現方法一:pandas之get_dummies方法

pandas.get_dummies(data, prefix=None, prefix_sep='_', dummy_na=False, columns=None, sparse=False, drop_first=False)

  該方法可以講類別變數轉換成新增的虛擬變數/指示變數。

  常用引數

複製程式碼

data : array-like, Series, or DataFrame 
輸入的資料
prefix : string, list of strings, or dict of strings, default None 
get_dummies轉換後,列名的字首 
*columns : list-like, default None 
指定需要實現類別轉換的列名
dummy_na : bool, default False 
增加一列表示空缺值,如果False就忽略空缺值
drop_first : bool, default False 
獲得k中的k-1個類別值,去除第一個

複製程式碼

  1、實驗

 實現方法二: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、010、001

0 2 1                                               同理,第三列為第三個特徵維度,有四中取值0\1\2\3,所以對應編碼方式為1000、0100、0010、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編碼對映到歐式空間,是因為,在迴歸,分類,聚類等機器學習演算法中,特徵之間距離的計算或相似度的計算是非常重要的,而我們常用的距離或相似度的計算都是在歐式空間的相似度計算,計算餘弦相似性,基於的就是歐式空間。

四 .獨熱編碼優缺點

  • 優點:獨熱編碼解決了分類器不好處理屬性資料的問題,在一定程度上也起到了擴充特徵的作用。它的值只有0和1,不同的型別儲存在垂直的空間。
  • 缺點:當類別的數量很多時,特徵空間會變得非常大。在這種情況下,一般可以用PCA來減少維度。而且one hot encoding+PCA這種組合在實際中也非常有用。

五. 什麼情況下(不)用獨熱編碼?

  • 用:獨熱編碼用來解決類別型資料的離散值問題,
  • 不用:將離散型特徵進行one-hot編碼的作用,是為了讓距離計算更合理,但如果特徵是離散的,並且不用one-hot編碼就可以很合理的計算出距離,那麼就沒必要進行one-hot編碼。 有些基於樹的演算法在處理變數時,並不是基於向量空間度量,數值只是個類別符號,即沒有偏序關係,所以不用進行獨熱編碼。  Tree Model不太需要one-hot編碼: 對於決策樹來說,one-hot的本質是增加樹的深度

  總的來說,要是one hot encoding的類別數目不太多,建議優先考慮。 

六.  什麼情況下(不)需要歸一化?

  • 需要: 基於引數的模型或基於距離的模型,都是要進行特徵的歸一化。
  • 不需要:基於樹的方法是不需要進行特徵的歸一化,例如隨機森林,bagging 和 boosting等。

七、one-hot編碼為什麼可以解決類別型資料的離散值問題 

  首先,one-hot編碼是N位狀態暫存器為N個狀態進行編碼的方式    eg:高、中、低不可分,→ 用0 0 0 三位編碼之後變得可分了,並且成為互相獨立的事件         類似 SVM中,原本線性不可分的特徵,經過project之後到高維之後變得可分了    GBDT處理高維稀疏矩陣的時候效果並不好,即使是低維的稀疏矩陣也未必比SVM好 

八、Tree Model不太需要one-hot編碼

  對於決策樹來說,one-hot的本質是增加樹的深度    tree-model是在動態的過程中生成類似 One-Hot + Feature Crossing 的機制      1. 一個特徵或者多個特徵最終轉換成一個葉子節點作為編碼 ,one-hot可以理解成三個獨立事件      2. 決策樹是沒有特徵大小的概念的,只有特徵處於他分佈的哪一部分的概念    one-hot可以解決線性可分問題 但是比不上label econding    one-hot降維後的缺點: 

  • 降維前可以交叉的降維後可能變得不能交叉