最近參加了兩場(chǎng)Kaggle比賽,收獲頗多,一直想寫篇文章總結(jié)一下推汽。接觸Kaggle到現(xiàn)在不到一年鸣峭,比賽成績(jī)一個(gè)銀牌(5%)一個(gè)銅牌(9%),勉強(qiáng)算入門了滤蝠,跟大神們還有很大的距離义郑。新學(xué)期準(zhǔn)備找實(shí)習(xí)面試姆蘸,整理一下項(xiàng)目經(jīng)驗(yàn)怨喘,于是動(dòng)筆總結(jié)總結(jié)參加Kaggle比賽的個(gè)人心得體會(huì)和技巧厅贪。
先放一張成績(jī)圖和Kaggle個(gè)人主頁(yè)的鏈接
我參加的這兩場(chǎng)比賽灶平,一個(gè)是Zillow Prize:Zillow公司有一個(gè)房?jī)r(jià)預(yù)測(cè)算法Zestimate伺通,根據(jù)房產(chǎn)的特征、歷史成交數(shù)據(jù)和Zestimate預(yù)測(cè)值之間的logerror(這里有點(diǎn)繞)逢享,來預(yù)測(cè)實(shí)際成交價(jià)和Zestimate預(yù)測(cè)值之間的logerror罐监。另一個(gè)是TensorFlow Speech Recoginition Challenge:識(shí)別長(zhǎng)度為1秒的英文語(yǔ)音指令,并且分為12個(gè)類瞒爬,包括10個(gè)指令(yes, no, up, down, left, right, on, off, stop, go)以及未知(unknown)和靜默(silence)弓柱。
這兩個(gè)比賽,剛好屬于Kaggle社區(qū)中兩個(gè)不同類別侧但。Zillow Prize給定了60個(gè)房產(chǎn)的特征矢空,數(shù)據(jù)量不是特別大并且有明確的特征,適合xgboost禀横、lgb這樣的樹模型屁药,對(duì)機(jī)器的要求不高。而語(yǔ)音識(shí)別這個(gè)比賽則相反柏锄,原始數(shù)據(jù)是wav文件酿箭,實(shí)際上相當(dāng)于對(duì)波形圖進(jìn)行分類立莉,不可能手動(dòng)選特征,因此這個(gè)比賽適用深度學(xué)習(xí)的各種模型七问。并且想要取得好成績(jī)蜓耻,需要使用復(fù)雜的模型,CPU就不夠用了械巡,需要一塊不錯(cuò)的顯卡(我用的是隊(duì)友的GTX 1070ti)刹淌。
兩場(chǎng)比賽下來,自己總結(jié)了一些kaggle比賽的基本流程:
- 特征工程
- 模型選擇
- 調(diào)參
- 模型融合
特征工程
特征工程是Kaggle比賽的重中之重讥耗,尤其是對(duì)于房?jī)r(jià)預(yù)測(cè)這類使用樹模型的比賽有勾。模型大同小異,基本是由GBDT模型演化而來古程,而且主要用XGBoost蔼卡、LightGBM等幾種開源框架。所以挣磨,模型大家都差不多雇逞,特征就是關(guān)鍵了。
每個(gè)比賽都有獨(dú)特的背景茁裙,想要發(fā)現(xiàn)甚至是自己創(chuàng)造出重要的特征塘砸,往往需要專業(yè)的領(lǐng)域知識(shí),比如Zillow這個(gè)比賽要預(yù)測(cè)美國(guó)的房?jī)r(jià)晤锥,原始特征有臥室數(shù)量掉蔬、面積,稅收等等矾瘾。想要自己通過原始特征組合女轿,創(chuàng)造出一個(gè)“magic feature”就需要了解美國(guó)的房地產(chǎn)業(yè)。所以壕翩,選擇一個(gè)自己熟悉領(lǐng)域的比賽蛉迹,會(huì)比較有優(yōu)勢(shì)。
比賽背景千變?nèi)f化戈泼,從數(shù)據(jù)科學(xué)的角度婿禽,還有許多通用的方法來做特征工程。這里列舉一些這個(gè)比賽里用到的方法:
- 基礎(chǔ)預(yù)處理:對(duì)category類型的數(shù)據(jù)OneHot編碼大猛;數(shù)值類型的數(shù)據(jù)歸一化(但是這里用到的大多數(shù)模型都是基于決策樹的扭倾,所以不需要)
- 缺失值處理:實(shí)際數(shù)據(jù)集中有許多數(shù)據(jù)是缺失的,考慮列出每個(gè)特征的缺失比例挽绩,比例過大的直接舍棄膛壹,否則想辦法填充。這個(gè)比例沒有什么定式,舍棄特征會(huì)丟掉有用信息模聋,填充會(huì)引入噪聲肩民,具體怎么操作要看模型實(shí)際的表現(xiàn)。填充的話链方,基礎(chǔ)的是用均值持痰、中位數(shù)等填充,更準(zhǔn)確的方法是用算法擬合祟蚀,還可以直接把缺失視為一種特殊的值(這個(gè)比賽中的許多模型就是用-1填充)工窍。對(duì)于樹模型來說,數(shù)據(jù)缺失并不影響樹的生成前酿,所以xgboost會(huì)在生成樹的同時(shí)患雏,根據(jù)training loss自動(dòng)學(xué)會(huì)將遇到缺失值時(shí)分裂到左子樹還是右子樹。作者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.
-
outlier: 由于各種原因罢维,往往有一些樣本的誤差特別大淹仑,把這些樣本加入模型會(huì)引入很大的噪聲,就像很多打分的比賽會(huì)去掉最高分和最低分之后再取平均值肺孵。這個(gè)比賽中去掉這樣大誤差的outlier能帶來很大的提升匀借。
下圖是所有樣本的logerror值,可以看到絕大部分都在0附近悬槽,去掉兩端logerror急劇上升的樣本怀吻,能讓模型更穩(wěn)定瞬浓。
outsider 相關(guān)性分析:特征之間并不是完全獨(dú)立的初婆,這時(shí)候可以計(jì)算correlation coefficient來確定特征之間的兩兩關(guān)系。還可以計(jì)算每個(gè)特征和目標(biāo)值(這里是logerror)之間的相關(guān)性猿棉,絕對(duì)值越大說明這個(gè)特征的作用越大磅叛。
模型權(quán)重分析:現(xiàn)在大多數(shù)模型在訓(xùn)練完成后都會(huì)給出獲取特征權(quán)重的接口,這時(shí)的權(quán)重是直接反映了一個(gè)特征在這個(gè)模型中的作用萨赁。這是判斷一個(gè)特征是否有用的重要方法弊琴。例如,原始特征有臥室數(shù)量和衛(wèi)生間數(shù)量杖爽,我們自己創(chuàng)造了一個(gè)特征房間總數(shù)(臥室數(shù)量+衛(wèi)生間數(shù)量)敲董。這時(shí)可以用這種方法判斷這個(gè)新特征是否有效。
特征工程在實(shí)際應(yīng)用中非常有挑戰(zhàn)性慰安,還有許多方法腋寨,上述只是一些皮毛。Zillow比賽里我嘗試了許多新特征化焕,但最終都沒有采用萄窜。
而對(duì)于語(yǔ)音識(shí)別比賽來說,特征工程就非常有限了。在語(yǔ)音識(shí)別領(lǐng)域廣泛使用的特征是log-mel頻譜和mfcc特征查刻,沒有必要自己再做特征工程键兜。而現(xiàn)在火熱的端到端(end-to-end)語(yǔ)音識(shí)別優(yōu)點(diǎn)就是省去特征提取,直接使用原始波形作為神經(jīng)網(wǎng)絡(luò)的輸入穗泵。
模型選擇
Kaggle比賽很重要的一點(diǎn)是普气,不可能只使用一個(gè)單一模型。在許多比賽的第一名公布的方案里佃延,往往有十幾個(gè)甚至幾十個(gè)不同的模型棋电。模型融合(ensemble)實(shí)在是太重要了,模型融合的方法下文再講苇侵,但是在選擇模型的時(shí)候就要考慮到如何讓這些模型在融合后效果更好赶盔。
不管用什么方法融合,想要模型融合之后效果好榆浓,模型之間要有多樣性于未。換句話說,模型之間越不相似陡鹃,模型融合的效果越好烘浦。
對(duì)于Zillow這樣給定特征,數(shù)據(jù)不是圖像音頻的比賽萍鲸,主要選用樹模型闷叉。這類Kaggle比賽,首選肯定是XGBoost和LightGBM脊阴。這兩個(gè)模型都是由梯度提升樹(GBDT)演化而來的握侧。簡(jiǎn)而言之,就是通過梯度提升(Gradient Boost)算法訓(xùn)練許多決策樹及其對(duì)應(yīng)的權(quán)重嘿期,然后投票得到最終的結(jié)果品擎。詳細(xì)的數(shù)學(xué)證明可以看林軒田老師的臺(tái)大機(jī)器學(xué)習(xí)技法課程
xgboost模型在生成決策樹時(shí)是level-wise的,即每一層上的所有節(jié)點(diǎn)都會(huì)一起分裂备徐,通過max_depth來控制樹的高度從而控制模型的擬合程度萄传。lightgbm模型則是leaf-wise的,每一次分裂會(huì)從所有葉子節(jié)點(diǎn)中找增益最大的節(jié)點(diǎn)來分裂蜜猾,所以主要通過num-leaves來控制模型的擬合程度秀菱。
只用這兩個(gè)模型顯然不夠,可以調(diào)整不同的參數(shù)來獲得許多個(gè)側(cè)重點(diǎn)不同的xgboost(lgb)模型:不同的深度(葉子數(shù))蹭睡、不同的損失函數(shù)等等衍菱。另外,在這個(gè)比賽里還用到了CatBoost棠笑、sklearn里的一些模型:隨機(jī)森林梦碗、ExtraTree等。
對(duì)于語(yǔ)音識(shí)別這類用深度學(xué)習(xí)的比賽而言,模型選擇主要在于神經(jīng)網(wǎng)絡(luò)的結(jié)構(gòu)和不同的輸入洪规。首先可以嘗試不同種類的網(wǎng)絡(luò)印屁,比如CNN、LSTM斩例。這里很難說有什么通用的技巧雄人,在這個(gè)比賽中,CNN的效果較好念赶,我用的所有6個(gè)模型都是以CNN為基礎(chǔ)的础钠。主要用到的結(jié)構(gòu)是VGGNet和SE-ResNet。對(duì)于VGGNet叉谜,實(shí)際上并沒有完全按照論文上的模型旗吁,只是參考了思路,整個(gè)網(wǎng)絡(luò)都使用了同樣大小的卷積核尺寸(33)和最大池化尺寸(22)停局。SE(Sequeeze-and-Excitation)Block是一個(gè)挺新的結(jié)構(gòu)很钓,在2017年提出,核心思想是學(xué)習(xí)特征權(quán)重董栽。主要是通過global average pool以及全連接層來學(xué)習(xí)feature map的權(quán)重码倦,然后作為scale乘到原始feature map上。然后锭碳,如下圖所示袁稽,將SE Block和ResNet結(jié)合。
在深度學(xué)習(xí)中擒抛,很多時(shí)候難以說清為什么這個(gè)網(wǎng)絡(luò)結(jié)構(gòu)效果好推汽,只能根據(jù)結(jié)果來證明。這次的語(yǔ)音識(shí)別比賽中闻葵,一個(gè)比較有用的trick是:為了增加模型的多樣性民泵,在每個(gè)模型卷積操作完成后分別對(duì)feature map用全局最大池化和全局平均池化,相當(dāng)于抓住了不同的特征槽畔,把一個(gè)模型變成了兩個(gè)。另外胁编,上文提到的三種特征:原始波形厢钧、log-mel頻譜、mfcc特征分別作為輸入嬉橙,這樣就形成了六個(gè)模型早直。
調(diào)參
調(diào)參這事很復(fù)雜,有很多經(jīng)驗(yàn)市框、方法霞扬,實(shí)際的比賽中往往還是需要一些玄學(xué)。調(diào)參最常用的方法就是GridSearch和RandomSearch。GridSearch是給定每個(gè)待調(diào)參數(shù)的幾個(gè)選擇喻圃,然后排列組合出所有可能性(就像網(wǎng)格一樣)萤彩,做Cross Validation,然后挑選出最好的那組參數(shù)組合斧拍。RandomSerach很類似雀扶,只是不直接給定參數(shù)的有限個(gè)取值可能,而是給出一個(gè)參數(shù)分布肆汹,從這個(gè)分布中隨機(jī)采樣一定個(gè)數(shù)的取值愚墓。
調(diào)參的方法理解了,那具體調(diào)什么參數(shù)呢昂勉?Zillow Prize比賽里浪册,主要用的模型是XGBoost和LightGBM。下面列出一些主要用到的參數(shù)岗照,更多的還是直接看文檔议经。
XGBoost:
- booster: gblinear/gbtree 基分類器用線性分類器還是決策樹
- max_depth: 樹最大深度
- learning_rate:學(xué)習(xí)率
- alpha:L1正則化系數(shù)
- lambda:L2正則化系數(shù)
- subsample: 訓(xùn)練時(shí)使用樣本的比例
LightGBM:
- num_leaves: 葉子節(jié)點(diǎn)的個(gè)數(shù)
- max_depth:最大深度,控制分裂的深度
- learning_rate: 學(xué)習(xí)率
- objective: 損失函數(shù)(mse, huber loss, fair loss等)
- min_data_in_leaf: 葉子節(jié)點(diǎn)必須包含的最少樣本數(shù)
- feature_fraction: 訓(xùn)練時(shí)使用feature的比例
- bagging_fraction: 訓(xùn)練時(shí)使用樣本的比例
調(diào)參的時(shí)候需要理解這些參數(shù)到底是什么意思谴返,如果過擬合了應(yīng)該增大還是減小某個(gè)參數(shù)煞肾,這樣才能有目的而不是盲目地調(diào)參。當(dāng)然嗓袱,想要找到最佳的參數(shù)很多時(shí)候需要一些經(jīng)驗(yàn)和運(yùn)氣籍救。也不需要極致追求最佳參數(shù),大多數(shù)情況下找到一組相對(duì)不錯(cuò)的參數(shù)就可以了渠抹,往往還有別的方法來提升總成績(jī)蝙昙。
Zillow Prize比賽中這些單個(gè)模型的訓(xùn)練時(shí)間是基本上是分鐘級(jí)別的,這樣可以有足夠的時(shí)間來進(jìn)行調(diào)參梧却。而語(yǔ)音識(shí)別這個(gè)比賽里的模型需要在GPU上訓(xùn)練奇颠,一個(gè)模型要訓(xùn)練幾個(gè)小時(shí),其實(shí)沒有什么時(shí)間來仔細(xì)的調(diào)參放航,更多的是靠經(jīng)驗(yàn)來估計(jì)烈拒。
值得一提的是,語(yǔ)音識(shí)別比賽中遇到一個(gè)問題广鳍,所有模型在訓(xùn)練集和驗(yàn)證集上表現(xiàn)都很好荆几,但是在提交的測(cè)試集上有15%-20%左右的差距。最后發(fā)現(xiàn)是測(cè)試集和給出的訓(xùn)練驗(yàn)證集樣本分布不同:這個(gè)比賽是12個(gè)類的分類問題赊时,最終的驗(yàn)證集上基本是均勻分布的吨铸,而給出的訓(xùn)練集和驗(yàn)證集上,未知(unknown)類樣本明顯多于其他類祖秒,而靜默(silence)類則只有6個(gè)音頻诞吱。最終構(gòu)建喂給神經(jīng)網(wǎng)絡(luò)的batch時(shí)舟奠,需要重新對(duì)訓(xùn)練集采樣。對(duì)于unknown和silence這兩個(gè)特殊類房维,他們的比例也可以算是超參數(shù)沼瘫,最后根據(jù)Kaggle社區(qū)里大神的分享,確定了10%是最佳的握巢。
模型融合
模型融合在Kaggle比賽中非常重要晕鹊,同時(shí)也是一個(gè)很大的話題。這里只記錄一下我應(yīng)用的兩種比較有效的方式暴浦。
- Averaging
Averaging是最簡(jiǎn)單粗暴也是最好理解的模型融合方式溅话,而且效果還挺好的。實(shí)際上就是加權(quán)平均歌焦,小學(xué)生也會(huì)計(jì)算飞几。雖然簡(jiǎn)單,但是非常有效独撇。如果模型的多樣性足夠屑墨,比如有的模型擅長(zhǎng)從稅收角度預(yù)測(cè)房?jī)r(jià),有的模型擅長(zhǎng)從房間數(shù)量來預(yù)測(cè)房?jī)r(jià)纷铣,把這些模型平均后卵史,取長(zhǎng)補(bǔ)短,就能獲得一個(gè)更準(zhǔn)確泛化能力更強(qiáng)的模型搜立。
每個(gè)模型的權(quán)重怎么算以躯?一般是根據(jù)單個(gè)模型的表現(xiàn)好壞來決定,可以看測(cè)試集上的表現(xiàn)啄踊,Kaggle比賽里可以看LB Score忧设,但是也不能完全看Public LB,這樣就過擬合了颠通。Zillow Prize比賽里我們的Public LB排到了前2%址晕,但是最終所有測(cè)試集公布后還是回到了5%。 -
Stacking
Stacking應(yīng)該是目前各類競(jìng)賽中最好用的模型融合方法了顿锰〗骼看下面這張流傳很廣的圖,其實(shí)Stacking并不難理解撵儿。
Stacking
Stacking的核心思想是把第一層模型的結(jié)果作為第二層模型的特征乘客,然后訓(xùn)練第二層模型得到最終結(jié)果。以5-fold stacking為例淀歇,將訓(xùn)練集隨機(jī)分成5份,分別用其中4份作訓(xùn)練匈织,來預(yù)測(cè)剩下的1份浪默,同時(shí)也預(yù)測(cè)所有的測(cè)試集牡直。這樣,一個(gè)模型訓(xùn)練了五次纳决,對(duì)訓(xùn)練集的預(yù)測(cè)拼起來碰逸,正好每一個(gè)訓(xùn)練集的樣本都有一個(gè)預(yù)測(cè)值。對(duì)測(cè)試集的每個(gè)樣本阔加,則有5個(gè)預(yù)測(cè)值饵史,求平均值作為測(cè)試集的預(yù)測(cè)值。這樣胜榔,訓(xùn)練集和測(cè)試集都有一個(gè)預(yù)測(cè)值胳喷,作為第二層模型的特征。
另外夭织,在語(yǔ)音識(shí)別比賽中還學(xué)到了一種類似Stacking的巧妙模型融合方法吭露。CNN模型在所有卷積池化操作完成得到feature后,先不做全連接尊惰,把各個(gè)模型的feature全部拼接在一起讲竿,然后作為一個(gè)全連接神經(jīng)網(wǎng)絡(luò)的輸入,相當(dāng)于stacking中的第二層模型弄屡。
總結(jié)
Kaggle比賽對(duì)于關(guān)注數(shù)據(jù)科學(xué)的人來說肯定不陌生题禀,參加一次比賽可以在實(shí)踐中學(xué)習(xí),遠(yuǎn)勝于看書看視頻膀捷。初學(xué)者可以參考這篇文章迈嘹,用經(jīng)典的泰坦尼克號(hào)之災(zāi)先練練手。很多知識(shí)只有實(shí)踐過才能真正理解担孔。Kaggle社區(qū)非辰牵活躍,有許多大神會(huì)分享自己的思路甚至是代碼糕篇,一起討論一起學(xué)習(xí)會(huì)有巨大的進(jìn)步啄育。比賽成績(jī)很有用,但更重要的是通過比賽學(xué)到東西拌消!