使用FeatureSelector實現高效的機器學習工作流程

使用FeatureSelector實現高效的機器學習工作流程

特徵選擇是查找和選擇數據集中最有用特徵的過程,是機器學習管道的關鍵步驟。不必要的功能降低了訓練速度,降低了模型的可解釋性,並且最重要的是降低了測試集的泛化性能。

在FeatureSelector(https://github.com/WillKoehrsen/feature-selector)包括了一些最常見的特徵選擇方法:

  1. 具有高百分比缺失值的特徵
  2. 共線(高度相關)特徵
  3. 在基於樹的模型中具有零重要性的特徵
  4. 低重要性的特徵
  5. 具有單個惟一值的特徵

在本文中,我們將通過使用FeatureSelector示例機器學習數據集進行介紹。我們將看到它如何讓我們快速實施這些方法,從而實現更高效的工作流程。

示例數據集

在這個例子中,我們將使用Kaggle 的Home Credit Default Risk機器學習競賽中的一個數據樣本。整個數據集可供下載(https://www.kaggle.com/c/home-credit-default-risk/data),在這裡我們將使用一個樣本進行說明。

使用FeatureSelector實現高效的機器學習工作流程

示例數據。TARGET是分類標籤

這是一個監督分類問題,這是一個很好的數據集,因為它有許多缺失的值,許多高度相關的(共線)特性,以及許多不相關的特性,這些特性對機器學習模型沒有幫助。

創建一個實例

要創建FeatureSelector類的實例,我們需要傳入結構化數據集,其中包含行中的觀察值和列中的特徵。我們可以僅使用一些功能的方法,但基於重要性的方法也需要訓練標籤。由於我們有監督分類任務,因此我們將使用一組特徵和一組標籤。

(請確保在與此目錄相同的目錄下運行feature_selector.py)

from feature_selector import FeatureSelector

# Features are in train and labels are in train_labels

fs = FeatureSelector(data = train, labels = train_labels)

方法

特徵選擇器有五種方法來查找要移除的特徵。我們可以訪問任何已識別的特徵並手動從數據中刪除它們,或使用特徵選擇器中的remove函數。

在這裡,我們將通過每種識別方法,並展示如何全部運行。在FeatureSelector另外有幾個繪圖功能,因為可視化檢測數據是機器學習的重要組成部分。

缺少值

查找刪除要素的第一種方法很簡單:找到缺少高於指定閾值的部分缺失值的要素。以下調用識別缺失值超過60%的特徵

fs.identify_missing(missing_threshold = 0.6)

17 features with greater than 0.60 missing values.

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

fs.missing_stats.head()

使用FeatureSelector實現高效的機器學習工作流程

為了查看要刪除的特性,我們訪問了FeatureSelector的ops屬性,該FeatureSelector是特徵值為列表。

missing_features = fs.ops['missing']

missing_features[:5]

['OWN_CAR_AGE',

'YEARS_BUILD_AVG',

'COMMONAREA_AVG',

'FLOORSMIN_AVG',

'LIVINGAPARTMENTS_AVG']

最後,我們繪製了所有特徵中缺失值的分佈圖:

fs.plot_missing()

使用FeatureSelector實現高效的機器學習工作流程

共線特徵

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

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

fs.identify_collinear(correlation_threshold = 0.98)

21 features with a correlation magnitude greater than 0.98.

我們可以使用相關性進行整潔的可視化是一個熱圖。這顯示了所有具有至少一個高於閾值的關聯的特徵:

fs.plot_collinear()

使用FeatureSelector實現高效的機器學習工作流程

像以前一樣,我們可以訪問將被刪除的整個關聯特徵列表,或者查看數據框中高度相關的特徵對

# list of collinear features to remove

collinear_features = fs.ops['collinear']

# dataframe of collinear features

fs.record_collinear.head()

使用FeatureSelector實現高效的機器學習工作流程

如果我們想調查我們的數據集,我們也可以通過傳遞plot_all = True給調用來繪製數據中所有相關性的圖表:

使用FeatureSelector實現高效的機器學習工作流程

零重要特徵

前兩種方法可以應用於任何結構化數據集並且是確定性的 - 每次給定閾值時結果都是相同的。下一個方法僅針對監督機器學習問題而設計,其中我們有訓練模型的標籤並且是非確定性的。該identify_zero_importance 函數根據梯度提升機器(GBM)學習模型查找具有零重要性的特徵。

通過基於樹的機器學習模型,例如boosting ensemble,我們可以發現特性的重要性。重要性的絕對值並不像相對值那麼重要,我們可以用相對值來確定任務最相關的特徵。我們還可以通過移除零重要性的特徵來使用特徵選擇。在基於樹的模型中,不使用不重要的特徵來分割任何節點,因此我們可以在不影響模型性能的情況下刪除它們。

特徵選擇器使用來自LightGBM庫的gradient boosting machine來發現特徵輸入。為了減少差異,對特徵輸入進行平均超過10次的GBM訓練。此外,該模型通過使用一個驗證集(有一個選項可以關閉它)進行提前停止來訓練,以防止對訓練數據的過度擬合。

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

# Pass in the appropriate parameters

fs.identify_zero_importance(task = 'classification',

eval_metric = 'auc',

n_iterations = 10,

early_stopping = True)

# list of zero importance features

zero_importance_features = fs.ops['zero_importance']

63 features with zero importance after one-hot encoding.

我們傳入的參數如下:

  • task :對應於我們的問題的“分類”或“迴歸”
  • eval_metric:用於提早停止的度量標準(如果禁用提前停止,則不需要)
  • n_iterations :訓練運行次數,以平均特徵重要性
  • early_stopping:是否使用提前停止訓練模型

繪製圖表:

# plot the feature importances

fs.plot_feature_importances(threshold = 0.99, plot_n = 12)

124 features required for 0.99 of cumulative importance

使用FeatureSelector實現高效的機器學習工作流程

在左邊,我們有plot_n最重要的特徵(按照標準化重要性繪製,總和為1)。在右側,我們對特徵數量具有累積重要性。垂直線繪製在threshold累積的重要性,在這種情況下是99%。

對於基於重要性的方法,需要記住兩點:

  • 訓練gradient boosting machine是隨機的,意味著每次模型運行時,要素重要性都會發生變化

這應該不會產生重大影響(至少最重要的功能不會突然變),但它會改變某些特徵的排序。它也會影響識別的零重要性特徵的數量。如果特徵重要性每次都改變,不要感到驚訝!

  • 為了訓練機器學習模型,這些特徵首先是one-hot 編碼。這意味著被認為具有0重要性的一些特徵可能是在建模期間添加的one-hot 編碼特徵。

當我們進入特徵刪除階段時,可以選擇刪除所有添加的one-hot 編碼特徵。但是,如果我們在特徵選擇之後進行機器學習,那麼我們必須對特徵進行one-hot 編碼!

低重要性特徵

下一個方法基於零重要性函數,使用模型中的要素重要性進一步選擇。該函數identify_low_importance找到不影響指定的總重要性的最低重要性特徵。

例如,下面的調用找到了達到總重要性99%所不需要的最不重要的特徵:

fs.identify_low_importance(cumulative_importance = 0.99)

123 features required for cumulative importance of 0.99 after one hot encoding.

116 features do not contribute to cumulative importance of 0.99.

這種方法的結果將在每次訓練中發生變化。

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

fs.feature_importances.head(10)

使用FeatureSelector實現高效的機器學習工作流程

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

單一的唯一價值特徵

最後的方法非常基礎:找到任何具有單一唯一值的列。僅具有一個唯一值的特徵對於機器學習不具有用處,因為此特徵具有零差異。例如,基於樹的模型不能僅使用一個值對特徵進行分割(因為沒有組將觀察分割)。

這裡沒有參數可供選擇,與其他方法不同:

fs.identify_single_unique()

4 features with a single unique value.

我們可以繪製每個類別中唯一值數量的直方圖:

fs.plot_unique()

使用FeatureSelector實現高效的機器學習工作流程

需要記住的一點是,在默認情況下,NaN在計算Pandas中的唯一值之前將其丟棄。

移除特徵

一旦我們確定了要丟棄的特徵,我們就有兩個選項可以刪除它們。所有要刪除的特徵都存儲在FeatureSelector的ops字典中,我們可以使用列表手動刪除特徵。另一種選擇是使用remove內置函數。

我們傳入methods以用於刪除特徵。如果我們想使用所有實現的方法,我們只需傳入methods = 'all'

#從所有方法中刪除特徵(返回一個df)

train_removed = fs.remove(methods ='all')

['missing', 'single_unique', 'collinear', 'zero_importance', 'low_importance'] methods have been run

Removed 140 features.

這個方法返回一個dataframe,去掉了這些特徵。也要刪除在機器學習過程中創建的one-hot編碼features:

train_removed_all = fs.remove(methods = 'all', keep_one_hot=False)

Removed 187 features including one-hot features.

在繼續操作之前檢查將要刪除的特徵可能是一個好主意!原始數據集存儲在作為備份的data屬性中FeatureSelector!

一次運行所有方法

與其單獨使用這些方法,我們可以全部使用它們identify_all。這需要每個方法的參數字典:

fs.identify_all(selection_params = {'missing_threshold':0.6,

'correlation_threshold':0.98,

'task':'classification',

'eval_metric':'auc',

'cumulative_importance':0.99})

151 total features out of 255 identified for removal after one-hot encoding.

注意,由於我們重新運行模型,所有特性的數量將會改變。然後可以調用remove函數來丟棄這些特徵。

結論

特徵選擇器類在訓練機器學習模型之前執行幾個常用的操作以去除特徵。它提供了識別刪除特徵以及可視化的特徵。方法可以單獨運行或同時運行,以實現高效的工作流程。

missing,collinear和single_unique方法是確定性的,而基於特徵的重要性的方法將每次運行時改變。特徵選擇很像機器學習領域,很大程度上是經驗性的,需要測試多個組合才能找到最佳答案


分享到:


相關文章: