作為一個非常有效的機器學習方法,Boosted Tree是數據挖掘和機器學習中最常用的算法之一。因為它效果好,對于輸入要求不敏感,往往是從統計學家到數據科學家必備的工具之一,它同時也是Kaggle比賽冠軍選手最常用的工具。Boosted Tree有各種馬甲,比如GBDT(Gradient Boosting Decision Tree), GBRT(Gradient Boosting Regression Tree)以及MART(Multiple Additive Regression Tree)。很多介紹Boosted tree的資料都是源于Friedman的較早的一篇文章[1]。
1. 分類和回歸樹(CART)
上面就是一個CART的例子。CART會把輸入根據輸入的屬性分配到各個葉子節點,而每個葉子節點上面都會對應一個實數分數。問題:預測一個人是否會喜歡電腦游戲。可以把葉子的分數理解為這個人喜歡電腦游戲的可能性。CART可以理解為是decision tree的一個擴展。從簡單的類標到分數之后,似乎能做更多的事情了(例如概率預測或是排序)。
2. Tree ensemble
同樣類比Random Forest的思想,當一棵樹解決不了問題時,可以將幾棵樹聯起來。
圖2的例子中,我們用兩棵樹來進行預測。我們對于每個樣本的預測結果就是每棵樹預測分數的和。我們常見的隨機森林和boosted tree和tree ensemble有什么關系呢?它們都是ensemble,只是構造模型參數的方法不同。
3. 模型學習
模型中的參數是什么?在tree ensemble中,參數對應了樹的結構,以及每個葉子節點上面的預測分數。同樣需要先定義合理的目標函數(一般會包括loss function 以及 regularizer ),然后嘗試優化目標函數。對于tree ensemble,可以將模型寫成為:
其中每個fk對應了一棵regression tree。
采用一種叫做additive training的方式(實際上boosting含義就是指additive training)。如每一次保留原來的模型不變,加入一個新的函數fk到我們的模型中。
3.1 目標函數的定義
在圖3中,如何選擇每一輪加入什么樣的fk呢?可以選取一個fk來使得我們的目標函數最大化的降低 。目標函數包括損失函數和正則化項。
目標函數 = 損失函數 + 正則項
目標函數圖5. 近似目標函數
3.2 樹的復雜度
樹的復雜度就是目標函數中的正則化項。將樹拆分成結構部分q 和葉子權重部分 w 。圖6是一個具體的例子。結構函數q把輸入映射到葉子的索引號上面去,而w給定了每個索引號對應的葉子分數是什么,使得fk成為一種條件函數。
定義一棵樹的復雜度,考慮復雜度包含了一棵樹節點的個數T,以及每個樹葉子節點上面輸出分數w,如圖7所示。
3.3 目標函數的最終形式
將正則項代入到目標函數中,確定目標函數的最終形式為
現在剩下最后一個問題就是樹的結構劃分。通過不斷地枚舉不同樹的結構,比較目標函數值來尋找一個最優結構的樹。暴力枚舉的時間開銷太大,同decision tree一樣采用貪心算法,每一次嘗試對已有的葉子加入一個分割。這樣,對于一個分割方案,我們可以獲得的增益可以由如下所示。
4.xgboost
xgboost是大規模并行boosted tree的工具,它是目前最快最好的開源boosted tree工具包,比常見的工具包快10倍以上。在數據科學方面,有大量kaggle選手選用它進行數據挖掘比賽,其中包括兩個以上kaggle比賽的奪冠方案。在工業界規模方面,xgboost的分布式版本有廣泛的可移植性,支持在YARN, MPI, Sungrid Engine等各個平臺上面運行,并且保留了單機并行版本的各種優化,使得它可以很好地解決于工業界規模的問題。XGBoost 所應用的算法就是 gradient boosting decision tree,既可以用于分類也可以用于回歸問題中。
應用案例:
先來用 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
- 基礎應用
#引入 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]
#將數據劃分為訓練集(67%)和測試集(33%)
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 建立模型
model = XGBClassifier()
model.fit(X_train, y_train)
#xgboost 的結果是樣本分類的概率值
y_pred = model.predict(X_test)
predictions = [round(value) for value in y_pred]
accuracy = accuracy_score(y_test, predictions)
print("Accuracy: %.2f%%" % (accuracy * 100.0))
- 輸出特征重要度
gradient boosting可以給出訓練好的模型的特征重要性,可以提供feature selection。僅需要需要引入:from xgboost import plot_importance和前面的代碼相比,就是在 fit 后面加入兩行畫出特征的重要性
plot_importance(model)
pyplot.show()
5. 學習資源
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
6. 參考文獻
【1】http://machinelearningmastery.com/develop-first-xgboost-model-python-scikit-learn/
【2】https://www.zhihu.com/question/37683881
【3】Friedman J H. Greedy Function Approximation: A Gradient Boosting Machine[J]. Annals of Statistics, 2001, 29(5): 1189-1232
【4】http://www.lxweimin.com/p/7e0e2d66b3d4
【5】https://xgboost.readthedocs.io/en/latest/