數據預處理與特征工程:啞變量(離散數據)


處理分類型特征:編碼與啞變量

在機器學習中,大多數算法,譬如邏輯回歸,支持向量機SVM,k近鄰算法等都只能夠處理數值型數據,不能處理
文字,在sklearn當中,除了專用來處理文字的算法,其他算法在fifit的時候全部要求輸入數組或矩陣,也不能夠導
入文字型數據(其實手寫決策樹和普斯貝葉斯可以處理文字,但是sklearn中規定必須導入數值型)。
然而在現實中,許多標簽和特征在數據收集完畢的時候,都不是以數字來表現的。比如說,學歷的取值可以是["小
學",“初中”,“高中”,"大學"],付費方式可能包含["支付寶",“現金”,“微信”]等等。在這種情況下,為了讓數據適
應算法和庫,我們必須將數據進行編碼,即是說,將文字型數據轉換為數值型。

 

一、sklearn中的處理啞變量方法

 

 

1.preprocessing.LabelEncoder:標簽專用,能夠將分類轉換為分類數值

 1 data = pd.DataFrame([ '司機', '農業技術人員', '臨時工', '種植業生產人員', '教師'])
 2 encoder = LabelEncoder()  #要輸入的是標簽,不是特征矩陣,所以允許一維
 3 encoder = encoder.fit(data.iloc[:,-1])#導入數據
 4 result = encoder.transform(data.iloc[:,-1])#transform接口調取結果
 5 
 6 encoder.classes_#屬性.classes_查看標簽中究竟有多少類別
 7 result#查看獲取的結果
 8 
 9 encoder.inverse_transform(result )#使用inverse_transform可以逆轉
10 
11 #一步簡寫
12 data.iloc[:,-1] =  LabelEncoder().fit_transform(data.iloc[:,-1])#
輸出結果:
result:
array([2, 1, 0, 4, 3])#這里輸出為一維矩陣

2.preprocessing.OrdinalEncoder:特征專用,能夠將分類特征轉換為分類數值

1 from sklearn.preprocessing import OrdinalEncoder
2 data = pd.DataFrame([ '司機', '農業技術人員', '臨時工', '種植業生產人員', '教師'])
3 x = data.iloc[:,-1].values.reshape(-1,1)#轉置為二維矩陣
4 OrdinalEncoder().fit(x).categories_#查看有多少分類
5 OrdinalEncoder().fit_transform(x)#轉換為二維矩陣

輸出結果:

array([[2.],
       [1.],
       [0.],
       [4.],
       [3.]])#與上面不同的是這里為二維矩陣

3.preprocessing.OneHotEncoder:獨熱編碼,創建啞變量

我們來思考三種不同性質的分類數據:
1) 艙門(S,C,Q)
三種取值S,C,Q是相互獨立的,彼此之間完全沒有聯系,表達的是S≠C≠Q的概念。這是名義變量。
2) 學歷(小學,初中,高中)
三種取值不是完全獨立的,我們可以明顯看出,在性質上可以有高中>初中>小學這樣的聯系,學歷有高低,但是學
歷取值之間卻不是可以計算的,我們不能說小學 + 某個取值 = 初中。這是有序變量。
3) 體重(>45kg,>90kg,>135kg)
各個取值之間有聯系,且是可以互相計算的,比如120kg - 45kg = 90kg,分類之間可以通過數學計算互相轉換。這
是有距變量。
對特征進行編碼的時候,這三種分類數據都會被我們轉換為[0,1,2],這三個數字在算法看來,是連續且可以
計算的,這三個數字相互不等,有大小,並且有着可以相加相乘的聯系。所以算法會把艙門,學歷這樣的分類特
征,都誤會成是體重這樣的分類特征。這是說,我們把分類轉換成數字的時候,忽略了數字中自帶的數學性質,所
以給算法傳達了一些不准確的信息,而這會影響我們的建模。
類別OrdinalEncoder可以用來處理有序變量,但對於名義變量,我們只有使用啞變量的方式來處理,才能夠盡量
向算法傳達最准確的信息:
 1 from sklearn.preprocessing import OneHotEncoder
 2 data = pd.DataFrame([ '司機', '農業技術人員', '臨時工', '種植業生產人員', '教師'],columns=['occupation'])
 3 X = data.iloc[:,-1].values.reshape(-1,1)#轉換為二維矩陣
 4 enc = OneHotEncoder(categories='auto').fit(X)#擬合
 5 result = enc.transform(X).toarray()#輸出轉化值
 6 
 7 輸出結果:
 8 array([[0., 0., 1., 0., 0.],
 9        [0., 1., 0., 0., 0.],
10        [1., 0., 0., 0., 0.],
11        [0., 0., 0., 0., 1.],
12        [0., 0., 0., 1., 0.]])
13 
14 OneHotEncoder(categories='auto').fit_transform(X).toarray()#一步到位
15 
16 enc.inverse_transform(result)#還原結果
17 輸出結果:
18 array([['司機'],
19        ['農業技術人員'],
20        ['臨時工'],
21        ['種植業生產人員'],
22        ['教師']], dtype=object)
23 
24 enc.get_feature_names()#獲取轉換后數值的標簽
25 輸出結果
26 array(['x0_臨時工', 'x0_農業技術人員', 'x0_司機', 'x0_教師', 'x0_種植業生產人員'],
27       dtype=object)
28 
29 #axis=1,表示跨行進行合並,也就是將量表左右相連,如果是axis=0,就是將量表上下相連
30 newdata = pd.concat([data,pd.DataFrame(result)],axis=1)

 

 

 

二、pandas中

方法一、pd.get_dummies( data, prefix=None, prefix_sep='_', dummy_na=False, columns=None, sparse=False, drop_first=False, dtype=None,)
1 data = [ '司機', '農業技術人員', '臨時工', '種植業生產人員', '教師']
2 data = pd.DataFrame(data,columns=['occupation'])
3 data_dummis=pd.get_dummies(data)
4 data_dummis

輸出結果:

 

  

 

方法二:pd.factorize

1 data_factorize = pd.factorize(data['occupation'])#只能填寫一列
2 data_factorize

輸出結果:為數組類型

1 (array([0, 1, 2, 3, 4], dtype=int64),
2  Index(['司機', '農業技術人員', '臨時工', '種植業生產人員', '教師'], dtype='object'))
1 data['factorize'] = pd.DataFrame(data_factorize[0])

 

 

 擴展:(來源:菜菜老師)

 

 

 

 

 

 

 


免責聲明!

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



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