两行代码完成特征工程-基于Python的特征自动化选择代码(提供下载)
本文介紹一個特征選擇神器:特征選擇器是用于減少機器學(xué)習(xí)數(shù)據(jù)集的維數(shù)的工具,可以傻瓜式地進行特征選擇,兩行代碼即可搞定!!
來源:Will Koehrsen
代碼整理及注釋翻譯:黃海廣
代碼和數(shù)據(jù)下載地址:
https://github.com/fengdu78/Data-Science-Notes/tree/master/9.feature-engineering/FeatureSelectorUsage
實現(xiàn)的功能
該選擇器基于Python編寫,有五種方法來標(biāo)識要刪除的特征:
缺失值
唯一值
共線特征
零重要性特征
低重要性特征
使用方法
?特征選擇器(Feature Selector)的用法
在這個Jupyter文件中, 我們將使用 FeatureSelector 類來選擇數(shù)據(jù)集中要刪除的特征,這個類提供五種方法來查找要刪除的功能:
查找缺失分?jǐn)?shù)大于指定閾值的列
查找只有唯一值的特征
查找由相關(guān)系數(shù)大于指定值的共線特征
使用梯度提升算法查找具有零重要性的特征
使用梯度提升算法查找中查找對指定的累積特征重要性無貢獻(xiàn)的特征
FeatureSelector 仍在進一步開發(fā)中! 歡迎大家在github提交PR.
from feature_selector import FeatureSelectorimport pandas as pd示例數(shù)據(jù)集
該數(shù)據(jù)集被用作Kaggle上房屋信用違約風(fēng)險競賽的(https://www.kaggle.com/c/home-credit-default-risk) ?一部分(文末提供下載)。它旨在用于有監(jiān)督的機器學(xué)習(xí)分類任務(wù),其目的是預(yù)測客戶是否會拖欠貸款。您可以在此處下載整個數(shù)據(jù)集,我們將處理10,000行的一小部分樣本。
特征選擇器旨在用于機器學(xué)習(xí)任務(wù),但可以應(yīng)用于任何數(shù)據(jù)集。基于特征重要性的方法需要使用機器學(xué)習(xí)的監(jiān)督學(xué)習(xí)問題。
train = pd.read_csv('data/credit_example.csv') train_labels = train['TARGET'] train.head()5 rows × 122 columns
數(shù)據(jù)集中有幾個分類列。`FeatureSelector`處理這些特征重要性的時候使用獨熱編碼。train = train.drop(columns = ['TARGET'])實施
在FeatureSelector具有用于標(biāo)識列,以除去五種特征 :
identify_missing(查找缺失值)
identify_single_unique(查找唯一值)
identify_collinear(查找共線特征)
identify_zero_importance (查找零重要特征)
identify_low_importance(查找低重要特征)
這些方法找到要根據(jù)指定條件刪除的特征。標(biāo)識的特征存儲在 FeatureSelector的 ops 屬性(Python詞典)中。我們可以手動刪除已識別的特征,也可以使用 FeatureSelector中的刪除特征函數(shù)真正刪除特征。
創(chuàng)建實例
FeatureSelector 僅需要一個在行中具有觀察值而在列中具有特征的數(shù)據(jù)集(標(biāo)準(zhǔn)結(jié)構(gòu)化數(shù)據(jù))。我們正在處理機器學(xué)習(xí)的分類問題,因此我們也需要訓(xùn)練的標(biāo)簽。
fs = FeatureSelector(data = train, labels = train_labels)1. 缺失值
第一種特征選擇方法很簡單:找到丟失分?jǐn)?shù)大于指定閾值的任何列。在此示例中,我們將使用閾值0.6,這對應(yīng)于查找缺失值超過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']我們還可以繪制數(shù)據(jù)集中所有列的缺失列分?jǐn)?shù)的直方圖。
fs.plot_missing()有關(guān)缺失分?jǐn)?shù)的詳細(xì)信息,我們可以訪問missing_stats屬性,這是所有特征缺失分?jǐn)?shù)的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']我們可以繪制數(shù)據(jù)集中每個特征中唯一值數(shù)量的直方圖。
fs.plot_unique()最后,我們可以訪問一個DataFrame,其中包含每個特征的唯一值數(shù)量。
fs.unique_stats.sample(5)| 4210 |
| 3 |
| 2 |
| 2 |
| 993 |
3. 共線(高相關(guān)性) 特征
該方法基于皮爾森相關(guān)系數(shù)找到共線特征對。對于高于指定閾值(就絕對值而言)的每一對,它標(biāo)識要刪除的變量之一。我們需要傳遞一個 correlation_threshold。
此方法基于在:https://chrisalbon.com/machine_learning/feature_selection/drop_highly_correlated_features/ 中找到的代碼。
對于每一對,將要刪除的特征是在DataFrame中列排序方面排在最后的特征。(除非one_hot = True,否則此方法不會預(yù)先對數(shù)據(jù)進行一次獨熱編碼。因此,僅在數(shù)字列之間計算相關(guān)性)
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']我們可以查看閾值以上相關(guān)性的熱圖。將要刪除的特征位于x軸上。
fs.plot_collinear()要繪制數(shù)據(jù)中的所有相關(guān)性,我們可以將 plot_all = True 傳遞給 plot_collinear函數(shù)。
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.要查看閾值以上的相關(guān)細(xì)節(jié),我們訪問record_collinear 屬性,它是一個DataFrame。?drop_feature 將被刪除,并且對于每個將被刪除的特征,它與 corr_feature可能存在多個相關(guān)性,而這些相關(guān)性都高于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. 零重要特征?
此方法依賴于機器學(xué)習(xí)模型來識別要刪除的特征。因此,它是有標(biāo)簽的監(jiān)督學(xué)習(xí)問題。該方法通過使用LightGBM庫中實現(xiàn)的梯度增強機找到特征重要性。
為了減少所計算的特征重要性的差異,默認(rèn)情況下對模型進行了10次訓(xùn)練。默認(rèn)情況下,還使用驗證集(訓(xùn)練數(shù)據(jù)的15%)通過提前停止訓(xùn)練模型,以識別要訓(xùn)練的最優(yōu)估計量。可以將以下參數(shù)傳遞給identify_zero_importance 方法:
task: 可以是 classification 或 regression。指標(biāo)和標(biāo)簽必須與任務(wù)匹配。
eval_metric: 用于提前停止的度量(例如,用于分類的auc或用于回歸的l2 )。要查看可用指標(biāo)的列表,請參閱LightGBM文檔:(http://testlightgbm.readthedocs.io/en/latest/Parameters.html#metric-parameters)。
n_iterations: 訓(xùn)練次數(shù)。特征重要性是在訓(xùn)練運行中平均得出的 (默認(rèn)為10)。
early_stopping: 訓(xùn)練模型時是否使用提前停止(默認(rèn)= True)。當(dāng)驗證集的性能對于指定數(shù)量的估計量(此實現(xiàn)中默認(rèn)為100)不再降低時,提早停止將停止訓(xùn)練估計量(決策樹)。早停是一種正則化形式,用于防止訓(xùn)練數(shù)據(jù)過擬合。
首先對數(shù)據(jù)進行一次獨熱編碼,以供模型使用。這意味著某些零重要性特征可以通過一鍵編碼來創(chuàng)建。要查看單編碼的列,我們可以訪問 FeatureSelector的one_hot_features 。
注意:與其他方法相比,模型的特征重要性是不確定的(具有少許隨機性)。每次運行此方法時,其結(jié)果都可能更改。
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屬性將保留原始數(shù)據(jù)以及獨熱編碼特征。
fs.data_all.head(10)10 rows × 255 columns
我們可以使用多種方法來檢查特征重要性的結(jié)果。首先,我們可以訪問具有零重要性的特征列表。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)。它還向我們顯示了累積特征重要性與特征數(shù)量之間的關(guān)系。
當(dāng)我們繪制特征重要性時,我們可以傳遞一個閾值,該閾值標(biāo)識達(dá)到指定的累積特征重要性所需的特征數(shù)量。例如,threshold = 0.99將告訴我們占總重要性的99%所需的特征數(shù)量。
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)通過查找達(dá)到指定的累積總特征重要性所需的最低特征重要性的特征,來構(gòu)建特征重要性。例如,如果我們輸入0.99,則將找到最不重要的特征重要性,這些特征總的不到總特征重要性的99%。
使用此方法時,我們必須已經(jīng)運行了identify_zero_importance ,并且需要傳遞一個cumulative_importance ,該值占總特征重要性的一部分。
**注意:**此方法建立在梯度提升模型的重要性基礎(chǔ)之上,并且還是不確定的。我建議使用不同的參數(shù)多次運行這兩種方法,并測試每個結(jié)果的特征集,而不是只選擇一個數(shù)字。
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.要刪除的低重要性特征是指那些對指定的累積重要性無貢獻(xiàn)的特征。這些特征也可以在 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 方法,傳入標(biāo)識我們要刪除的特征的方法。
此方法返回結(jié)果數(shù)據(jù),然后我們可以將其用于機器學(xué)習(xí)。仍然可以在特征選擇器的 data 屬性中訪問原始數(shù)據(jù)。
請注意用于刪除特征的方法!在使用刪除特征之前,最好先檢查將要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'。在執(zhí)行此操作之前,我們可以使用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']現(xiàn)在我們可以刪除所有已識別的特征。
train_removed = fs.remove(methods = 'all') ['missing', 'single_unique', 'collinear', 'zero_importance', 'low_importance'] methods have been runRemoved 156 features.處理獨熱特征
如果我們查看返回的DataFrame,可能會注意到原始數(shù)據(jù)中沒有的幾個新列。這些是在對數(shù)據(jù)進行獨熱編碼以進行機器學(xué)習(xí)時創(chuàng)建的。要刪除所有獨熱特征,我們可以將 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 在一次調(diào)用中運行所有方法。對于此功能,我們需要傳入?yún)?shù)字典以用于每種單獨的識別方法。
以下代碼在一個調(diào)用中完成了上述步驟。
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 |
由于特征重要性已更改,因此刪除的特征數(shù)略有差異。由缺失的(missing)、單一的(single_unique)和共線( collinear)確定要刪除的特征數(shù)量將保持不變,因為它們是確定性的,但是由于多次訓(xùn)練模型,零重要性( zero_importance )和低重要性(low_importance )的特征數(shù)量可能會有所不同。
結(jié)論
本筆記本演示了如何使用FeatureSelector類從數(shù)據(jù)集中刪除特征。此實現(xiàn)中有幾個重要注意事項:
在機器學(xué)習(xí)模型的多次運行中,特征重要性將發(fā)生變化。
決定是否保留從一個獨熱編碼創(chuàng)建的額外特征。
為不同的參數(shù)嘗試幾個不同的值,以確定哪些參數(shù)最適合機器學(xué)習(xí)任務(wù)。
對于相同的參數(shù),缺失的(missing)、單一的(single_unique)和共線( collinear)的輸出將保持不變。
特征選擇是機器學(xué)習(xí)工作流中的一個關(guān)鍵步驟,它可能需要多次迭代來優(yōu)化。
我很感激你對這個項目的任何評論、反饋或幫助。
代碼和數(shù)據(jù)下載地址:
https://github.com/fengdu78/Data-Science-Notes/tree/master/9.feature-engineering/FeatureSelectorUsage
參考
WillKoehrsen:https://github.com/WillKoehrsen/feature-selector
備注:公眾號菜單包含了整理了一本AI小抄,非常適合在通勤路上用學(xué)習(xí)。
往期精彩回顧適合初學(xué)者入門人工智能的路線及資料下載機器學(xué)習(xí)在線手冊深度學(xué)習(xí)在線手冊AI基礎(chǔ)下載(第一部分)備注:加入本站微信群或者qq群,請回復(fù)“加群”獲取一折本站知識星球優(yōu)惠券,請回復(fù)“知識星球”喜歡文章,點個在看
總結(jié)
以上是生活随笔為你收集整理的两行代码完成特征工程-基于Python的特征自动化选择代码(提供下载)的全部內(nèi)容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: 基于深度学习的CTR模型DeepCTR
- 下一篇: 数据分析的必备材料:学完可以解决90%以