xgboost: 速度快效果好的boosting模型

xgboost: 速度快效果好的boosting模型

Python R

本文作者:何通,SupStat Inc(總部在紐約,中國分部為北京數博思達信息科技有限公司)數據科學家,加拿大Simon Fraser University計算機學院研究生,研究興趣為數據挖掘和生物信息學。

主頁:https://github.com/hetong007

引言

在數據分析的過程中,我們經常需要對數據建模并做預測。在眾多的選擇中,randomForest,gbmglmnet是三個尤其流行的R包,它們在Kaggle的各大數據挖掘競賽中的出現頻率獨占鰲頭,被坊間人稱為R數據挖掘包中的三駕馬車。根據我的個人經驗,gbm包比同樣是使用樹模型的randomForest包占用的內存更少,同時訓練速度較快,尤其受到大家的喜愛。在python的機器學習庫sklearn里也有GradientBoostingClassifier的存在。

Boosting分類器屬于集成學習模型,它基本思想是把成百上千個分類準確率較低的樹模型組合起來,成為一個準確率很高的模型。這個模型會不斷地迭代,每次迭代就生成一顆新的樹。對于如何在每一步生成合理的樹,大家提出了很多的方法,我們這里簡要介紹由Friedman提出的Gradient Boosting Machine。它在生成每一棵樹的時候采用梯度下降的思想,以之前生成的所有樹為基礎,向著最小化給定目標函數的方向多走一步。在合理的參數設置下,我們往往要生成一定數量的樹才能達到令人滿意的準確率。在數據集較大較復雜的時候,我們可能需要幾千次迭代運算,如果生成一個樹模型需要幾秒鐘,那么這么多迭代的運算耗時,應該能讓你專心地想靜靜……

現在,我們希望能通過xgboost工具更好地解決這個問題。xgboost的全稱是eXtreme Gradient Boosting。正如其名,它是Gradient Boosting Machine的一個c++實現,作者為正在華盛頓大學研究機器學習的大牛陳天奇。他在研究中深感自己受制于現有庫的計算速度和精度,因此在一年前開始著手搭建xgboost項目,并在去年夏天逐漸成型。xgboost最大的特點在于,它能夠自動利用CPU的多線程進行并行,同時在算法上加以改進提高了精度。它的處女秀是Kaggle的希格斯子信號識別競賽,因為出眾的效率與較高的預測準確度在比賽論壇中引起了參賽選手的廣泛關注,在1700多支隊伍的激烈競爭中占有一席之地。隨著它在Kaggle社區知名度的提高,最近也有隊伍借助xgboost在比賽中奪得第一

為了方便大家使用,陳天奇將xgboost封裝成了python庫。我有幸和他合作,制作了xgboost工具的R語言接口,并將其提交到了CRAN上。也有用戶將其封裝成了julia庫。python和R接口的功能一直在不斷更新,大家可以通過下文了解大致的功能,然后選擇自己最熟悉的語言進行學習。

功能介紹

一、基礎功能

首先,我們從github上安裝這個包:

devtools::install_github('dmlc/xgboost',subdir='R-package')

動手時間到!第一步,運行下面的代碼載入樣例數據:

require(xgboost)data(agaricus.train,package='xgboost')data(agaricus.test,package='xgboost')train <- agaricus.traintest <- agaricus.test

這份數據需要我們通過一些蘑菇的若干屬性判斷這個品種是否有毒。數據以1或0來標記某個屬性存在與否,所以樣例數據為稀疏矩陣類型:

>class(train$data)[1]"dgCMatrix"attr(,"package")[1]"Matrix"

不用擔心,xgboost支持稀疏矩陣作為輸入。下面就是訓練模型的命令

> bst <- xgboost(data = train$data, label = train$label, max.depth =2, eta =1,+? ? ? ? ? ? ? ? nround =2, objective ="binary:logistic")[0]train-error:0.046522[1]train-error:0.022263

我們迭代了兩次,可以看到函數輸出了每一次迭代模型的誤差信息。這里的數據是稀疏矩陣,當然也支持普通的稠密矩陣。如果數據文件太大不希望讀進R中,我們也可以通過設置參數data = 'path_to_file'使其直接從硬盤讀取數據并分析。目前支持直接從硬盤讀取libsvm格式的文件。

做預測只需要一句話:

pred <- predict(bst,test$data)

做交叉驗證的函數參數與訓練函數基本一致,只需要在原有參數的基礎上設置nfold:

