Kaggle 神器 xgboost

在 Kaggle 的很多比賽中,我們可以看到很多 winner 喜歡用 xgboost,而且獲得非常好的表現,今天就來看看 xgboost 到底是什么以及如何應用。

本文結構:

  • 什么是 xgboost?
  • 為什么要用它?
  • 怎么應用?
  • 學習資源

什么是 xgboost?

XGBoost :eXtreme Gradient Boosting
項目地址:https://github.com/dmlc/xgboost

是由 Tianqi Chen http://homes.cs.washington.edu/~tqchen/ 最初開發的實現可擴展,便攜,分布式 gradient boosting (GBDT, GBRT or GBM) 算法的一個庫,可以下載安裝并應用于 C++,Python,R,Julia,Java,Scala,Hadoop,現在有很多協作者共同開發維護。

XGBoost 所應用的算法就是 gradient boosting decision tree,既可以用于分類也可以用于回歸問題中。

那什么是 Gradient Boosting?

Gradient boosting 是 boosting 的其中一種方法

所謂 Boosting ,就是將弱分離器 f_i(x) 組合起來形成強分類器 F(x) 的一種方法。

所以 Boosting 有三個要素

  • A loss function to be optimized:
    例如分類問題中用 cross entropy,回歸問題用 mean squared error。

  • A weak learner to make predictions:
    例如決策樹。

  • An additive model:
    將多個弱學習器累加起來組成強學習器,進而使目標損失函數達到極小。

Gradient boosting 就是通過加入新的弱學習器,來努力糾正前面所有弱學習器的殘差,最終這樣多個學習器相加在一起用來進行最終預測,準確率就會比單獨的一個要高。之所以稱為 Gradient,是因為在添加新模型時使用了梯度下降算法來最小化的損失。


為什么要用 xgboost?

前面已經知道,XGBoost 就是對 gradient boosting decision tree 的實現,但是一般來說,gradient boosting 的實現是比較慢的,因為每次都要先構造出一個樹并添加到整個模型序列中。

而 XGBoost 的特點就是計算速度快,模型表現好,這兩點也正是這個項目的目標。

表現快是因為它具有這樣的設計:

  • Parallelization:
    訓練時可以用所有的 CPU 內核來并行化建樹。
  • Distributed Computing :
    用分布式計算來訓練非常大的模型。
  • Out-of-Core Computing:
    對于非常大的數據集還可以進行 Out-of-Core Computing。
  • Cache Optimization of data structures and algorithms:
    更好地利用硬件。

下圖就是 XGBoost 與其它 gradient boosting 和 bagged decision trees 實現的效果比較,可以看出它比 R, Python,Spark,H2O 中的基準配置要更快。

另外一個優點就是在預測問題中模型表現非常好,下面是幾個 kaggle winner 的賽后采訪鏈接,可以看出 XGBoost 的在實戰中的效果。


怎么應用?

先來用 Xgboost 做一個簡單的二分類問題,以下面這個數據為例,來判斷病人是否會在 5 年內患糖尿病,這個數據前 8 列是變量,最后一列是預測值為 0 或 1。

數據描述:
https://archive.ics.uci.edu/ml/datasets/Pima+Indians+Diabetes

下載數據集,并保存為 “pima-indians-diabetes.csv“ 文件:
https://archive.ics.uci.edu/ml/machine-learning-databases/pima-indians-diabetes/pima-indians-diabetes.data

1. 基礎應用

引入 xgboost 等包

from numpy import loadtxt
from xgboost import XGBClassifier
from sklearn.model_selection import train_test_split
from sklearn.metrics import accuracy_score

分出變量和標簽

dataset = loadtxt('pima-indians-diabetes.csv', delimiter=",")

X = dataset[:,0:8]
Y = dataset[:,8]

將數據分為訓練集和測試集,測試集用來預測,訓練集用來學習模型

seed = 7
test_size = 0.33
X_train, X_test, y_train, y_test = train_test_split(X, Y, test_size=test_size, random_state=seed)

xgboost 有封裝好的分類器和回歸器,可以直接用 XGBClassifier 建立模型
這里是 XGBClassifier 的文檔:
http://xgboost.readthedocs.io/en/latest/python/python_api.html#module-xgboost.sklearn

model = XGBClassifier()
model.fit(X_train, y_train)

xgboost 的結果是每個樣本屬于第一類的概率,需要用 round 將其轉換為 0 1 值

y_pred = model.predict(X_test)
predictions = [round(value) for value in y_pred]

得到 Accuracy: 77.95%

