GradientBoost算法 python實現,該系列文章主要是對《統計學習方法》的實現。
完整的筆記和代碼以上傳到Github,地址為(覺得有用的話,歡迎Fork,請給作者個Star):
https://github.com/Vambooo/lihang-dl
提升樹利用加法模型與前向分步算法實現學習的優化過程,當損失函數為平方損失和指數損失函數時,每一步優化都較為簡單。但對一般損失函數來說,每一步的優化并不容易。Fredman為了解決這一問題,便提出了梯度提升(Gradient Boosting)方法。
梯度提升法利用最速下降的近似方法,這里的關鍵是利用損失函數的負梯度在當前模型的值r_{mi}作為回歸問題提升樹算法中的殘差的近似值,擬合一個回歸樹。
梯度提升方法(Gradient Boosting)算法
注:該步通過估計使損失函數極小化的常數值,得到一個根結點的樹。
Gradient Boost算法案例 python實現(馬疝病數據)
(代碼可以左右滑動看)
import pandas as pdimport numpy as npimportmatplotlib.pyplotaspltfrom sklearn import ensemblefrom sklearn import linear_model
第一步:構建數據
# 創建模擬數據xx = np.arange(0, 60)y=[ x / 2 + (x // 10) % 2 * 20 * x / 5 + np.random.random() * 10 for x in xx] x = pd.DataFrame({'x': x}) # Plot mock dataplt.figure(figsize=(10, 5))plt.scatter(x, y)plt.show()
線性回歸模型來擬合數據
linear_regressor=linear_model.LinearRegression()linear_regressor.fit(x, y) plt.figure(figsize=(10, 5))plt.title("Linear Regression")plt.scatter(x, y)plt.plot(x, linear_regressor.predict(x), color='r')plt.show()
線性回歸模型旨在將預測與實際產出之間的平方誤差最小化,從我們的殘差模式可以清楚地看出,殘差之和約為0:
梯度提升法使用一組串聯的決策樹來預測y
下面從只有一個估計量的梯度提升回歸模型和一個只有深度為1的樹開始:
params = { 'n_estimators': 1, 'max_depth': 1, 'learning_rate': 1, 'criterion': 'mse'} gradient_boosting_regressor = ensemble.GradientBoostingRegressor(**params) gradient_boosting_regressor.fit(x, y) plt.figure(figsize=(10, 5))plt.title('Gradient Boosting model (1 estimators, Single tree split)')plt.scatter(x, y)plt.plot(x, gradient_boosting_regressor.predict(x), color='r')plt.show()
從上圖可以看到深度1決策樹在x<50??和x>50處被拆分,其中:
if x<50 ,y=56;
if x>=50,y=250.
這樣的拆分結果肯定是不好的,下面用一個估計量時,30-40之間的殘差很。猜想:如果使用兩個估計量,把第一棵樹的殘差輸入下一棵樹中,有怎樣的效果?驗證代碼如下:
params['n_estimators'] = 2 gradient_boosting_regressor = ensemble.GradientBoostingRegressor(**params) gradient_boosting_regressor.fit(x, y) plt.figure(figsize=(10, 5))plt.title('Gradient Boosting model (1 estimators, Single tree split)')plt.scatter(x, y)plt.plot(x, gradient_boosting_regressor.predict(x), color='r')plt.show()
如上圖,當有連個估計量時,第二棵樹是在30處拆分的,如果我們繼續增加估計量,我們得到Y分布的一個越來越接近的近似值:
f, ax = plt.subplots(2, 2, figsize=(15, 10)) for idx, n_estimators in enumerate([5, 10, 20, 50]): params['n_estimators'] = n_estimators gradient_boosting_regressor = ensemble.GradientBoostingRegressor(**params) gradient_boosting_regressor.fit(x, y) subplot = ax[idx // 2][idx % 2] subplot.set_title('Gradient Boosting model ({} estimators, Single tree split)'.format(n_estimators)) subplot.scatter(x, y) subplot.plot(x, gradient_boosting_regressor.predict(x), color='r')plt.show()
上面是改變估計量,保持樹深度的效果,下面保持估計量為10,改變樹的深度.
params['n_estimators'] = 10 f, ax = plt.subplots(2, 2, figsize=(15, 10)) for idx, max_depth in enumerate([1, 2, 3, 5]): params['max_depth'] = max_depth gradient_boosting_regressor = ensemble.GradientBoostingRegressor(**params) gradient_boosting_regressor.fit(x, y) subplot = ax[idx // 2][idx % 2] subplot.set_title('Gradient Boosting model (10 estimators, {} max tree splits)'.format(max_depth)) subplot.scatter(x, y) subplot.plot(x, gradient_boosting_regressor.predict(x), color='r')plt.show()
上兩圖可以看到如何通過增加估計量和最大深度來擬合y值。不過有點過擬合了。
-
算法
+關注
關注
23文章
4608瀏覽量
92844 -
python
+關注
關注
56文章
4793瀏覽量
84631
原文標題:機器學習筆記系列(十三) | GradientBoost算法 python實現
文章出處:【微信號:AI_class_vip,微信公眾號:人工智能學研社】歡迎添加關注!文章轉載請注明出處。
發布評論請先 登錄
相關推薦
評論