> cv.res <- xgb.cv(data = train$data, label = train$label, max.depth =2, +? ? ? ? ? ? ? ? ? eta =1, nround =2, objective ="binary:logistic", +? ? ? ? ? ? ? ? ? nfold =5)[0]train-error:0.046522+0.001102test-error:0.046523+0.004410[1]train-error:0.022264+0.000864test-error:0.022266+0.003450> cv.res? train.error.mean train.error.std test.error.mean test.error.std1:0.0465220.0011020.0465230.0044102:0.0222640.0008640.0222660.003450

交叉驗證的函數會返回一個data.table類型的結果,方便我們監控訓練集和測試集上的表現,從而確定最優的迭代步數。

二、高速準確

上面的幾行代碼只是一個入門,使用的樣例數據沒法表現出xgboost高效準確的能力。xgboost通過如下的優化使得效率大幅提高:

xgboost借助OpenMP,能自動利用單機CPU的多核進行并行計算。需要注意的是,Mac上的Clang對OpenMP的支持較差,所以默認情況下只能單核運行。

xgboost自定義了一個數據矩陣類DMatrix,會在訓練開始時進行一遍預處理,從而提高之后每次迭代的效率。

在盡量保證所有參數都一致的情況下,我們使用希格斯子競賽的數據做了對照實驗。

Model and Parametergbmxgboost

1 thread2 threads4 threads8 threads

Time (in secs)761.48450.22102.4144.1834.04

以上實驗使用的CPU是i7-4700MQ。python的sklearn速度與gbm相仿。如果想要自己對這個結果進行測試,可以在比賽的官方網站下載數據,并參考這份demo中的代碼。

除了明顯的速度提升外,xgboost在比賽中的效果也非常好。在這個競賽初期,大家驚訝地發現R和python中的gbm竟然難以突破組織者預設的benchmark。而xgboost橫空出世,用不到一分鐘的訓練時間便打入當時的top 10,引起了大家的興趣與關注。準確度提升的主要原因在于,xgboost的模型和傳統的GBDT相比加入了對于模型復雜度的控制以及后期的剪枝處理,使得學習出來的模型更加不容易過擬合。更多算法上的細節可以參考這份陳天奇給出的介紹性講義

三、進階特征

除了速度快精度高,xgboost還有一些很有用的進階特性。下面的“demo”鏈接對應著相應功能的簡單樣例代碼。

只要能夠求出目標函數的梯度和Hessian矩陣,用戶就可以自定義訓練模型時的目標函數。demo

允許用戶在交叉驗證時自定義誤差衡量方法,例如回歸中使用RMSE還是RMSLE,分類中使用AUC,分類錯誤率或是F1-score。甚至是在希格斯子比賽中的“奇葩”衡量標準AMSdemo

交叉驗證時可以返回模型在每一折作為預測集時的預測結果,方便構建ensemble模型。demo

允許用戶先迭代1000次,查看此時模型的預測效果,然后繼續迭代1000次,最后模型等價于一次性迭代2000次。demo

可以知道每棵樹將樣本分類到哪片葉子上,facebook介紹過如何利用這個信息提高模型的表現。demo

可以計算變量重要性并畫出樹狀圖。demo

可以選擇使用線性模型替代樹模型,從而得到帶L1+L2懲罰的線性回歸或者logistic回歸。demo

這些豐富的功能來源于對日常使用場景的總結,數據挖掘比賽需求以及許多用戶給出的精彩建議。

四、未來計劃

現在,機器學習工具在實用中會不可避免地遇到“單機性能不夠”的問題。目前,xgboost的多機分布式版本正在開發當中。基礎設施搭建完成之日,便是新一輪R包開始設計與升級之時。

結語

我為xgboost制作R接口的目的就是希望引進好的工具,讓大家使用R的時候心情更愉悅。總結下來,xgboost的特點有三個:速度快,效果好,功能多,希望它能受到大家的喜愛,成為一駕新的馬車。

xgboost功能較多,參數設置比較繁雜,希望在上手之后有更全面了解的讀者可以參考項目wiki。歡迎大家多多交流,在項目issue區提出疑問與建議。我們也邀請有興趣的讀者提交代碼完善功能,讓xgboost成為更好用的工具。

另外,在使用github開發的過程中,我深切地感受到了協作寫代碼帶來的變化。一群人在一起的時候,可以寫出更有效率的代碼,在豐富的使用場景中發現新的需求,在極端情況發現隱藏很深的bug,甚至在主代碼手拖延癥較為忙碌的時候有人挺身而出拿下一片issue。這樣的氛圍,能讓一個語言社區的交流豐富起來,從而充滿生命力地活躍下去。

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

推薦閱讀更多精彩內容