天天看點

如何在Kaggle比賽上擊敗98%的對手?你需要一份七步秘笈

怎樣才能在Kaggle舉辦的各式各樣的比賽裡,拿到驕人的成績?

如何在Kaggle比賽上擊敗98%的對手?你需要一份七步秘笈

一位叫做Abhay Pawar的少年,在2600多支隊伍參加的Instacart Market Basket Analysis比賽上,擊敗了98%的對手。

這是一個預測使用者未來将購買何種商品的比賽,依據的是過往交易資料。

如何在Kaggle比賽上擊敗98%的對手?你需要一份七步秘笈

少年對參加比賽充滿了心得,說最重要的就是要充分了解特征,特别是搞定嘈雜特征。

于是,他寫了一套七步秘笈出來,和小夥伴們分享自己探索特征的經驗。

這份秘笈,封裝在一個名叫featexp的Python包裡,傳送門在文底。

舉栗用的資料集,是來自Kaggle Home Credit Default Risk (違約者預測) 比賽。

現在,了解一下具體步驟吧。

支配特征,七步大法

少年說,仔細觀察一個模型的部分依賴圖 (Partial Dependency Plot,PDP) , 可以幫助大家了解output是如何随着特征而變化的。

如何在Kaggle比賽上擊敗98%的對手?你需要一份七步秘笈

問題是,這種圖像是用訓練好的模型做的。而如果直接用訓練資料來做圖,就可以讓大家更好地了解underlying data。

1. 了解特征

如果因變量 (目标) 是二進制,散點圖就不好用,因為所有點不是0就是1。

如何在Kaggle比賽上擊敗98%的對手?你需要一份七步秘笈

針對連續目标,資料點太多的話,會讓人很難了解目标和特征之間的關系。

用featexp可以做出更加友善的圖像。

拿這行代碼試一下吧:

1from featexp import get_univariate_plots

2

3# Plots drawn for all features if nothing is passed in feature_list parameter.

4get_univariate_plots(data=data_train, target_col='target',

5 features_list=['DAYS_BIRTH'], bins=10)

Featexp可以把一個數字特征,分成很多個樣本數相等的區間 (Equal Population Bins) 。

然後,計算出目标的平均值 (Mean) ,做出一個這樣的圖像:

如何在Kaggle比賽上擊敗98%的對手?你需要一份七步秘笈

在這裡,平均值代表違約率。圖像告訴我們,年紀 (DAYS_BIRTH) 越大的人,違約率越低。

嗯,如果年輕人不太在意違約,也比較符合常理。

還有另外一個圖像,表示每個區間的人數 (分的時候就是相等的) :

如何在Kaggle比賽上擊敗98%的對手?你需要一份七步秘笈

不過,這個栗子是比較友好的特征。少年說了,下一個章節才是最有趣的。

2. 識别嘈雜特征

嘈雜特征容易造成過拟合,識别這樣的特征一點也不容易。

在featexp裡面,可以跑一下測試集,然後對比驗證集和測試集的特征趨勢,來找出嘈雜的特征。

這是對比用的代碼:

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

做出的圖像長這樣:

如何在Kaggle比賽上擊敗98%的對手?你需要一份七步秘笈

為了衡量嘈雜程度,featexp會計算兩個名額:

一是趨勢相關性 (Trend Correlation) :如果一個特征在訓練集和測試集裡面,表現出來的趨勢不一樣,就可能導緻過拟合。這是因為,模型從測試集裡學到的一些東西,在驗證集裡不适用。

趨勢相關性可以告訴我們,訓練集和測試集趨勢的相似度,以及每個區間的平均值,以及這些數值要怎麼用。

上面這個特征,兩個集子的相關性達到99%。

很好,一點也不嘈雜的樣子。

二是趨勢變化 (Trend Changes) :有時候,趨勢會發生突變 (Sudden Changes) 和反複變化 (Repeated Changes) 。

這可能就是很嘈雜的表現了,但也有可能是那個區間,因為其他特征的表現非常與衆不同,而受到影響了。

如果出現這種情況,這個區間的違約率就沒辦法和其他區間直接相比了。

下面這個特征,就是嘈雜特征,相關性隻有85%。有時候,可以選擇丢掉這個特征。

如何在Kaggle比賽上擊敗98%的對手?你需要一份七步秘笈

抛棄相關性低的特征,這種做法在特征非常多、特征之間又很相關的情況下,比較适用。

它可以減少過拟合,避免資訊丢失。不過:

注意,别把太多重要的特征都丢掉了。否則,模型的預測效果可能就有損失了。

