業界 | 如何達到Kaggle競賽top 2%?這裏有一篇特徵探索經驗帖

選自Towards Data Science

作者:Abhay Pawar

機器之心編譯

機器之心編輯部

本文作者 Abhay Pawar 多次參加 Kaggle 競賽,並在 Instacart Market Basket Analysis 競賽中拿到 top 2% 的名次。他在多年競賽中總結出了一套特徵探索和構建更好機器學習模型的標準方式,本文將介紹這套方法。

在數值數據上構建任意監督學習模型的一個重要方面是理解特徵。查看模型的部分依賴圖可幫助理解任意特徵對模型輸出的影響。

圖源:http://scikit-learn.org/stable/auto_examples/ensemble/plot_partial_dependence.html

但是,部分依賴圖存在一個問題,即它們是使用訓練好的模型創建的。如果我們可以從訓練數據中直接創建部分依賴圖,那麼它將幫助我們更好地理解底層數據。事實上,它能夠幫助你做好以下事情:

  1. 特徵理解
  2. 識別帶噪聲的特徵
  3. 特徵工程
  4. 特徵重要性
  5. 特徵 debug
  6. 泄露檢測和理解
  7. 模型監控

爲了使其更加易於使用,作者將這些技術封裝進一個 Python 包 featexp 中,本文將介紹如何使用它進行特徵探索。本文使用的是 Kaggle Home Credit Default Risk 競賽的應用數據集。該競賽的任務是使用給定數據預測違約者。

featexp:https://github.com/abhayspawar/featexp

1. 特徵理解

特徵散點圖 vs. 無用的目標

如果依賴變量(目標)是二元的,則散點圖無效,因爲所有點要麼是 0 要麼是 1。對於連續目標來說,數據點太多會造成難以理解目標 vs 特徵趨勢。featexp 創建了更好的圖,可幫助解決該問題。我們來試一下!

from featexp import get_univariate_plots

# Plots drawn for all features if nothing is passed in feature_list parameter.
get_univariate_plots(data=data_train, target_col='target', 
                     features_list=['DAYS_BIRTH'], bins=10)

DAYS_BIRTH (age) 的特徵 vs 目標圖

featexp 爲數值特徵創建了同等人口數量的 bin(x 軸),然後計算每個 bin 的目標平均值,再繪製出來(如上圖左)。在我們的案例中,目標平均值是違約率。該圖告訴我們年齡越大的客戶違約率越低。這些圖幫助我們理解特徵表達的意義,及其對模型的影響。右圖顯示了每個 bin 中客戶的數量。

2. 識別帶噪聲的特徵

帶噪聲的特徵導致過擬合,識別它們並非易事。在 featexp 中,你可以輸出一個測試集(或者驗證集),對比訓練/測試集中的特徵趨勢來確定帶噪聲的特徵。

get_univariate_plots(data=data_train, target_col='target', data_test=data_test, features_list=['DAYS_EMPLOYED'])

訓練和測試特徵趨勢對比。

featexp 計算兩個指標(如上圖所示),來幫助測量噪聲:

  1. 趨勢相關度(見測試圖):如果某個特徵未體現目標在訓練集和測試集中的同樣趨勢,它會導致過擬合,因爲模型會學習一些在測試數據中並不使用的東西。趨勢相關度有助於理解訓練/測試趨勢的相似度,如何利用訓練和測試集的 bin 的平均目標值來計算趨勢相關度。上圖中的特徵相關度爲 99%,幾乎沒有噪聲。
  2. 趨勢變化:趨勢方向中突然和重複的變化可能表明有噪聲。但是,此類趨勢變化也會在 bin 的人口數量與其它特徵不同時,導致其違約率無法與其它 bin 進行對比。

下圖中的特徵沒有展現同樣的趨勢,因爲趨勢相關度爲 85%。這兩個指標可用於刪除帶噪聲的特徵。

帶噪聲特徵示例。

