kaggle比賽流程(轉)

1、比賽概述html

  • 不一樣比賽有不一樣的任務,分類、迴歸、推薦、排序等。比賽開始後訓練集和測試集就會開放下載。
  • 比賽一般持續 2 ~ 3 個月,每一個隊伍天天能夠提交的次數有限,一般爲 5 次。
  • 比賽結束前一週是一個 Deadline,在這以後不能再組隊,也不能再新加入比賽。因此想要參加比賽請務必在這一 Deadline 以前有過至少一次有效的提交
  • 通常狀況下在提交後會馬上獲得得分的反饋。不一樣比賽會採起不一樣的評分基準,能夠在分數欄最上方看到使用的評分方法。
  • 反饋的分數是基於測試集的一部分計算的,剩下的另外一部分會被用於計算最終的結果。因此最後排名會變更。
  • LB 指的就是在 Leaderboard 獲得的分數,由上,有 Public LB 和 Private LB 之分。
  • 本身作的 Cross Validation 獲得的分數通常稱爲 CV 或是 Local CV。通常來講 CV 的結果比 LB 要可靠

2、可視化python

  一般來講 matplotlib 和 seaborn 提供的繪圖功能就能夠知足需求了。git

比較經常使用的圖表有:github

  • 查看目標變量的分佈。當分佈不平衡時,根據評分標準和具體模型的使用不一樣,可能會嚴重影響性能。
  • 對 Numerical Variable,能夠用 Box Plot 來直觀地查看它的分佈。
  • 對於座標類數據,能夠用 Scatter Plot 來查看它們的分佈趨勢和是否有離羣點的存在。
  • 對於分類問題,將數據根據 Label 的不一樣着不一樣的顏色繪製出來,這對 Feature 的構造頗有幫助。
  • 繪製變量之間兩兩的分佈和相關度圖表。

3、數據處理

大部分狀況下,在構造 Feature 以前,咱們須要對比賽提供的數據集進行一些處理。一般的步驟有:算法

  • 有時數據會分散在幾個不一樣的文件中,須要 Join 起來。
  • 處理 Missing Data
  • 處理 Outlier
  • 必要時轉換某些 Categorical Variable 的表示方式。
  • 有些 Float 變量多是從未知的 Int 變量轉換獲得的,這個過程當中發生精度損失會在數據中產生沒必要要的 Noise,即兩個數值本來是相同的卻在小數點後某一位開始有不一樣。這對 Model 可能會產生很負面的影響,須要設法去除或者減弱 Noise。

這一部分的處理策略多半依賴於在前一步中探索數據集所獲得的結論以及建立的可視化圖表。在實踐中,我建議使用 iPython Notebook 進行對數據的操做,並熟練掌握經常使用的 pandas 函數。spring

4、特徵工程

總的來講,咱們應該生成儘可能多的 Feature,相信 Model 可以挑出最有用的 Feature。但有時先作一遍 Feature Selection 也能帶來一些好處:windows

  • Feature 越少,訓練越快。
  • 有些 Feature 之間可能存在線性關係,影響 Model 的性能。
  • 經過挑選出最重要的 Feature,能夠將它們之間進行各類運算和操做的結果做爲新的 Feature,可能帶來意外的提升。

Feature Selection 最實用的方法也就是看 Random Forest 訓練完之後獲得的 Feature Importance 了。其餘有一些更復雜的算法在理論上更加 Robust,可是缺少實用高效的實現,好比這個。從原理上來說,增長 Random Forest 中樹的數量能夠在必定程度上增強其對於 Noisy Data 的 Robustness。數組

看 Feature Importance 對於某些數據通過脫敏處理的比賽尤爲重要。這能夠省得你浪費大把時間在琢磨一個不重要的變量的意義上。網絡

 

這裏用一個例子來講明在一些狀況下 Raw Feature 可能須要通過一些轉換才能起到比較好的效果。dom

假設有一個 Categorical Variable 一共有幾萬個取值可能,那麼建立 Dummy Variables 的方法就不可行了。這時一個比較好的方法是根據 Feature Importance 或是這些取值自己在數據中的出現頻率,爲最重要(好比說前 95% 的 Importance)那些取值(有很大可能只有幾個或是十幾個)建立 Dummy Variables,而全部其餘取值都歸到一個「其餘」類裏面。

 

5、模型選擇

準備好 Feature 之後,就能夠開始選用一些常見的模型進行訓練了。Kaggle 上最經常使用的模型基本都是基於樹的模型:

  • Gradient Boosting
  • Random Forest
  • Extra Randomized Trees

如下模型每每在性能上稍遜一籌,可是很適合做爲 Ensemble 的 Base Model。這一點以後再詳細解釋。(固然,在跟圖像有關的比賽中神經網絡的重要性仍是不能小覷的。)

  • SVM
  • Linear Regression
  • Logistic Regression
  • Neural Networks

以上這些模型基本均可以經過 sklearn 來使用。