注意x2,也不能用重要性來評價特征是否嘈雜,因為有些特征就是可以既重要,又嘈雜得不得了。

用 (與訓練集) 不同時間段的資料來做測試集,可能會比較好。這樣,就能看出來資料是不是随時間變化的了。

請看下面的示範。

Featexp裡有一個 get_trend_stats() 函數,可以傳回一個資料框 (Dataframe) ,顯示趨勢相關性和趨勢變化。代碼如下:

1from featexp import get_trend_stats

2stats = get_trend_stats(data=data_train, target_col='target', data_test=data_test)

如何在Kaggle比賽上擊敗98%的對手?你需要一份七步秘笈

現在,可以試着丢棄一些特征了。不妨參考這些标準來執行:

如何在Kaggle比賽上擊敗98%的對手?你需要一份七步秘笈

△ AUC=Area Under Curve,曲線下的面積,是評價模型的名額

丢棄特征的相關性門檻值越高,排行榜上的AUC越高。

加上不要丢棄重要特征這一條規則,AUC提升到了0.74。

有趣的是,測試集的AUC并沒有像排行榜的AUC變化那麼大。

完整代碼可以在featexp_demo記事本裡面找到:

https://github.com/abhayspawar/featexp/blob/master/featexp_demo.ipynb

3. 特征工程

通過檢視這些圖表獲得的見解有助于建立更好的特征。

隻需更好地了解資料就可以實作更好的特征工程。 除此之外,它還可以幫助你改進現有特征。下面來看另一個功能EXT_SOURCE_1:

如何在Kaggle比賽上擊敗98%的對手?你需要一份七步秘笈

△ EXT_SOURCE_1的特征與目标圖

具有較高EXT_SOURCE_1值的客戶違約率較低。 但是,第一個區間(違約率約8%)不遵循這個特征趨勢(上升然後下降)。 它隻有-99.985左右的負值且人群數量較多。這可能意味着這些是特殊值,是以不遵循特征趨勢。

幸運的是,非線性模型在學習這種關系時不會有問題。 但是,對于像邏輯回歸這樣的線性模型,這些特殊值和空值應該用來自具有相似違約率的區間的值來估算,而不是簡單地用特征均值。

4. 特征重要性

Featexp還可以幫助衡量特征的重要性。 DAYS_BIRTH和EXT_SOURCE_1都有很好的趨勢。 但是,EXT_SOURCE_1的人群集中在特殊值區間中,這表明它可能不如DAYS_BIRTH那麼重要。 基于XGBoost模型的特征重要性,DAYS_BIRTH實際上比EXT_SOURCE_1更重要。

5. 特征調試

檢視Featexp的圖表,可以幫助你通過以下兩項操作來發現複雜特征工程代碼中的錯誤:

如何在Kaggle比賽上擊敗98%的對手?你需要一份七步秘笈

1)檢查特征的人群分布是否正确。 由于一些小錯誤,作者遇到過多次極端情況。

2)在檢視這些圖之前,總是假設特征趨勢會是什麼樣子。 特征趨勢看起來不符合預期,可能暗示着某些問題。 坦率地說,這個假設趨勢的過程使ML模型更有趣!

6. 洩漏檢測

從目标到特征的資料洩漏導緻過度拟合。 洩露的特征具有很高的功能重要性。 但是,要了解為什麼在特征中會發生洩漏,這很是困難的。 檢視featexp圖可以幫助了解這一問題。

以下特征在“Nulls”區間中的違約率為0%,在其他所有區間中的違約率為100%。 顯然,這是洩漏的極端情況。 隻有當客戶違約時,此特征才有價值。 了解洩漏特征的問題所在能讓你更快地debug。

如何在Kaggle比賽上擊敗98%的對手?你需要一份七步秘笈

7. 模型監控

由于featexp可計算兩個資料集之間的趨勢相關性,是以它可以很容易地用于模型監控。 每次重新訓練模型時,都可以将新的訓練資料與測試好的訓練資料(通常是第一次構模組化型時的訓練資料)進行比較。 趨勢相關性可以幫助您監控特征資訊是否與目标的關系發生了變化。

featexp項目

作者Abhay Pawar在文中大篇幅使用了featexp,這是一個用于監督學習的特征探索項目,本文也是主要針對此工具得使用展開讨論。它對前面提到的特征了解、識别帶噪聲的特征、特征除錯、洩露探測和模型監控都有幫助。

它的安裝也很簡單,可以通過pip直接安裝:

pip install featexp

原文釋出時間為:2018-11-7

本文作者:關注前沿科技

本文來自雲栖社群合作夥伴“

量子位

”,了解相關資訊可以關注“

”。

繼續閱讀