機(jī)器學(xué)習(xí):08. sklearn中的特征選擇feature_selection

特征選擇

概念:就是從所有的特征中,選擇出有意義,對(duì)模型有幫助的特征屯碴,以避免必須將所有特征都導(dǎo)入模型去訓(xùn)練的情況巧涧。
特征選擇常用的方法有:過濾法,嵌入法判哥,包裝法献雅,和降維算法。

導(dǎo)入數(shù)據(jù)

import pandas as pd
data = pd.read_csv(r"C:\Users\18700\Desktop\03數(shù)據(jù)預(yù)處理和特征工程\digit recognizor.csv")
data.head()

X = data.iloc[:,1:] #特征矩陣
y = data.iloc[:,0] #標(biāo)簽
X.shape #維度指的是特征的數(shù)量塌计,這個(gè)數(shù)據(jù)維度太高
#(42000, 784)
"""
這個(gè)數(shù)據(jù)量相對(duì)夸張挺身,如果使用支持向量機(jī)和神經(jīng)網(wǎng)絡(luò),很可能會(huì)直接跑不出來锌仅。使用KNN跑一次大概需要半個(gè)小時(shí)章钾。
用這個(gè)數(shù)據(jù)舉例,能更夠體現(xiàn)特征工程的重要性热芹。
"""

1. Filter過濾法

過濾方法通常用作預(yù)處理步驟贱傀,特征選擇完全獨(dú)立于任何機(jī)器學(xué)習(xí)算法。

全部特征——最佳特征子集——算法——評(píng)估

1.1 方差過濾 (一般來說伊脓,只用來過濾到0/1的方差小的特征)

1.1.1 VarianceThreshold

通過特征本身的方差來篩選特征的類府寒。優(yōu)先消除方差為0的特征。VarianceThreshold有重要參數(shù)threshold,表示方差的閾值株搔,表示舍棄所有方差小于threshold的特征剖淀,不填默認(rèn)為0,即刪除所有的記錄都相同的特征纤房。

from sklearn.feature_selection import VarianceThreshold
selector = VarianceThreshold() #實(shí)例化纵隔,不填參數(shù)默認(rèn)方差為0
X_var0 = selector.fit_transform(X) #獲取刪除不合格特征之后的新特征矩陣
#也可以直接寫成 X = VairanceThreshold().fit_transform(X)
X_var0.shape #是一個(gè)ndarray
#(42000, 708) #可將特征變少了,刪除了方差為0的特征

#X_var0.head() #會(huì)報(bào)錯(cuò)
pd.DataFrame(X_var0).head() #所以需要轉(zhuǎn)換為dataframe

根據(jù)方差的中位數(shù)進(jìn)行過濾

#通過var的中位數(shù)進(jìn)行過濾
import numpy as np
X_fsvar = VarianceThreshold(np.median(X.var().values)).fit_transform(X) #就是舍棄方差小于中位數(shù)方差的特征
#X.var()是一個(gè)series帆卓,.values提取對(duì)應(yīng)的值
X.var().values
np.median(X.var().values)
X_fsvar.shape
#(42000, 392)

特征是伯努利隨機(jī)變量(二分類)

#若特征是伯努利隨機(jī)變量巨朦,假設(shè)p=0.8,即二分類特征中某種分類占到80%以上的時(shí)候刪除特征
X_bvar = VarianceThreshold(.8 * (1 - .8)).fit_transform(X)
X_bvar.shape
#(42000, 685)

1.1.2 方差過濾對(duì)模型的影響

  1. 最近鄰算法KNN剑令,單棵決策樹糊啡,支持向量機(jī)SVM,神經(jīng)網(wǎng)絡(luò)吁津,回歸算法棚蓄,都需要遍歷特征或升維來進(jìn)行運(yùn)算,所以他們本身的運(yùn)算量就很大碍脏,需要的時(shí)間就很長(zhǎng)梭依,因此方差過濾這樣的特征選擇對(duì)他們來說就尤為重要。
  2. 但對(duì)于不需要遍歷特征的算法典尾,比如隨機(jī)森林役拴,它隨機(jī)選取特征進(jìn)行分枝,本身運(yùn)算就非臣毓。快速河闰,因此特征選擇對(duì)它來說效果平平。

過濾法的主要對(duì)象是:需要遍歷特征或升維的算法們;
過濾法的主要目的是:在維持算法表現(xiàn)的前提下褥紫,幫助算法們降低計(jì)算成本姜性。

方差過濾的影響

如果過濾之后模型的效果反而變差了,那么被過濾掉的特征中有很多是有效特征髓考,就需要放棄過濾部念。

1.2 相關(guān)性過濾

1.2.1 卡方過濾

卡方過濾是專門針對(duì)離散型標(biāo)簽(即分類問題)的相關(guān)性過濾。卡方檢驗(yàn)類feature_selection.chi2計(jì)算每個(gè)非負(fù)特征和標(biāo)簽之間的卡方統(tǒng)計(jì)量氨菇,并依照卡方統(tǒng)計(jì)量由高到低為特征排名儡炼。再結(jié)合feature_selection.SelectKBest這個(gè)可以輸入”評(píng)分標(biāo)準(zhǔn)“來選出前K個(gè)分?jǐn)?shù)最高的特征的類,我們可以借此除去最可能獨(dú)立于標(biāo)簽门驾,與我們分類目的無關(guān)的特征射赛。

from sklearn.ensemble import RandomForestClassifier as RFC
from sklearn.model_selection import cross_val_score
from sklearn.feature_selection import SelectKBest #選擇k個(gè)分?jǐn)?shù)最高的特征
from sklearn.feature_selection import chi2 #卡方檢驗(yàn)

#假設(shè)在這里我需要300個(gè)特征
X_fschi = SelectKBest(chi2, k=300).fit_transform(X_fsvar, y) #選擇前300個(gè)卡方值的特征
X_fschi.shape
#(42000, 300)

驗(yàn)證模型的效果如何

cross_val_score(RFC(n_estimators=10,random_state=0),X_fschi,y,cv=5).mean()

輸出結(jié)果

0.9344761904761905
'''
如果模型的效果降低了,這說明我們?cè)谠O(shè)定k=300的時(shí)候刪除了與模型相關(guān)且有效的特征奶是,
我們的K值設(shè)置得太小楣责,要么我們需要調(diào)整K值竣灌,要么我們必須放棄相關(guān)性過濾。
'''

1.2.2 選擇超參數(shù)K

卡方檢驗(yàn)的本質(zhì)是推測(cè)兩組數(shù)據(jù)之間的差異秆麸,其檢驗(yàn)的原假設(shè)是”兩組數(shù)據(jù)是相互獨(dú)立的”初嘹。卡方檢驗(yàn)返回卡方值和P值兩個(gè)統(tǒng)計(jì)量沮趣,我們可以根據(jù)P值進(jìn)行篩選屯烦,p<=0.05或0.01,說明兩組數(shù)據(jù)是相關(guān)的。
從特征工程的角度房铭,我們希望選取卡方值很大驻龟,p值小于0.05的特征,即和標(biāo)簽是相關(guān)聯(lián)的特征缸匪。

#選擇超參數(shù)K
chivalue, pvalues_chi = chi2(X_fsvar,y) #返回卡方值和P值
chivalue
pvalues_chi

#k取多少翁狐?我們想要消除所有p值大于設(shè)定值,比如0.05或0.01的特征:
#chivalue.shape[0]就是取出特征總個(gè)數(shù)凌蔬,pvalues_chi > 0.05返回TRUE Flase,False=0,TRUE=1,所以就是總特征數(shù)減去所以p>0.05的特征露懒,就是想保留的特征的數(shù)量
k = chivalue.shape[0] - (pvalues_chi > 0.05).sum() 
#X_fschi = SelectKBest(chi2, k=填寫具體的k).fit_transform(X_fsvar, y) #就可以把上述的K值帶進(jìn)去
#cross_val_score(RFC(n_estimators=10,random_state=0),X_fschi,y,cv=5).mean()

1.2.3 F檢驗(yàn)

F檢驗(yàn),又稱ANOVA砂心,方差齊性檢驗(yàn)懈词,是用來捕捉每個(gè)特征與標(biāo)簽之間的線性關(guān)系的過濾方法。它即可以做回歸也可以做分類辩诞,因此包含feature_selection.f_classif(F檢驗(yàn)分類)和feature_selection.f_regression(F檢驗(yàn)回歸)兩個(gè)類坎弯。它返回F值和p值兩個(gè)統(tǒng)計(jì)量。和卡方過濾一樣译暂,選取p值小于0.05或0.01的特征荞怒,這些特征與標(biāo)簽時(shí)顯著線性相關(guān)的。

#F檢驗(yàn)
from sklearn.feature_selection import f_classif
F, pvalues_f = f_classif(X_fsvar,y)
F
pvalues_f
k = F.shape[0] - (pvalues_f > 0.05).sum()

#X_fsF = SelectKBest(f_classif, k=填寫具體的k).fit_transform(X_fsvar, y)
#cross_val_score(RFC(n_estimators=10,random_state=0),X_fsF,y,cv=5).mean()

1.2.4 互信息法

互信息法是用來捕捉每個(gè)特征與標(biāo)簽之間的任意關(guān)系(包括線性和非線性關(guān)系)的過濾方法秧秉。和F檢驗(yàn)相似,它既可以做回歸也可以做分類衰抑,并且包含兩個(gè)類feature_selection.mutual_info_classif(互信息分類)和feature_selection.mutual_info_regression(互信息回歸)象迎。
它返回“每個(gè)特征與目標(biāo)之間的互信息量的估計(jì)”,這個(gè)估計(jì)量在[0,1]之間取值呛踊,為0則表示兩個(gè)變量獨(dú)立砾淌,為1則表示兩個(gè)變量完全相關(guān)。

from sklearn.feature_selection import mutual_info_classif as MIC
result = MIC(X_fsvar,y)
k = result.shape[0] - sum(result <= 0)
#X_fsmic = SelectKBest(MIC, k=填寫具體的k).fit_transform(X_fsvar, y)
#cross_val_score(RFC(n_estimators=10,random_state=0),X_fsmic,y,cv=5).mean()

1.3 過濾法總結(jié)

先使用方差過濾谭网,然后使用互信息法來捕捉相關(guān)性

image.png

2. Embedded嵌入法

嵌入法是一種讓算法自己決定使用哪些特征的方法汪厨,即特征選擇和算法訓(xùn)練同時(shí)進(jìn)行。

image.png

feature_selection.SelectFromModel

class sklearn.feature_selection.SelectFromModel (estimator, threshold=None, prefit=False, norm_order=1,max_features=None)

參數(shù):
estimator:使用的模型評(píng)估器愉择,只要是帶feature_importances_或者coef_屬性劫乱,或帶有l(wèi)1和l2懲罰項(xiàng)的模型都可以使用织中。
threshold:特征重要性的閾值,重要性低于這個(gè)閾值的特征都將被刪除衷戈。

from sklearn.feature_selection import SelectFromModel 
from sklearn.ensemble import RandomForestClassifier as RFC

RFC_ = RFC(n_estimators =10,random_state=0) #需要先實(shí)例化隨機(jī)森林狭吼,再帶入SelectFromModel。
X_embedded = SelectFromModel(RFC_,threshold=0.005).fit_transform(X,y) #這個(gè)是嵌入法的實(shí)例化
#在這里我只想取出來有限的特征殖妇。0.005這個(gè)閾值對(duì)于有780個(gè)特征的數(shù)據(jù)來說刁笙,是非常高的閾值,因?yàn)槠骄總€(gè)特征只能夠分到大約0.001的feature_importances_
X_embedded.shape
#(42000, 47)  模型的維度明顯被降低了

繪制threshold的學(xué)習(xí)曲線

import numpy as np
import matplotlib.pyplot as plt

RFC_.fit(X,y).feature_importances_ #看特征重要性
#linspace(小值谦趣,大值疲吸,個(gè)數(shù)) 在最大值和最小值之間取20個(gè)數(shù)
threshold = np.linspace(0,(RFC_.fit(X,y).feature_importances_).max(),20) #讓閾值的取值在0到最大值之間取出20個(gè)數(shù)

score = []
for i in threshold:
    X_embedded = SelectFromModel(RFC_,threshold=i).fit_transform(X,y)
    once = cross_val_score(RFC_,X_embedded,y,cv=5).mean()
    score.append(once)

plt.plot(threshold,score)
plt.show()

image.png

可見,隨著閾值越來越高前鹅,模型的效果逐漸變差摘悴,被刪除的特征越來越多,信息損失也逐漸變大嫡纠。但是在0.003之前烦租,模型的效果都可以維持在0.93以上,因此我們可以從中挑選一個(gè)數(shù)值來驗(yàn)證一下模型的效果除盏。
驗(yàn)證模型

X_embedded = SelectFromModel(RFC_,threshold=0.00067).fit_transform(X,y)
X_embedded.shape
#(42000, 324)

cross_val_score(RFC_,X_embedded,y,cv=5).mean()
#0.9391190476190475

接著叉橱,可以使用細(xì)化的學(xué)習(xí)曲線來找到最佳值

score2 = []
for i in np.linspace(0,0.002,20):
    X_embedded = SelectFromModel(RFC_,threshold=i).fit_transform(X,y)
    once = cross_val_score(RFC_,X_embedded,y,cv=5).mean()
    score2.append(once)
plt.figure(figsize=[20,5])
plt.plot(np.linspace(0,0.002,20),score2)
plt.xticks(np.linspace(0,0.002,20))
plt.show()

可以看到,在0.000632時(shí)者蠕,模型效果提升到了94%以上窃祝,然后使用0.000632來跑一跑我們的SelectFromModel

模型驗(yàn)證

X_embedded = SelectFromModel(RFC_,threshold=0.000632).fit_transform(X,y)
X_embedded.shape 
#(42000, 332) 可以看到特征其實(shí)增加了,因?yàn)殚撝翟O(shè)置的更小了

#驗(yàn)證模型效果如何
cross_val_score(RFC_,X_embedded,y,cv=5).mean()
#0.9407857142857143

我們可能已經(jīng)找到了現(xiàn)有模型下的最佳結(jié)果踱侣,如果我們調(diào)整一下隨機(jī)森林的參數(shù)呢粪小?

cross_val_score(RFC(n_estimators=100,random_state=0),X_embedded,y,cv=5).mean()
# 0.9630714285714287

可見,在嵌入法下抡句,我們很容易就能夠?qū)崿F(xiàn)特征選擇的目標(biāo):減少計(jì)算量探膊,提升模型表現(xiàn)。

3 Wrapper包裝法

包裝法也是一個(gè)特征選擇和算法訓(xùn)練同時(shí)進(jìn)行的方法待榔,但我們往往使用一個(gè)目標(biāo)函數(shù)作為黑盒來幫助我們選取特征逞壁,而不是自己輸入某個(gè)評(píng)估指標(biāo)或統(tǒng)計(jì)量的閾值。锐锣。區(qū)別于過濾法和嵌入法的一次訓(xùn)練解決所有問題腌闯,包裝法要使用特征子集進(jìn)行多次訓(xùn)練,計(jì)算成本位于嵌入法和過濾法之間雕憔。

image.png

最典型的目標(biāo)函數(shù)是遞歸特征消除法(Recursive feature elimination, 簡(jiǎn)寫為RFE)姿骏。它是一種貪婪的優(yōu)化算法,旨在找到性能最佳的特征子集斤彼。 它反復(fù)創(chuàng)建模型分瘦,并在每次迭代時(shí)保留最佳特征或剔除最差特征蘸泻,下一次迭代時(shí),它會(huì)使用上一次建模中沒有被選中的特征來構(gòu)建下一個(gè)模型擅腰,直到所有特征都耗盡為止蟋恬。

feature_selection.RFE

class sklearn.feature_selection.RFE (estimator, n_features_to_select=None, step=1, verbose=0)

參數(shù)estimator是需要填寫的實(shí)例化后的評(píng)估器,n_features_to_select是想要選擇的特征個(gè)數(shù)趁冈,step表示每次迭代中希望移除的特征個(gè)數(shù)歼争。
除此之外,RFE類有兩個(gè)很重要的屬性渗勘,.support_:返回所有的特征的是否最后被選中的布爾矩陣沐绒,以及.ranking_返回特征的按數(shù)次迭代中綜合重要性的排名。

from sklearn.feature_selection import RFE

RFC_ = RFC(n_estimators =10,random_state=0) #實(shí)例化RFC
#n_features_to_select是模型選擇的個(gè)數(shù)旺坠,step每迭代一次刪除50個(gè)特征
selector = RFE(RFC_, n_features_to_select=332, step=50).fit(X, y) #RFE的實(shí)例化和訓(xùn)練 332是上述模型效果最好時(shí)的特征數(shù)

selector.support_.sum() #support_返回特征是否被選中的布爾矩陣乔遮,求和其實(shí)就是n_features_to_select
selector.ranking_ #返回特征的重要性排名
X_wrapper = selector.transform(X) 
#交叉驗(yàn)證驗(yàn)證模型
cross_val_score(RFC_,X_wrapper,y,cv=5).mean()
#0.9398809523809524

對(duì)包裝法畫學(xué)習(xí)曲線

score = []
for i in range(1,751,50): #每50個(gè)取一個(gè)值,和linspace不同取刃。
    X_wrapper = RFE(RFC_,n_features_to_select=i, step=50).fit_transform(X,y)
    once = cross_val_score(RFC_,X_wrapper,y,cv=5).mean()
    score.append(once)
plt.figure(figsize=[20,5])
plt.plot(range(1,751,50),score)
plt.xticks(range(1,751,50))
plt.show()
在包裝法下面蹋肮,應(yīng)用50個(gè)特征時(shí),模型的表現(xiàn)就已經(jīng)達(dá)到了90%以上璧疗,比嵌入法和過濾法都高效很多坯辩。

4 特征選擇總結(jié)

  1. 當(dāng)數(shù)據(jù)量很大的時(shí)候,優(yōu)先使用方差過濾和互信息法調(diào)整崩侠,再上其他特征選擇方法漆魔。
  2. 使用邏輯回歸時(shí),優(yōu)先使用嵌入法却音。
  3. 使用支持向量機(jī)時(shí)改抡,優(yōu)先使用包裝法。
  4. 迷茫的時(shí)候系瓢,從過濾法走起阿纤,看具體數(shù)據(jù)具體分析。
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請(qǐng)聯(lián)系作者
  • 序言:七十年代末夷陋,一起剝皮案震驚了整個(gè)濱河市阵赠,隨后出現(xiàn)的幾起案子,更是在濱河造成了極大的恐慌,老刑警劉巖匕荸,帶你破解...
    沈念sama閱讀 217,542評(píng)論 6 504
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件诺凡,死亡現(xiàn)場(chǎng)離奇詭異东揣,居然都是意外死亡,警方通過查閱死者的電腦和手機(jī)嘶卧,發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 92,822評(píng)論 3 394
  • 文/潘曉璐 我一進(jìn)店門芥吟,熙熙樓的掌柜王于貴愁眉苦臉地迎上來钟鸵,“玉大人棺耍,你說我怎么就攤上這事蒙袍『Ψ” “怎么了矫限?”我有些...
    開封第一講書人閱讀 163,912評(píng)論 0 354
  • 文/不壞的土叔 我叫張陵叼风,是天一觀的道長(zhǎng)无宿。 經(jīng)常有香客問我孽鸡,道長(zhǎng)彬碱,這世上最難降的妖魔是什么巷疼? 我笑而不...
    開封第一講書人閱讀 58,449評(píng)論 1 293
  • 正文 為了忘掉前任嚼沿,我火速辦了婚禮骡尽,結(jié)果婚禮上攀细,老公的妹妹穿的比我還像新娘辨图。我一直安慰自己故河,他們只是感情好鱼的,可當(dāng)我...
    茶點(diǎn)故事閱讀 67,500評(píng)論 6 392
  • 文/花漫 我一把揭開白布猿规。 她就那樣靜靜地躺著姨俩,像睡著了一般环葵。 火紅的嫁衣襯著肌膚如雪。 梳的紋絲不亂的頭發(fā)上地梨,一...
    開封第一講書人閱讀 51,370評(píng)論 1 302
  • 那天洁闰,我揣著相機(jī)與錄音,去河邊找鬼襟雷。 笑死耸弄,一個(gè)胖子當(dāng)著我的面吹牛,可吹牛的內(nèi)容都是我干的捌显。 我是一名探鬼主播扶歪,決...
    沈念sama閱讀 40,193評(píng)論 3 418
  • 文/蒼蘭香墨 我猛地睜開眼善镰,長(zhǎng)吁一口氣:“原來是場(chǎng)噩夢(mèng)啊……” “哼!你這毒婦竟也來了年枕?” 一聲冷哼從身側(cè)響起炫欺,我...
    開封第一講書人閱讀 39,074評(píng)論 0 276
  • 序言:老撾萬榮一對(duì)情侶失蹤品洛,失蹤者是張志新(化名)和其女友劉穎,沒想到半個(gè)月后摩桶,有當(dāng)?shù)厝嗽跇淞掷锇l(fā)現(xiàn)了一具尸體岛宦,經(jīng)...
    沈念sama閱讀 45,505評(píng)論 1 314
  • 正文 獨(dú)居荒郊野嶺守林人離奇死亡变汪,尸身上長(zhǎng)有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點(diǎn)故事閱讀 37,722評(píng)論 3 335
  • 正文 我和宋清朗相戀三年番官,在試婚紗的時(shí)候發(fā)現(xiàn)自己被綠了。 大學(xué)時(shí)的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片徘熔。...
    茶點(diǎn)故事閱讀 39,841評(píng)論 1 348
  • 序言:一個(gè)原本活蹦亂跳的男人離奇死亡门躯,死狀恐怖,靈堂內(nèi)的尸體忽然破棺而出酷师,到底是詐尸還是另有隱情懂讯,我是刑警寧澤,帶...
    沈念sama閱讀 35,569評(píng)論 5 345
  • 正文 年R本政府宣布台颠,位于F島的核電站褐望,受9級(jí)特大地震影響,放射性物質(zhì)發(fā)生泄漏蓉媳。R本人自食惡果不足惜譬挚,卻給世界環(huán)境...
    茶點(diǎn)故事閱讀 41,168評(píng)論 3 328
  • 文/蒙蒙 一、第九天 我趴在偏房一處隱蔽的房頂上張望酪呻。 院中可真熱鬧减宣,春花似錦、人聲如沸玩荠。這莊子的主人今日做“春日...
    開封第一講書人閱讀 31,783評(píng)論 0 22
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽阶冈。三九已至闷尿,卻和暖如春,著一層夾襖步出監(jiān)牢的瞬間女坑,已是汗流浹背填具。 一陣腳步聲響...
    開封第一講書人閱讀 32,918評(píng)論 1 269
  • 我被黑心中介騙來泰國(guó)打工, 沒想到剛下飛機(jī)就差點(diǎn)兒被人妖公主榨干…… 1. 我叫王不留匆骗,地道東北人劳景。 一個(gè)月前我還...
    沈念sama閱讀 47,962評(píng)論 2 370
  • 正文 我出身青樓,卻偏偏與公主長(zhǎng)得像碉就,于是被迫代替她去往敵國(guó)和親盟广。 傳聞我的和親對(duì)象是個(gè)殘疾皇子,可洞房花燭夜當(dāng)晚...
    茶點(diǎn)故事閱讀 44,781評(píng)論 2 354

推薦閱讀更多精彩內(nèi)容