scikit-learn 中 OneHotEncoder 解析


概要

在 sklearn 包中,OneHotEncoder 函數非常實用,它可以實現將分類特征的每個元素轉化為一個可以用來計算的值。本篇詳細講解該函數的用法,也可以參考官網 sklearn.preprocessing.OneHotEncoder

 


解析

 
該函數在 sklearn.preprocessing 類中,格式為:

OneHotEncoder(n_values=’auto’,  categorical_features=’all’,  dtype=<class ‘numpy.float64’>,  sparse=True,  handle_unknown=’error’)

為了方便理解,我們先看下面一個例子:

# -*- coding: utf-8 -*-

from sklearn.preprocessing import  OneHotEncoder

enc = OneHotEncoder()
enc.fit([[0, 0, 3],
         [1, 1, 0],
         [0, 2, 1],
         [1, 0, 2]])

ans = enc.transform([[0, 1, 3]]).toarray()  # 如果不加 toarray() 的話,輸出的是稀疏的存儲格式,即索引加值的形式,也可以通過參數指定 sparse = False 來達到同樣的效果
print(ans) # 輸出 [[ 1.  0.  0.  1.  0.  0.  0.  0.  1.]]

下面解釋輸出結果的意思。對於輸入數組,這依舊是把每一行當作一個樣本,每一列當作一個特征,

  • 我們先來看第一個特征,即第一列 \([0, 1, 0, 1]\),也就是說它有兩個取值 0 或者 1,那么 one-hot 就會使用兩位來表示這個特征,\([1,0]\) 表示 0, \([0,1]\) 表示 1,在上例輸出結果中的前兩位 \([1,0...]\) 也就是表示該特征為 0
  • 第二個特征,第二列 \([0,1,2,0]\),它有三種值,那么 one-hot 就會使用三位來表示這個特征,\([1,0,0]\) 表示 0, \([0,1,0]\) 表示 1,\([0,0,1]\) 表示 2,在上例輸出結果中的第三位到第六位 \([...0,1,0,0...]\) 也就是表示該特征為 1
  • 第二個特征,第三列 \([3,0,1,2]\),它有四種值,那么 one-hot 就會使用四位來表示這個特征,\([1,0,0,0]\) 表示 0, \([0,1,0,0]\) 表示 1,\([0,0,1,0]\) 表示 2,\([0,0,0,1]\) 表示 3,在上例輸出結果中的最后四位 \([...0,0,0,1]\) 也就是表示該特征為 3

好了,到此相信我們已經很明白它的意思了。值得注意的是,雖然訓練樣本中的數值僅僅代表類別,但是也必須使用數值格式的數據,如果使用字符串格式的數據會報錯。

 
下面解釋一下函數中參數的意思,

  • n_values=’auto’,表示每個特征使用幾維的數值由數據集自動推斷,即幾種類別就使用幾位來表示。當然也可以自己指定,看下面這個例子:
# -*- coding: utf-8 -*-

from sklearn.preprocessing import  OneHotEncoder

enc = OneHotEncoder(n_values = [2, 3, 4])
enc.fit([[0, 0, 3],
         [1, 1, 0]])

ans = enc.transform([[0, 2, 3]]).toarray()
print(ans) # 輸出 [[ 1.  0.  0.  0.  1.  0.  0.  0.  1.]]

注意到訓練樣本中第二個特征列沒有類別 2,但是結果中依然將類別 2 給編碼了出來,這就是自己指定維數的作用了(我們使用 3 位來表示第二個特征,自然包括了類別 2),第三列特征同樣如此。這也告誡我們,如果訓練樣本中有丟失的分類特征值,我們就必須顯示地設置參數 n_values 了,這樣防止編碼出錯。
 

  • categorical_features = 'all',這個參數指定了對哪些特征進行編碼,默認對所有類別都進行編碼。也可以自己指定選擇哪些特征,通過索引或者 bool 值來指定,看下例:
# -*- coding: utf-8 -*-

from sklearn.preprocessing import  OneHotEncoder

enc = OneHotEncoder(categorical_features = [0,2]) # 等價於 [True, False, True]
enc.fit([[0, 0, 3],
         [1, 1, 0],
         [0, 2, 1],
         [1, 0, 2]])

ans = enc.transform([[0, 2, 3]]).toarray()
print(ans) # 輸出 [[ 1.  0.  0.  0.  0.  1.  2.]]

輸出結果中前兩位 \([1,0]\) 表示 0,中間四位 \([0,0,0,1]\) 表示對第三個特征 3 編碼,第二個特征 2 沒有進行編碼,就放在最后一位。
 

  • dtype=<class ‘numpy.float64’> 表示編碼數值格式,默認是浮點型。
     
  • sparse=True 表示編碼的格式,默認為 True,即為稀疏的格式,指定 False 則就不用 toarray() 了
     
  • handle_unknown=’error’,其值可以指定為 "error" 或者 "ignore",即如果碰到未知的類別,是返回一個錯誤還是忽略它。

 
方法 transform(X) 就是對 \(X\) 進行編碼了。在實際應用中,我們更常用方法 fit_transform(),也就是一步到位,看下例:

# -*- coding: utf-8 -*-

from sklearn.preprocessing import  OneHotEncoder

enc = OneHotEncoder(sparse = False) 
ans = enc.fit_transform([[0, 0, 3],
                         [1, 1, 0],
                         [0, 2, 1],
                         [1, 0, 2]])

print(ans) # 輸出 [[ 1.  0.  1. ...,  0.  0.  1.]
           #      [ 0.  1.  0. ...,  0.  0.  0.]
           #      [ 1.  0.  0. ...,  1.  0.  0.]
           #      [ 0.  1.  1. ...,  0.  1.  0.]]

 
 
 


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM