Python之特征選擇實戰(zhàn)
1 特征工程是什么?
有這么一句話在業(yè)界廣泛流傳:數(shù)據(jù)和特征決定了機器學習的上限,而模型和算法只是逼近這個上限而已。那特征工程到底是什么呢?顧名思義,其本質是一項工程活動,目的是最大限度地從原始數(shù)據(jù)中提取特征以供算法和模型使用。通過總結和歸納,人們認為特征工程包括以下方面:

特征處理是特征工程的核心部分,sklearn提供了較為完整的特征處理方法,包括數(shù)據(jù)預處理,特征選擇,降維等。首次接觸到sklearn,通常會被其豐富且方便的算法模型庫吸引,但是這里介紹的特征處理庫也十分強大!
本文中使用sklearn中的IRIS(鳶尾花)數(shù)據(jù)集來對特征處理功能進行說明。IRIS數(shù)據(jù)集由Fisher在1936年整理,包含4個特征(Sepal.Length(花萼長度)、Sepal.Width(花萼寬度)、Petal.Length(花瓣長度)、Petal.Width(花瓣寬度)),特征值都為正浮點數(shù),單位為厘米。目標值為鳶尾花的分類(Iris Setosa(山鳶尾)、Iris Versicolour(雜色鳶尾),Iris Virginica(維吉尼亞鳶尾))。導入IRIS數(shù)據(jù)集的代碼如下:
from?sklearn.datasets?import?load_iris
?
#導入IRIS數(shù)據(jù)集
iris?=?load_iris()
#特征矩陣
iris.data
#目標向量
iris.target
???????
2 數(shù)據(jù)預處理
通過特征提取,我們能得到未經(jīng)處理的特征,這時的特征可能有以下問題:
不屬于同一量綱:即特征的規(guī)格不一樣,不能夠放在一起比較。無量綱化可以解決這一問題。
信息冗余:對于某些定量特征,其包含的有效信息為區(qū)間劃分,例如學習成績,假若只關心“及格”或不“及格”,那么需要將定量的考分,轉換成“1”和“0”表示及格和未及格。二值化可以解決這一問題。
定性特征不能直接使用:某些機器學習算法和模型只能接受定量特征的輸入,那么需要將定性特征轉換為定量特征。最簡單的方式是為每一種定性值指定一個定量值,但是這種方式過于靈活,增加了調參的工作。通常使用啞編碼的方式將定性特征轉換為定量特征:假設有N種定性值,則將這一個特征擴展為N種特征,當原始特征值為第i種定性值時,第i個擴展特征賦值為1,其他擴展特征賦值為0。啞編碼的方式相比直接指定的方式,不用增加調參的工作,對于線性模型來說,使用啞編碼后的特征可達到非線性的效果。
存在缺失值:缺失值需要補充。
信息利用率低:不同的機器學習算法和模型對數(shù)據(jù)中信息的利用是不同的,之前提到在線性模型中,使用對定性特征啞編碼可以達到非線性的效果。類似地,對定量變量多項式化,或者進行其他的轉換,都能達到非線性的效果。
我們使用sklearn中的preproccessing庫來進行數(shù)據(jù)預處理,可以覆蓋以上問題的解決方案。
2.1 無量綱化
無量綱化使不同規(guī)格的數(shù)據(jù)轉換到同一規(guī)格。常見的無量綱化方法有標準化和區(qū)間縮放法。標準化的前提是特征值服從正態(tài)分布,標準化后,其轉換成標準正態(tài)分布。區(qū)間縮放法利用了邊界值信息,將特征的取值區(qū)間縮放到某個特點的范圍,例如[0, 1]等。
2.1.1 標準化
標準化需要計算特征的均值和標準差,公式表達為:
使用preproccessing庫的StandardScaler類對數(shù)據(jù)進行標準化的代碼如下:

from?sklearn.preprocessing?import?StandardScaler
?
#標準化,返回值為標準化后的數(shù)據(jù)
StandardScaler().fit_transform(iris.data)
???????
2.1.2 區(qū)間縮放法
區(qū)間縮放法的思路有多種,常見的一種為利用兩個最值進行縮放,公式表達為:
使用preproccessing庫的MinMaxScaler類對數(shù)據(jù)進行區(qū)間縮放的代碼如下:

from?sklearn.preprocessing?import?MinMaxScaler
#區(qū)間縮放,返回值為縮放到[0,?1]區(qū)間的數(shù)據(jù)
MinMaxScaler().fit_transform(iris.data)
???????
2.1.3 標準化與歸一化的區(qū)別
簡單來說,標準化是依照特征矩陣的列處理數(shù)據(jù),其通過求z-score的方法,將樣本的特征值轉換到同一量綱下。歸一化是依照特征矩陣的行處理數(shù)據(jù),其目的在于樣本向量在點乘運算或其他核函數(shù)計算相似性時,擁有統(tǒng)一的標準,也就是說都轉化為“單位向量”。規(guī)則為l2的歸一化公式如下:

使用preproccessing庫的Normalizer類對數(shù)據(jù)進行歸一化的代碼如下:
from?sklearn.preprocessing?import?Normalizer
#歸一化,返回值為歸一化后的數(shù)據(jù)
Normalizer().fit_transform(iris.data)
???????
2.2 對定量特征二值化
定量特征二值化的核心在于設定一個閾值,大于閾值的賦值為1,小于等于閾值的賦值為0,公式表達如下:

使用preproccessing庫的Binarizer類對數(shù)據(jù)進行二值化的代碼如下:
from?sklearn.preprocessing?import?Binarizer
#二值化,閾值設置為3,返回值為二值化后的數(shù)據(jù)
Binarizer(threshold=3).fit_transform(iris.data)
???????
2.3 對定性特征啞編碼
由于IRIS數(shù)據(jù)集的特征皆為定量特征,故使用其目標值進行啞編碼(實際上是不需要的)。使用preproccessing庫的OneHotEncoder類對數(shù)據(jù)進行啞編碼的代碼如下:
from?sklearn.preprocessing?import?OneHotEncoder
#啞編碼,對IRIS數(shù)據(jù)集的目標值,返回值為啞編碼后的數(shù)據(jù)
OneHotEncoder().fit_transform(iris.target.reshape((-1,1)))
2.4 缺失值計算
由于IRIS數(shù)據(jù)集沒有缺失值,故對數(shù)據(jù)集新增一個樣本,4個特征均賦值為NaN,表示數(shù)據(jù)缺失。使用preproccessing庫的Imputer類對數(shù)據(jù)進行缺失值計算的代碼如下:
from?numpy?import?vstack,?array,?nan
from?sklearn.preprocessing?import?Imputer
#缺失值計算,返回值為計算缺失值后的數(shù)據(jù)
#參數(shù)missing_value為缺失值的表示形式,默認為NaN
#參數(shù)strategy為缺失值填充方式,默認為mean(均值)
Imputer().fit_transform(vstack((array([nan,?nan,?nan,?nan]),?iris.data)))
2.5 數(shù)據(jù)變換
常見的數(shù)據(jù)變換有基于多項式的、基于指數(shù)函數(shù)的、基于對數(shù)函數(shù)的。4個特征,度為2的多項式轉換公式如下:

使用preproccessing庫的PolynomialFeatures類對數(shù)據(jù)進行多項式轉換的代碼如下:
from?sklearn.preprocessing?import?PolynomialFeatures
#多項式轉換
#參數(shù)degree為度,默認值為2
PolynomialFeatures().fit_transform(iris.data)
基于單變元函數(shù)的數(shù)據(jù)變換可以使用一個統(tǒng)一的方式完成,使用preproccessing庫的FunctionTransformer對數(shù)據(jù)進行對數(shù)函數(shù)轉換的代碼如下:
from?numpy?import?log1p
from?sklearn.preprocessing?import?FunctionTransformer
#自定義轉換函數(shù)為對數(shù)函數(shù)的數(shù)據(jù)變換
#第一個參數(shù)是單變元函數(shù)
FunctionTransformer(log1p).fit_transform(iris.data)
《數(shù)據(jù)科學與人工智能》公眾號推薦朋友們學習和使用Python語言,需要加入Python語言群的,請掃碼加我個人微信,備注【姓名-Python群】,我誠邀你入群,大家學習和分享。
