丁香五月天婷婷久久婷婷色综合91|国产传媒自偷自拍|久久影院亚洲精品|国产欧美VA天堂国产美女自慰视屏|免费黄色av网站|婷婷丁香五月激情四射|日韩AV一区二区中文字幕在线观看|亚洲欧美日本性爱|日日噜噜噜夜夜噜噜噜|中文Av日韩一区二区

您正在使用IE低版瀏覽器,為了您的雷峰網(wǎng)賬號(hào)安全和更好的產(chǎn)品體驗(yàn),強(qiáng)烈建議使用更快更安全的瀏覽器
此為臨時(shí)鏈接,僅用于文章預(yù)覽,將在時(shí)失效
人工智能 正文
發(fā)私信給AI研習(xí)社
發(fā)送

0

TOP5%Kaggler:如何在 Kaggle 首戰(zhàn)中進(jìn)入前 10% | 干貨

本文作者: AI研習(xí)社 2017-03-17 19:31
導(dǎo)語(yǔ):作者第一次參加Kaggle,在 2125 個(gè)參賽隊(duì)伍中排名第 98 位(~ 5%),本文為他根據(jù)自己第一次比賽的經(jīng)驗(yàn)總結(jié),給新手們提供一些參考

雷鋒網(wǎng)按:本文作者章凌豪,復(fù)旦大學(xué)計(jì)算機(jī)科學(xué)專(zhuān)業(yè)。有興趣的同學(xué)可以移步他的個(gè)人主頁(yè):Linghao Zhang

Introduction

Kaggle 是目前最大的 Data Scientist 聚集地。很多公司會(huì)拿出自家的數(shù)據(jù)并提供獎(jiǎng)金,在 Kaggle 上組織數(shù)據(jù)競(jìng)賽。我最近完成了第一次比賽,在 2125 個(gè)參賽隊(duì)伍中排名第 98 位(~ 5%)。因?yàn)槭堑谝淮螀①?,所以?duì)這個(gè)成績(jī)我已經(jīng)很滿(mǎn)意了。在 Kaggle 上一次比賽的結(jié)果除了排名以外,還會(huì)顯示的就是 Prize Winner,10% 或是 25% 這三檔。所以剛剛接觸 Kaggle 的人很多都會(huì)以 25% 或是 10% 為目標(biāo)。在本文中,我試圖根據(jù)自己第一次比賽的經(jīng)驗(yàn)和從其他 Kaggler 那里學(xué)到的知識(shí),為剛剛聽(tīng)說(shuō) Kaggle 想要參賽的新手提供一些切實(shí)可行的沖刺 10% 的指導(dǎo)。

本文的英文版見(jiàn)這里。

TOP5%Kaggler:如何在 Kaggle 首戰(zhàn)中進(jìn)入前 10% | 干貨

Kaggler 絕大多數(shù)都是用 Python 和 R 這兩門(mén)語(yǔ)言的。因?yàn)槲抑饕褂?Python,所以本文提到的例子都會(huì)根據(jù) Python 來(lái)。不過(guò) R 的用戶(hù)應(yīng)該也能不費(fèi)力地了解到工具背后的思想。

首先簡(jiǎn)單介紹一些關(guān)于 Kaggle 比賽的知識(shí):

  • 不同比賽有不同的任務(wù),分類(lèi)、回歸、推薦、排序等。比賽開(kāi)始后訓(xùn)練集和測(cè)試集就會(huì)開(kāi)放下載。

  • 比賽通常持續(xù) 2 ~ 3 個(gè)月,每個(gè)隊(duì)伍每天可以提交的次數(shù)有限,通常為 5 次。

  • 比賽結(jié)束前一周是一個(gè) Deadline,在這之后不能再組隊(duì),也不能再新加入比賽。所以想要參加比賽請(qǐng)務(wù)必在這一 Deadline 之前有過(guò)至少一次有效的提交。

  • 一般情況下在提交后會(huì)立刻得到得分的反饋。不同比賽會(huì)采取不同的評(píng)分基準(zhǔn),可以在分?jǐn)?shù)欄最上方看到使用的評(píng)分方法。

  • 反饋的分?jǐn)?shù)是基于測(cè)試集的一部分計(jì)算的,剩下的另一部分會(huì)被用于計(jì)算最終的結(jié)果。所以最后排名會(huì)變動(dòng)。

  • LB 指的就是在 Leaderboard 得到的分?jǐn)?shù),由上,有 Public LB 和 Private LB 之分。

  • 自己做的 Cross Validation 得到的分?jǐn)?shù)一般稱(chēng)為 CV 或是 Local CV。一般來(lái)說(shuō) CV 的結(jié)果比 LB 要可靠。

  • 新手可以從比賽的 Forum 和 Scripts 中找到許多有用的經(jīng)驗(yàn)和洞見(jiàn)。不要吝嗇提問(wèn),Kaggler 都很熱情。

那么就開(kāi)始吧!

P.S. 本文假設(shè)讀者對(duì) Machine Learning 的基本概念和常見(jiàn)模型已經(jīng)有一定了解。 Enjoy Reading!

General Approach

在這一節(jié)中我會(huì)講述一次 Kaggle 比賽的大致流程。

Data Exploration

在這一步要做的基本就是 EDA (Exploratory Data Analysis),也就是對(duì)數(shù)據(jù)進(jìn)行探索性的分析,從而為之后的處理和建模提供必要的結(jié)論。

通常我們會(huì)用 pandas 來(lái)載入數(shù)據(jù),并做一些簡(jiǎn)單的可視化來(lái)理解數(shù)據(jù)。

Visualization

通常來(lái)說(shuō) matplotlib 和 seaborn 提供的繪圖功能就可以滿(mǎn)足需求了。

