機器學習中會遇到一些離散型數據,無法帶入模型進行訓練,所以要對其進行編碼,常用的編碼方式有兩種:
1、特征不具備大小意義的直接獨熱編碼(one-hot encoding)
2、特征有大小意義的采用映射編碼(map encoding)
兩種編碼在sklearn.preprocessing包里有實現方法
映射編碼就是用一個字典指定不同離散型數據對應哪些數字
import pandas as pd df = pd.DataFrame([ ['green', 'M', 10.1, 'label1'], ['red', 'L', 13.5, 'label2'], ['blue', 'XL', 15.3, 'label2']]) # color、label不具備大小含義,size具有大小意義 df.columns = ['color', 'size', 'length', 'label'] size_mapping = { 'XL': 3, 'L': 2, 'M': 1} df['size'] = df['size'].map(size_mapping)
one-hot編碼有兩種形式:
1.one-hot編碼,又稱獨熱編碼、一位有效編碼。其方法是使用N位狀態寄存器來對N個狀態進行編碼,每個狀態都有它獨立的寄存器位,並且在任意時候,其中只有一位有效。舉個例子,假設我們有四個樣本(行),每個樣本有三個特征(列),如圖:

上圖中我們已經對每個特征進行了普通的數字編碼:我們的feature_1有兩種可能的取值,比如是男/女,這里男用1表示,女用2表示。那么one-hot編碼是怎么搞的呢?我們再拿feature_2來說明:
這里feature_2 有4種取值(狀態),我們就用4個狀態位來表示這個特征,one-hot編碼就是保證每個樣本中的單個特征只有1位處於狀態1,其他的都是0。

對於2種狀態、三種狀態、甚至更多狀態都是這樣表示,所以我們可以得到這些樣本特征的新表示:

one-hot編碼將每個狀態位都看成一個特征。對於前兩個樣本我們可以得到它的特征向量分別為

one-hot在提取文本特征上的應用
one hot在特征提取上屬於詞袋模型(bag of words)。關於如何使用one-hot抽取文本特征向量我們通過以下例子來說明。假設我們的語料庫中有三段話:
我愛中國
爸爸媽媽愛我
爸爸媽媽愛中國
我們首先對預料庫分離並獲取其中所有的詞,然后對每個此進行編號:
1 我; 2 愛; 3 爸爸; 4 媽媽;5 中國
然后使用one hot對每段話提取特征向量:
;
;
因此我們得到了最終的特征向量為
我愛中國 -> 1,1,0,0,1
爸爸媽媽愛我 -> 1,1,1,1,0
爸爸媽媽愛中國 -> 0,1,1,1,1
優缺點分析
優點:一是解決了分類器不好處理離散數據的問題,二是在一定程度上也起到了擴充特征的作用(上面樣本特征數從3擴展到了9)
缺點:在文本特征表示上有些缺點就非常突出了。首先,它是一個詞袋模型,不考慮詞與詞之間的順序(文本中詞的順序信息也是很重要的);其次,它假設詞與詞相互獨立(在大多數情況下,詞與詞是相互影響的);最后,它得到的特征是離散稀疏的。
one-hot的基本思想:將離散型特征的每一種取值都看成一種狀態,若你的這一特征中有N個不相同的取值,那么我們就可以將該特征抽象成N種不同的狀態,one-hot編碼保證了每一個取值只會使得一種狀態處於“激活態”,也就是說這N種狀態中只有一個狀態位值為1,其他狀態位都是0。舉個例子,假設我們以學歷為例,我們想要研究的類別為小學、中學、大學、碩士、博士五種類別,我們使用one-hot對其編碼就會得到:

2.dummy encoding,啞變量編碼直觀的解釋就是任意的將一個狀態位去除。還是拿上面的例子來說,我們用4個狀態位就足夠反應上述5個類別的信息,也就是我們僅僅使用前四個狀態位 [0,0,0,0] 就可以表達博士了。只是因為對於一個我們研究的樣本,他已不是小學生、也不是中學生、也不是大學生、又不是研究生,那么我們就可以默認他是博士,是不是。(額,當然他現實生活也可能上幼兒園,但是我們統計的樣本中他並不是,^-^)。所以,我們用啞變量編碼可以將上述5類表示成:

dummy encoding在pandas中有get_dummies()方法可以實現
