▍前言
本篇主要介紹一個(gè)基礎(chǔ)的特征選擇工具feature-selector,feature-selector是由Feature Labs的一名數(shù)據(jù)科學(xué)家williamkoehrsen寫(xiě)的特征選擇庫(kù)。feature-selector主要對(duì)以下類(lèi)型的特征進(jìn)行選擇:
具有高missing-values百分比的特征
具有高相關(guān)性的特征
對(duì)模型預(yù)測(cè)結(jié)果無(wú)貢獻(xiàn)的特征(即zero importance)
對(duì)模型預(yù)測(cè)結(jié)果只有很小貢獻(xiàn)的特征(即low importance)
具有單個(gè)值的特征(即數(shù)據(jù)集中該特征取值的集合只有一個(gè)元素)
從上面可以看出feature-selector確實(shí)是非常基礎(chǔ)的特征選擇工具,正因?yàn)榉浅5幕A(chǔ),所以才非常的常用(這也是為什么williamkoehrsen要寫(xiě)這個(gè)特征選擇庫(kù)的原因),在拿到一個(gè)數(shù)據(jù)集的時(shí)候,往往都需要將上述類(lèi)型的特征從數(shù)據(jù)集中剔除掉。針對(duì)上面五種類(lèi)型的特征,feature-selector分別提供以下五個(gè)函數(shù)來(lái)對(duì)此處理:
identify_missing(*)
identify_collinear(*)
identify_zero_importance(*)
identify_low_importance(*)
identify_single_unique(*)
▍數(shù)據(jù)集選擇
在這里使用kaggle上的訓(xùn)練數(shù)據(jù)集。原訓(xùn)練數(shù)據(jù)集稍微有點(diǎn)大,30+萬(wàn)行(150+MB),pandas導(dǎo)入數(shù)據(jù)都花了一點(diǎn)時(shí)間,為此我從原數(shù)據(jù)集中采樣了1萬(wàn)+行數(shù)據(jù)作為此次練習(xí)的數(shù)據(jù)集。數(shù)據(jù)集采樣代碼如下:
https://www.kaggle.com/c/home-credit-default-risk/data
importpandasaspddata=pd.read_csv('./appliation_train.csv')#從原數(shù)據(jù)中采樣5%的數(shù)據(jù)sample=data.sample(frac=0.05)#重新創(chuàng)建索引sample.reset_index(drop=True)#將采樣數(shù)據(jù)存到'application_train_sample.csv'文件中sample.to_csv('./application_train_sample.csv')
▍f(xié)eature-selector用法
導(dǎo)入數(shù)據(jù)并創(chuàng)建feaure-selector實(shí)例
importpandasaspd#注意:#作者并沒(méi)有把feature-selector發(fā)布到pypi上,所以不能使用pip和conda進(jìn)行安裝,只能手動(dòng)#從github下載下來(lái),然后把feature_selector.py文件放到當(dāng)前工作目錄,然后再進(jìn)行import操作。fromfeature_selectorimportFeatureSelectordata=pd.read_csv('./application_train_sample.csv',index_col=0)#數(shù)據(jù)集中TARGET字段為對(duì)應(yīng)樣本的labeltrain_labels=data.TARGET#獲取allfeaturestrain_features=data.drop(columns='TARGET')#創(chuàng)建feature-selector實(shí)例,并傳入features和labelsfs=FeatureSelector(data=train_features,lables=train_labels)1
特征選取方法
(1)identify_missing
該方法用于選擇missing value 百分比大于指定值(通過(guò)missing_threshold指定百分比)的feature。該方法能應(yīng)用于監(jiān)督學(xué)習(xí)和非監(jiān)督學(xué)習(xí)的特征選擇。
#選擇出missingvalue百分比大于60%的特征fs.identify_missing(missing_threshold=0.6)#查看選擇出的特征fs.ops['missing']#繪制所有特征missingvalue百分比的直方圖fs.plot_missing()
圖1. 所有特征missing value百分比的直方圖
該方法內(nèi)部使用pandas 統(tǒng)計(jì)數(shù)據(jù)集中所有feature的missing value 的百分比,然后選擇出百分比大于閾值的特征,詳見(jiàn)feature-selector.py的114-136行。
https://github.com/WillKoehrsen/feature-selector/blob/master/feature_selector/feature_selector.py#L114-L136
(2) identify_collinear
該方法用于選擇相關(guān)性大于指定值(通過(guò)correlation_threshold指定值)的feature。該方法同樣適用于監(jiān)督學(xué)習(xí)和非監(jiān)督學(xué)習(xí)。
#不對(duì)feature進(jìn)行one-hotencoding(默認(rèn)為False),然后選擇出相關(guān)性大于98%的feature,fs.identify_collinear(correlation_threshold=0.98,one_hot=False)#查看選擇的featurefs.ops['collinear']#繪制選擇的特征的相關(guān)性heatmapfs.plot_collinear()#繪制所有特征的相關(guān)性heatmap
圖2. 選擇的特征的相關(guān)矩陣圖
圖3. 所有特征相關(guān)矩陣圖
該方法內(nèi)部主要執(zhí)行步驟如下:
1.根據(jù)參數(shù)'one_hot'對(duì)數(shù)據(jù)集特征進(jìn)行one-hot encoding(調(diào)用pd.get_dummies方法)。如果'one_hot=True'則對(duì)特征將進(jìn)行one-hot encoding,并將編碼的特征與原數(shù)據(jù)集整合起來(lái)組成新的數(shù)據(jù)集,如果'one_hot=False'則什么不做,進(jìn)入下一步;
2.計(jì)算步驟1得出數(shù)據(jù)集的相關(guān)矩陣C(通過(guò)DataFrame.corr(),注意 C也為一個(gè)DateFrame),并取相關(guān)矩陣的上三角部分得到 C_upper;
3.遍歷C_upper的每一列(即每一個(gè)特征),如果該列的任何一個(gè)相關(guān)值大于correlation_threshold,則取出該列,并放到一個(gè)列表中(該列表中的feature,即具有high 相關(guān)性的特征,之后會(huì)從數(shù)據(jù)集去除);
4.到這一步,做什么呢?回到源碼看一波就知道了;
具體請(qǐng)見(jiàn)feature-selector.py的157-227行。
(3) identify_zero_importance
該方法用于選擇對(duì)模型預(yù)測(cè)結(jié)果毫無(wú)貢獻(xiàn)的feature(即zero importance,從數(shù)據(jù)集中去除或者保留該feature對(duì)模型的結(jié)果不會(huì)有任何影響)。
該方法以及之后的identify_low_importance都只適用于監(jiān)督學(xué)習(xí)(即需要label,這也是為什么實(shí)例化feature-selector時(shí)需要傳入labels參數(shù)的原因)。feature-selector通過(guò)用數(shù)據(jù)集訓(xùn)練一個(gè)梯度提升機(jī)(Gradient Boosting machine, GBM),然后由GBM得到每一個(gè)feature的重要性分?jǐn)?shù),對(duì)所有特征的重要性分?jǐn)?shù)進(jìn)行歸一化處理,選擇出重要性分?jǐn)?shù)等于零的feature。
為了使計(jì)算得到的feature重要性分?jǐn)?shù)具有很小的方差,identify_zero_importance內(nèi)部會(huì)對(duì)GBM訓(xùn)練多次,取多次訓(xùn)練的平均值,得到最終的feature重要性分?jǐn)?shù)。同時(shí)為了防止過(guò)擬合,identify_zero_importance內(nèi)部從數(shù)據(jù)集中抽取一部分作為驗(yàn)證集,在訓(xùn)練GBM的時(shí)候,計(jì)算GBM在驗(yàn)證集上的某一metric,當(dāng)metric滿足一定條件時(shí),停止GBM的訓(xùn)練。
#選擇zeroimportance的feature,##參數(shù)說(shuō)明:#task:'classification'/'regression',如果數(shù)據(jù)的模型是分類(lèi)模型選擇'classificaiton',#否則選擇'regression'#eval_metric:判斷提前停止的metric.forexample,'auc'forclassification,and'l2'forregressionproblem#n_iteration:訓(xùn)練的次數(shù)#early_stopping:True/False,是否需要提前停止fs.identify_zero_importance(task='classification',eval_metric='auc',n_iteration=10,early_stopping=True)#查看選擇出的zeroimportancefeaturefs.ops['zero_importance']#繪制featureimportance關(guān)系圖#參數(shù)說(shuō)明:#plot_n:指定繪制前plot_n個(gè)最重要的feature的歸一化importance條形圖,如圖4所示#threshold:指定importance分?jǐn)?shù)累積和的閾值,用于指定圖4中的藍(lán)色虛線.#藍(lán)色虛線指定了importance累積和達(dá)到threshold時(shí),所需要的feature個(gè)數(shù)。#注意:在計(jì)算importance累積和之前,對(duì)feature列表安裝featureimportance的大小#進(jìn)行了降序排序fs.plot_feature_importances(threshold=0.99,plot_n=12)
圖4. 前12個(gè)最重要的feature歸一化后的importance分?jǐn)?shù)的條形圖
圖5. feature 個(gè)數(shù)與feature importance累積和的關(guān)系圖
需要注意GBM訓(xùn)練過(guò)程是隨機(jī)的,所以每次運(yùn)行identify_zero_importance得到feature importance分?jǐn)?shù)都會(huì)發(fā)生變化,但按照importance排序之后,至少前幾個(gè)最重要的feature順序不會(huì)變化。
該方法內(nèi)部主要執(zhí)行了以下步驟:
1.對(duì)各個(gè)feature進(jìn)行one-hot encoding,然后將one-hot encoding的feature和原數(shù)據(jù)集合并成新的數(shù)據(jù)集(使用pd.get_dummies完成);
2.根據(jù)參數(shù) task 的取值,實(shí)例化lightgbm.LGBMClassifier, 或者實(shí)例化 lightgbm.LGBMRegressor model;
3.根據(jù)early_stopping的取值選擇是否需要提前停止訓(xùn)練,并向model.fit傳入相應(yīng)的參數(shù),然后開(kāi)始訓(xùn)練model;
4.根據(jù)model得到該次訓(xùn)練的feature importance;
5.執(zhí)行n_iterations次步驟1-4;
6.取多次訓(xùn)練的feature importance的平均值,得到最終的feature importance;
7.選擇出feature importance等于0的feature;
8.到這一步,主要步驟完成了,其他部分請(qǐng)查看源碼。
具體請(qǐng)見(jiàn)feature-selector.py的229-342行。
(4) identify_low_importance
該方法是使用identify_zero_importance計(jì)算的結(jié)果,選擇出對(duì)importance累積和達(dá)到指定閾值沒(méi)有貢獻(xiàn)的feature(這樣說(shuō)有點(diǎn)拗口),即圖5中藍(lán)色虛線之后的feature。該方法只適用于監(jiān)督學(xué)習(xí)。identify_low_importance有點(diǎn)類(lèi)似于PCA中留下主要分量去除不重要的分量。
#選擇出對(duì)importance累積和達(dá)到99%沒(méi)有貢獻(xiàn)的featurefs.identify_low_importance(cumulative_importance=0.99)#查看選擇出的featurefs.ops['low_importance']
該方法選擇出的feature其實(shí)包含了zero importance的feature。內(nèi)部實(shí)現(xiàn)沒(méi)什么可說(shuō)的,具體請(qǐng)見(jiàn)feature-selector.py的344-378行。
(5) identify_single_unique
該方法用于選擇只有單個(gè)取值的feature,單個(gè)值的feature的方差為0,對(duì)于模型的訓(xùn)練不會(huì)有任何作用(從信息熵的角度看,該feature的熵為0)。該方法可應(yīng)用于監(jiān)督學(xué)習(xí)和非監(jiān)督學(xué)習(xí)。
#選擇出只有單個(gè)值的featurefs.identify_single_unique()#查看選擇出的featurefs.ops['single_unique']#繪制所有featureuniquevalue的直方圖fs.plot_unique()
圖6. 所有feature unique value的直方圖
該方法內(nèi)部的內(nèi)部實(shí)現(xiàn)很簡(jiǎn)單,只是通過(guò)DataFrame.nunique方法統(tǒng)計(jì)了每個(gè)feature取值的個(gè)數(shù),然后選擇出nunique==1等于1的feature。具體請(qǐng)見(jiàn)feature-selector.py的138-155行。
從數(shù)據(jù)集去除選擇的特征
上面介紹了feature-selector提供的特征選擇方法,這些方法從數(shù)據(jù)集中識(shí)別了feature,但并沒(méi)有從數(shù)據(jù)集中將這些feature去除。feature-selector中提供了remove方法將選擇的特征從數(shù)據(jù)集中去除,并返回去除特征之后的數(shù)據(jù)集。
#去除所有類(lèi)型的特征#參數(shù)說(shuō)明:#methods:#desc:需要去除哪些類(lèi)型的特征#type:string/list-likeobject#values:'all'或者是['missing','single_unique','collinear','zero_importance','low_importance']#中多個(gè)方法名的組合#keep_one_hot:#desc:是否需要保留one-hotencoding的特征#type:boolean#values:True/False#default:Truetrain_removed=fs.remove(methods='all',keep_one_hot=False)
注意:調(diào)用remove函數(shù)的時(shí)候,必須先調(diào)用特征選擇函數(shù),即identify_*函數(shù)。
該方法的實(shí)現(xiàn)代碼在feature-selector.py的430-510行。
一次性選擇所有類(lèi)型的特征
feature-selector除了能每次運(yùn)行一個(gè)identify_*函數(shù)來(lái)選擇一種類(lèi)型特征外,還可以使用identify_all函數(shù)一次性選擇5種類(lèi)型的特征選。
#注意:#少了下面任何一個(gè)參數(shù)都會(huì)報(bào)錯(cuò),raiseValueErrorfs.identify_all(selection_params= {'missing_threshold':0.6,'correlation_threshold':0.98,'task':'classification','eval_metric':'auc','cumulative_importance':0.99})
▍總結(jié)
feature-selector屬于非?;A(chǔ)的特征選擇工具,它提供了五種特征的選擇函數(shù),每個(gè)函數(shù)負(fù)責(zé)選擇一種類(lèi)型的特征。一般情況下,在對(duì)某一數(shù)據(jù)集構(gòu)建模型之前,都需要考慮從數(shù)據(jù)集中去除這五種類(lèi)型的特征,所以feature-selector幫你省去data-science生活中一部分重復(fù)性的代碼工作。
如果有興趣和充足的時(shí)間,建議閱讀一下feature-selector的代碼,代碼量很少,七百多行,相信看了之后對(duì)feature-selector各個(gè)函數(shù)的實(shí)現(xiàn)思路以及相應(yīng)代碼實(shí)現(xiàn)有一定認(rèn)識(shí),有心者還可以貢獻(xiàn)一下自己的代碼。
-
函數(shù)
+關(guān)注
關(guān)注
3文章
4344瀏覽量
62813 -
數(shù)據(jù)集
+關(guān)注
關(guān)注
4文章
1208瀏覽量
24754
原文標(biāo)題:一款非常棒的特征選擇工具:feature-selector
文章出處:【微信號(hào):AI_shequ,微信公眾號(hào):人工智能愛(ài)好者社區(qū)】歡迎添加關(guān)注!文章轉(zhuǎn)載請(qǐng)注明出處。
發(fā)布評(píng)論請(qǐng)先 登錄
相關(guān)推薦
評(píng)論