kaggle比賽經驗


Kaggle比賽心得

 

最近參加了兩場Kaggle比賽,收獲頗多,一直想寫篇文章總結一下。接觸Kaggle到現在不到一年,比賽成績一個銀牌(5%)一個銅牌(9%),勉強算入門了,跟大神們還有很大的距離。新學期准備找實習面試,整理一下項目經驗,於是動筆總結總結參加Kaggle比賽的個人心得體會和技巧。

 

先放一張成績圖和Kaggle個人主頁的鏈接(https://www.kaggle.com/yiyuanliu)

 

640?wx_fmt=png&wxfrom=5&wx_lazy=1

成績

 

我參加的這兩場比賽,一個是Zillow Prize:Zillow公司有一個房價預測算法Zestimate,根據房產的特征、歷史成交數據和Zestimate預測值之間的logerror(這里有點繞),來預測實際成交價和Zestimate預測值之間的logerror。另一個是TensorFlow Speech Recoginition Challenge:識別長度為1秒的英文語音指令,並且分為12個類,包括10個指令(yes, no, up, down, left, right, on, off, stop, go)以及未知(unknown)和靜默(silence)。

 

這兩個比賽,剛好屬於Kaggle社區中兩個不同類別。Zillow Prize給定了60個房產的特征,數據量不是特別大並且有明確的特征,適合xgboost、lgb這樣的樹模型,對機器的要求不高。而語音識別這個比賽則相反,原始數據是wav文件,實際上相當於對波形圖進行分類,不可能手動選特征,因此這個比賽適用深度學習的各種模型。並且想要取得好成績,需要使用復雜的模型,CPU就不夠用了,需要一塊不錯的顯卡(我用的是隊友的GTX 1070ti)。

兩場比賽下來,自己總結了一些kaggle比賽的基本流程:

 

  1. 特征工程

  2. 模型選擇

  3. 調參

  4. 模型融合

 

 

特征工程

 

特征工程是Kaggle比賽的重中之重,尤其是對於房價預測這類使用樹模型的比賽。模型大同小異,基本是由GBDT模型演化而來,而且主要用XGBoost、LightGBM等幾種開源框架。所以,模型大家都差不多,特征就是關鍵了。


每個比賽都有獨特的背景,想要發現甚至是自己創造出重要的特征,往往需要專業的領域知識,比如Zillow這個比賽要預測美國的房價,原始特征有卧室數量、面積,稅收等等。想要自己通過原始特征組合,創造出一個“magic feature”就需要了解美國的房地產業。所以,選擇一個自己熟悉領域的比賽,會比較有優勢。


比賽背景千變萬化,從數據科學的角度,還有許多通用的方法來做特征工程。這里列舉一些這個比賽里用到的方法:

 

1、基礎預處理:對category類型的數據OneHot編碼;數值類型的數據歸一化(但是這里用到的大多數模型都是基於決策樹的,所以不需要)

 

2、缺失值處理:實際數據集中有許多數據是缺失的,考慮列出每個特征的缺失比例,比例過大的直接舍棄,否則想辦法填充。這個比例沒有什么定式,舍棄特征會丟掉有用信息,填充會引入噪聲,具體怎么操作要看模型實際的表現。填充的話,基礎的是用均值、中位數等填充,更准確的方法是用算法擬合,還可以直接把缺失視為一種特殊的值(這個比賽中的許多模型就是用-1填充)。

 

對於樹模型來說,數據缺失並不影響樹的生成,所以xgboost會在生成樹的同時,根據training loss自動學會將遇到缺失值時分裂到左子樹還是右子樹。作者Tianqi Chen的原話:

 

Internally, XGBoost will automatically learn what is the best direction to go when a value is missing. Equivalently, this can be viewed as automatically "learn" what is the best imputation value for missing values based on reduction on training loss.

 

3、outlier: 由於各種原因,往往有一些樣本的誤差特別大,把這些樣本加入模型會引入很大的噪聲,就像很多打分的比賽會去掉最高分和最低分之后再取平均值。這個比賽中去掉這樣大誤差的outlier能帶來很大的提升。

 

下圖是所有樣本的logerror值,可以看到絕大部分都在0附近,去掉兩端logerror急劇上升的樣本,能讓模型更穩定。

 

640?wx_fmt=png

outsider

 

3、相關性分析:特征之間並不是完全獨立的,這時候可以計算correlation coefficient來確定特征之間的兩兩關系。還可以計算每個特征和目標值(這里是logerror)之間的相關性,絕對值越大說明這個特征的作用越大。

 

4、模型權重分析:現在大多數模型在訓練完成后都會給出獲取特征權重的接口,這時的權重是直接反映了一個特征在這個模型中的作用。這是判斷一個特征是否有用的重要方法。例如,原始特征有卧室數量和衛生間數量,我們自己創造了一個特征房間總數(卧室數量+衛生間數量)。這時可以用這種方法判斷這個新特征是否有效。

 

特征工程在實際應用中非常有挑戰性,還有許多方法,上述只是一些皮毛。Zillow比賽里我嘗試了許多新特征,但最終都沒有采用。

 

而對於語音識別比賽來說,特征工程就非常有限了。在語音識別領域廣泛使用的特征是log-mel頻譜和mfcc特征,沒有必要自己再做特征工程。而現在火熱的端到端(end-to-end)語音識別優點就是省去特征提取,直接使用原始波形作為神經網絡的輸入。

 

模型選擇

 

Kaggle比賽很重要的一點是,不可能只使用一個單一模型。在許多比賽的第一名公布的方案里,往往有十幾個甚至幾十個不同的模型。模型融合(ensemble)實在是太重要了,模型融合的方法下文再講,但是在選擇模型的時候就要考慮到如何讓這些模型在融合后效果更好。

 

不管用什么方法融合,想要模型融合之后效果好,模型之間要有多樣性。換句話說,模型之間越不相似,模型融合的效果越好。


對於Zillow這樣給定特征,數據不是圖像音頻的比賽,主要選用樹模型。這類Kaggle比賽,首選肯定是XGBoost和LightGBM。這兩個模型都是由梯度提升樹(GBDT)演化而來的。簡而言之,就是通過梯度提升(Gradient Boost)算法訓練許多決策樹及其對應的權重,然后投票得到最終的結果。詳細的數學證明可以看林軒田老師的台大機器學習技法課程


xgboost模型在生成決策樹時是level-wise的,即每一層上的所有節點都會一起分裂,通過max_depth來控制樹的高度從而控制模型的擬合程度。lightgbm模型則是leaf-wise的,每一次分裂會從所有葉子節點中找增益最大的節點來分裂,所以主要通過num-leaves來控制模型的擬合程度。


只用這兩個模型顯然不夠,可以調整不同的參數來獲得許多個側重點不同的xgboost(lgb)模型:不同的深度(葉子數)、不同的損失函數等等。另外,在這個比賽里還用到了CatBoost、sklearn里的一些模型:隨機森林、ExtraTree等。

 

對於語音識別這類用深度學習的比賽而言,模型選擇主要在於神經網絡的結構和不同的輸入。首先可以嘗試不同種類的網絡,比如CNN、LSTM。這里很難說有什么通用的技巧,在這個比賽中,CNN的效果較好,我用的所有6個模型都是以CNN為基礎的。主要用到的結構是VGGNet和SE-ResNet。

 

對於VGGNet,實際上並沒有完全按照論文上的模型,只是參考了思路,整個網絡都使用了同樣大小的卷積核尺寸(33)和最大池化尺寸(22)。SE(Sequeeze-and-Excitation)Block是一個挺新的結構,在2017年提出,核心思想是學習特征權重。主要是通過global average pool以及全連接層來學習feature map的權重,然后作為scale乘到原始feature map上。然后,如下圖所示,將SE Block和ResNet結合。

 

640?wx_fmt=png

SE-ResNet

 

在深度學習中,很多時候難以說清為什么這個網絡結構效果好,只能根據結果來證明。這次的語音識別比賽中,一個比較有用的trick是:為了增加模型的多樣性,在每個模型卷積操作完成后分別對feature map用全局最大池化和全局平均池化,相當於抓住了不同的特征,把一個模型變成了兩個。另外,上文提到的三種特征:原始波形、log-mel頻譜、mfcc特征分別作為輸入,這樣就形成了六個模型。

 

640?wx_fmt=png

architecture

 

調參

 

調參這事很復雜,有很多經驗、方法,實際的比賽中往往還是需要一些玄學。調參最常用的方法就是GridSearch和RandomSearch。GridSearch是給定每個待調參數的幾個選擇,然后排列組合出所有可能性(就像網格一樣),做Cross Validation,然后挑選出最好的那組參數組合。RandomSerach很類似,只是不直接給定參數的有限個取值可能,而是給出一個參數分布,從這個分布中隨機采樣一定個數的取值。


調參的方法理解了,那具體調什么參數呢?Zillow Prize比賽里,主要用的模型是XGBoost和LightGBM。下面列出一些主要用到的參數,更多的還是直接看文檔。

 

XGBoost:

  • booster: gblinear/gbtree 基分類器用線性分類器還是決策樹

  • max_depth: 樹最大深度

  • learning_rate:學習率

  • alpha:L1正則化系數

  • lambda:L2正則化系數

  • subsample: 訓練時使用樣本的比例

 

LightGBM:

  • num_leaves: 葉子節點的個數

  • max_depth:最大深度,控制分裂的深度

  • learning_rate: 學習率

  • objective: 損失函數(mse, huber loss, fair loss等)

  • min_data_in_leaf: 葉子節點必須包含的最少樣本數

  • feature_fraction: 訓練時使用feature的比例

  • bagging_fraction: 訓練時使用樣本的比例

 

調參的時候需要理解這些參數到底是什么意思,如果過擬合了應該增大還是減小某個參數,這樣才能有目的而不是盲目地調參。當然,想要找到最佳的參數很多時候需要一些經驗和運氣。也不需要極致追求最佳參數,大多數情況下找到一組相對不錯的參數就可以了,往往還有別的方法來提升總成績。

 

Zillow Prize比賽中這些單個模型的訓練時間是基本上是分鍾級別的,這樣可以有足夠的時間來進行調參。而語音識別這個比賽里的模型需要在GPU上訓練,一個模型要訓練幾個小時,其實沒有什么時間來仔細的調參,更多的是靠經驗來估計。

 

值得一提的是,語音識別比賽中遇到一個問題,所有模型在訓練集和驗證集上表現都很好,但是在提交的測試集上有15%-20%左右的差距。最后發現是測試集和給出的訓練驗證集樣本分布不同:這個比賽是12個類的分類問題,最終的驗證集上基本是均勻分布的,而給出的訓練集和驗證集上,未知(unknown)類樣本明顯多於其他類,而靜默(silence)類則只有6個音頻。最終構建喂給神經網絡的batch時,需要重新對訓練集采樣。

 

對於unknown和silence這兩個特殊類,他們的比例也可以算是超參數,最后根據Kaggle社區里大神的分享,確定了10%是最佳的。

 

模型融合

 

模型融合在Kaggle比賽中非常重要,同時也是一個很大的話題。這里只記錄一下我應用的兩種比較有效的方式。

 

1、Averaging

 

Averaging是最簡單粗暴也是最好理解的模型融合方式,而且效果還挺好的。實際上就是加權平均,小學生也會計算。雖然簡單,但是非常有效。如果模型的多樣性足夠,比如有的模型擅長從稅收角度預測房價,有的模型擅長從房間數量來預測房價,把這些模型平均后,取長補短,就能獲得一個更准確泛化能力更強的模型。

 

每個模型的權重怎么算?一般是根據單個模型的表現好壞來決定,可以看測試集上的表現,Kaggle比賽里可以看LB Score,但是也不能完全看Public LB,這樣就過擬合了。Zillow Prize比賽里我們的Public LB排到了前2%,但是最終所有測試集公布后還是回到了5%。

 

2、Stacking


Stacking應該是目前各類競賽中最好用的模型融合方法了。看下面這張流傳很廣的圖,其實Stacking並不難理解。

 

640?wx_fmt=png

Stacking

 

Stacking的核心思想是把第一層模型的結果作為第二層模型的特征,然后訓練第二層模型得到最終結果。以5-fold stacking為例,將訓練集隨機分成5份,分別用其中4份作訓練,來預測剩下的1份,同時也預測所有的測試集。這樣,一個模型訓練了五次,對訓練集的預測拼起來,正好每一個訓練集的樣本都有一個預測值。對測試集的每個樣本,則有5個預測值,求平均值作為測試集的預測值。這樣,訓練集和測試集都有一個預測值,作為第二層模型的特征。

 

另外,在語音識別比賽中還學到了一種類似Stacking的巧妙模型融合方法。CNN模型在所有卷積池化操作完成得到feature后,先不做全連接,把各個模型的feature全部拼接在一起,然后作為一個全連接神經網絡的輸入,相當於stacking中的第二層模型。

 

總結

 

Kaggle比賽對於關注數據科學的人來說肯定不陌生,參加一次比賽可以在實踐中學習,遠勝於看書看視頻。初學者可以參考這篇文章,用經典的泰坦尼克號之災先練練手。很多知識只有實踐過才能真正理解。Kaggle社區非常活躍,有許多大神會分享自己的思路甚至是代碼,一起討論一起學習會有巨大的進步。比賽成績很有用,但更重要的是通過比賽學到東西!

 


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM