簡(jiǎn)介
大概是今年6月份參加微信大數(shù)據(jù)挑戰(zhàn)賽的時(shí)候拂檩,我才開始認(rèn)識(shí)到特征選擇也是機(jī)器學(xué)習(xí)中非常重要的一環(huán)芬迄。在諸如CTR等比賽中便贵,原始特征往往是不足以挖掘出數(shù)據(jù)中隱藏的信息的隅茎,因此很多時(shí)候需要進(jìn)行特征組合,衍生出更多的組合特征嫉沽,但是這隨之也帶來了一個(gè)問題辟犀,那就是在成千上百的特征中,其實(shí)有很多特征對(duì)模型性能的提升是毫無幫助的绸硕,我們需要篩選出合適的堂竟,相對(duì)少量的特征來作為模型的輸入,這樣有助于模型的訓(xùn)練和提高精確度玻佩。但是我們?nèi)绾卧谳^多的特征池中挑選出合適的特征呢出嘹?這就是本文所要討論的特征選擇問題。
特征選擇
特征選擇(Feature Selection)又可稱特征子集的的選擇或者屬性選擇咬崔,是從大量的特征中選擇合適的领跛,相對(duì)少量的特征子集用來作為最終模型的輸入疙挺。通俗地來說,特征選擇就是在較多的特征中選擇最能體現(xiàn)數(shù)據(jù)本質(zhì)的的特征,猶如人類的學(xué)習(xí)過程蘑拯,將知識(shí)化繁為簡(jiǎn)枯怖,從紛繁復(fù)雜的信息中提煉挑選出最具代表性的特征唐片,進(jìn)而抓住最重要和最本質(zhì)的部分厚柳。
特征選擇是特征工程中最重要的內(nèi)容之一,我們期望丟棄不重要的特征熊杨,保留有效的特征曙旭。特征選擇之后,雖然特征數(shù)量減少了晶府,但是模型效果并沒有顯著下降甚至?xí)憩F(xiàn)得更好桂躏。特征選擇在某種程度上也是一種權(quán)衡的過程。
特征選擇有點(diǎn)類似于“降維”川陆,它有以下優(yōu)勢(shì):
- 工程上剂习,避免‘維數(shù)災(zāi)難’,更少的特征需要的資源更小书劝,有利于模型訓(xùn)練和推理进倍,建模效率高,維護(hù)成本低
- 理論上购对,更少的特征降低了模型假設(shè)類的復(fù)雜度猾昆,符合奧卡姆剃刀原則,有利于降低估計(jì)誤差并防止過擬合骡苞,在特征質(zhì)量較差的情況下垂蜗,甚至能避免建模的錯(cuò)誤楷扬。
- 業(yè)務(wù)上,更少的特征有利于模型的解釋贴见,一定數(shù)量的特征是在人類的理解承受范圍之內(nèi)烘苹,并且可以對(duì)數(shù)據(jù)進(jìn)行可視化分析。但是超過上百個(gè)特征對(duì)于人類來說是難以理解的片部,也降低了業(yè)務(wù)上的推廣效率镣衡。
特征選擇算法
特征選擇技術(shù)的發(fā)展過程中,一種廣為流傳的特征選擇算法分類如下:
- 過濾法(Filter Method)
原理是對(duì)特征進(jìn)行某種得分排序档悠,去排名靠前的特征廊鸥。 - 包裹法(Wrapper Method)
借助模型,評(píng)價(jià)不同特征子集的效果辖所,去效果最好的子集 - 嵌入法(Embedding Method)
借助模型自帶的特征選擇功能實(shí)現(xiàn)特征選擇惰说,未被選擇的特征的系數(shù)或權(quán)重為0。
本文將針對(duì)這三種算法缘回,分別挑選具有代表性的算法來演示一下特征選擇的過程吆视。
過濾法
過濾法首先需要選擇評(píng)分方法,然后計(jì)算所有特征的得分酥宴,對(duì)特征排序啦吧,最后根據(jù)閾值或要求的特征數(shù)量過濾得到選中的特征。該特征選擇方法不涉及后續(xù)的模型構(gòu)建幅虑,通常被認(rèn)為是一種無偏的特征選擇方法丰滑。另外根據(jù)在進(jìn)行特征選擇的時(shí)候,是否使用到了目標(biāo)變量的相關(guān)信息倒庵,可以將特征方法分為有監(jiān)督的特征選擇和無監(jiān)督的特征選擇,下面會(huì)分別舉例炫刷。
首先我們需要確定評(píng)分方法擎宝,即如何來評(píng)價(jià)一個(gè)特征的好壞程度?這里先從簡(jiǎn)單的開始----方差指標(biāo)浑玛。方差的大小表明了數(shù)據(jù)的離散程度绍申,如果一個(gè)特征所有的取值都是一樣的或者接近,那說明它數(shù)據(jù)分布比較集中不夠分散顾彰,換言之這個(gè)特征對(duì)目標(biāo)變量沒有區(qū)分度极阅。通過方差指標(biāo)來篩選特征算法很簡(jiǎn)單,便于解釋和理解涨享,由于并沒有使用到目標(biāo)變量的信息筋搏,所以這屬于無監(jiān)督的特征選擇方法。sklearn中給出了相應(yīng)的實(shí)現(xiàn)厕隧,下面是官方的例子奔脐。如下:
from sklearn.feature_selection import VarianceThreshold
# f1 f2 f3 f4
X = [[0, 2, 0, 3],
[0, 1, 4, 3],
[0, 1, 1, 3]]
selector = VarianceThreshold(threshold=0.0)
selector.fit_transform(X)
方差篩選的閾值設(shè)置為0.0俄周,原始一共有4個(gè)特征f1,f2,f3,f4,經(jīng)過方差篩選后只剩下f2髓迎,f3峦朗。因?yàn)樘卣鱢1,f4的方差為0,故被篩選掉了排龄。
上面的特征選擇使用的是無監(jiān)督的方差指標(biāo)評(píng)分方法波势,其優(yōu)點(diǎn)是簡(jiǎn)單快捷,但是不足以選擇出更具有代表性的特征橄维,并且沒有利用到目標(biāo)變量的信息艰亮,下面介紹相關(guān)性指標(biāo)評(píng)分方法。所謂相關(guān)性代表了特征與特征之間挣郭,以及特征與目標(biāo)變量之間的變化關(guān)系迄埃。如果特征值的變化會(huì)導(dǎo)致預(yù)測(cè)值的變化,那么特征就是相關(guān)的兑障。相關(guān)性的強(qiáng)弱代表了這種關(guān)系的程度侄非。如果在預(yù)測(cè)模型中使用特征A能明顯消除分類的模糊性,那么它就是強(qiáng)相關(guān)的流译,否則 為弱相關(guān)逞怨。如果從特征集中刪除掉某些特征后,特征A才變得相關(guān)福澡,那么它是弱相關(guān)的叠赦。如果一個(gè)特征既不是強(qiáng)相關(guān)的,也不是弱相關(guān)的革砸,那么認(rèn)為它是不相關(guān)的除秀。特征選擇的目標(biāo)是選擇相關(guān)性強(qiáng)的特征。評(píng)價(jià)相關(guān)性的指標(biāo)有很多算利,不過文本主要介紹皮爾遜相關(guān)系數(shù)册踩。兩個(gè)變量之間的皮爾遜相關(guān)系數(shù)定義為兩個(gè)變量的協(xié)方差除以它們標(biāo)準(zhǔn)差的乘積,如下:
關(guān)于協(xié)方差與相關(guān)系數(shù)等概念可以參考知乎如何通俗易懂地解釋「協(xié)方差」與「相關(guān)系數(shù)」的概念低散?
知道了皮爾遜相關(guān)系數(shù)的作用之后俯邓,我們就可以用它來做特征選擇了,具體來說就是分別計(jì)算每個(gè)特征與目標(biāo)變量之間的相關(guān)系數(shù)以及相關(guān)系數(shù)的P值熔号』蓿可以使用scipy中的pearsonr函數(shù)來計(jì)算皮爾遜相關(guān)系數(shù)從而來進(jìn)行特征選擇,代碼如下:
from sklearn.feature_selection import SelectKBest
from scipy.stats import pearsonr
from sklearn.datasets import load_iris
iris = load_iris()
def scoring(x, y):
t = [pearsonr(x[:,i], y) for i in range(x.shape[1])]
l = [i[0] for i in t]
tu = (i[1] for i in t)
return l, tu
X_new = SelectKBest(lambda X, Y: scoring(X, Y), k=2).fit_transform(iris.data, iris.target)
X_new
選擇的特征為:
當(dāng)然也可以使用卡方檢驗(yàn)來衡量自變量uid定性因變量餓的相關(guān)性。假設(shè)自變量有N種取值弟头,因變量有M種取值吩抓,考慮自變量等于i且因變量等于j的樣本頻數(shù)的觀察值與期望的差距,構(gòu)建統(tǒng)計(jì)量:
from sklearn.feature_selection import SelectKBest
from sklearn.feature_selection import chi2
#選擇K個(gè)最好的特征,返回選擇特征后的數(shù)據(jù)
x_new = SelectKBest(chi2, k=2).fit_transform(iris.data, iris.target)
x_new
結(jié)果跟使用皮爾遜相關(guān)系數(shù)選擇的特征一樣伦连。
互信息也是測(cè)量變量之間關(guān)聯(lián)程度的一種評(píng)價(jià)方法雨饺,當(dāng)且僅當(dāng)兩個(gè)隨機(jī)變量獨(dú)立時(shí),MI值為0惑淳,當(dāng)兩個(gè)隨機(jī)變量關(guān)聯(lián)性越強(qiáng)额港,MI值越大∑缃梗互信息在決策樹中成為信息增益移斩,它是信息論的基本概念之一。經(jīng)典的互信息也是評(píng)價(jià)定性自變量對(duì)定性因變量的相關(guān)性的绢馍,互信息計(jì)算公式如下:為了處理定量數(shù)據(jù)向瓷,最大信息系數(shù)法被提出,使用feature_selection庫的SelectKBest類結(jié)合最大信息系數(shù)法來選擇特征的代碼如下:
from sklearn.feature_selection import SelectKBest
from minepy import MINE
def scoring(x, y):
m = MINE()
res = []
for i in range(x.shape[1]):
m.compute_score(x[:,i], y)
res.append(m.mic())
tu = (0.5 for _ in res)
return res, tu
X_new = SelectKBest(lambda X, Y: scoring(X, Y), k=2).fit_transform(iris.data, iris.target)
X_new
這里得到的結(jié)果也是一樣的痕貌。
包裹法
如果特征加入后风罩,模型的性能提升只有萬分之幾,一般這樣的特征就不應(yīng)該被選中舵稠。包裹法設(shè)計(jì)模型構(gòu)建和子集搜索,相對(duì)過濾法是一種計(jì)算成本很高的特征選擇方法入宦,但是往往精度不高哺徊。有這樣一種觀點(diǎn),特征選擇方法的最終目的是尋找對(duì)性能有提升的特征(組合)乾闰,而不一定要找到相關(guān)的特征落追。
遞歸消除特征法使用一個(gè)基模型來進(jìn)行多輪訓(xùn)練,每輪訓(xùn)練后涯肩,消除若干權(quán)值系數(shù)的特征轿钠,再基于新的特征集進(jìn)行下一輪訓(xùn)練巢钓。使用feature_selection庫的RFE類來選擇特征的代碼如下:
from sklearn.feature_selection import RFE
from sklearn.linear_model import LogisticRegression
#遞歸特征消除法,返回特征選擇后的數(shù)據(jù)
#參數(shù)estimator為基模型
#參數(shù)n_features_to_select為選擇的特征個(gè)數(shù)
x_new = RFE(estimator=LogisticRegression(), n_features_to_select=2).fit_transform(iris.data, iris.target)
x_new
輸出依然是一樣的疗垛。
嵌入法
嵌入法特征選擇比較特殊症汹,它要求學(xué)習(xí)算法本身具有特征選擇的功能。例如帶L1正則項(xiàng)的回歸算法贷腕,算法輸出回歸系數(shù)為0的特征即是被刪除掉的特征背镇,說明其重要程度不高,從而表現(xiàn)為學(xué)習(xí)算法自帶特征選擇功能泽裳。正則化的決策樹也具有同樣的功能瞒斩。樹模型中權(quán)重為0的特征是沒有被模型選中的特征,所以樹模型的特征選擇也應(yīng)該歸屬于嵌入法涮总。
由于嵌入法設(shè)置未選中的特征稀疏或權(quán)重為0胸囱,所以在實(shí)踐中,嵌入法會(huì)是一個(gè)循環(huán)的過程瀑梗,例如第二次建模只輸入第一次選中的特征烹笔,此時(shí)由于特征空間的變化,第二次建模的時(shí)候也可能產(chǎn)生系數(shù)或權(quán)重為0的特征夺克,此時(shí)再重復(fù)運(yùn)行箕宙,直到所有的特征系數(shù)或權(quán)重都不為0。
1铺纽、基于隨機(jī)森林的特征選擇
決策樹構(gòu)造的過程也是特征選擇的過程柬帕。決策樹在構(gòu)造的過程中會(huì)選擇具有最大信息增益(ID3算法)、最大信息增益比(C4.5)狡门、最大GINI指數(shù)(CART算法)的特征陷寝,關(guān)于決策樹的構(gòu)造算法,可以參考我這篇博客機(jī)器學(xué)習(xí)中的特征工程(四)---- 特征離散化處理方法其馏。隨機(jī)森林基于決策樹在行列上采樣構(gòu)造樹模型凤跑,最終計(jì)算每個(gè)特征的不純度或基尼的減少的平均數(shù),排序后的得到特征的重要性叛复,從而得到平均不純度減少仔引、基尼減少、方差的特征選擇方法褐奥。該方法具有穩(wěn)定性特征選擇的特點(diǎn)咖耘。同樣,也可以使用梯度提升樹(GBDT)來作為特征選擇的基模型撬码,它們本質(zhì)上原理都差不多儿倒。基于隨機(jī)森林和GBDT的特征選擇算法代碼示例如下:
from sklearn.feature_selection import SelectFromModel
from sklearn.ensemble import GradientBoostingClassifier, RandomForestClassifier
#GBDT作為基模型的特征選擇
# clf = GradientBoostingClassifier()
# x_new = SelectFromModel(GradientBoostingClassifier()).fit_transform(iris.data, iris.target)
# 隨機(jī)森林作為基模型的特征選擇
clf = RandomForestClassifier()
x_new = SelectFromModel(clf).fit_transform(iris.data, iris.target)
clf.fit(iris.data, iris.target)
print("selected feature's shape: ", x_new.shape)
print("the importances of all original features: ", clf.feature_importances_.round(6))
這里打印出來了選擇的特征的形狀呜笑,跟上面一樣夫否,是選擇了后面2個(gè)特征彻犁。并且打印出了每個(gè)特征的重要程度,也可以看出是后面兩個(gè)特征更加重要一點(diǎn)凰慈。
2汞幢、基于正則的特征選擇
使用L1正則的模型中會(huì)得到稀疏解,即大部分特征對(duì)應(yīng)的系數(shù)為0溉瓶,很明顯系數(shù)為0或者接近0的特征是沒有被選擇的特征急鳄,即L1正則化的效果具有特征選擇的作用。使用L2的模型中則會(huì)輸出趨于一致的系數(shù)堰酿,得到較為穩(wěn)定的模型疾宏。下面是Sklearn中給出的使用帶L1正則的邏輯回歸來進(jìn)行特征選擇的例子。如下:
from sklearn.feature_selection import SelectFromModel
from sklearn.linear_model import LogisticRegression
X = [[ 0.87, -1.34, 0.31 ],
[-2.79, -0.02, -0.85 ],
[-1.34, -0.48, -2.55 ],
[ 1.92, 1.48, 0.65 ]]
y = [0, 1, 0, 1]
lr = LogisticRegression(penalty='l2', C=0.01)
selector = SelectFromModel(estimator=lr).fit(X, y)
print('特征的系數(shù): ', selector.estimator_.coef_)
print('選擇器的閾值: ', selector.threshold_)
print('特征選擇: ', selector.get_support())
print(selector.transform(X))
注意触创,最新的sklearn版本中的SelecFromModel貌似已經(jīng)不支持L1正則化坎藐,會(huì)報(bào)錯(cuò),因此這里使用的是L1正則化哼绑。
參考
- https://scikit-learn.org/stable/modules/generated/sklearn.feature_selection.VarianceThreshold.html
- https://zh.wikipedia.org/wiki/%E7%9A%AE%E5%B0%94%E9%80%8A%E7%A7%AF%E7%9F%A9%E7%9B%B8%E5%85%B3%E7%B3%BB%E6%95%B0
- https://www.kaggle.com/sz8416/6-ways-for-feature-selection
- https://www.zhihu.com/question/28641663