python小白之路:第十九章 Boosting模型(二)
提升樹模型(Boosting Decision Tree,BDT)
以決策樹為基函式的提升方法。
對於分類問題的決策樹是二叉分類樹;對於迴歸問題是二叉迴歸樹。
一個根結點直接連兩個葉結點的簡單決策樹稱為決策樹樁。
1 演算法
前向分步演算法+加法模型
針對不同問題,損失函式有所不同
第m步模型:
f
m
(
x
)
=
f
m
−
1
(
x
)
+
T
(
x
i
;
Θ
m
)
f_m(x)=f_{m-1}(x)+T(x_i;\Theta_m)
fm(x)=fm−1(x)+T(xi;Θm)
引數
Θ
m
\Theta_m
Θm:
Θ
^
m
=
a
r
g
min
Θ
m
∑
i
=
1
N
L
(
y
i
,
f
m
−
1
(
x
i
)
+
T
(
x
i
;
Θ
m
)
)
\hat\Theta_m =arg\min_{\Theta_m}\sum_{i=1}^NL(y_i,f_{m-1}(x_i)+T(x_i;\Theta_m))
Θ^m=argΘmmini=1∑NL(yi,fm−1(xi)+T(xi;Θm))
1.1 分類問題
對於二分類問題,只要使用二類分類樹作為基分類器就行。
損失函式是指數損失函式
1.2 迴歸問題
思路:學習迴歸樹擬合殘差
損失函式是平方誤差損失函式
在劃分時可以按照SSE最小
樹可表示為:
J J J是迴歸樹的複雜度即葉結點個數, c j c_j cj是各劃分的區域上的常數
T ( x ; Θ ) = ∑ j = 1 J c j I ( x ∈ R j ) T(x;\Theta)=\sum_{j=1}^Jc_jI(x\in R_j) T(x;Θ)=j=1∑JcjI(x∈Rj)
初始化:
f
0
(
x
)
=
0
f_0(x)=0
f0(x)=0
第m步的模型:
f
m
(
x
)
=
f
m
−
1
(
x
)
+
T
(
x
;
Θ
m
)
,
m
=
1
,
2
,
.
.
.
,
M
f_m(x)=f_{m-1}(x)+T(x;\Theta_m), \quad \text m=1,2,...,M
fm(x)=fm−1(x)+T(x;Θm),m=1,2,...,M
採用平方誤差損失函式:
r = y − f m − 1 ( x ) r=y-f_{m-1}(x) r=y−fm−1(x)是當前模型擬合資料的殘差(residual)
L ( y , f m − 1 ( x ) + T ( x i ; Θ m ) ) = [ y − f m − 1 ( x ) − T ( x i ; Θ m ) ] 2 = [ r − T ( x i ; Θ m ) ] 2 L(y,f_{m-1}(x)+T(x_i;\Theta_m))=[y-f_{m-1}(x)-T(x_i;\Theta_m)]^2\\ =[r-T(x_i;\Theta_m)]^2 L(y,fm−1(x)+T(xi;Θm))=[y−fm−1(x)−T(xi;Θm)]2=[r−T(xi;Θm)]2
1.3 梯度提升(Gradient Boosting)
大致和上面步驟一樣
對一般的損失函式,使用梯度提升演算法。利用損失函式的負梯度在當前模型的值作為殘差的近似值。
當損失函式是平方差損失函式時,殘差就是負梯度。但是,平方差損失函式對於異常值太敏感。
殘差近似值:
−
[
∂
L
(
y
,
f
(
x
i
)
)
∂
f
(
x
i
)
]
f
(
x
)
=
f
m
−
1
(
x
)
-[\frac{\partial L(y,f(x_i))}{\partial f(x_i)}]_{f(x)=f_{m-1}(x)}
−[∂f(xi)∂L(y,f(xi))]f(x)=fm−1(x)
第m步:
-
對 i = 1 , 2 , . . . , N i=1,2,...,N i=1,2,...,N:
r m i = − [ ∂ L ( y , f ( x i ) ) ∂ f ( x i ) ] f ( x ) = f m − 1 ( x ) r_{mi}=-[\frac{\partial L(y,f(x_i))}{\partial f(x_i)}]_{f(x)=f_{m-1}(x)} rmi=−[∂f(xi)∂L(y,f(xi))]f(x)=fm−1(x) -
對 r m i r_{mi} rmi擬合一個迴歸樹,得到第m棵樹的葉結點區域 R m j R_{mj} Rmj
-
對 j = 1 , 2 , . . . , J j=1,2,...,J j=1,2,...,J:
c m j = a r g min c ∑ x i ∈ R m j L ( y i , f m − 1 ( x i ) + c ) c_{mj}=arg\min_{c}\sum_{x_i\in R_{mj}}L(y_i,f_{m-1}(x_i)+c) cmj=argcminxi∈Rmj∑L(yi,fm−1(xi)+c) -
更新:
f m x = f m − 1 ( x ) + ∑ j = 1 J c m j I ( x ∈ R m j ) f_m{x}=f_{m-1}(x)+\sum^J_{j=1}c_{mj}I(x\in R_{mj}) fmx=fm−1(x)+j=1∑JcmjI(x∈Rmj)
最終迴歸樹:
f
^
(
x
)
=
f
M
(
x
)
=
∑
m
=
1
M
∑
j
=
1
J
c
m
j
I
(
x
∈
R
m
j
)
\hat f(x)=f_M(x)=\sum^M_{m=1}\sum^J_{j=1}c_{mj}I(x\in R_{mj})
f^(x)=fM(x)=m=1∑Mj=1∑JcmjI(x∈Rmj)
2 程式碼
# 以李航老師的《統計學習方法》(第二版)的p168例子為例
import numpy as np
x = [1,2,3,4,5,6,7,8,9,10]
y = [5.56,5.70,5.91,6.40,6.80,7.05,8.90,8.70,9.00,9.05]
def BDT(MS,x,y):
ms_f = 1000 # 初始化提升樹擬合資料的平方損失誤差
f = [0]*len(x) # 初始化提升樹
n = 1 # 記錄迭代次數
r = y # 第一次殘差為y
while ms_f >= MS: # 平方損失誤差要求
ms_f = 0
R1_best = []
R2_best = []
ms_min = 1000 # 初始化劃分的最小平方誤差
s_best = 0 # 初始化最優劃分點
c1_best = 0 # 初始化最優劃分時使葉結點內部平方損失誤差最小的引數
c2_best = 0 # 初始化最優劃分時使葉結點內部平方損失誤差最小的引數
# 根據最小化損失函式求最優的劃分點和對應的係數
for s in np.linspace(1.5,9.5,9):
ms = 0
R1 = []
R2 = []
c1 = 0
c2 = 0
n1,n2,ms1,ms2 = 0,0,0,0
for i in range(0,len(x)):
if x[i] < s or x[i] == s:
R1.append(x[i])
c1 += r[i]
n1 += 1
else:
R2.append(x[i])
c2 += r[i]
n2 += 1
c1 = c1/n1 # 使R1平方誤差最小時的引數
c2 = c2/n2 # 使R2平方誤差最小時的引數
for i in R1:
ms1 += (r[i-1] - c1)**2
for i in R2:
ms2 += (r[i-1] - c2)**2
ms = ms1 + ms2 # 損失函式
if ms_min > ms:
ms_min = ms
s_best = s
c1_best = c1
c2_best = c2
R1_best = R1
R2_best = R2
# 迴歸樹
T = []
for i in range(0,len(x)):
if x[i] < s_best:
T.append(c1_best)
else:
T.append(c2_best)
# 提升樹
for i in range(0,len(T)):
f[i] += T[i]
# 殘差及擬合殘差的平方損失誤差
r = []
for i in range(0,len(f)):
r.append(y[i]-f[i])
ms_f += r[i]**2
# 記錄
with open('record_BDT.txt','a+',encoding='utf-8') as fp:
fp.write(
f'第{n}次:當s={s_best}時,m(s)達到最小值{ms_min},此時R1={R1_best},R2={R2_best},c1={c1_best},c2={c2_best},迴歸樹為{T},提升樹為{f},殘差為{r},平方損失誤差為{ms_f}\n\n'
)
fp.close()
n += 1
return f
BDT(0.5,x,y)
# 結果
#[5.87,5.87,5.87,6.603333333333333,6.603333333333333,6.603333333333333,8.9125,8.9125,8.9125,8.9125]
第1次:
當s=6.5時,m(s)達到最小值1.9300083333333338,此時R1=[1, 2, 3, 4, 5, 6],R2=[7, 8, 9, 10],c1=6.236666666666667,c2=8.912500000000001,迴歸樹為[6.236666666666667, 6.236666666666667, 6.236666666666667, 6.236666666666667, 6.236666666666667, 6.236666666666667, 8.912500000000001, 8.912500000000001, 8.912500000000001, 8.912500000000001],提升樹為[6.236666666666667, 6.236666666666667, 6.236666666666667, 6.236666666666667, 6.236666666666667, 6.236666666666667, 8.912500000000001, 8.912500000000001, 8.912500000000001, 8.912500000000001],殘差為[-0.6766666666666676, -0.5366666666666671, -0.3266666666666671, 0.1633333333333331, 0.5633333333333326, 0.8133333333333326, -0.012500000000001066, -0.21250000000000213, 0.08749999999999858, 0.1374999999999993],平方損失誤差為1.9300083333333338
第2次:
當s=3.5時,m(s)達到最小值0.8006750000000016,此時R1=[1, 2, 3],R2=[4, 5, 6, 7, 8, 9, 10],c1=-0.513333333333334,c2=0.219999999999999,迴歸樹為[-0.513333333333334, -0.513333333333334, -0.513333333333334, 0.219999999999999, 0.219999999999999, 0.219999999999999, 0.219999999999999, 0.219999999999999, 0.219999999999999, 0.219999999999999],提升樹為[5.723333333333334, 5.723333333333334, 5.723333333333334, 6.456666666666666, 6.456666666666666, 6.456666666666666, 9.1325, 9.1325, 9.1325, 9.1325],殘差為[-0.163333333333334, -0.023333333333333428, 0.18666666666666654, -0.056666666666665755, 0.3433333333333337, 0.5933333333333337, -0.23249999999999993, -0.432500000000001, -0.13250000000000028, -0.08249999999999957],平方損失誤差為0.8006750000000015
第3次:
當s=6.5時,m(s)達到最小值0.47800833333333437,此時R1=[1, 2, 3, 4, 5, 6],R2=[7, 8, 9, 10],c1=0.1466666666666668,c2=-0.2200000000000002,迴歸樹為[0.1466666666666668, 0.1466666666666668, 0.1466666666666668, 0.1466666666666668, 0.1466666666666668, 0.1466666666666668, -0.2200000000000002, -0.2200000000000002, -0.2200000000000002, -0.2200000000000002],提升樹為[5.87, 5.87, 5.87, 6.603333333333333, 6.603333333333333, 6.603333333333333, 8.9125, 8.9125, 8.9125, 8.9125],殘差為[-0.3100000000000005, -0.16999999999999993, 0.040000000000000036, -0.20333333333333226, 0.1966666666666672, 0.4466666666666672, -0.01249999999999929, -0.21250000000000036, 0.08750000000000036, 0.13750000000000107],平方損失誤差為0.47800833333333437
# sklearn的GBDT演算法api
from sklearn.ensemble import GradientBoostingClassifier
from sklearn.ensemble import GradientBoostingRegressor
相關文章
- 第十九章:集合檢視(十七)
- 第九章%第十章
- ML《整合學習(二)Boosting之Adaboosting》
- 常用的模型整合方法介紹:bagging、boosting 、stacking模型
- 小白自學Python(二)Python開發環境搭建Python開發環境
- Python學習之路20-資料模型Python模型
- Python小白的數學建模課-09 微分方程模型Python模型
- 零基礎Python學習路線,小白的進階之路!Python
- 第九章第十二題(幾何:交點)(Geometry: Intersections)
- 小白從零到AIoT之路(前言)AI
- 張小白的滲透之路(二)——SQL隱碼攻擊漏洞原理詳解SQL
- Python 第十節 第十七課Python
- Git小白到老鳥的進階之路Git
- Python 爬蟲從入門到進階之路(二)Python爬蟲
- Python小白的數學建模課-B5. 新冠疫情 SEIR模型Python模型
- 寶付談小白IT職場奮鬥之路
- 從0到1,小白的前端摸索之路前端
- 第十八章:MVVM(二)MVVM
- 第十三週週二
- 第十四周週二
- 小白自學Python(一) -- Python教程Python
- 前端小白麵試之旅二前端
- Xgboost - A scalable tree boosting system Chiang
- python語言心得(小白)Python
- 引數匹配模型——Python學習之引數(二)模型Python
- 小白自學Python(五)Python運算子Python
- 小白自學Python(六)Python字串(上)Python字串
- React 進階之路(二)React
- IDC銷售:從小白到高手的荊棘之路
- 第0篇---電子小白的打怪升級之路
- Boosting提升演算法之AdaBoost演算法
- Python開發之路Python
- 小白學 Python(1):開篇Python
- python小白檔案讀取Python
- 小白學python系列-(4)listPython
- 小白學python系列-(5) tuplePython
- 小白學python系列-(8)dictPython
- python適合小白學嗎?Python