有了這個神器,機器學習特徵選擇再也不用愁!

有了這個神器,機器學習特徵選擇再也不用愁!

18 人贊了文章

文:William Koehrsen

譯:之餚

歡迎大家關注微信訂閱號:優達學城Udacity,免費試聽包括機器學習、數據分析、無人車開發在內的矽谷網紅課程。

Udacity?

cn.udacity.com圖標

這篇文章歸納起來就一句話:用 FeatureSelector 實現高效的機器學習工作流程,以後特徵選擇就不用愁了,實用不實用你說了算~

所謂特徵選擇,就是要查找和選出數據集中最有用的特徵,是機器學習中的關鍵流程。不必要的特徵會降低訓練速度,降低模型的可解釋性,並且最重要的是降低測試集的泛化性能。

在我用過各種機器學習特定的特徵選擇方法後,我實在受不了了,就在 Github 上弄了個特徵選擇器 FeatureSelector,處理一些最常見的特徵:

1.缺失值多的特徵

2.共線(高度相關)特徵

3.樹模型中零重要性的特徵

4.低重要性的特徵

5.有單一值的特徵

接下來我會在一個機器學習數據集上使用FeatureSelector,你可以看到如何進行快速操作,來實現高效的工作流程。

完整的代碼放在GitHub上(github.com/WillKoehrsen),歡迎任何contributions。特徵選擇器還在銳意製作中,將根據社區需求繼續改進!

示例數據集

我們用到的數據集來自 Kaggle 上的 Home Credit Default Risk machine learning competition ,數據集可供下載,我們會用其中一部分數據作為示範。

示例數據集。TARGET是分類標籤。

數據集下載:kaggle.com/c/home-credi

這個比賽聚焦於監督式分類問題,用它的原因是因為它有很多缺失值,有很多高度相關的(共線)特徵,也有一些對機器學習模型沒什麼用的不相關特徵。

創建實例

要創建 FeatureSelector 類的實例,我們需要傳入一個結構化數據集,其中包含行上的結果和列上的特徵。我們可以用一些只需要特徵的方法,但一些基於重要性的方法也需要訓練標籤。又因為這是個監督式分類問題,因此我們將使用一組特徵和一組標籤。

記住,確保在和feature_selector.py相同的目錄下運行

方法

特徵選擇器有五種刪除特徵的方法。 我們可以訪問任何已識別的特徵然後手動將其從數據中刪除,或者使用特徵選擇器中的刪除特徵。

接下來我會挨個介紹每種方法,並展示如何同時運行他們。 FeatureSelector 還具有多種繪圖功能,親眼看看數據也是機器學習的重要組成部分。

缺失值

第一種刪特徵的方法很簡單:找到缺失值高於指定閾值的特徵。 下面的函數調用標出了缺失值超過60%的特徵(粗體是輸出值)。

我們可以在數據欄的每一列中看到缺失值的分數:

我們可以通過 FeatureSelector 的 ops 屬性,來看看哪些特徵會被刪除,ops 是 Python 中的 dict,特徵被列入值中。

最後,我們畫了張缺失值分布圖:

共線特徵

共線特徵是彼此高度相關的特徵。 在機器學習中,由於高方差和較低的模型可解釋性,共線特徵會導致測試集上的泛化性能降低。

identify_collinear方法能基於指定的相關係數值找到共線特徵。 對於每對相關特徵,它會標出其中一個特徵來刪除(因為我們只需要刪除一個):

我們可以用熱圖來對相關性進行可視化。 它能展示特徵之間或多或少都有相關性:

和之前同理,我們可以查看將要刪除的相關特徵列表,或者查看數據欄中高相關的特徵。

如果我們想要研究數據集,我們還可以通過設置plot_all = True來繪製數據中所有具備相關性的圖:

零重要特徵

前兩種方法可以應用於任何結構化數據集,並且具備確定性 ——對於給定閾值,每次結果都是相同的。 而這種方法僅針對監督式機器學習問題而設計,訓練的模型有相應標籤,而且是非確定性的。

identify_zero_importance 函數根據梯度增強機器學習模型(GBM)找到具有零重要性的特徵。

我們可以用例如增強集成之類的基於樹的機器學習模型,來找到特徵的重要性。 重要性的絕對值沒有相對值重要,我們可以用它來確定問題中最為相關的特徵,或者刪除零重要性特徵。 在基於樹的模型中,零重要性的特徵不會拆分任何節點,因此我們可以在不影響模型性能的情況下刪除它們。

FeatureSelector 使用 LightGBM 庫中的漸變增強模型來尋找特徵重要性。 所得出的值取 GBM 訓練 10 次後的平均值,以減少差異。 除此之外,模型可以用驗證集提前停止(或者選擇關閉)以防止過擬合訓練數據。

* LightGBM:lightgbm.readthedocs.io

下面的代碼調用方法並提取零重要性特徵:

傳遞的參數如下:

?task:對應問題分別為「分類」或「回歸」

?eval_metric:衡量提前停止的指標(如果禁用提前停止就不需要)

?n_iterations:為了平均特徵重要性所需的訓練次數

?early_stopping:是否使用提前停止來訓練模型

這次我們得到兩個plot_feature_importances的圖:

上圖,我們有plot_n個最重要的特徵(將重要性歸一化後繪製,總和為1)。 下圖,x軸為特徵數量,y軸為累積重要性。 垂線為累積重要性的閾值,此圖中為99%。

基於重要性的方法有兩個注意事項:

?梯度增強的訓練是隨機的,這意味著每次運行模型時特徵重要性都會改變

這應該不會產生重大影響(最重要的特徵不會突然變得最少),但它會改變某些特徵的順序。 它還可以影響所識別的零重要性特徵的數量。 如果看到特徵重要性每次都在變化,不用大驚小怪!

?為了訓練機器學習模型,這些特徵會首先被獨熱編碼。 這意味著被識別為具有零重要性的一些特徵可能是在建模期間被加進來的。

當我們進入特徵刪除階段時,可以選擇刪除任何添加的獨熱編碼特徵。 但是如果我們在特徵選擇後進行機器學習,我們還是得對特徵獨熱編碼一遍!

低重要性特徵

這個方法建立在零重要性函數的基礎上,它會利用模型中的特徵重要性進行進一步選擇。 函數identify_low_importance能找到那些對總重要性沒有貢獻的低重要性特徵。

舉個例子,下面的函數調用找到了對實現99%總重要性不怎麼重要的特徵:

基於累積重要性的那張圖,梯度增強會認為許多特徵與學習過程無關。 和零重要性一樣,此方法的結果會在每次訓練運行時發生變化。

要查看數據欄中的所有特徵的重要性,請執行以下操作:

low_importance方法借鑒了一種使用主成分分析(PCA)的方法,其中通常只保留有一定百分比方差的主成分(例如95%)。 保留多少總重要性也是相同思路。

實際上,我們只有在要使用基於樹的模型進行預測時才會用基於特徵重要性的方法。 因為除了隨機性之外,基於重要性的方法也是一種黑盒方法,我們並不實際知道為什麼模型認為這些特徵是無關緊要的。 如果真要用這些方法,請多次運行它們以查看結果變化如何,並且儘可能創建具有不同參數的多個數據集來進行測試!

單一值特徵

最後一種方法更為基本:查找只有單一值的列。 只有單一值的特徵對於機器學習無效,因為此特徵的方差為零。 例如,基於樹的模型永遠不能在只有一個值的特徵上進行拆分(因為這樣就沒有組可以分了)。

和其它方法不同,此函數沒有參數可供選擇:

我們可以給每個類別中唯一值的數量畫張直方圖:

需要記住的一點是,默認情況下,在計算Pandas中的唯一值之前會去掉NaN。

刪除特徵

一旦確定要刪除的特徵,我們有兩個辦法來刪掉它們。 由於要刪除的所有特徵都存儲在FeatureSelector的ops dict中,我們可以使用這個列表手動刪除。 另一種選擇是使用內置的remove函數。如果你想試試用所有手段刪除後的效果,需要將參數設置為methods = 『all』。

它會返回已刪除特徵的數據欄。 為了一併刪除機器學習期間創建的獨熱編碼特徵,還得這麼做:

最好在繼續操作之前檢查下要刪除的特徵! 原始數據集作為備份存儲在FeatureSelector的data屬性中!

一次運行所有方法

與其單獨使用這些方法,我們可以將所有方法與identify_all共同使用。 這就得為每個方法設個參數:

注意,由於重新運行模型,總特徵的數量會發生變化。 這之後可以調用remove函數來刪除這些特徵。

結論

Feature Selector 在訓練機器學習模型之前實現了幾種用於刪除特徵的常用操作。 它能識別要刪除的特徵還可能進行可視化。每個方法可以單獨運行,也可以集體運行,實現高效的工作流程。

缺失值、共線和單一值方法具備確定性,而基於特徵重要性的方法將隨每次運行而改變。 特徵選擇與機器學習領域非常相似,需要根據經驗測試多種組合以找到最佳答案。 最好在工作流程中嘗試多種配置,特徵選擇器提供了一種快速評估特徵選擇參數的方法。


機器學習專業課程_深入機器學習培訓_高級機器學習教程-優達學城(Udacity)官網?

cn.udacity.com圖標

weixin.qq.com/r/qDopMVH (二維碼自動識別)


推薦閱讀:

真正的遠方,到底在哪裡?
Python實現動態圖的解析、合成與倒放
這或許是對小白最友好的python入門了吧——11,if語句初體驗
ELEMENTARY.03.First Word

TAG:機器學習 | 特徵選擇 | Python |