固然,這裏不能不提一下 XgboostGradient Boosting 自己優秀的性能加上 Xgboost 高效的實現,使得它在 Kaggle 上廣爲使用。幾乎每場比賽的獲獎者都會用 Xgboost 做爲最終 Model 的重要組成部分。在實戰中,咱們每每會以 Xgboost 爲主來創建咱們的模型而且驗證 Feature 的有效性。順帶一提,在 Windows 上安裝 Xgboost 很容易遇到問題,目前已知最簡單、成功率最高的方案能夠參考我在這篇帖子中的描述

 

6、模型訓練

在訓練時,咱們主要但願經過調整參數來獲得一個性能不錯的模型。一個模型每每有不少參數,但其中比較重要的通常不會太多。好比對 sklearn 的 RandomForestClassifier 來講,比較重要的就是隨機森林中樹的數量 n_estimators 以及在訓練每棵樹時最多選擇的特徵數量max_features。因此咱們須要對本身使用的模型有足夠的瞭解,知道每一個參數對性能的影響是怎樣的

一般咱們會經過一個叫作 Grid Search 的過程來肯定一組最佳的參數。其實這個過程說白了就是根據給定的參數候選對全部的組合進行暴力搜索。

1
2
3
param_grid = {'n_estimators': [300, 500], 'max_features': [10, 12, 14]}
model = grid_search.GridSearchCV(estimator=rfr, param_grid=param_grid, n_jobs=1, cv=10, verbose=20, scoring=RMSE)
model.fit(X_train, y_train)

順帶一提,Random Forest 通常在 max_features 設爲 Feature 數量的平方根附近獲得最佳結果。

這裏要重點講一下 Xgboost 的調參。一般認爲對它性能影響較大的參數有:

  • eta:每次迭代完成後更新權重時的步長。越小訓練越慢。
  • num_round:總共迭代的次數。
  • subsample:訓練每棵樹時用來訓練的數據佔所有的比例。用於防止 Overfitting。
  • colsample_bytree:訓練每棵樹時用來訓練的特徵的比例,相似 RandomForestClassifier 的 max_features
  • max_depth:每棵樹的最大深度限制。與 Random Forest 不一樣,Gradient Boosting 若是不對深度加以限制,最終是會 Overfit 的
  • early_stopping_rounds:用於控制在 Out Of Sample 的驗證集上連續多少個迭代的分數都沒有提升後就提早終止訓練。用於防止 Overfitting。

通常的調參步驟是:

  1. 將訓練數據的一部分劃出來做爲驗證集。
  2. 先將 eta 設得比較高(好比 0.1),num_round 設爲 300 ~ 500。
  3. 用 Grid Search 對其餘參數進行搜索
  4. 逐步將 eta 下降,找到最佳值。
  5. 以驗證集爲 watchlist,用找到的最佳參數組合從新在訓練集上訓練。注意觀察算法的輸出,看每次迭代後在驗證集上分數的變化狀況,從而獲得最佳的 early_stopping_rounds
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
X_dtrain, X_deval, y_dtrain, y_deval = cross_validation.train_test_split(X_train, y_train, random_state=1026, test_size=0.3)
dtrain = xgb.DMatrix(X_dtrain, y_dtrain)
deval = xgb.DMatrix(X_deval, y_deval)
watchlist = [(deval, 'eval')]
params = {
'booster': 'gbtree',
'objective': 'reg:linear',
'subsample': 0.8,
'colsample_bytree': 0.85,
'eta': 0.05,
'max_depth': 7,
'seed': 2016,
'silent': 0,
'eval_metric': 'rmse'
}
clf = xgb.train(params, dtrain, 500, watchlist, early_stopping_rounds=50)
pred = clf.predict(xgb.DMatrix(df_test))

最後要提一點,全部具備隨機性的 Model 通常都會有一個 seed 或是 random_state 參數用於控制隨機種子。獲得一個好的 Model 後,在記錄參數時務必也記錄下這個值,從而可以在以後重現 Model。

7、交叉驗證

Cross Validation 是很是重要的一個環節。它讓你知道你的 Model 有沒有 Overfit,是否是真的可以 Generalize 到測試集上。在不少比賽中 Public LB 都會由於這樣那樣的緣由而不可靠。當你改進了 Feature 或是 Model 獲得了一個更高的 CV 結果,提交以後獲得的 LB 結果卻變差了,通常認爲這時應該相信 CV 的結果。固然,最理想的狀況是多種不一樣的 CV 方法獲得的結果和 LB 同時提升,但這樣的比賽並非太多。

在數據的分佈比較隨機均衡的狀況下,5-Fold CV 通常就足夠了。若是不放心,能夠提到 10-Fold可是 Fold 越多訓練也就會越慢,須要根據實際狀況進行取捨。

不少時候簡單的 CV 獲得的分數會不大靠譜,Kaggle 上也有不少關於如何作 CV 的討論。好比這個。但總的來講,靠譜的 CV 方法是 Case By Case 的,須要在實際比賽中進行嘗試和學習,這裏就再也不(也不能)敘述了。

 

8、Ensemble Generation

