基于Python的特征自动化选择:两行代码完成特征工程
本文介紹一個特征選擇神器:特征選擇器是用于減少機器學習數據集的維數的工具,可以傻瓜式地進行特征選擇,兩行代碼即可搞定!!
來源:Will Koehrsen
代碼整理及注釋翻譯:黃海廣
代碼和數據下載地址:
https://github.com/fengdu78/Data-Science-Notes/tree/master/9.feature-engineering/FeatureSelectorUsage
實現的功能
該選擇器基于Python編寫,有五種方法來標識要刪除的特征:
缺失值
唯一值
共線特征
零重要性特征
低重要性特征
使用方法
?特征選擇器(Feature Selector)的用法
在這個Jupyter文件中, 我們將使用 FeatureSelector 類來選擇數據集中要刪除的特征,這個類提供五種方法來查找要刪除的功能:
查找缺失分數大于指定閾值的列
查找只有唯一值的特征
查找由相關系數大于指定值的共線特征
使用梯度提升算法查找具有零重要性的特征
使用梯度提升算法查找中查找對指定的累積特征重要性無貢獻的特征
FeatureSelector 仍在進一步開發中! 歡迎大家在github提交PR.
from feature_selector import FeatureSelectorimport pandas as pd示例數據集
該數據集被用作Kaggle上房屋信用違約風險競賽的(https://www.kaggle.com/c/home-credit-default-risk) ?一部分(文末提供下載)。它旨在用于有監督的機器學習分類任務,其目的是預測客戶是否會拖欠貸款。您可以在此處下載整個數據集,我們將處理10,000行的一小部分樣本。
特征選擇器旨在用于機器學習任務,但可以應用于任何數據集。基于特征重要性的方法需要使用機器學習的監督學習問題。
train = pd.read_csv('data/credit_example.csv') train_labels = train['TARGET'] train.head()5 rows × 122 columns
數據集中有幾個分類列。`FeatureSelector`處理這些特征重要性的時候使用獨熱編碼。train = train.drop(columns = ['TARGET'])實施
在FeatureSelector具有用于標識列,以除去五種特征 :
identify_missing(查找缺失值)
identify_single_unique(查找唯一值)
identify_collinear(查找共線特征)
identify_zero_importance (查找零重要特征)
identify_low_importance(查找低重要特征)
這些方法找到要根據指定條件刪除的特征。標識的特征存儲在 FeatureSelector的 ops 屬性(Python詞典)中。我們可以手動刪除已識別的特征,也可以使用 FeatureSelector中的刪除特征函數真正刪除特征。
創建實例
FeatureSelector 僅需要一個在行中具有觀察值而在列中具有特征的數據集(標準結構化數據)。我們正在處理機器學習的分類問題,因此我們也需要訓練的標簽。
fs = FeatureSelector(data = train, labels = train_labels)1. 缺失值
第一種特征選擇方法很簡單:找到丟失分數大于指定閾值的任何列。在此示例中,我們將使用閾值0.6,這對應于查找缺失值超過60%的特征。(此方法不會首先對特征進行一次獨熱編碼)。
fs.identify_missing(missing_threshold=0.6) 17 features with greater than 0.60 missing values.可以通過 FeatureSelector 對象的ops詞典訪問已確定要刪除的特征。
missing_features = fs.ops['missing'] missing_features[:10] ['OWN_CAR_AGE','YEARS_BUILD_AVG','COMMONAREA_AVG','FLOORSMIN_AVG','LIVINGAPARTMENTS_AVG','NONLIVINGAPARTMENTS_AVG','YEARS_BUILD_MODE','COMMONAREA_MODE','FLOORSMIN_MODE','LIVINGAPARTMENTS_MODE']我們還可以繪制數據集中所有列的缺失列分數的直方圖。
fs.plot_missing()有關缺失分數的詳細信息,我們可以訪問missing_stats屬性,這是所有特征缺失分數的DataFrame。
fs.missing_stats.head(10)| 0.6953 |
| 0.6953 |
| 0.6953 |
| 0.6945 |
| 0.6945 |
| 0.6945 |
| 0.6846 |
| 0.6846 |
| 0.6846 |
| 0.6820 |
2. 唯一值
下一個方法很簡單:找到只有一個唯一值的所有特征。(這不會對特征進行獨熱編碼)。
fs.identify_single_unique() 4 features with a single unique value. single_unique = fs.ops['single_unique'] single_unique ['FLAG_MOBIL', 'FLAG_DOCUMENT_10', 'FLAG_DOCUMENT_12', 'FLAG_DOCUMENT_17']我們可以繪制數據集中每個特征中唯一值數量的直方圖。
fs.plot_unique()最后,我們可以訪問一個DataFrame,其中包含每個特征的唯一值數量。
fs.unique_stats.sample(5)| 4210 |
| 3 |
| 2 |
| 2 |
| 993 |
3. 共線(高相關性) 特征
該方法基于皮爾森相關系數找到共線特征對。對于高于指定閾值(就絕對值而言)的每一對,它標識要刪除的變量之一。我們需要傳遞一個 correlation_threshold。
此方法基于在:https://chrisalbon.com/machine_learning/feature_selection/drop_highly_correlated_features/ 中找到的代碼。
對于每一對,將要刪除的特征是在DataFrame中列排序方面排在最后的特征。(除非one_hot = True,否則此方法不會預先對數據進行一次獨熱編碼。因此,僅在數字列之間計算相關性)
fs.identify_collinear(correlation_threshold=0.975) 24 features with a correlation magnitude greater than 0.97. correlated_features = fs.ops['collinear'] correlated_features[:5] ['AMT_GOODS_PRICE','FLAG_EMP_PHONE','YEARS_BUILD_MODE','COMMONAREA_MODE','ELEVATORS_MODE']我們可以查看閾值以上相關性的熱圖。將要刪除的特征位于x軸上。
fs.plot_collinear()要繪制數據中的所有相關性,我們可以將 plot_all = True 傳遞給 plot_collinear函數。
fs.plot_collinear(plot_all=True) fs.identify_collinear(correlation_threshold=0.98) fs.plot_collinear() 21 features with a correlation magnitude greater than 0.98.要查看閾值以上的相關細節,我們訪問record_collinear 屬性,它是一個DataFrame。?drop_feature 將被刪除,并且對于每個將被刪除的特征,它與 corr_feature可能存在多個相關性,而這些相關性都高于correlation_threshold。
fs.record_collinear.head()| AMT_CREDIT | 0.987232 | AMT_GOODS_PRICE |
| DAYS_EMPLOYED | -0.999533 | FLAG_EMP_PHONE |
| YEARS_BUILD_AVG | 0.992120 | YEARS_BUILD_MODE |
| COMMONAREA_AVG | 0.988074 | COMMONAREA_MODE |
| FLOORSMAX_AVG | 0.984663 | FLOORSMAX_MODE |
4. 零重要特征?
此方法依賴于機器學習模型來識別要刪除的特征。因此,它是有標簽的監督學習問題。該方法通過使用LightGBM庫中實現的梯度增強機找到特征重要性。
為了減少所計算的特征重要性的差異,默認情況下對模型進行了10次訓練。默認情況下,還使用驗證集(訓練數據的15%)通過提前停止訓練模型,以識別要訓練的最優估計量。可以將以下參數傳遞給identify_zero_importance 方法:
task: 可以是 classification 或 regression。指標和標簽必須與任務匹配。
eval_metric: 用于提前停止的度量(例如,用于分類的auc或用于回歸的l2 )。要查看可用指標的列表,請參閱LightGBM文檔:(http://testlightgbm.readthedocs.io/en/latest/Parameters.html#metric-parameters)。
n_iterations: 訓練次數。特征重要性是在訓練運行中平均得出的 (默認為10)。
early_stopping: 訓練模型時是否使用提前停止(默認= True)。當驗證集的性能對于指定數量的估計量(此實現中默認為100)不再降低時,提早停止將停止訓練估計量(決策樹)。早停是一種正則化形式,用于防止訓練數據過擬合。
首先對數據進行一次獨熱編碼,以供模型使用。這意味著某些零重要性特征可以通過一鍵編碼來創建。要查看單編碼的列,我們可以訪問 FeatureSelector的one_hot_features 。
注意:與其他方法相比,模型的特征重要性是不確定的(具有少許隨機性)。每次運行此方法時,其結果都可能更改。
fs.identify_zero_importance(task = 'classification', eval_metric = 'auc',n_iterations = 10, early_stopping = True) Training Gradient Boosting ModelTraining until validation scores don't improve for 100 rounds. Early stopping, best iteration is: [57] valid_0's auc: 0.760957 valid_0's binary_logloss: 0.250579 Training until validation scores don't improve for 100 rounds. Early stopping, best iteration is: [29] valid_0's auc: 0.681283 valid_0's binary_logloss: 0.266277 Training until validation scores don't improve for 100 rounds. Early stopping, best iteration is: [50] valid_0's auc: 0.73881 valid_0's binary_logloss: 0.257822 Training until validation scores don't improve for 100 rounds. Early stopping, best iteration is: [34] valid_0's auc: 0.720575 valid_0's binary_logloss: 0.262094 Training until validation scores don't improve for 100 rounds. Early stopping, best iteration is: [48] valid_0's auc: 0.769376 valid_0's binary_logloss: 0.247709 Training until validation scores don't improve for 100 rounds. Early stopping, best iteration is: [35] valid_0's auc: 0.713877 valid_0's binary_logloss: 0.262254 Training until validation scores don't improve for 100 rounds. Early stopping, best iteration is: [76] valid_0's auc: 0.753081 valid_0's binary_logloss: 0.251867 Training until validation scores don't improve for 100 rounds. Early stopping, best iteration is: [70] valid_0's auc: 0.722385 valid_0's binary_logloss: 0.259535 Training until validation scores don't improve for 100 rounds. Early stopping, best iteration is: [45] valid_0's auc: 0.752703 valid_0's binary_logloss: 0.252175 Training until validation scores don't improve for 100 rounds. Early stopping, best iteration is: [49] valid_0's auc: 0.757385 valid_0's binary_logloss: 0.25035681 features with zero importance after one-hot encoding.運行梯度提升模型需要對特征進行獨熱編碼。這些特征保存在 FeatureSelector的 one_hot_features 屬性中。原始特征保存在base_features中。
one_hot_features = fs.one_hot_features base_features = fs.base_features print('There are %d original features' % len(base_features)) print('There are %d one-hot features' % len(one_hot_features)) There are 121 original features There are 134 one-hot featuresFeatureSelector 的 data 屬性保存原始DataFrame。獨熱編碼后, data_all屬性將保留原始數據以及獨熱編碼特征。
fs.data_all.head(10)10 rows × 255 columns
我們可以使用多種方法來檢查特征重要性的結果。首先,我們可以訪問具有零重要性的特征列表。zero_importance_features = fs.ops['zero_importance'] zero_importance_features[10:15] ['ORGANIZATION_TYPE_Transport: type 1','ORGANIZATION_TYPE_Security','FLAG_DOCUMENT_15','FLAG_DOCUMENT_17','ORGANIZATION_TYPE_Religion']畫出特征重要性
使用 plot_feature_importances 的特征重要性畫圖將向我們顯示 plot_n 最重要的特征(按歸一化比例將特征加總為1)。它還向我們顯示了累積特征重要性與特征數量之間的關系。
當我們繪制特征重要性時,我們可以傳遞一個閾值,該閾值標識達到指定的累積特征重要性所需的特征數量。例如,threshold = 0.99將告訴我們占總重要性的99%所需的特征數量。
fs.plot_feature_importances(threshold = 0.99, plot_n = 12) 111 features required for 0.99 of cumulative importance在 FeatureSelector中的 feature_importances 屬性中可以訪問所有的特征重要性。
fs.feature_importances.head(10)| EXT_SOURCE_2 | 145.2 | 0.098174 | 0.098174 |
| EXT_SOURCE_3 | 127.7 | 0.086342 | 0.184517 |
| EXT_SOURCE_1 | 82.7 | 0.055916 | 0.240433 |
| DAYS_BIRTH | 71.4 | 0.048276 | 0.288709 |
| DAYS_REGISTRATION | 64.1 | 0.043340 | 0.332049 |
| DAYS_ID_PUBLISH | 59.3 | 0.040095 | 0.372143 |
| SK_ID_CURR | 57.7 | 0.039013 | 0.411156 |
| DAYS_EMPLOYED | 55.5 | 0.037525 | 0.448682 |
| DAYS_LAST_PHONE_CHANGE | 47.0 | 0.031778 | 0.480460 |
| AMT_INCOME_TOTAL | 41.0 | 0.027721 | 0.508181 |
5. 低重要性特征
此方法使用梯度提升算法(必須首先運行identify_zero_importance)通過查找達到指定的累積總特征重要性所需的最低特征重要性的特征,來構建特征重要性。例如,如果我們輸入0.99,則將找到最不重要的特征重要性,這些特征總的不到總特征重要性的99%。
使用此方法時,我們必須已經運行了identify_zero_importance ,并且需要傳遞一個cumulative_importance ,該值占總特征重要性的一部分。
**注意:**此方法建立在梯度提升模型的重要性基礎之上,并且還是不確定的。我建議使用不同的參數多次運行這兩種方法,并測試每個結果的特征集,而不是只選擇一個數字。
fs.identify_low_importance(cumulative_importance = 0.99) 110 features required for cumulative importance of 0.99 after one hot encoding. 129 features do not contribute to cumulative importance of 0.99.要刪除的低重要性特征是指那些對指定的累積重要性無貢獻的特征。這些特征也可以在 ops 詞典中找到。
low_importance_features = fs.ops['low_importance'] low_importance_features[:5] ['NAME_FAMILY_STATUS_Widow','WEEKDAY_APPR_PROCESS_START_SATURDAY','ORGANIZATION_TYPE_Business Entity Type 2','ORGANIZATION_TYPE_Business Entity Type 1','NAME_INCOME_TYPE_State servant']刪除特征
一旦確定了要刪除的特征,便可以通過多種方式刪除這些特征。我們可以訪問removal_ops詞典中的任何功能列表,并手動刪除列。我們還可以使用 remove 方法,傳入標識我們要刪除的特征的方法。
此方法返回結果數據,然后我們可以將其用于機器學習。仍然可以在特征選擇器的 data 屬性中訪問原始數據。
請注意用于刪除特征的方法!在使用刪除特征之前,最好先檢查將要remove的特征。
train_no_missing = fs.remove(methods = ['missing']) Removed 17 features. train_no_missing_zero = fs.remove(methods = ['missing', 'zero_importance']) Removed 98 features.要從所有方法中刪除特征,請傳入 method='all'。在執行此操作之前,我們可以使用check_removal檢查將刪除了多少個特征。這將返回已被識別為要刪除的所有特征的列表。
all_to_remove = fs.check_removal() all_to_remove[10:25] Total of 156 features identified for removal['FLAG_OWN_REALTY_Y','FLAG_DOCUMENT_19','ORGANIZATION_TYPE_Agriculture','FLOORSMIN_MEDI','ORGANIZATION_TYPE_Restaurant','NAME_HOUSING_TYPE_With parents','NONLIVINGAREA_MEDI','NAME_INCOME_TYPE_Pensioner','HOUSETYPE_MODE_specific housing','ORGANIZATION_TYPE_Industry: type 5','ORGANIZATION_TYPE_Realtor','OCCUPATION_TYPE_Cleaning staff','ORGANIZATION_TYPE_Industry: type 12','OCCUPATION_TYPE_Realty agents','ORGANIZATION_TYPE_Trade: type 6']現在我們可以刪除所有已識別的特征。
train_removed = fs.remove(methods = 'all') ['missing', 'single_unique', 'collinear', 'zero_importance', 'low_importance'] methods have been runRemoved 156 features.處理獨熱特征
如果我們查看返回的DataFrame,可能會注意到原始數據中沒有的幾個新列。這些是在對數據進行獨熱編碼以進行機器學習時創建的。要刪除所有獨熱特征,我們可以將 keep_one_hot = False 傳遞給 remove 方法。
train_removed_all = fs.remove(methods = 'all', keep_one_hot=False) ['missing', 'single_unique', 'collinear', 'zero_importance', 'low_importance'] methods have been runRemoved 190 features including one-hot features. print('Original Number of Features', train.shape[1]) print('Final Number of Features: ', train_removed_all.shape[1]) Original Number of Features 121 Final Number of Features: 65使用所有方法的替代選項
如果我們不想一次運行一個識別方法,則可以使用identify_all 在一次調用中運行所有方法。對于此功能,我們需要傳入參數字典以用于每種單獨的識別方法。
以下代碼在一個調用中完成了上述步驟。
fs = FeatureSelector(data = train, labels = train_labels)fs.identify_all(selection_params = {'missing_threshold': 0.6, 'correlation_threshold': 0.98,'task': 'classification', 'eval_metric': 'auc','cumulative_importance': 0.99}) 17 features with greater than 0.60 missing values.4 features with a single unique value.21 features with a correlation magnitude greater than 0.98.Training Gradient Boosting ModelTraining until validation scores don't improve for 100 rounds. Early stopping, best iteration is: [46] valid_0's auc: 0.743917 valid_0's binary_logloss: 0.254668 Training until validation scores don't improve for 100 rounds. Early stopping, best iteration is: [82] valid_0's auc: 0.766619 valid_0's binary_logloss: 0.244264 Training until validation scores don't improve for 100 rounds. Early stopping, best iteration is: [55] valid_0's auc: 0.72614 valid_0's binary_logloss: 0.26157 Training until validation scores don't improve for 100 rounds. Early stopping, best iteration is: [81] valid_0's auc: 0.756286 valid_0's binary_logloss: 0.251242 Training until validation scores don't improve for 100 rounds. Early stopping, best iteration is: [39] valid_0's auc: 0.686351 valid_0's binary_logloss: 0.269367 Training until validation scores don't improve for 100 rounds. Early stopping, best iteration is: [41] valid_0's auc: 0.744124 valid_0's binary_logloss: 0.255549 Training until validation scores don't improve for 100 rounds. Early stopping, best iteration is: [90] valid_0's auc: 0.761742 valid_0's binary_logloss: 0.249119 Training until validation scores don't improve for 100 rounds. Early stopping, best iteration is: [49] valid_0's auc: 0.751569 valid_0's binary_logloss: 0.254504 Training until validation scores don't improve for 100 rounds. Early stopping, best iteration is: [76] valid_0's auc: 0.726789 valid_0's binary_logloss: 0.257181 Training until validation scores don't improve for 100 rounds. Early stopping, best iteration is: [46] valid_0's auc: 0.714889 valid_0's binary_logloss: 0.26048280 features with zero importance after one-hot encoding.115 features required for cumulative importance of 0.99 after one hot encoding. 124 features do not contribute to cumulative importance of 0.99.150 total features out of 255 identified for removal after one-hot encoding. train_removed_all_once = fs.remove(methods = 'all', keep_one_hot = True) ['missing', 'single_unique', 'collinear', 'zero_importance', 'low_importance'] methods have been runRemoved 150 features. fs.feature_importances.head()| EXT_SOURCE_2 | 165.3 | 0.091074 | 0.091074 |
| EXT_SOURCE_3 | 154.7 | 0.085234 | 0.176309 |
| EXT_SOURCE_1 | 97.5 | 0.053719 | 0.230028 |
| DAYS_BIRTH | 84.6 | 0.046612 | 0.276639 |
| DAYS_REGISTRATION | 75.9 | 0.041818 | 0.318457 |
由于特征重要性已更改,因此刪除的特征數略有差異。由缺失的(missing)、單一的(single_unique)和共線( collinear)確定要刪除的特征數量將保持不變,因為它們是確定性的,但是由于多次訓練模型,零重要性( zero_importance )和低重要性(low_importance )的特征數量可能會有所不同。
結論
本筆記本演示了如何使用FeatureSelector類從數據集中刪除特征。此實現中有幾個重要注意事項:
在機器學習模型的多次運行中,特征重要性將發生變化。
決定是否保留從一個獨熱編碼創建的額外特征。
為不同的參數嘗試幾個不同的值,以確定哪些參數最適合機器學習任務。
對于相同的參數,缺失的(missing)、單一的(single_unique)和共線( collinear)的輸出將保持不變。
特征選擇是機器學習工作流中的一個關鍵步驟,它可能需要多次迭代來優化。
我很感激你對這個項目的任何評論、反饋或幫助。
代碼和數據下載地址:
https://github.com/fengdu78/Data-Science-Notes/tree/master/9.feature-engineering/FeatureSelectorUsage
參考
WillKoehrsen:https://github.com/WillKoehrsen/feature-selector
往期精彩回顧適合初學者入門人工智能的路線及資料下載機器學習及深度學習筆記等資料打印機器學習在線手冊深度學習筆記專輯《統計學習方法》的代碼復現專輯 AI基礎下載機器學習的數學基礎專輯獲取一折本站知識星球優惠券,復制鏈接直接打開:
https://t.zsxq.com/y7uvZF6
本站qq群704220115。
加入微信群請掃碼:
總結
以上是生活随笔為你收集整理的基于Python的特征自动化选择:两行代码完成特征工程的全部內容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: 常用算法25讲,拿走不谢!
- 下一篇: 【Python基础】为什么更改列表'y'