天天看點

資料預處理之獨熱編碼(One-Hot)1.前言2.獨熱編碼(One-Hot)簡介3.簡例4.在 python 中的應用5.one-hot 優缺點6.實際應用場景

1.前言

在機器學習算法中,我們經常會遇到分類特征,例如:人的性别有男女,祖國有中國,美國,法國等。

這些特征值并不是連續的,而是離散的,無序的。通常我們需要對其進行特征數字化。

那什麼是特征數字化呢?例子如下:

性别特征:[“男”,“女”]

祖國特征:[“中國”,"美國,“法國”]

運動特征:[“足球”,“籃球”,“羽毛球”,“乒乓球”]

假如某個樣本(某個人),他的特征是這樣的[“男”,“中國”,“乒乓球”],我們可以用 [0,0,4] 來表示,但是這樣的特征處理并不能直接放入機器學習算法中。因為類别之間是無序的(運動資料就是任意排序的)。

2.獨熱編碼(One-Hot)簡介

One-Hot編碼,又稱為一位有效編碼,主要是采用N位狀态寄存器來對N個狀态進行編碼,每個狀态都由他獨立的寄存器位,并且在任意時候隻有一位有效。

One-Hot編碼是分類變量作為二進制向量的表示。這首先要求将分類值映射到整數值。然後,每個整數值被表示為二進制向量,除了整數的索引之外,它都是零值,它被标記為1。

為什麼要使用 one-hot 編碼處理離散資料:

  在回歸,分類,聚類等機器學習算法中,特征之間距離的計算或相似度的計算是非常重要的,而我們常用的距離或相似度的計算都是在歐式空間的相似度計算,計算餘弦相似性,基于的就是歐式空間。

  而我們使用one-hot編碼,将離散特征的取值擴充到了歐式空間,離散特征的某個取值就對應歐式空間的某個點。

  将離散型特征使用one-hot編碼,确實會讓特征之間的距離計算更加合理。

  比如,有一個離散型特征,代表工作類型,該離散型特征,共有三個取值,不使用one-hot編碼,其表示分别是

  • x_1 = (1)
  • x_2 = (2)
  • x_3 = (3)

    兩個工作之間的距離是

  • (x_1, x_2) = 1
  • d(x_2, x_3) = 1
  • d(x_1, x_3) = 2

    那麼x_1和x_3工作之間就越不相似嗎?顯然這樣的表示,計算出來的特征的距離是不合理。那如果使用one-hot編碼,則得到

  • x_1 = (1, 0, 0)
  • x_2 = (0, 1, 0)
  • x_3 = (0, 0, 1)

    那麼兩個工作之間的距離就都是sqrt(2).即每兩個工作之間的距離是一樣的,顯得更合理。

3.簡例

  已知三個feature,三個feature分别取值如下:

  • feature1=[“male”, “female”]
  • feature2=[“from Europe”, “from US”, “from Asia”]
  • feature3=[“uses Firefox”, “uses Chrome”, “uses Safari”, “uses Internet Explorer”]

  如果做普通資料處理,那麼我們就按0,1,2,3進行編号就行了。例如

  • feature1=[0,1],
  • feature2=[0,1,2],
  • feature3=[0,1,2,3]。

    那麼,如果某個樣本為 [“male”,“from Asia”, “uses Chrome”],它就可以表示為 [0,2,1]。

    以上為普通編碼方式。 獨熱編碼(One-hot)換了一種方式編碼,先看看百科定義的:

  獨熱編碼即 One-Hot 編碼,又稱一位有效編碼,其方法是使用N位狀态寄存器來對N個狀态進行編碼,每個狀态都有它獨立的寄存器位,并且在任意時候,其中隻有一位有效。 例如對六個狀态進行編碼: 自然順序碼為 000,001,010,011,100,101 獨熱編碼則是 000001,000010,000100,001000,010000,100000

  通過以上可以看到,獨熱編碼每一個碼的總的位數取決于狀态的種類數,每一個碼裡的“1”的位置,就代表了哪個狀态生效。 還是回到我們最開始的例子,那麼我們将它換成獨熱編碼後,應該是:

  • feature1=[01,10]
  • feature2=[001,010,100]
  • feature3=[0001,0010,0100,1000]

  注意,

獨熱編碼還有個特性是,當某個特征裡的某一狀态生效後,此特征的其他狀态因為是互斥的關系,必須全部為0,切必須全部添加到特征裡,不能省略不寫。 是以,對于前邊樣本 [“male”,“from Asia”, “uses Chrome”],經過獨熱編碼後,它應該為: [01,00, 000,000,100, 0000,0010,0000,0000] 。

以上的獨熱編碼可以寫成簡寫形式: [1,0, 0,0,1, 0,1,0,0]

4.在 python 中的應用

>>> from sklearn.preprocessing import OneHotEncoder
>>> enc = OneHotEncoder()

>>> enc.fit([[0, 0, 3], [1, 1, 0], [0, 2, 1], [1, 0, 2]])  	#這裡一共有4個資料,3種特征

>>> enc.n_values_
array([2, 3, 4])

>>> enc.feature_indices_
array([0, 2, 5, 9])

>>> enc.transform([[0, 1, 1]]).toarray()
array([[ 1.,  0.,  0.,  1.,  0.,  0.,  1.,  0.,  0.]])
           

關于代碼的解釋:

比如在

enc.fit([[0, 0, 3], [1, 1, 0], [0, 2, 1], [1, 0, 2]]) 這個fit中,所有的數組第一個元素取值分别為:0,1,0,1,最大為1,且為兩種元素(0,1),說明用2個狀态位來表示就可以了,且該次元的value值為2(該值隻與最大值有關系,最大值為1)

所有的數組第二個元素取值分别為:0,1,2,0,最大為2,且為兩種元素(0,1,2),說明用3個狀态位來表示就可以了,且該次元的value值為3(該值隻與最大值有關系,最大值為2)

所有的數組第三個元素取值分别為:3,0,1,2,最大為3,且為兩種元素(0,1,2,3),說明用4個狀态位來表示就可以了,且該次元的value值為4(該值隻與最大值有關系,最大值為4)

是以整個的value值為(2,3,4),這也就解釋了 enc.n_values_等于array([2,3,4])的原因。而enc.feature_indices_則是特征索引,該例子中value值為(2,3,4),則特征索引從0開始,到2的位置為第一個,到2+3=5的位置為第二個,到2+3+4的位置為第三個,索引為array([0,2,5,9])

即:

  • enc.n_values_ is :每個特征值的特征數目,第一個特征數目是2,第二個特征數目是3,第三個特征數目是4。
  • enc.feature_indices_ is :表明每個特征在one-hot向量中的坐标範圍,0-2 是第一個特征,2-5就是第二個特征,5-9是第三個特征。

那麼接下來了解

>>> enc.transform([[0, 1, 1]]).toarray()
array([[ 1.,  0.,  0.,  1.,  0.,  0.,  1.,  0.,  0.]])
           

這個就好辦了,enc.transform就是将[0,1,1]這組特征轉換成one hot編碼,toarray()則是轉成數組形式。[0,1,1],

  • 第一個元素是0,由于之前的fit的第一個次元為2(有兩種表示:10,01.程式中10表示0,01表示1),是以用1,0表示);
  • 第二個元素是1,由于之前的fit的第二個次元為3(有三種表示:100,010,001.程式中100表示0,010表示1,001表示2),是以用0,1,0表示);
  • 第三個元素是1,由于之前的fit的第三個次元為4(有四種表示:1000,0100,0010,0001.程式中1000表示0,0100表示1,0010表示2,0001表示3),

    是以用0,1,0,0表示。綜上所述:[0,1,1]就被表示為array([[ 1., 0., 0., 1., 0., 0., 1., 0., 0.]])。

5.one-hot 優缺點

優點:

  • 能夠處理非連續型數值特征,也就是離散值。
  • 在一定程度上也擴充了特征。比如性别本身是一個特征,經過one hot編碼以後,就變成了男或女兩個特征,将離散特征通過one-hot編碼映射到歐式空間,在回歸,分類,聚類等機器學習算法中,特征之間距離的計算或相似度的計算是非常重要的,而我們常用的距離或相似度的計算都是在歐式空間的相似度計算,計算餘弦相似性,基于的就是歐式空間。
  • 将離散型特征使用one-hot編碼,可以會讓特征之間的距離計算更加合理。比如,有一個離散型特征,代表工作類型,該離散型特征,共有三個取值,不使用one-hot編碼,其表示分别是x_1 = (1), x_2 = (2), x_3 = (3)。兩個工作之間的距離是,(x_1, x_2) = 1, d(x_2, x_3) = 1, d(x_1, x_3) = 2。那麼x_1和x_3工作之間就越不相似嗎?顯然這樣的表示,計算出來的特征的距離是不合理。那如果使用one-hot編碼,則得到x_1 = (1, 0, 0), x_2 = (0, 1, 0), x_3 = (0, 0, 1),那麼兩個工作之間的距離就都是sqrt(2).即每兩個工作之間的距離是一樣的,顯得更合理。

缺點:

  • 如果原本的标簽編碼是有序的,那one hot編碼就不合适了——會丢失順序資訊。
  • 如果特征的特征值數目特别多,特征向量就會非常大,且非常稀疏。

6.實際應用場景

  我們在自然語言領域,可以将文本分詞,分詞後的所有單詞作為一個總體的特征數目,進行one-hot編碼,其中每一個單詞就是一個one-hot向量,然後文本中每個句子也同樣分詞,分詞後将這些單詞作為一個句子的表示方式,這樣一個句子就是一個二維向量,向量的行數是這個句子包含的單詞總數,如此還可以用one-hot向量組成表示為文章。

參考文章:

one-hot向量形式

機器學習:資料預處理之獨熱編碼(One-Hot)

對one hot 編碼的了解,sklearn. preprocessing.OneHotEncoder()如何進行fit()的?

繼續閱讀