accuracy = accuracy_score(y_test, predictions)
print("Accuracy: %.2f%%" % (accuracy * 100.0))
2. 監控模型表現

xgboost 可以在模型訓練時,評價模型在測試集上的表現,也可以輸出每一步的分數

只需要將

model = XGBClassifier()
model.fit(X_train, y_train)

變為:

model = XGBClassifier()
eval_set = [(X_test, y_test)]
model.fit(X_train, y_train, early_stopping_rounds=10, eval_metric="logloss", eval_set=eval_set, verbose=True)

那么它會在每加入一顆樹后打印出 logloss

[31]    validation_0-logloss:0.487867
[32]    validation_0-logloss:0.487297
[33]    validation_0-logloss:0.487562

并打印出 Early Stopping 的點:

Stopping. Best iteration:
[32]    validation_0-logloss:0.487297
3. 輸出特征重要度

gradient boosting 還有一個優點是可以給出訓練好的模型的特征重要性,
這樣就可以知道哪些變量需要被保留,哪些可以舍棄

需要引入下面兩個類

from xgboost import plot_importance
from matplotlib import pyplot

和前面的代碼相比,就是在 fit 后面加入兩行畫出特征的重要性

model.fit(X, y)

plot_importance(model)
pyplot.show()
4. 調參

如何調參呢,下面是三個超參數的一般實踐最佳值,可以先將它們設定為這個范圍,然后畫出 learning curves,再調解參數找到最佳模型:

  • learning_rate = 0.1 或更小,越小就需要多加入弱學習器;
  • tree_depth = 2~8;
  • subsample = 訓練集的 30%~80%;

接下來我們用 GridSearchCV 來進行調參會更方便一些:

可以調的超參數組合有:

樹的個數和大小 (n_estimators and max_depth).
學習率和樹的個數 (learning_rate and n_estimators).
行列的 subsampling rates (subsample, colsample_bytree and colsample_bylevel).

下面以學習率為例:

先引入這兩個類

from sklearn.model_selection import GridSearchCV
from sklearn.model_selection import StratifiedKFold

設定要調節的 learning_rate = [0.0001, 0.001, 0.01, 0.1, 0.2, 0.3]
和原代碼相比就是在 model 后面加上 grid search 這幾行:

model = XGBClassifier()
learning_rate = [0.0001, 0.001, 0.01, 0.1, 0.2, 0.3]
param_grid = dict(learning_rate=learning_rate)
kfold = StratifiedKFold(n_splits=10, shuffle=True, random_state=7)
grid_search = GridSearchCV(model, param_grid, scoring="neg_log_loss", n_jobs=-1, cv=kfold)
grid_result = grid_search.fit(X, Y)

最后會給出最佳的學習率為 0.1
Best: -0.483013 using {'learning_rate': 0.1}

print("Best: %f using %s" % (grid_result.best_score_, grid_result.best_params_))

我們還可以用下面的代碼打印出每一個學習率對應的分數:

means = grid_result.cv_results_['mean_test_score']
stds = grid_result.cv_results_['std_test_score']
params = grid_result.cv_results_['params']
for mean, stdev, param in zip(means, stds, params):
    print("%f (%f) with: %r" % (mean, stdev, param))
-0.689650 (0.000242) with: {'learning_rate': 0.0001}
-0.661274 (0.001954) with: {'learning_rate': 0.001}
-0.530747 (0.022961) with: {'learning_rate': 0.01}
-0.483013 (0.060755) with: {'learning_rate': 0.1}
-0.515440 (0.068974) with: {'learning_rate': 0.2}
-0.557315 (0.081738) with: {'learning_rate': 0.3}

前面就是關于 xgboost 的一些基礎概念和應用實例,下面還有一些學習資源供參考:

學習資源:

Tianqi Chen 的講座:
https://www.youtube.com/watch?v=Vly8xGnNiWs&feature=youtu.be
講義:
https://speakerdeck.com/datasciencela/tianqi-chen-xgboost-overview-and-latest-news-la-meetup-talk

入門教程:
https://xgboost.readthedocs.io/en/latest/

安裝教程:
http://xgboost.readthedocs.io/en/latest/build.html

應用示例:
https://github.com/dmlc/xgboost/tree/master/demo

最好的資源當然就是項目的 Github 主頁:
https://github.com/dmlc/xgboost

參考:
http://machinelearningmastery.com/develop-first-xgboost-model-python-scikit-learn/
https://www.zhihu.com/question/37683881


推薦閱讀 歷史技術博文鏈接匯總
http://www.lxweimin.com/p/28f02bb59fe5
也許可以找到你想要的

最后編輯于
?著作權歸作者所有,轉載或內容合作請聯系作者
平臺聲明:文章內容(如有圖片或視頻亦包括在內)由作者上傳并發布,文章內容僅代表作者本人觀點,簡書系信息發布平臺,僅提供信息存儲服務。
  • 序言:七十年代末,一起剝皮案震驚了整個濱河市,隨后出現的幾起案子,更是在濱河造成了極大的恐慌,老刑警劉巖,帶你破解...
    沈念sama閱讀 228,606評論 6 533
  • 序言:濱河連續發生了三起死亡事件,死亡現場離奇詭異,居然都是意外死亡,警方通過查閱死者的電腦和手機,發現死者居然都...
    沈念sama閱讀 98,582評論 3 418
  • 文/潘曉璐 我一進店門,熙熙樓的掌柜王于貴愁眉苦臉地迎上來,“玉大人,你說我怎么就攤上這事。” “怎么了?”我有些...
    開封第一講書人閱讀 176,540評論 0 376
  • 文/不壞的土叔 我叫張陵,是天一觀的道長。 經常有香客問我,道長,這世上最難降的妖魔是什么? 我笑而不...
    開封第一講書人閱讀 63,028評論 1 314
  • 正文 為了忘掉前任,我火速辦了婚禮,結果婚禮上,老公的妹妹穿的比我還像新娘。我一直安慰自己,他們只是感情好,可當我...
    茶點故事閱讀 71,801評論 6 410
  • 文/花漫 我一把揭開白布。 她就那樣靜靜地躺著,像睡著了一般。 火紅的嫁衣襯著肌膚如雪。 梳的紋絲不亂的頭發上,一...
    開封第一講書人閱讀 55,223評論 1 324
  • 那天,我揣著相機與錄音,去河邊找鬼。 笑死,一個胖子當著我的面吹牛,可吹牛的內容都是我干的。 我是一名探鬼主播,決...
    沈念sama閱讀 43,294評論 3 442
  • 文/蒼蘭香墨 我猛地睜開眼,長吁一口氣:“原來是場噩夢啊……” “哼!你這毒婦竟也來了?” 一聲冷哼從身側響起,我...
    開封第一講書人閱讀 42,442評論 0 289
  • 序言:老撾萬榮一對情侶失蹤,失蹤者是張志新(化名)和其女友劉穎,沒想到半個月后,有當地人在樹林里發現了一具尸體,經...
    沈念sama閱讀 48,976評論 1 335
  • 正文 獨居荒郊野嶺守林人離奇死亡,尸身上長有42處帶血的膿包…… 初始之章·張勛 以下內容為張勛視角 年9月15日...
    茶點故事閱讀 40,800評論 3 354
  • 正文 我和宋清朗相戀三年,在試婚紗的時候發現自己被綠了。 大學時的朋友給我發了我未婚夫和他白月光在一起吃飯的照片。...
    茶點故事閱讀 42,996評論 1 369
  • 序言:一個原本活蹦亂跳的男人離奇死亡,死狀恐怖,靈堂內的尸體忽然破棺而出,到底是詐尸還是另有隱情,我是刑警寧澤,帶...
    沈念sama閱讀 38,543評論 5 360
  • 正文 年R本政府宣布,位于F島的核電站,受9級特大地震影響,放射性物質發生泄漏。R本人自食惡果不足惜,卻給世界環境...
    茶點故事閱讀 44,233評論 3 347
  • 文/蒙蒙 一、第九天 我趴在偏房一處隱蔽的房頂上張望。 院中可真熱鬧,春花似錦、人聲如沸。這莊子的主人今日做“春日...
    開封第一講書人閱讀 34,662評論 0 26
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽。三九已至,卻和暖如春,著一層夾襖步出監牢的瞬間,已是汗流浹背。 一陣腳步聲響...
    開封第一講書人閱讀 35,926評論 1 286
  • 我被黑心中介騙來泰國打工, 沒想到剛下飛機就差點兒被人妖公主榨干…… 1. 我叫王不留,地道東北人。 一個月前我還...
    沈念sama閱讀 51,702評論 3 392
  • 正文 我出身青樓,卻偏偏與公主長得像,于是被迫代替她去往敵國和親。 傳聞我的和親對象是個殘疾皇子,可洞房花燭夜當晚...
    茶點故事閱讀 47,991評論 2 374

推薦閱讀更多精彩內容