怎樣才能在Kaggle舉辦的各式各樣的比賽裡,拿到驕人的成績?
![](https://img.laitimes.com/img/9ZDMuAjOiMmIsIjOiQnIsIyZuBnLzETZmFDZzYmN1MWMkVTMwATM4EzYihTZkVGOmZWN3QTM1YWZkNWOm9CXt92Yu4GZjlGbh5SZslmZxl3Lc9CX6MHc0RHaiojIsJye.png)
一位叫做Abhay Pawar的少年,在2600多支隊伍參加的Instacart Market Basket Analysis比賽上,擊敗了98%的對手。
這是一個預測使用者未來将購買何種商品的比賽,依據的是過往交易資料。
少年對參加比賽充滿了心得,說最重要的就是要充分了解特征,特别是搞定嘈雜特征。
于是,他寫了一套七步秘笈出來,和小夥伴們分享自己探索特征的經驗。
這份秘笈,封裝在一個名叫featexp的Python包裡,傳送門在文底。
舉栗用的資料集,是來自Kaggle Home Credit Default Risk (違約者預測) 比賽。
現在,了解一下具體步驟吧。
支配特征,七步大法
少年說,仔細觀察一個模型的部分依賴圖 (Partial Dependency Plot,PDP) , 可以幫助大家了解output是如何随着特征而變化的。
問題是,這種圖像是用訓練好的模型做的。而如果直接用訓練資料來做圖,就可以讓大家更好地了解underlying data。
1. 了解特征
如果因變量 (目标) 是二進制,散點圖就不好用,因為所有點不是0就是1。
針對連續目标,資料點太多的話,會讓人很難了解目标和特征之間的關系。
用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) ,做出一個這樣的圖像:
在這裡,平均值代表違約率。圖像告訴我們,年紀 (DAYS_BIRTH) 越大的人,違約率越低。
嗯,如果年輕人不太在意違約,也比較符合常理。
還有另外一個圖像,表示每個區間的人數 (分的時候就是相等的) :
不過,這個栗子是比較友好的特征。少年說了,下一個章節才是最有趣的。
2. 識别嘈雜特征
嘈雜特征容易造成過拟合,識别這樣的特征一點也不容易。
在featexp裡面,可以跑一下測試集,然後對比驗證集和測試集的特征趨勢,來找出嘈雜的特征。
這是對比用的代碼:
1get_univariate_plots(data=data_train, target_col='target', data_test=data_test, features_list=['DAYS_EMPLOYED'])
做出的圖像長這樣:
為了衡量嘈雜程度,featexp會計算兩個名額:
一是趨勢相關性 (Trend Correlation) :如果一個特征在訓練集和測試集裡面,表現出來的趨勢不一樣,就可能導緻過拟合。這是因為,模型從測試集裡學到的一些東西,在驗證集裡不适用。
趨勢相關性可以告訴我們,訓練集和測試集趨勢的相似度,以及每個區間的平均值,以及這些數值要怎麼用。
上面這個特征,兩個集子的相關性達到99%。
很好,一點也不嘈雜的樣子。
二是趨勢變化 (Trend Changes) :有時候,趨勢會發生突變 (Sudden Changes) 和反複變化 (Repeated Changes) 。
這可能就是很嘈雜的表現了,但也有可能是那個區間,因為其他特征的表現非常與衆不同,而受到影響了。
如果出現這種情況,這個區間的違約率就沒辦法和其他區間直接相比了。
下面這個特征,就是嘈雜特征,相關性隻有85%。有時候,可以選擇丢掉這個特征。
抛棄相關性低的特征,這種做法在特征非常多、特征之間又很相關的情況下,比較适用。
它可以減少過拟合,避免資訊丢失。不過:
注意,别把太多重要的特征都丢掉了。否則,模型的預測效果可能就有損失了。
注意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)
現在,可以試着丢棄一些特征了。不妨參考這些标準來執行:
△ 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:
△ 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的圖表,可以幫助你通過以下兩項操作來發現複雜特征工程代碼中的錯誤:
1)檢查特征的人群分布是否正确。 由于一些小錯誤,作者遇到過多次極端情況。
2)在檢視這些圖之前,總是假設特征趨勢會是什麼樣子。 特征趨勢看起來不符合預期,可能暗示着某些問題。 坦率地說,這個假設趨勢的過程使ML模型更有趣!
6. 洩漏檢測
從目标到特征的資料洩漏導緻過度拟合。 洩露的特征具有很高的功能重要性。 但是,要了解為什麼在特征中會發生洩漏,這很是困難的。 檢視featexp圖可以幫助了解這一問題。
以下特征在“Nulls”區間中的違約率為0%,在其他所有區間中的違約率為100%。 顯然,這是洩漏的極端情況。 隻有當客戶違約時,此特征才有價值。 了解洩漏特征的問題所在能讓你更快地debug。
7. 模型監控
由于featexp可計算兩個資料集之間的趨勢相關性,是以它可以很容易地用于模型監控。 每次重新訓練模型時,都可以将新的訓練資料與測試好的訓練資料(通常是第一次構模組化型時的訓練資料)進行比較。 趨勢相關性可以幫助您監控特征資訊是否與目标的關系發生了變化。
featexp項目
作者Abhay Pawar在文中大篇幅使用了featexp,這是一個用于監督學習的特征探索項目,本文也是主要針對此工具得使用展開讨論。它對前面提到的特征了解、識别帶噪聲的特征、特征除錯、洩露探測和模型監控都有幫助。
它的安裝也很簡單,可以通過pip直接安裝:
pip install featexp
原文釋出時間為:2018-11-7
本文作者:關注前沿科技
本文來自雲栖社群合作夥伴“
量子位”,了解相關資訊可以關注“
”。