比較常用的圖表有:

  • 查看目標(biāo)變量的分布。當(dāng)分布不平衡時(shí),根據(jù)評(píng)分標(biāo)準(zhǔn)和具體模型的使用不同,可能會(huì)嚴(yán)重影響性能。

  • 對(duì) Numerical Variable,可以用 Box Plot 來(lái)直觀地查看它的分布。

  • 對(duì)于坐標(biāo)類(lèi)數(shù)據(jù),可以用 Scatter Plot 來(lái)查看它們的分布趨勢(shì)和是否有離群點(diǎn)的存在。

  • 對(duì)于分類(lèi)問(wèn)題,將數(shù)據(jù)根據(jù) Label 的不同著不同的顏色繪制出來(lái),這對(duì) Feature 的構(gòu)造很有幫助。

  • 繪制變量之間兩兩的分布和相關(guān)度圖表。

這里有一個(gè)在著名的 Iris 數(shù)據(jù)集上做了一系列可視化的例子,非常有啟發(fā)性。

Statistical Tests

我們可以對(duì)數(shù)據(jù)進(jìn)行一些統(tǒng)計(jì)上的測(cè)試來(lái)驗(yàn)證一些假設(shè)的顯著性。雖然大部分情況下靠可視化就能得到比較明確的結(jié)論,但有一些定量結(jié)果總是更理想的。不過(guò),在實(shí)際數(shù)據(jù)中經(jīng)常會(huì)遇到非 i.i.d. 的分布。所以要注意測(cè)試類(lèi)型的的選擇和對(duì)顯著性的解釋。

在某些比賽中,由于數(shù)據(jù)分布比較奇葩或是噪聲過(guò)強(qiáng),Public LB 的分?jǐn)?shù)可能會(huì)跟Local CV 的結(jié)果相去甚遠(yuǎn)??梢愿鶕?jù)一些統(tǒng)計(jì)測(cè)試的結(jié)果來(lái)粗略地建立一個(gè)閾值,用來(lái)衡量一次分?jǐn)?shù)的提高究竟是實(shí)質(zhì)的提高還是由于數(shù)據(jù)的隨機(jī)性導(dǎo)致的。

Data Preprocessing

大部分情況下,在構(gòu)造 Feature 之前,我們需要對(duì)比賽提供的數(shù)據(jù)集進(jìn)行一些處理。通常的步驟有:

  • 有時(shí)數(shù)據(jù)會(huì)分散在幾個(gè)不同的文件中,需要 Join 起來(lái)。

  • 處理 Missing Data。

  • 處理 Outlier

  • 必要時(shí)轉(zhuǎn)換某些 Categorical Variable 的表示方式。

  • 有些 Float 變量可能是從未知的 Int 變量轉(zhuǎn)換得到的,這個(gè)過(guò)程中發(fā)生精度損失會(huì)在數(shù)據(jù)中產(chǎn)生不必要的 Noise,即兩個(gè)數(shù)值原本是相同的卻在小數(shù)點(diǎn)后某一位開(kāi)始有不同。這對(duì) Model 可能會(huì)產(chǎn)生很負(fù)面的影響,需要設(shè)法去除或者減弱 Noise。

這一部分的處理策略多半依賴(lài)于在前一步中探索數(shù)據(jù)集所得到的結(jié)論以及創(chuàng)建的可視化圖表。在實(shí)踐中,我建議使用 iPython Notebook 進(jìn)行對(duì)數(shù)據(jù)的操作,并熟練掌握常用的 pandas 函數(shù)。這樣做的好處是可以隨時(shí)得到結(jié)果的反饋和進(jìn)行修改,也方便跟其他人進(jìn)行交流(在 Data Science 中 Reproducible Results 是很重要的)。

下面給兩個(gè)例子。

Outlier

TOP5%Kaggler:如何在 Kaggle 首戰(zhàn)中進(jìn)入前 10% | 干貨

這是經(jīng)過(guò) Scaling 的坐標(biāo)數(shù)據(jù)??梢园l(fā)現(xiàn)右上角存在一些離群點(diǎn),去除以后分布比較正常。

Dummy Variables

對(duì)于 Categorical Variable,常用的做法就是 One-hot encoding。即對(duì)這一變量創(chuàng)建一組新的偽變量,對(duì)應(yīng)其所有可能的取值。這些變量中只有這條數(shù)據(jù)對(duì)應(yīng)的取值為 1,其他都為 0。

如下,將原本有 7 種可能取值的 Weekdays 變量轉(zhuǎn)換成 7 個(gè) Dummy Variables。

TOP5%Kaggler:如何在 Kaggle 首戰(zhàn)中進(jìn)入前 10% | 干貨

要注意,當(dāng)變量可能取值的范圍很大(比如一共有成百上千類(lèi))時(shí),這種簡(jiǎn)單的方法就不太適用了。這時(shí)沒(méi)有有一個(gè)普適的方法,但我會(huì)在下一小節(jié)描述其中一種。

Feature Engineering

有人總結(jié) Kaggle 比賽是 “Feature 為主,調(diào)參和 Ensemble 為輔”,我覺(jué)得很有道理。Feature Engineering 能做到什么程度,取決于對(duì)數(shù)據(jù)領(lǐng)域的了解程度。比如在數(shù)據(jù)包含大量文本的比賽中,常用的 NLP 特征就是必須的。怎么構(gòu)造有用的 Feature,是一個(gè)不斷學(xué)習(xí)和提高的過(guò)程。

一般來(lái)說(shuō),當(dāng)一個(gè)變量從直覺(jué)上來(lái)說(shuō)對(duì)所要完成的目標(biāo)有幫助,就可以將其作為 Feature。至于它是否有效,最簡(jiǎn)單的方式就是通過(guò)圖表來(lái)直觀感受。比如:

TOP5%Kaggler:如何在 Kaggle 首戰(zhàn)中進(jìn)入前 10% | 干貨

Feature Selection

總的來(lái)說(shuō),我們應(yīng)該生成盡量多的 Feature,相信 Model 能夠挑出最有用的 Feature。但有時(shí)先做一遍 Feature Selection 也能帶來(lái)一些好處:

Feature 越少,訓(xùn)練越快。

有些 Feature 之間可能存在線性關(guān)系,影響 Model 的性能。

通過(guò)挑選出最重要的 Feature,可以將它們之間進(jìn)行各種運(yùn)算和操作的結(jié)果作為新的 Feature,可能帶來(lái)意外的提高。

Feature Selection 最實(shí)用的方法也就是看 Random Forest 訓(xùn)練完以后得到的Feature Importance 了。其他有一些更復(fù)雜的算法在理論上更加 Robust,但是缺乏實(shí)用高效的實(shí)現(xiàn),比如這個(gè)。從原理上來(lái)講,增加 Random Forest 中樹(shù)的數(shù)量可以在一定程度上加強(qiáng)其對(duì)于 Noisy Data 的 Robustness。

看 Feature Importance 對(duì)于某些數(shù)據(jù)經(jīng)過(guò)脫敏處理的比賽尤其重要。這可以免得你浪費(fèi)大把時(shí)間在琢磨一個(gè)不重要的變量的意義上。

Feature Encoding

這里用一個(gè)例子來(lái)說(shuō)明在一些情況下 Raw Feature 可能需要經(jīng)過(guò)一些轉(zhuǎn)換才能起到比較好的效果。

假設(shè)有一個(gè) Categorical Variable 一共有幾萬(wàn)個(gè)取值可能,那么創(chuàng)建 Dummy Variables 的方法就不可行了。這時(shí)一個(gè)比較好的方法是根據(jù) Feature Importance 或是這些取值本身在數(shù)據(jù)中的出現(xiàn)頻率,為最重要(比如說(shuō)前 95% 的 Importance)那些取值(有很大可能只有幾個(gè)或是十幾個(gè))創(chuàng)建 Dummy Variables,而所有其他取值都?xì)w到一個(gè)“其他”類(lèi)里面。

Model Selection

準(zhǔn)備好 Feature 以后,就可以開(kāi)始選用一些常見(jiàn)的模型進(jìn)行訓(xùn)練了。Kaggle 上最常用的模型基本都是基于樹(shù)的模型:

  • Gradient Boosting

  • Random Forest

  • Extra Randomized Trees

以下模型往往在性能上稍遜一籌,但是很適合作為 Ensemble 的 Base Model。這一點(diǎn)之后再詳細(xì)解釋。(當(dāng)然,在跟圖像有關(guān)的比賽中神經(jīng)網(wǎng)絡(luò)的重要性還是不能小覷的。)

  • SVM

  • Linear Regression

  • Logistic Regression

  • Neural Networks

以上這些模型基本都可以通過(guò) sklearn 來(lái)使用。

當(dāng)然,這里不能不提一下 Xgboost。Gradient Boosting 本身優(yōu)秀的性能加上Xgboost 高效的實(shí)現(xiàn),使得它在 Kaggle 上廣為使用。幾乎每場(chǎng)比賽的獲獎(jiǎng)?wù)叨紩?huì)用 Xgboost 作為最終 Model 的重要組成部分。在實(shí)戰(zhàn)中,我們往往會(huì)以 Xgboost 為主來(lái)建立我們的模型并且驗(yàn)證 Feature 的有效性。順帶一提,在 Windows 上安裝 Xgboost 很容易遇到問(wèn)題,目前已知最簡(jiǎn)單、成功率最高的方案可以參考我在這篇帖子中的描述。

Model Training

在訓(xùn)練時(shí),我們主要希望通過(guò)調(diào)整參數(shù)來(lái)得到一個(gè)性能不錯(cuò)的模型。一個(gè)模型往往有很多參數(shù),但其中比較重要的一般不會(huì)太多。比如對(duì) sklearn 的 RandomForestClassifier 來(lái)說(shuō),比較重要的就是隨機(jī)森林中樹(shù)的數(shù)量 n_estimators 以及在訓(xùn)練每棵樹(shù)時(shí)最多選擇的特征數(shù)量 max_features。所以我們需要對(duì)自己使用的模型有足夠的了解,知道每個(gè)參數(shù)對(duì)性能的影響是怎樣的。

通常我們會(huì)通過(guò)一個(gè)叫做 Grid Search 的過(guò)程來(lái)確定一組最佳的參數(shù)。其實(shí)這個(gè)過(guò)程說(shuō)白了就是根據(jù)給定的參數(shù)候選對(duì)所有的組合進(jìn)行暴力搜索。

1  param_grid = {'n_estimators': [300, 500], 'max_features': [10, 12, 14]}

2  model = grid_search.GridSearchCV(estimator=rfr, param_grid=param_grid, n_jobs=1, cv=10, verbose=20, scoring=RMSE)

3  model.fit(X_train, y_train)

順帶一提,Random Forest 一般在 max_features 設(shè)為 Feature 數(shù)量的平方根附近得到最佳結(jié)果。

這里要重點(diǎn)講一下 Xgboost 的調(diào)參。通常認(rèn)為對(duì)它性能影響較大的參數(shù)有:

  • eta:每次迭代完成后更新權(quán)重時(shí)的步長(zhǎng)。越小訓(xùn)練越慢。

  • num_round:總共迭代的次數(shù)。

  • subsample:訓(xùn)練每棵樹(shù)時(shí)用來(lái)訓(xùn)練的數(shù)據(jù)占全部的比例。用于防止 Overfitting。

  • colsample_bytree:訓(xùn)練每棵樹(shù)時(shí)用來(lái)訓(xùn)練的特征的比例,類(lèi)似 RandomForestClassifier 的 max_features。

  • max_depth:每棵樹(shù)的最大深度限制。與 Random Forest 不同,Gradient Boosting 如果不對(duì)深度加以限制,最終是會(huì) Overfit 的。

  • early_stopping_rounds:用于控制在 Out Of Sample 的驗(yàn)證集上連續(xù)多少個(gè)迭代的分?jǐn)?shù)都沒(méi)有提高后就提前終止訓(xùn)練。用于防止 Overfitting。

一般的調(diào)參步驟是:

  1. 將訓(xùn)練數(shù)據(jù)的一部分劃出來(lái)作為驗(yàn)證集。

  2. 先將 eta 設(shè)得比較高(比如 0.1),num_round 設(shè)為 300 ~ 500。

  3. 用 Grid Search 對(duì)其他參數(shù)進(jìn)行搜索

  4. 逐步將 eta 降低,找到最佳值。

  5. 以驗(yàn)證集為 watchlist,用找到的最佳參數(shù)組合重新在訓(xùn)練集上訓(xùn)練。注意觀察算法的輸出,看每次迭代后在驗(yàn)證集上分?jǐn)?shù)的變化情況,從而得到最佳的early_stopping_rounds。

1  X_dtrain, X_deval, y_dtrain, y_deval = cross_validation.train_test_split(X_train, y_train, random_state=1026, test_size=0.3)

2  dtrain = xgb.DMatrix(X_dtrain, y_dtrain)

3  deval = xgb.DMatrix(X_deval, y_deval)

4  watchlist = [(deval, 'eval')]

5  params = {

6                 'booster': 'gbtree',

7                 'objective': 'reg:linear',

8                  'subsample': 0.8,

9                  'colsample_bytree': 0.85,

10                'eta': 0.05,

11                 'max_depth': 7,

12                'seed': 2016,

13               'silent': 0,

14               'eval_metric': 'rmse'

15  }

16  clf = xgb.train(params, dtrain, 500, watchlist, early_stopping_rounds=50)

17  pred = clf.predict(xgb.DMatrix(df_test))

最后要提一點(diǎn),所有具有隨機(jī)性的 Model 一般都會(huì)有一個(gè) seed 或是 random_state 參數(shù)用于控制隨機(jī)種子。得到一個(gè)好的 Model 后,在記錄參數(shù)時(shí)務(wù)必也記錄下這個(gè)值,從而能夠在之后重現(xiàn) Model。

Cross Validation

Cross Validation 是非常重要的一個(gè)環(huán)節(jié)。它讓你知道你的 Model 有沒(méi)有 Overfit,是不是真的能夠 Generalize 到測(cè)試集上。在很多比賽中 Public LB 都會(huì)因?yàn)檫@樣那樣的原因而不可靠。當(dāng)你改進(jìn)了 Feature 或是 Model 得到了一個(gè)更高的 CV 結(jié)果,提交之后得到的 LB 結(jié)果卻變差了,一般認(rèn)為這時(shí)應(yīng)該相信 CV 的結(jié)果。當(dāng)然,最理想的情況是多種不同的 CV 方法得到的結(jié)果和 LB 同時(shí)提高,但這樣的比賽并不是太多。

在數(shù)據(jù)的分布比較隨機(jī)均衡的情況下,5-Fold CV 一般就足夠了。如果不放心,可以提到 10-Fold。但是 Fold 越多訓(xùn)練也就會(huì)越慢,需要根據(jù)實(shí)際情況進(jìn)行取舍。

很多時(shí)候簡(jiǎn)單的 CV 得到的分?jǐn)?shù)會(huì)不大靠譜,Kaggle 上也有很多關(guān)于如何做 CV 的討論。比如這個(gè)。但總的來(lái)說(shuō),靠譜的 CV 方法是 Case By Case 的,需要在實(shí)際比賽中進(jìn)行嘗試和學(xué)習(xí),這里就不再(也不能)敘述了。

Ensemble Generation

Ensemble Learning 是指將多個(gè)不同的 Base Model 組合成一個(gè) Ensemble Model 的方法。它可以同時(shí)降低最終模型的 Bias 和 Variance(證明可以參考這篇論文,我最近在研究類(lèi)似的理論,可能之后會(huì)寫(xiě)新文章詳述),從而在提高分?jǐn)?shù)的同時(shí)又降低 Overfitting 的風(fēng)險(xiǎn)。在現(xiàn)在的 Kaggle 比賽中要不用 Ensemble 就拿到獎(jiǎng)金幾乎是不可能的。

常見(jiàn)的 Ensemble 方法有這么幾種:

  • Bagging:使用訓(xùn)練數(shù)據(jù)的不同隨機(jī)子集來(lái)訓(xùn)練每個(gè) Base Model,最后進(jìn)行每個(gè) Base Model 權(quán)重相同的 Vote。也即 Random Forest 的原理。

  • Boosting:迭代地訓(xùn)練 Base Model,每次根據(jù)上一個(gè)迭代中預(yù)測(cè)錯(cuò)誤的情況修改訓(xùn)練樣本的權(quán)重。也即 Gradient Boosting 的原理。比 Bagging 效果好,但更容易 Overfit。

  • Blending:用不相交的數(shù)據(jù)訓(xùn)練不同的 Base Model,將它們的輸出?。訖?quán))平均。實(shí)現(xiàn)簡(jiǎn)單,但對(duì)訓(xùn)練數(shù)據(jù)利用少了。

  • Stacking:接下來(lái)會(huì)詳細(xì)介紹。

從理論上講,Ensemble 要成功,有兩個(gè)要素:

  • Base Model 之間的相關(guān)性要盡可能的小。這就是為什么非 Tree-based Model 往往表現(xiàn)不是最好但還是要將它們包括在 Ensemble 里面的原因。Ensemble 的 Diversity 越大,最終 Model 的 Bias 就越低。

  • Base Model 之間的性能表現(xiàn)不能差距太大。這其實(shí)是一個(gè) Trade-off,在實(shí)際中很有可能表現(xiàn)相近的 Model 只有寥寥幾個(gè)而且它們之間相關(guān)性還不低。但是實(shí)踐告訴我們即使在這種情況下 Ensemble 還是能大幅提高成績(jī)。

Stacking

相比 Blending,Stacking 能更好地利用訓(xùn)練數(shù)據(jù)。以 5-Fold Stacking 為例,它的基本原理如圖所示:

TOP5%Kaggler:如何在 Kaggle 首戰(zhàn)中進(jìn)入前 10% | 干貨

整個(gè)過(guò)程很像 Cross Validation。首先將訓(xùn)練數(shù)據(jù)分為 5 份,接下來(lái)一共 5 個(gè)迭代,每次迭代時(shí),將 4 份數(shù)據(jù)作為 Training Set 對(duì)每個(gè) Base Model 進(jìn)行訓(xùn)練,然后在剩下一份 Hold-out Set 上進(jìn)行預(yù)測(cè)。同時(shí)也要將其在測(cè)試數(shù)據(jù)上的預(yù)測(cè)保存下來(lái)。這樣,每個(gè) Base Model 在每次迭代時(shí)會(huì)對(duì)訓(xùn)練數(shù)據(jù)的其中 1 份做出預(yù)測(cè),對(duì)測(cè)試數(shù)據(jù)的全部做出預(yù)測(cè)。5 個(gè)迭代都完成以后我們就獲得了一個(gè) #訓(xùn)練數(shù)據(jù)行數(shù) x #Base Model 數(shù)量 的矩陣,這個(gè)矩陣接下來(lái)就作為第二層的 Model 的訓(xùn)練數(shù)據(jù)。當(dāng)?shù)诙拥?Model 訓(xùn)練完以后,將之前保存的 Base Model 對(duì)測(cè)試數(shù)據(jù)的預(yù)測(cè)(因?yàn)槊總€(gè) Base Model 被訓(xùn)練了 5 次,對(duì)測(cè)試數(shù)據(jù)的全體做了 5 次預(yù)測(cè),所以對(duì)這 5 次求一個(gè)平均值,從而得到一個(gè)形狀與第二層訓(xùn)練數(shù)據(jù)相同的矩陣)拿出來(lái)讓它進(jìn)行預(yù)測(cè),就得到最后的輸出。

這里給出我的實(shí)現(xiàn)代碼:

1  class Ensemble(object):

2        def __init__(self, n_folds, stacker, base_models):

3             self.n_folds = n_folds

4             self.stacker = stacker

5            self.base_models = base_models

6      def fit_predict(self, X, y, T):

7           X = np.array(X)

8          y = np.array(y)

9          T = np.array(T)

10        folds = list(KFold(len(y), n_folds=self.n_folds, shuffle=True, random_state=2016))

11       S_train = np.zeros((X.shape[0], len(self.base_models)))

12       S_test = np.zeros((T.shape[0], len(self.base_models)))

13       for i, clf in enumerate(self.base_models):

14      S_test_i = np.zeros((T.shape[0], len(folds)))

15      for j, (train_idx, test_idx) in enumerate(folds):

16           X_train = X[train_idx]

17           y_train = y[train_idx]

18           X_holdout = X[test_idx]

19          # y_holdout = y[test_idx]

20         clf.fit(X_train, y_train)

21         y_pred = clf.predict(X_holdout)[:]

22         S_train[test_idx, i] = y_pred

23         S_test_i[:, j] = clf.predict(T)[:]

24         S_test[:, i] = S_test_i.mean(1)

25     self.stacker.fit(S_train, y)

26     y_pred = self.stacker.predict(S_test)[:]

27    return y_pred

獲獎(jiǎng)選手往往會(huì)使用比這復(fù)雜得多的 Ensemble,會(huì)出現(xiàn)三層、四層甚至五層,不同的層數(shù)之間有各種交互,還有將經(jīng)過(guò)不同的 Preprocessing 和不同的 Feature Engineering 的數(shù)據(jù)用 Ensemble 組合起來(lái)的做法。但對(duì)于新手來(lái)說(shuō),穩(wěn)穩(wěn)當(dāng)當(dāng)?shù)貙?shí)現(xiàn)一個(gè)正確的 5-Fold Stacking 已經(jīng)足夠了。

*Pipeline

可以看出 Kaggle 比賽的 Workflow 還是比較復(fù)雜的。尤其是 Model Selection 和 Ensemble。理想情況下,我們需要搭建一個(gè)高自動(dòng)化的 Pipeline,它可以做到:

  • 模塊化 Feature Transform,只需寫(xiě)很少的代碼就能將新的 Feature 更新到訓(xùn)練集中。

  • 自動(dòng)化 Grid Search,只要預(yù)先設(shè)定好使用的 Model 和參數(shù)的候選,就能自動(dòng)搜索并記錄最佳的 Model。

  • 自動(dòng)化 Ensemble Generation,每個(gè)一段時(shí)間將現(xiàn)有最好的 K 個(gè) Model 拿來(lái)做 Ensemble。

對(duì)新手來(lái)說(shuō),第一點(diǎn)可能意義還不是太大,因?yàn)?Feature 的數(shù)量總是人腦管理的過(guò)來(lái)的;第三點(diǎn)問(wèn)題也不大,因?yàn)橥褪窃谧詈笞鰩状?Ensemble。但是第二點(diǎn)還是很有意義的,手工記錄每個(gè) Model 的表現(xiàn)不僅浪費(fèi)時(shí)間而且容易產(chǎn)生混亂。

Crowdflower Search Results Relevance 的第一名獲得者 Chenglong Chen 將他在比賽中使用的 Pipeline 公開(kāi)了,非常具有參考和借鑒意義。只不過(guò)看懂他的代碼并將其中的邏輯抽離出來(lái)搭建這樣一個(gè)框架,還是比較困難的一件事??赡茉趨⒓舆^(guò)幾次比賽以后專(zhuān)門(mén)抽時(shí)間出來(lái)做會(huì)比較好。

Home Depot Search Relevance

在這一節(jié)中我會(huì)具體分享我在 Home Depot Search Relevance 比賽中是怎么做的,以及比賽結(jié)束后從排名靠前的隊(duì)伍那邊學(xué)到的做法。

首先簡(jiǎn)單介紹這個(gè)比賽。Task 是判斷用戶(hù)搜索的關(guān)鍵詞和網(wǎng)站返回的結(jié)果之間的相關(guān)度有多高。相關(guān)度是由 3 個(gè)人類(lèi)打分取平均得到的,每個(gè)人可能打 1 ~ 3 分,所以這是一個(gè)回歸問(wèn)題。數(shù)據(jù)中包含用戶(hù)的搜索詞,返回的產(chǎn)品的標(biāo)題和介紹,以及產(chǎn)品相關(guān)的一些屬性比如品牌、尺寸、顏色等。使用的評(píng)分基準(zhǔn)是 RMSE。

這個(gè)比賽非常像 Crowdflower Search Results Relevance 那場(chǎng)比賽。不過(guò)那邊用的評(píng)分基準(zhǔn)是 Quadratic Weighted Kappa,把 1 誤判成 4 的懲罰會(huì)比把 1 判成 2 的懲罰大得多,所以在最后 Decode Prediction 的時(shí)候會(huì)更麻煩一點(diǎn)。除此以外那次比賽沒(méi)有提供產(chǎn)品的屬性。

EDA

由于加入比賽比較晚,當(dāng)時(shí)已經(jīng)有相當(dāng)不錯(cuò)的 EDA 了。尤其是這個(gè)。從中我得到的啟發(fā)有:

  • 同一個(gè)搜索詞/產(chǎn)品都出現(xiàn)了多次,數(shù)據(jù)分布顯然不 i.i.d.。

  • 文本之間的相似度很有用。

  • 產(chǎn)品中有相當(dāng)大一部分缺失屬性,要考慮這會(huì)不會(huì)使得從屬性中得到的 Feature 反而難以利用。

  • 產(chǎn)品的 ID 對(duì)預(yù)測(cè)相關(guān)度很有幫助,但是考慮到訓(xùn)練集和測(cè)試集之間的重疊度并不太高,利用它會(huì)不會(huì)導(dǎo)致 Overfitting?

Preprocessing

這次比賽中我的 Preprocessing 和 Feature Engineering 的具體做法都可以在這里看到。我只簡(jiǎn)單總結(jié)一下和指出重要的點(diǎn)。

  1. 利用 Forum 上的 Typo Dictionary 修正搜索詞中的錯(cuò)誤。

  2. 統(tǒng)計(jì)屬性的出現(xiàn)次數(shù),將其中出現(xiàn)次數(shù)多又容易利用的記錄下來(lái)。

  3. 將訓(xùn)練集和測(cè)試集合并,并與產(chǎn)品描述和屬性 Join 起來(lái)。這是考慮到后面有一系列操作,如果不合并的話就要重復(fù)寫(xiě)兩次了。

  4. 對(duì)所有文本能做 Stemming 和 Tokenizing,同時(shí)手工做了一部分格式統(tǒng)一化(比如涉及到數(shù)字和單位的)和同義詞替換。

Feature

  • *Attribute Features

  1. 是否包含某個(gè)特定的屬性(品牌、尺寸、顏色、重量、內(nèi)用/外用、是否有能源之星認(rèn)證等)

  2. 這個(gè)特定的屬性是否匹配

  • Meta Features

  1. 各個(gè)文本域的長(zhǎng)度

  2. 是否包含屬性域

  3. 品牌(將所有的品牌做數(shù)值離散化)

  4. 產(chǎn)品 ID

  • 簡(jiǎn)單匹配

  1. 搜索詞是否在產(chǎn)品標(biāo)題、產(chǎn)品介紹或是產(chǎn)品屬性中出現(xiàn)

  2. 搜索詞在產(chǎn)品標(biāo)題、產(chǎn)品介紹或是產(chǎn)品屬性中出現(xiàn)的數(shù)量和比例

  3. *搜索詞中的第 i 個(gè)詞是否在產(chǎn)品標(biāo)題、產(chǎn)品介紹或是產(chǎn)品屬性中出現(xiàn)

  • 搜索詞和產(chǎn)品標(biāo)題、產(chǎn)品介紹以及產(chǎn)品屬性之間的文本相似度

  1. BOW Cosine Similairty

  2. TF-IDF Cosine Similarity

  3. Jaccard Similarity

  4. *Edit Distance

  5. Word2Vec Distance(由于效果不好,最后沒(méi)有使用,但似乎是因?yàn)橛玫牟粚?duì))

  • Latent Semantic Indexing:通過(guò)將 BOW/TF-IDF Vectorization 得到的矩陣進(jìn)行 SVD 分解,我們可以得到不同搜索詞/產(chǎn)品組合的 Latent 標(biāo)識(shí)。這個(gè) Feature 使得 Model 能夠在一定程度上對(duì)不同的組合做出區(qū)別,從而解決某些產(chǎn)品缺失某些 Feature 的問(wèn)題。

值得一提的是,上面打了 * 的 Feature 都是我在最后一批加上去的。問(wèn)題是,使用這批 Feature 訓(xùn)練得到的 Model 反而比之前的要差,而且還差不少。我一開(kāi)始是以為因?yàn)?Feature 的數(shù)量變多了所以一些參數(shù)需要重新調(diào)優(yōu),但在浪費(fèi)了很多時(shí)間做 Grid Search 以后卻發(fā)現(xiàn)還是沒(méi)法超過(guò)之前的分?jǐn)?shù)。這可能就是之前提到的 Feature 之間的相互作用導(dǎo)致的問(wèn)題。當(dāng)時(shí)我設(shè)想過(guò)一個(gè)看到過(guò)好幾次的解決方案,就是將使用不同版本 Feature 的 Model 通過(guò) Ensemble 組合起來(lái)。但最終因?yàn)闀r(shí)間關(guān)系沒(méi)有實(shí)現(xiàn)。事實(shí)上排名靠前的隊(duì)伍分享的解法里面基本都提到了將不同的 Preprocessing 和 Feature Engineering 做 Ensemble 是獲勝的關(guān)鍵。

Model

我一開(kāi)始用的是 RandomForestRegressor,后來(lái)在 Windows 上折騰Xgboost 成功了就開(kāi)始用 XGBRegressor。XGB 的優(yōu)勢(shì)非常明顯,同樣的數(shù)據(jù)它只需要不到一半的時(shí)間就能跑完,節(jié)約了很多時(shí)間。

比賽中后期我基本上就是一邊臺(tái)式機(jī)上跑 Grid Search,一邊在筆記本上繼續(xù)研究 Feature。

這次比賽數(shù)據(jù)分布很不獨(dú)立,所以期間多次遇到改進(jìn)的 Feature 或是 Grid Search新得到的參數(shù)訓(xùn)練出來(lái)的模型反而 LB 分?jǐn)?shù)下降了。由于被很多前輩教導(dǎo)過(guò)要相信自己的 CV,我的決定是將 5-Fold 提到 10-Fold,然后以 CV 為標(biāo)準(zhǔn)繼續(xù)前進(jìn)。

Ensemble

最終我的 Ensemble 的 Base Model 有以下四個(gè):

  • RandomForestRegressor

  • ExtraTreesRegressor

  • GradientBoostingRegressor

  • XGBRegressor

第二層的 Model 還是用的 XGB。

因?yàn)?nbsp;Base Model 之間的相關(guān)都都太高了(最低的一對(duì)也有 0.9),我原本還想引入使用 gblinear 的 XGBRegressor 以及 SVR,但前者的 RMSE 比其他幾個(gè) Model 高了 0.02(這在 LB 上有幾百名的差距),而后者的訓(xùn)練實(shí)在太慢了。最后還是只用了這四個(gè)。

值得一提的是,在開(kāi)始做 Stacking 以后,我的 CV 和 LB 成績(jī)的提高就是完全同步的了。

在比賽最后兩天,因?yàn)樯硇钠v加上想不到還能有什么顯著的改進(jìn),我做了一件事情:用 20 個(gè)不同的隨機(jī)種子來(lái)生成 Ensemble,最后取 Weighted Average。這個(gè)其實(shí)算是一種變相的 Bagging。其意義在于按我實(shí)現(xiàn) Stacking 的方式,我在訓(xùn)練 Base Model 時(shí)只用了 80% 的訓(xùn)練數(shù)據(jù),而訓(xùn)練第二層的 Model 時(shí)用了 100% 的數(shù)據(jù),這在一定程度上增大了 Overfitting 的風(fēng)險(xiǎn)。而每次更改隨機(jī)種子可以確保每次用的是不同的 80%,這樣在多次訓(xùn)練取平均以后就相當(dāng)于逼近了使用 100% 數(shù)據(jù)的效果。這給我?guī)?lái)了大約 0.0004 的提高,也很難受說(shuō)是真的有效還是隨機(jī)性了。

比賽結(jié)束后我發(fā)現(xiàn)我最好的單個(gè) Model 在 Private LB 上的得分是 0.46378,而最終 Stacking 的得分是 0.45849。這是 174 名和 98 名的差距。也就是說(shuō),我單靠 Feature 和調(diào)參進(jìn)到了 前 10%,而 Stacking 使我進(jìn)入了前 5%。

Lessons Learned

比賽結(jié)束后一些隊(duì)伍分享了他們的解法,從中我學(xué)到了一些我沒(méi)有做或是做的不夠好的地方:

  • 產(chǎn)品標(biāo)題的組織方式是有 Pattern 的,比如一個(gè)產(chǎn)品是否帶有某附件一定會(huì)用With/Without XXX 的格式放在標(biāo)題最后。

  • 使用外部數(shù)據(jù),比如 WordNet,Reddit 評(píng)論數(shù)據(jù)集等來(lái)訓(xùn)練同義詞和上位詞(在一定程度上替代 Word2Vec)詞典。

  • 基于字母而不是單詞的 NLP Feature。這一點(diǎn)我讓我十分費(fèi)解,但請(qǐng)教以后發(fā)現(xiàn)非常有道理。舉例說(shuō),排名第三的隊(duì)伍在計(jì)算匹配度時(shí),將搜索詞和內(nèi)容中相匹配的單詞的長(zhǎng)度也考慮進(jìn)去了。這是因?yàn)樗麄儼l(fā)現(xiàn)越長(zhǎng)的單詞約具體,所以越容易被用戶(hù)認(rèn)為相關(guān)度高。此外他們還使用了逐字符的序列比較(difflib.SequenceMatcher),因?yàn)檫@個(gè)相似度能夠衡量視覺(jué)上的相似度。像這樣的 Feature 的確不是每個(gè)人都能想到的。

  • 標(biāo)注單詞的詞性,找出中心詞,計(jì)算基于中心詞的各種匹配度和距離。這一點(diǎn)我想到了,但沒(méi)有時(shí)間嘗試。

  • 將產(chǎn)品標(biāo)題/介紹中 TF-IDF 最高的一些 Trigram 拿出來(lái),計(jì)算搜索詞中出現(xiàn)在這些 Trigram 中的比例;反過(guò)來(lái)以搜索詞為基底也做一遍。這相當(dāng)于是從另一個(gè)角度抽取了一些 Latent 標(biāo)識(shí)。

  • 一些新穎的距離尺度,比如 Word Movers Distance

  • 除了 SVD 以外還可以用上 NMF

  • 最重要的 Feature 之間的 Pairwise Polynomial Interaction。

  • 針對(duì)數(shù)據(jù)不 i.i.d. 的問(wèn)題,在 CV 時(shí)手動(dòng)構(gòu)造測(cè)試集與驗(yàn)證集之間產(chǎn)品 ID 不重疊和重疊的兩種不同分割,并以與實(shí)際訓(xùn)練集/測(cè)試集的分割相同的比例來(lái)做 CV 以逼近 LB 的得分分布。

至于 Ensemble 的方法,我暫時(shí)還沒(méi)有辦法學(xué)到什么,因?yàn)樽约褐挥凶詈?jiǎn)單的 Stacking 經(jīng)驗(yàn)。

Summary

Takeaways

比較早的時(shí)候就開(kāi)始做 Ensemble 是對(duì)的,這次比賽到倒數(shù)第三天我還在糾結(jié) Feature。

很有必要搭建一個(gè) Pipeline,至少要能夠自動(dòng)訓(xùn)練并記錄最佳參數(shù)。

Feature 為王。我花在 Feature 上的時(shí)間還是太少。

可能的話,多花點(diǎn)時(shí)間去手動(dòng)查看原始數(shù)據(jù)中的 Pattern。

Issues Raised

我認(rèn)為在這次比賽中遇到的一些問(wèn)題是很有研究?jī)r(jià)值的:

在數(shù)據(jù)分布并不 i.i.d. 甚至有 Dependency 時(shí)如何做靠譜的 CV。

如何量化 Ensemble 中 Diversity vs. Accuracy 的 Trade-off。

如何處理 Feature 之間互相影響導(dǎo)致性能反而下降。

Beginner Tips

給新手的一些建議:

  1. 選擇一個(gè)感興趣的比賽。如果你對(duì)相關(guān)領(lǐng)域原本就有一些洞見(jiàn)那就更理想了。

  2. 根據(jù)我描述的方法開(kāi)始探索、理解數(shù)據(jù)并進(jìn)行建模。

  3. 通過(guò) Forum 和 Scripts 學(xué)習(xí)其他人對(duì)數(shù)據(jù)的理解和構(gòu)建 Feature 的方式。

  4. 如果之前有過(guò)類(lèi)似的比賽,可以去找當(dāng)時(shí)獲獎(jiǎng)?wù)叩?Interview 和 Blog Post 作為參考,往往很有用。

  5. 在得到一個(gè)比較不錯(cuò)的 LB 分?jǐn)?shù)(比如已經(jīng)接近前 10%)以后可以開(kāi)始嘗試做 Ensemble。

  6. 如果覺(jué)得自己有希望拿到獎(jiǎng)金,開(kāi)始找人組隊(duì)吧!

  7. 到比賽結(jié)束為止要繃緊一口氣不能斷,盡量每天做一些新嘗試。

  8. 比賽結(jié)束后學(xué)習(xí)排名靠前的隊(duì)伍的方法,思考自己這次比賽中的不足和發(fā)現(xiàn)的問(wèn)題,可能的話再花點(diǎn)時(shí)間將學(xué)到的新東西用實(shí)驗(yàn)進(jìn)行確認(rèn),為下一次比賽做準(zhǔn)備。

  9. 好好休息!

Reference

  1. Beating Kaggle the Easy Way - Dong Ying

  2. Solution for Prudential Life Insurance Assessment - Nutastray

  3. Search Results Relevance Winner’s Interview: 1st place, Chenglong Chen

雷峰網(wǎng)版權(quán)文章,未經(jīng)授權(quán)禁止轉(zhuǎn)載。詳情見(jiàn)轉(zhuǎn)載須知。

TOP5%Kaggler:如何在 Kaggle 首戰(zhàn)中進(jìn)入前 10% | 干貨

分享:
相關(guān)文章

編輯

聚焦數(shù)據(jù)科學(xué),連接 AI 開(kāi)發(fā)者。更多精彩內(nèi)容,請(qǐng)?jiān)L問(wèn):yanxishe.com
當(dāng)月熱門(mén)文章
最新文章
請(qǐng)?zhí)顚?xiě)申請(qǐng)人資料
姓名
電話
郵箱
微信號(hào)
作品鏈接
個(gè)人簡(jiǎn)介
為了您的賬戶(hù)安全,請(qǐng)驗(yàn)證郵箱
您的郵箱還未驗(yàn)證,完成可獲20積分喲!
請(qǐng)驗(yàn)證您的郵箱
立即驗(yàn)證
完善賬號(hào)信息
您的賬號(hào)已經(jīng)綁定,現(xiàn)在您可以設(shè)置密碼以方便用郵箱登錄
立即設(shè)置 以后再說(shuō)