在機器學習的特征處理環節,免不了需要用到類别型特征,這類特征進入模型的方式與一般數值型變量有所不同。
通常根據模型的需要,類别型特征需要進行啞變量處理,即按照特征類别進行編碼,一般一個類别為k的特征需要編碼為一組k-1【避免引起多重共線性】個衍生啞變量,這樣就可以表示特征内部所有的類别(将其中基準比較類設為0,當k-1個啞變量都為0時,即為基準類)。
這種啞變量的編碼過程在R和Python中的有成熟的方案,而無需我們手動進行編碼,使用成熟的編碼方案可以提升特征處理的過程。
R語言啞變量處理:
data(iris)
![](https://img.laitimes.com/img/9ZDMuAjOiMmIsIjOiQnIsIyZuBnLldjMlNDM2E2MjVGZjZ2YwIjM0YWNwkTNhV2Y2QjYjZzMwYTZmRTMk9CXt92Yu4GZjlGbh5SZslmZxl3Lc9CX6MHc0RHaiojIsJye.png)
這裡仍以iris資料集為例,假設這裡的Species變量是要進入模型的其中一個自變量,在模組化前需要對齊進行啞變量處理。
方法一——dummy包:
library("dummy")
dumy <- dummy(x=iris)
dummy函數會自動檢查你輸入資料集對象中的字元型/因子型變量,并全量輸出字元型/因子型變量的啞變量編碼結果。注意這裡編碼結果是全量輸出,即類别型特征的每一個類别都有一個編碼後的特征。為了編碼引起多重共線性,我們需要舍棄一個(代表比較基準類的特征),這裡Species類别變量一共有三個類别:setosa、versicolor 、virginica,各自都有一個對應編碼變量,當原始類别變量取對應類别時,則對應類别啞變量位置取值為1,否則為0.
假設這裡我們想要對比的基準類是setosa,隻需要保留versicolor、virginica對應的編碼後變量。那麼當versicolor、virginica都取值為0時,則代表取值為setosa。
最終我們要将保留的啞變量與原始資料集合并,以備之後其他特征處理環節需要。
iris_data <- cbind(iris,dumy[,-1])
此時就可以完美的用Species_versicolor、Species_virginica這兩個新生成的啞變量來代表原始分類變量Species了。
方法二——model.matrix函數:
R語言内置包stat中有一個model.matrix函數(無需單獨加載既可用),它可以處理分類變量的啞變量處理過程,文法非常簡單。
dumy <- model.matrix( ~ Species -1, data = iris)
iris_data <- cbind(iris,dumy[,-1])
這裡需要在表達式中設定消除截距【公式中減一,否則輸出的啞變量帶有截距項】,選擇的時候同上,隻取比較基準類之外的所有啞變量。
方法三——caret包中的dummyVars函數:
library("caret")
dumy <- dummyVars(~gender,data=customers)
trfs <- predict(dumy,newdata=customers)
iris_data <- iris %>% dummyVars(~Species,.) %>% predict(iris) %>% .[,-1] %>% cbind(iris,.)
選擇規則同上。
Python中的啞變量處理工具:
from sklearn.preprocessing import Imputer,LabelEncoder,OneHotEncoder
from sklearn import preprocessing
from sklearn.model_selection import train_test_split
from sklearn.datasets import load_iris
import pandas as pd
import numpy as np
方案一——:sk-learn中的OneHotEncoder方法:
iris = load_iris()
data = iris['data']
iris_data = pd.DataFrame(
data = data,
columns = ['sepal_length','sepal_width','petal_length','petal_width']
)
iris_data["Species"] = iris[ 'target']
iris_data["Species"] = iris_data["Species"].map({0:"setosa",1:"versicolor",2:"virginica"})
labelencoder_X = LabelEncoder()
iris_data["Species_code"] = labelencoder_X.fit_transform(iris_data.iloc[:,4])
onehotencoder = OneHotEncoder(categorical_features = [0])
X = onehotencoder.fit_transform(iris_data[["Species_code"]]).toarray()
iris_data = pd.DataFrame(
data = np.hstack((iris_data.values,X[:,0:2])),
columns = iris_data.columns.tolist() + ['Species_versicolor','Species_virginica']
)
方案二——pandas中的get_dummies方法:
可以看到sk-learn中的OneHotEncoder方法必須保證處理的輸入值是array,而且隻能處理數值型(也就是數字編碼之後的類别變量),無法直接處理仔字元型變量。
其實如果能夠直接在資料框中處理完這一切就友善很多。
dummy = pd.get_dummies(iris_data.iloc[:,4],prefix = "Species")
iris_data = pd.concat([iris_data,dummy.iloc[:,0:2]], axis= 1)
pandas中的get_dummies方法提供了非常簡單高效的啞變量處理方案,隻有短短的一句代碼即可。
回顧一下今天分享的啞變量處理知識點:
R語言:
● 方案一——:dummy包的dummy函數
● 方法二——:model.matrix函數
● 方法三——:caret包中的dummyVars函數
Python:
● 方法一——:caret包中的dummyVars函數
● 方案二——:pandas中的get_dummies方法
原文釋出時間為:2018-10-1
本文作者:杜雨
本文來自雲栖社群合作夥伴“
資料小魔方”,了解相關資訊可以關注“
”。