Ensemble Learning 是指將多個不一樣的 Base Model 組合成一個 Ensemble Model 的方法。它能夠同時下降最終模型的 Bias 和 Variance(證實能夠參考這篇論文,我最近在研究相似的理論,可能以後會寫新文章詳述),從而在提升分數的同時又下降 Overfitting 的風險。在如今的 Kaggle 比賽中要不用 Ensemble 就拿到獎金幾乎是不可能的。

常見的 Ensemble 方法有這麼幾種:

  • Bagging:使用訓練數據的不一樣隨機子集來訓練每一個 Base Model,最後進行每一個 Base Model 權重相同的 Vote。也即 Random Forest 的原理。
  • Boosting:迭代地訓練 Base Model,每次根據上一個迭代中預測錯誤的狀況修改訓練樣本的權重。也即 Gradient Boosting 的原理。比 Bagging 效果好,但更容易 Overfit。
  • Blending:用不相交的數據訓練不一樣的 Base Model,將它們的輸出取(加權)平均。實現簡單,但對訓練數據利用少了。
  • Stacking:接下來會詳細介紹。

從理論上講,Ensemble 要成功,有兩個要素:

  • Base Model 之間的相關性要儘量的小。這就是爲何非 Tree-based Model 每每表現不是最好但仍是要將它們包括在 Ensemble 裏面的緣由。Ensemble 的 Diversity 越大,最終 Model 的 Bias 就越低。
  • Base Model 之間的性能表現不能差距太大。這實際上是一個 Trade-off,在實際中頗有可能表現相近的 Model 只有寥寥幾個並且它們之間相關性還不低。可是實踐告訴咱們即便在這種狀況下 Ensemble 仍是能大幅提升成績。

9、Stacking

相比 Blending,Stacking 能更好地利用訓練數據。以 5-Fold Stacking 爲例,它的基本原理如圖所示:

Stacking

整個過程很像 Cross Validation。首先將訓練數據分爲 5 份,接下來一共 5 個迭代,每次迭代時,將 4 份數據做爲 Training Set 對每一個 Base Model 進行訓練,而後在剩下一份 Hold-out Set 上進行預測。同時也要將其在測試數據上的預測保存下來。這樣,每一個 Base Model 在每次迭代時會對訓練數據的其中 1 份作出預測,對測試數據的所有作出預測。5 個迭代都完成之後咱們就得到了一個 #訓練數據行數 x #Base Model 數量 的矩陣,這個矩陣接下來就做爲第二層的 Model 的訓練數據。當第二層的 Model 訓練完之後,將以前保存的 Base Model 對測試數據的預測(由於每一個 Base Model 被訓練了 5 次,對測試數據的全體作了 5 次預測,因此對這 5 次求一個平均值,從而獲得一個形狀與第二層訓練數據相同的矩陣)拿出來讓它進行預測,就獲得最後的輸出。

這裏給出個人實現代碼:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
class Ensemble(object):
def __init__(self, n_folds, stacker, base_models):
self.n_folds = n_folds
self.stacker = stacker
self.base_models = base_models

def fit_predict(self, X, y, T):
X = np.array(X)
y = np.array(y)
T = np.array(T)

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

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

for i, clf in enumerate(self.base_models):
S_test_i = np.zeros((T.shape[0], len(folds)))

for j, (train_idx, test_idx) in enumerate(folds):
X_train = X[train_idx]
y_train = y[train_idx]
X_holdout = X[test_idx]
# y_holdout = y[test_idx]
clf.fit(X_train, y_train)
y_pred = clf.predict(X_holdout)[:]
S_train[test_idx, i] = y_pred
S_test_i[:, j] = clf.predict(T)[:]

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

self.stacker.fit(S_train, y)
y_pred = self.stacker.predict(S_test)[:]
return y_pred

獲獎選手每每會使用比這複雜得多的 Ensemble,會出現三層、四層甚至五層,不一樣的層數之間有各類交互,還有將通過不一樣的 Preprocessing 和不一樣的 Feature Engineering 的數據用 Ensemble 組合起來的作法。但對於新手來講,穩妥當當地實現一個正確的 5-Fold Stacking 已經足夠了。

10、Pipeline

能夠看出 Kaggle 比賽的 Workflow 仍是比較複雜的。尤爲是 Model Selection 和 Ensemble。理想狀況下,咱們須要搭建一個高自動化的 Pipeline,它能夠作到:

  • 模塊化 Feature Transform,只需寫不多的代碼就能將新的 Feature 更新到訓練集中。
  • 自動化 Grid Search,只要預先設定好使用的 Model 和參數的候選,就能自動搜索並記錄最佳的 Model。
  • 自動化 Ensemble Generation,每一個一段時間將現有最好的 K 個 Model 拿來作 Ensemble。

對新手來講,第一點可能意義還不是太大,由於 Feature 的數量老是人腦管理的過來的;第三點問題也不大,由於每每就是在最後作幾回 Ensemble。可是第二點仍是頗有意義的,手工記錄每一個 Model 的表現不只浪費時間並且容易產生混亂。

原文:http://www.cnblogs.com/zhizhan/p/5826089.html

相關文章
相關標籤/搜索