當特徵很多且相互關聯時,刪除低趨勢相關度特徵的效果很好。它會帶來更少的過擬合,其它相關特徵可以避免信息損失。同時需要注意不要刪除太多重要特徵,因爲這可能導致性能下降。此外,你無法利用特徵重要性來判斷特徵是否帶噪聲,因爲重要的特徵也會帶噪聲!

使用不同時間段的測試數據效果更好,因爲你可以藉此確定特徵趨勢是否一直如此。

featexp 中的 get_trend_stats() 函數返回展示趨勢相關度的數據幀,並隨着特徵而改變。

from featexp import get_trend_stats
stats = get_trend_stats(data=data_train, target_col='target', data_test=data_test)

get_trend_stats() 返回的數據幀。

下面我們就試着刪除數據中低趨勢相關度的特徵,然後看結果是否有所改進。

使用趨勢相關度的不同特徵選擇的 AUC。

我們可以看到,趨勢相關度閾值越高,排行榜(LB)AUC 越高。不刪除重要的特徵進一步將 LB AUC 提高到 0.74。測試 AUC 的變化與 LB AUC 不同,這一點也很有趣。完整代碼詳見 featexp_demo notebook:https://github.com/abhayspawar/featexp/blob/master/featexp_demo.ipynb。

3. 特徵工程

通過查看這些圖所獲取的見解可以幫助你創建更好的特徵。更好地理解數據將帶來更好的特徵工程。此外,它還可以幫助你改善現有特徵。下面我們來看另一個特徵 EXT_SOURCE_1:

EXT_SOURCE_1 的特徵 vs. 目標圖。

具備高 EXT_SOURCE_1 的客戶具備較低的違約率。但是,第一個 bin(違約率約 8%)沒有遵循該特徵趨勢(向上升後下降)。它的負值是-99.985,而且人口數量較多。這可能表明這些是特殊的值,因此不遵循特徵趨勢。幸運的是,非線性模型在學習該關係方面不會有問題。而對於線性模型(如 logistic 迴歸),此類特殊值和空缺值應該採用類似樣本的默認值進行估計,而不是特徵平均值。

4. 特徵重要性

featexp 還可以幫助衡量特徵重要性。DAYS_BIRTH 和 EXT_SOURCE_1 都具備很好的趨勢。但是 EXT_SOURCE_1 的人口數量集中於特殊值 bin,這表明其重要性可能不如 DAYS_BIRTH。基於 XGBoost 模型的特徵重要性,DAYS_BIRTH 的重要性高於 EXT_SOURCE_1。

5. 特徵 debug

查看 featexp 圖可以幫助你捕捉複雜特徵工程中的 bug:

零變化特徵僅顯示單個 bin。

檢查一下特徵的人數分佈看起來是否正確。由於存在一些小 bug,我個人經常遭遇上述極端情況。

在看這些圖之前,一定要假設特徵趨勢會是什麼樣子。如果特徵趨勢看起來不像你期望的那樣,可能表示其中存在一些問題。坦率地說,這種假設趨勢的過程使得構建 ML 模型更加有趣!

6 泄露檢測

從目標到特徵的數據泄露會導致過擬合。泄露特徵具有很高的特徵重要性,但很難理解爲什麼特徵會發生泄露。查看下列 featexp 圖可以幫助你理解。

下面的特徵在「Null」bin 中違約率爲 0%,在其它 bin 中爲 100%。很明顯,這是極端的泄露案例。該特徵只有在客戶違約時才有價值。根據特徵是什麼,這可能是因爲 bug 或者該特徵只爲違約者填充(在這種情況下它會下降)。弄清楚特徵泄露的原因可以加速 debug。

理解特徵爲何泄露。

7 模型監控

由於 featexp 計算兩個數據集之間的趨勢相關性,它可以很輕易地用於模型監控。每次模型被重新訓練之後,就可以把新的訓練數據與測試好的訓練數據(通常從第一次構建模型開始訓練數據)進行對比。趨勢相關性能夠幫助你監控特徵信息與目標的關係是否發生任何變化。

原文鏈接:https://towardsdatascience.com/my-secret-sauce-to-be-in-top-2-of-a-kaggle-competition-57cff0677d3c

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章