天天看點

DNN深度學習模型 機器學習模型 特征篩選 各個特征重要度排序

背景

在機器學習或者深度學習模型訓練完成後,通常我們需要對輸入特征進行重要度排序及篩選,好去找到一些重要度沒這麼高的特征,将其排除以提高模型收斂速度及準确率。

特征重要程度排序

特征排序方法1 特征分裂

訓練過程中計算訓練過程中通過記錄特征的分裂總次數、總/平均資訊增益來對特征重要性進行量化。例如實際工程中我們會用特征在整個GBDT、XgBoost裡面被使用的次數或者帶來的總/平均資訊增益來給特征重要度打分,最後進行排序。由于本身Ensemble模型在選擇特征分裂時帶有一定随機性,一般會跑多個模型然後把特征重要性求平均後排序。

特征排序方法2 OOB

訓練後使用OOB(Out of Bag)資料計算第二種方式是訓練好模型之後,用Out of Bag(或稱Test)資料進行特征重要性的量化計算。具體來說,先用訓練好的模型對OOB資料進行打分,計算出AUC或其他業務定義的評估名額;接着對OOB資料中的每個特征:

(1)随機shuffle目前特征的取值;

(2)重新對目前資料進行打分,計算評估名額;

(3)計算名額變化率按照上面方式,對每個特征都會得到一個變化率,最後按照變化率排序來量化特征重要性。再

每次一個特征shffle并預測,評判方式是輸出與之前預測結果內插補點的标準差

下面是代碼參考

for key in COLUMNS:
    copy = origin.copy()
    copy[key] = copy[key].sample(frac=1, random_state=1).reset_index()[key]
    cp_out = predict(copy)
    out[key] = out['tag'] - cp_out['tag']
    out[key] = out[key]**2
    print('key = ', key ,' affect = ', out[key].sum()**0.5)
    
(pd.DataFrame(out.sum(axis=0))**0.5).sort_values(by=0 , ascending=False)           

複制

DNN深度學習模型不像Boosting這類模型那樣存在所謂的分裂次數與資訊增益,就需要使用第二種方式,對每個特征進行随機shuffle,觀察模型名額的變化,最後按照變化率進行排序。比如AUC下滑率,下滑的越多說明目前這個名額越重要。當然,實際操作中需要結合業務經驗先指定一個候選變量池,對這部分變量計算重要度,不然計算開銷太大。

特征篩選

接下來我們使用特征篩選的幾種方法去篩選特征

基于對抗驗證(Adversarial Validation)的特征篩選

基本思路:通過找出并去掉在訓練和測試集上(或者是兩個不同時間視窗内)分布不一緻的特征,減小模型對訓練資料的過拟合,進而提高模型泛化性和效果

實作方案:将訓練和測試集分别打上1,0的标簽并進行訓練,最終模型特征重要度越高的特征就是訓練和測試樣本分布差別越大的特征,通過嘗試去掉這些特征實作模型效果提升

DNN深度學習模型 機器學習模型 特征篩選 各個特征重要度排序

image.png

基于SHAP值一緻性的特征篩選

什麼是SHAP值:可以了解為用于解釋特征對預測結果貢獻的一個名額(具體參考https://christophm.github.io/interpretable-ml-book/shapley.html),假如有A,B,C三個特征,那麼對于每條樣本,A、B、C三個特征都對應一個SHAP值展現其對結果的貢獻。

基本思路:有效的特征應該保證對預測結果的貢獻具有一緻性(對相似的樣本,特征貢獻都為正或都為負)

實作方案:在樣本集A、B上分别訓練模型并對B中的樣本計算SHAP值a、b,計算a、b中每個特征SHAP值的相關系數,如果呈正相關說明該特征預測結果具有一緻性,如果不相關甚至負相關,則代表該特征對預測結果貢獻不穩定,需要舍棄。

Ref

  1. https://cloud.tencent.com/developer/article/1061660
  2. https://www.zhihu.com/question/310837513/answer/588954482