One_Hot資料預處理
在很多機器學習任務中,特徵並不總是連續值,而有可能是分類值
資料預處理之One-Hot
0.說在前面
1.什麼是One_Hot?
2.One_Hot編碼處理離散特徵
3.One_Hot編碼實現
4.作者的話
0.說在前面
前面一節我們講了機器學習過程中的特徵工程處理,那麼這一節是不是該到資料預處理了呢,對頭!
接下來,我們進入資料預處理環節,而在資料預處理過程中,非常重要的一節就是One-Hot編碼問題,之前在研究TensorFlow時候,聽說過One-Hot編碼(獨熱編碼),但不清楚是什麼,那麼我們現在一起來深入學習一下什麼是One-Hot編碼,它對我們的機器學習過程的模型又有什麼影響呢?
對於這些問題我們從問題由來,問題分析,及實戰操作,深入探究!
1.什麼是One_Hot?
對於這個問題,之前谷歌了一下,還涉及暫存器了(one-hot編碼是N位狀態暫存器為N個狀態進行編碼的方式)。。真的無語。這裡不說那些很底層的,我們只需要瞭解one-hot編碼是將類別變數轉換為機器學習演算法中容易處理的一種形式!
概念太抽象了,對太抽了,那麼從實際例子來說明。
如下我們有兩個特徵:
我們看到有兩個特證名為:animal與food,解釋一下兩列值意思,第一列代表的是動物的名字,第二列是食物的個數,比如第一行cat 2 描述為貓吃了兩個食物,這裡是測試資料,主要是想通過,這些資料給予直觀的認識及實際操作。
而對上述資料做one-hot編碼後得結果為:
animal列資料型別是字串,而第二列是數值型,如果我們能將這些特徵值用0/1表示,是不是在機器學習中,對這些非連續值非常有幫助。
綜上,我們推論出,如果你在處理的資料中,通過特徵工程這一步操作,能夠將特徵的型別判別出來,哪些是連續的,哪些是非連續的,那麼我們就可以對它進行特殊處理,比如此處的one-hot編碼!
對於定義我們有了基礎的瞭解之後,下面我們來深入瞭解一下為什麼one-hot編碼可以用來處理非連續(離散)特徵?
2.One_Hot處理離散特徵
在使用one-hot編碼中,我們可以將離散特徵的取值擴充套件到歐式空間,在機器學習中,我們的研究範圍就是在歐式空間中,首先這一步,保證了能夠適用於機器學習中;而另外對於one-hot處理的離散的特徵的某個取值也就對應了歐式空間的某個點!
那麼對於上面這句話,你會有很多疑問,比如:為何one-hot編碼能將離散特徵對映到歐式空間?
原因是,在統計機器學習演算法中的迴歸,分類這些問題中,特徵之間距離的計算或相似度計算非常重要,比如大家常用的k-means,而我們常用的這些計算都在歐式空間中進行相似度計算。換句話說,就是我上面說的研究範圍在歐式空間,保證了one-hot編碼的成立!
3.One_Hot編碼實現
還是以上述animal為例:
【資料展示】
import pandas as pd
data = {
'animal':['cat','dog','cat','lion'],
'food':[2,3,5,3]
}
data_learn = pd.DataFrame(data)
print(data_learn)
輸出:
animal food
0 cat 2
1 dog 3
2 cat 5
3 lion 3
Process finished with exit code 0
【完整特徵編碼】
dummies = pd.get_dummies(data_learn,columns=data_learn.columns)
print(dummies)
輸出:
animal_cat animal_dog animal_lion food_2 food_3 food_5
0 1 0 0 1 0 0
1 0 1 0 0 1 0
2 1 0 0 0 0 1
3 0 0 1 0 1 0
Process finished with exit code 0
【特定特徵編碼】
dummies = pd.get_dummies(data_learn['animal'])
dummies = dummies.add_prefix("{}_".format('animal'))
data_learn.drop('animal',axis=1,inplace=True)
data_learn = data_learn.join(dummies)
print(data_learn)
對於這裡的特定特徵編碼,我這裡只選取了一個特定特徵,你也可以選擇多個,通過列表儲存,遍歷操作,即可實現!
food animal_cat animal_dog animal_lion
0 2 1 0 0
1 3 0 1 0
2 5 1 0 0
3 3 0 0 1
機器學習中,經常會用到one-hot編碼。pandas中已經提供了這一函式。
但是這裡有一個神坑,得到的one-hot編碼資料型別是uint8,進行數值計算時會溢位!!!
import pandas as pd
import numpy as np
a = [1, 2, 3, 1]
one_hot = pd.get_dummies(a)
print(one_hot.dtypes)
print(one_hot)
print(-one_hot)
1 uint8
2 uint8
3 uint8
dtype: object
1 2 3
0 1 0 0
1 0 1 0
2 0 0 1
3 1 0 0
1 2 3
0 255 0 0
1 0 255 0
2 0 0 255
3 255 0 0
---------------------
正確做法,將其轉換成浮點數:
one_hot = one_hot.astype('float')
print(-one_hot)
1 2 3
0 -1.0 -0.0 -0.0
1 -0.0 -1.0 -0.0
2 -0.0 -0.0 -1.0
3 -1.0 -0.0 -0.0