導航:首頁 > 源碼編譯 > python實現gbdt演算法

python實現gbdt演算法

發布時間:2023-05-25 01:54:28

python gradientboostingregressor可以做預測嗎

可以

最近項目中涉及基於Gradient Boosting Regression 演算法擬合時間序列曲線的內容,利用python機器學習包scikit-learn 中的GradientBoostingRegressor完成

因此就學習了下Gradient Boosting演算法,在這里分享下我的理解

Boosting 演算法簡介

Boosting演算法,我理解的就是兩個思想:

1)「三個臭皮匠頂個諸葛亮」,一堆弱分類器的組合就可以成為一個強分類器;

2)「知錯能改,善莫大焉」,不斷地在錯誤中學習,迭代來降低犯錯概率

當然,要理解好Boosting的思想,首先還是從弱學習演算法和強學習演算法來引入:

1)強學習演算法:存在一個多項式時間的學習演算法以識別一組概念,且識別的正確率很高;

2)弱學習演算法:識別一組概念的正確率僅比隨機猜測略好;

Kearns & Valiant證明了弱學習演算法與強學習演算法的等價問題,如果兩者等價,只需找到一個比隨機猜測略好的學習演算法,就可以將其提升為強學習演算法。

那麼是怎麼實現「知錯就改」的呢?

Boosting演算法,通過一系列的迭代來優化分類結果,每迭代一次引入一個弱分類器,來克服現在已經存在的弱分類器組合的shortcomings

在Adaboost演算法中,這個shortcomings的表徵就是權值高的樣本點

而在Gradient Boosting演算法中,這個shortcomings的表徵就是梯度

無論是Adaboost還是Gradient Boosting,都是通過這個shortcomings來告訴學習器怎麼去提升模型,也就是「Boosting」這個名字的由來吧

Adaboost演算法

Adaboost是由Freund 和 Schapire在1997年提出的,在整個訓練集上維護一個分布權值向量W,用賦予權重的訓練集通過弱分類演算法產生分類假設(基學習器)y(x),然後計算錯誤率,用得到的錯誤率去更新分布權值向量w,對錯誤分類的樣本分配更大的權值,正確分類的樣本賦予更小的權值。每次更新後用相同的弱分類演算法產生新的分類假設,這些分類假設的序列構成多分類器。對這些多分類器用加權的方法進行聯合,最後得到決策結果。

其結構如下圖所示:

可以發現,如果要用Gradient Boosting 演算法的話,在sklearn包里調用還是非常方便的,幾行代碼即可完成,大部分的工作應該是在特徵提取上。

感覺目前做數據挖掘的工作,特徵設計是最重要的,據說現在kaggle競賽基本是GBDT的天下,優劣其實還是特徵上,感覺做項目也是,不斷的在研究數據中培養對數據的敏感度。

② gbdt演算法是什麼

如下圖:


在建立GBDT對象並作fit之後,可以使用如下代碼獲得要的規則代碼:

dot_data = tree。export_graphviz(model_tree, out_file=None,

max_depth=5, feature_names=names_list, filled=True, rounded=True) # 將決策樹規則生成dot對象。

模型最終可以描述為:

Fm(x)=∑m=1MT(x;θm)Fm(x)=∑m=1MT(x;θm)

模型一共訓練M輪,每輪產生一個弱分類器T(x;θm)T(x;θm)。弱分類器的損失函數

θ^m=argminθm∑i=1NL(yi,Fm−1(xi)+T(xi;θm))θ^m=arg⁡minθm⁡∑i=1NL(yi,Fm−1(xi)+T(xi;θm))

Fm−1(x)Fm−1(x)為當前的模型,gbdt通過經驗風險極小化來確定下一個弱分類器的參數。具體到損失函數本身的選擇也就是L的選擇,有平方損失函數,0-1損失函數,對數損失函數等等。如果我們選擇平方損失函數,那麼這個差值其實就是我們平常所說的殘差。

③ GBDT —— 梯度提升決策樹

GBDT(Gradient Boosting Decision Tree) 又叫 MART(Multiple Additive Regression Tree),是一種迭代的決策樹演算法,該演算法由多棵決策樹組成,所有樹的結論累加起來做最終答案。它在被提出之初就和SVM一起被認為是泛化能力較強的演算法。
GBDT中的樹是回歸樹(不是分類樹),GBDT用來做回歸預測,調整後也可以用於分類。
GBDT主要由三個概念組成:Regression Decistion Tree(即DT),Gradient Boosting(即GB),Shrinkage (演算法的一個重要演進分枝,目前大部分源碼都按該版本實現)。搞定這三個概念後就能明白GBDT是如何工作的。

提起決策樹(DT, Decision Tree) 絕大部分人首先想到的就是C4.5分類決策樹。但如果一開始就把GBDT中的樹想成分類樹,那就錯了。千萬不要以為GBDT是很多棵分類樹。決策樹分為兩大類,回歸樹和分類樹。前者用於預測實數值,如明天的溫度、用戶的年齡、網頁的相關程度;後者用於分類標簽值,如晴天/陰天/霧/雨、用戶性別、網頁是否是垃圾頁面。這里要強調的是,前者的結果加減是有意義的,如10歲+5歲-3歲=12歲,後者則無意義,如男+男+女=到底是男是女?GBDT的核心在於累加所有樹的結果作為最終結果,就像前面對年齡的累加(-3是加負3),而分類樹的結果顯然是沒辦法累加的,所以 GBDT中的樹都是回歸樹,不是分類樹 ,這點對理解GBDT相當重要(盡管GBDT調整後也可用於分類但不代表GBDT的樹是分類樹)。

回歸樹總體流程類似於分類樹,區別在於,回歸樹的每一個節點都會得一個預測值,以年齡為例,該預測值等於屬於這個節點的所有人年齡的平均值。分枝時窮舉每一個feature的每個閾值找最好的分割點,但衡量最好的標准不再是最大熵,而是最小化平方誤差。也就是被預測出錯的人數越多,錯的越離譜,平方誤差就越大,通過最小化平方誤差能夠找到最可靠的分枝依據。分枝直到每個葉子節點上人的年齡都唯一或者達到預設的終止條件(如葉子個數上限), 若最終葉子節點上人的年齡不唯一,則以該節點上所有人的平均年齡做為該葉子節點的預測年齡。

回歸樹演算法如下圖(截圖來自《統計學習方法》5.5.1 CART生成):

梯度提升(Gradient boosting)是一種用於回歸、分類和排序任務的機器學習技術 [1] ,屬於Boosting演算法族的一部分。Boosting是一族可將弱學習器提升為強學習器的演算法,屬於集成學習(ensemble learning)的范疇。Boosting方法基於這樣一種思想:對於一個復雜任務來說,將多個專家的判斷進行適當的綜合所得出的判斷,要比其中任何一個專家單獨的判斷要好。通俗地說,就是「三個臭皮匠頂個諸葛亮」的道理。梯度提升同其他boosting方法一樣,通過集成(ensemble)多個弱學習器,通常是決策樹,來構建最終的預測模型。

Boosting、bagging和stacking是集成學習的三種主要方法。不同於bagging方法,boosting方法通過分步迭代(stage-wise)的方式來構建模型,在迭代的每一步構建的弱學習器都是為了彌補已有模型的不足。Boosting族演算法的著名代表是AdaBoost,AdaBoost演算法通過給已有模型預測錯誤的樣本更高的權重,使得先前的學習器做錯的訓練樣本在後續受到更多的關注的方式來彌補已有模型的不足。與AdaBoost演算法不同,梯度提升方法在迭代的每一步構建一個能夠沿著梯度最陡的方向降低損失(steepest-descent)的學習器來彌補已有模型的不足。經典的AdaBoost演算法只能處理採用指數損失函數的二分類學習任務 [2] ,而梯度提升方法通過設置不同的可微損失函數可以處理各類學習任務(多分類、回歸、Ranking等),應用范圍大大擴展。另一方面,AdaBoost演算法對異常點(outlier)比較敏感,而梯度提升演算法通過引入bagging思想、加入正則項等方法能夠有效地抵禦訓練數據中的噪音,具有更好的健壯性。這也是為什麼梯度提升演算法(尤其是採用決策樹作為弱學習器的GBDT演算法)如此流行的原因,

提升樹是迭代多棵回歸樹來共同決策。當採用平方誤差損失函數時,每一棵回歸樹學習的是之前所有樹的結論和殘差,擬合得到一個當前的殘差回歸樹,殘差的意義如公式:殘差 = 真實值 - 預測值 。提升樹即是整個迭代過程生成的回歸樹的累加。 GBDT的核心就在於,每一棵樹學的是之前所有樹結論和的殘差,這個殘差就是一個加預測值後能得真實值的累加量。

提升樹利用 加法模型和前向分步演算法 實現學習的優化過程。當損失函數時平方損失和指數損失函數時,每一步的優化很簡單,如平方損失函數學習殘差回歸樹。

提升方法其實是一個比adaboost概念更大的演算法,因為adaboost可以表示為boosting的前向分布演算法(Forward stagewise additive modeling)的一個特例,boosting最終可以表示為:

其中的w是權重,Φ是弱分類器(回歸器)的集合,其實就是一個加法模型(即基函數的線性組合)

前向分布演算法 實際上是一個貪心的演算法,也就是在每一步求解弱分類器Φ(m)和其參數w(m)的時候不去修改之前已經求好的分類器和參數:

OK,這也就是提升方法(之前向分布演算法)的大致結構了,可以看到其中存在變數的部分其實就是極小化損失函數 這關鍵的一步了,如何選擇損失函數決定了演算法的最終效果(名字)……這一步你可以看出演算法的「趨勢」,以後再單獨把「趨勢」拿出來說吧,因為我感覺理解演算法的關鍵之一就是理解演算法公式的「趨勢」

不同的損失函數和極小化損失函數方法決定了boosting的最終效果,我們現在來說幾個常見的boosting:

廣義上來講,所謂的Gradient Boosting 其實就是在更新的時候選擇梯度下降的方向來保證最後的結果最好,一些書上講的「殘差」 方法其實就是L2Boosting吧,因為它所定義的殘差其實就是L2Boosting的Derivative,接下來我們著重講一下弱回歸器(不知道叫啥了,自己編的)是決策樹的情況,也就是GBDT。

GBDT演算法可以看成是由K棵樹組成的加法模型:

解這一優化問題,可以用前向分布演算法(forward stagewise algorithm)。因為學習的是加法模型,如果能夠從前往後,每一步只學習一個基函數及其系數(結構),逐步逼近優化目標函數,那麼就可以簡化復雜度。這一學習過程稱之為Boosting。具體地,我們從一個常量預測開始,每次學習一個新的函數,過程如下:

舉個例子,參考自一篇博客, 該博客舉出的例子較直觀地展現出多棵決策樹線性求和過程以及殘差的意義。
還是年齡預測,簡單起見訓練集只有4個人,A,B,C,D,他們的年齡分別是14,16,24,26。其中A、B分別是高一和高三學生;C,D分別是應屆畢業生和工作兩年的員工。如果是用一棵傳統的回歸決策樹來訓練,會得到如下圖1所示結果:

現在我們使用GBDT來做這件事,由於數據太少,我們限定葉子節點做多有兩個,即每棵樹都只有一個分枝,並且限定只學兩棵樹。我們會得到如下圖2所示結果:

在第一棵樹分枝和圖1一樣,由於A,B年齡較為相近,C,D年齡較為相近,他們被分為兩撥,每撥用平均年齡作為預測值。此時計算殘差 (殘差的意思就是: A的預測值 + A的殘差 = A的實際值) ,所以A的殘差就是16-15=1(注意,A的預測值是指前面所有樹累加的和,這里前面只有一棵樹所以直接是15,如果還有樹則需要都累加起來作為A的預測值)。進而得到A,B,C,D的殘差分別為-1,1,-1,1。然後我們拿殘差替代A,B,C,D的原值,到第二棵樹去學習,如果我們的預測值和它們的殘差相等,則只需把第二棵樹的結論累加到第一棵樹上就能得到真實年齡了。這里的數據顯然是我可以做的,第二棵樹只有兩個值1和-1,直接分成兩個節點。此時所有人的殘差都是0,即每個人都得到了真實的預測值。

換句話說,現在A,B,C,D的預測值都和真實年齡一致了。Perfect!:
A: 14歲高一學生,購物較少,經常問學長問題;預測年齡A = 15 – 1 = 14
B: 16歲高三學生;購物較少,經常被學弟問問題;預測年齡B = 15 + 1 = 16
C: 24歲應屆畢業生;購物較多,經常問師兄問題;預測年齡C = 25 – 1 = 24
D: 26歲工作兩年員工;購物較多,經常被師弟問問題;預測年齡D = 25 + 1 = 26

那麼哪裡體現了Gradient呢?其實回到第一棵樹結束時想一想,無論此時的cost function是什麼,是均方差還是均差,只要它以誤差作為衡量標准,殘差向量(-1, 1, -1, 1)都是它的全局最優方向,這就是Gradient。

講到這里我們已經把GBDT最核心的概念、運算過程講完了!沒錯就是這么簡單。

該例子很直觀的能看到,預測值等於所有樹值得累加,如A的預測值 = 樹1左節點 值 15 + 樹2左節點 -1 = 14。
因此,給定當前模型 fm-1(x),只需要簡單的擬合當前模型的殘差。現將回歸問題的提升樹演算法敘述如下:

答案是過擬合。過擬合是指為了讓訓練集精度更高,學到了很多」僅在訓練集上成立的規律「,導致換一個數據集當前規律就不適用了。其實只要允許一棵樹的葉子節點足夠多,訓練集總是能訓練到100%准確率的(大不了最後一個葉子上只有一個instance)。在訓練精度和實際精度(或測試精度)之間,後者才是我們想要真正得到的。
我們發現圖1為了達到100%精度使用了3個feature(上網時長、時段、網購金額),其中分枝「上網時長>1.1h」 很顯然已經過擬合了,這個數據集上A,B也許恰好A每天上網1.09h, B上網1.05小時,但用上網時間是不是>1.1小時來判斷所有人的年齡很顯然是有悖常識的;
相對來說圖2的boosting雖然用了兩棵樹 ,但其實只用了2個feature就搞定了,後一個feature是問答比例,顯然圖2的依據更靠譜。(當然,這里是LZ故意做的數據,所以才能靠譜得如此狗血。實際中靠譜不靠譜總是相對的) Boosting的最大好處在於,每一步的殘差計算其實變相地增大了分錯instance的權重,而已經分對的instance則都趨向於0。這樣後面的樹就能越來越專注那些前面被分錯的instance。就像我們做互聯網,總是先解決60%用戶的需求湊合著,再解決35%用戶的需求,最後才關注那5%人的需求,這樣就能逐漸把產品做好,因為不同類型用戶需求可能完全不同,需要分別獨立分析。如果反過來做,或者剛上來就一定要做到盡善盡美,往往最終會竹籃打水一場空。

Shrinkage(縮減)的思想認為,每次走一小步逐漸逼近結果的效果,要比每次邁一大步很快逼近結果的方式更容易避免過擬合。即它不完全信任每一個棵殘差樹,它認為每棵樹只學到了真理的一小部分,累加的時候只累加一小部分,通過多學幾棵樹彌補不足。用方程來看更清晰,即
沒用Shrinkage時:(yi表示第i棵樹上y的預測值, y(1~i)表示前i棵樹y的綜合預測值)
y(i+1) = 殘差(y1~yi), 其中: 殘差(y1~yi) = y真實值 - y(1 ~ i)
y(1 ~ i) = SUM(y1, ..., yi)
Shrinkage不改變第一個方程,只把第二個方程改為:
y(1 ~ i) = y(1 ~ i-1) + step * yi

即Shrinkage仍然以殘差作為學習目標,但對於殘差學習出來的結果,只累加一小部分(step 殘差)逐步逼近目標,step一般都比較小,如0.01~0.001(注意該step非gradient的step),導致各個樹的殘差是漸變的而不是陡變的。直覺上這也很好理解,不像直接用殘差一步修復誤差,而是只修復一點點,其實就是把大步切成了很多小步。 本質上,Shrinkage為每棵樹設置了一個weight,累加時要乘以這個weight,但和Gradient並沒有關系 *。 這個weight就是step。就像Adaboost一樣,Shrinkage能減少過擬合發生也是經驗證明的,目前還沒有看到從理論的證明。

該版本GBDT幾乎可用於所有回歸問題(線性/非線性),相對logistic regression僅能用於線性回歸,GBDT的適用面非常廣。亦可用於二分類問題(設定閾值,大於閾值為正例,反之為負例)。

參考資料:
http://blog.csdn.net/w28971023/article/details/8240756
http://blog.csdn.net/dark_scope/article/details/24863289
https://www.jianshu.com/p/005a4e6ac775
https://www.zybuluo.com/yxd/note/611571

④ python sklearn 怎麼根據gbdt apply函數 和原來特徵加起來

跟版本沒關系。函數需要的傳參類型不一致。明顯已經說需要 字元串 和數字類型的參數了。而不是 一個字元串 和數字類型的 zip包

閱讀全文

與python實現gbdt演算法相關的資料

熱點內容
下班之後的程序員 瀏覽:71
檢測支持ssl加密演算法 瀏覽:342
衢州發布新聞什麼APP 瀏覽:83
中國移動長沙dns伺服器地址 瀏覽:249
wifi密碼加密了怎麼破解嗎 瀏覽:596
linux命令cpu使用率 瀏覽:67
linux實用命令 瀏覽:238
傳奇引擎修改在線時間命令 瀏覽:109
php取域名中間 瀏覽:897
cad命令欄太小 瀏覽:830
php開發環境搭建eclipse 瀏覽:480
qt文件夾名稱大全 瀏覽:212
金山雲伺服器架構 瀏覽:230
安卓系統筆記本怎麼切換系統 瀏覽:618
u盤加密快2個小時還沒有搞完 瀏覽:93
小米有品商家版app叫什麼 瀏覽:94
行命令調用 瀏覽:436
菜鳥裹裹員用什麼app 瀏覽:273
窮查理寶典pdf下載 瀏覽:515
csgo您已被禁用此伺服器怎麼辦 瀏覽:398