整合學習(1)AdaBoost分別應用於分類和迴歸及其python實現
AdaBoost分別應用於分類和迴歸及其python實現
前言:近期在做比賽的時候建模階段普遍都是使用整合模型效果更好,如xgboost、lgb、catboost等,但是對其中原理並不瞭解,所以準備從adaboost開始慢慢學習這一系列的整合模型…
1.AdaBoost分類
整合模型主要有bagging和boosting兩種,這裡都是boosting類的。
1.1Boosting基本思路
- 先用每個樣本權重相等的訓練集訓練一個初始的基學習器。
- 根據上輪得到的學習器對訓練集的預測表現情況調整訓練集中的樣本權重,然後據此訓練一個新的基學習器。
- 重複上面的步驟2得到M個基學習器,最終的整合結果就是這M個基學習器的組合。
上面的步驟很明顯是一個序列的過程,並且所使用到的基學習器都是比較簡單的。
1.2AdaBoost分類的基本思路
- 提高上一輪被錯誤分類的樣本的權值,降低被正確正確分類的樣本權值。
- 在最後整合結果線性加權求和過程中,誤差率小的基學習器擁有更大的權值,誤差率大的基學習器擁有較小的權值。
其中第二步整合的思想也經常用於模型融合。
1.3AdaBoost的演算法步驟
首先假設樣本數量為N,基學習器的數目為M。
- 初始化樣本權重: D 1 = ( w 11 , w 12 , . . . , w 1 N ) , w 1 i = 1 N , i = 1 , 2 , . . . , N D_1=(w_{11},w_{12},...,w_{1N}), w_{1i}=\frac{1}{N},i=1,2,...,N D1=(w11,w12,...,w1N),w1i=N1,i=1,2,...,N;
- 對
m
=
1
,
2
,
.
.
.
,
M
m=1,2,...,M
m=1,2,...,M重複以下操作得到M個基學習器:
(1)按照樣本權重分佈 D m D_m Dm訓練資料得到第 m m m個基學習器 G m ( x ) G_m(x) Gm(x);
(2)計算 G m ( x ) G_m(x) Gm(x)在加權訓練資料集上的分類誤差率: e m = ∑ i = 1 N D ( G m ( x i ) ≠ y i ) = ∑ i = 1 N w m , i I ( G m ( x i ) ≠ y i ) e_m=\sum_{i=1}^ND(G_m(x_i)\neq y_i)=\sum_{i=1}^Nw_{m,i}I(G_m(x_i)\neq y_i) em=∑i=1ND(Gm(xi)=yi)=∑i=1Nwm,iI(Gm(xi)=yi)
(3)計算 G m ( x ) G_m(x) Gm(x)的係數(即最終整合的基學習器的權重): α m = 1 2 l o g ( 1 − e m e m ) \alpha_m=\frac{1}{2}log(\frac{1-e_m}{e_m}) αm=21log(em1−em),可以看到誤差率 e m e_m em越大,基學習器權重 α m \alpha_m αm越小。
(4)更新樣本權重: D m + 1 = ( w m , 1 , w m , 2 , . . . , w m , N ) D_{m+1}=(w_{m,1},w_{m,2},...,w_{m,N}) Dm+1=(wm,1,wm,2,...,wm,N), w m + 1 , i = w m , i Z m e x p ( − α m y i G m ( x i ) ) , i = 1 , 2 , . . . , N w_{m+1,i}=\frac{w_{m,i}}{Z_m}exp(-\alpha_my_iG_m(x_i)),i=1,2,...,N wm+1,i=Zmwm,iexp(−αmyiGm(xi)),i=1,2,...,N。其中 Z m Z_m Zm是規範化因子,目的就是為了使 D m + 1 D_{m+1} Dm+1得所有元素之和為1, Z m = ∑ i = 1 N w m , i e x p ( − α m y i G m ( x i ) ) Z_m=\sum_{i=1}^{N}w_{m,i}exp(-\alpha_my_iG_m(x_i)) Zm=∑i=1Nwm,iexp(−αmyiGm(xi))。可以看到當分類錯誤時, y i G m ( x i ) = − 1 y_iG_m(x_i)=-1 yiGm(xi)=−1,對應的權值增加。 - 構建最終的分類器線性組合: f ( x ) = ∑ m = 1 M α m G m ( x ) f(x)=\sum_{m=1}^M\alpha_mG_m(x) f(x)=∑m=1MαmGm(x),分類器 G ( x ) = s i g n ( f ( x ) ) G(x)=sign(f(x)) G(x)=sign(f(x))。
1.4AdaBoost演算法的解釋
在上面演算法步驟中可以看到基學習器權重 α m \alpha_m αm得更新公式和樣本權重 w m w_m wm的更新公式是符合基本思路的,但是對於為什麼是要這麼更新?我們可以從另一個角度出發,把AdaBoost看作模型是加法模型、損失函式是指數損失函式、學習演算法為前向分步演算法的二分類學習方法。
(1)首先看一下前向分步演算法的基本思想(這裡為了一般化,用其他符號進行表示):
對於我們的加法模型:
f
(
x
)
=
∑
m
=
1
M
β
m
b
(
x
;
γ
m
)
f(x)=\sum_{m=1}^M\beta_mb(x;\gamma_m)
f(x)=∑m=1Mβmb(x;γm), 其中
b
(
x
;
γ
m
)
b(x;\gamma_m)
b(x;γm)是基函式,
γ
m
\gamma_m
γm是基函式的引數,
β
m
\beta_m
βm是基函式的係數;在給定損失函式
L
(
y
,
f
(
x
)
)
L(y,f(x))
L(y,f(x))的條件下,學習加法模型的過程就是最小化損失函式:
m
i
n
∑
i
=
1
N
L
(
y
i
,
∑
m
=
1
M
β
m
b
(
x
;
γ
m
)
)
min\sum_{i=1}^NL(y_i,\sum_{m=1}^M\beta_mb(x;\gamma_m))
min∑i=1NL(yi,∑m=1Mβmb(x;γm)),而這個最優化的過程通常比較複雜,前向分佈演算法解決這個優化問題的思想就是每次只學習一個基函式,然後再用學習得到的這個基函式更新我們的加法模型。
(2)演算法步驟:
輸入訓練集
T
=
{
(
x
1
,
y
1
)
,
(
x
2
,
y
2
)
,
.
.
.
,
(
x
N
,
y
N
)
}
T=\{(x_1,y_1), (x_2,y_2),...,(x_N,y_N)\}
T={(x1,y1),(x2,y2),...,(xN,yN)};損失函式
L
(
y
,
f
(
x
)
)
L(y,f(x))
L(y,f(x));基函式集
{
b
(
x
;
γ
)
}
\{b(x;\gamma)\}
{b(x;γ)}
- 初始化 f 0 ( x ) = 0 f_0(x)=0 f0(x)=0
- 對
m
=
1
,
2
,
.
.
.
,
M
m=1,2,...,M
m=1,2,...,M
(1)極小化損失函式: ( β m , γ m ) = a r g m i n β , γ ∑ i = 1 N L ( y i , f m − 1 ( x i ) + β b ( x ; γ ) ) (\beta_m,\gamma_m)=argmin_{\beta,\gamma}\sum_{i=1}^{N}L(y_i,f_{m-1}(x_i)+\beta b(x;\gamma)) (βm,γm)=argminβ,γ∑i=1NL(yi,fm−1(xi)+βb(x;γ)),得到第m個基函式引數
(2)更新加法模型: f m ( x ) = f m − 1 ( x ) + β m b ( x ; γ m ) f_m(x)=f_{m-1}(x)+\beta_mb(x;\gamma_m) fm(x)=fm−1(x)+βmb(x;γm) - 得到加法模型: f ( x ) = f M ( x ) = ∑ m = 1 M β m b ( x ; γ m ) f(x)=f_M(x)=\sum_{m=1}^M\beta_mb(x;\gamma_m) f(x)=fM(x)=∑m=1Mβmb(x;γm)
我們在1.3中得到的加法分類器也是這樣的一個加法模型,所以也可以使用前向分步演算法來進行求解。
(3)具體推導:
首先基於前向分步演算法的思想和AdaBoost得到的加法模型,AdaBoost可以看作前向分步演算法的一個特例,其基函式為基本分類器
G
(
x
)
G(x)
G(x),損失函式為指數損失函式
L
(
y
,
f
(
x
)
)
=
e
x
p
(
−
y
f
(
x
)
)
L(y,f(x))=exp(-yf(x))
L(y,f(x))=exp(−yf(x))。結合上面的演算法步驟,假設前m-1輪已經得到
f
m
−
1
(
x
)
f_{m-1}(x)
fm−1(x),我們的第m輪的優化目標如下:
a
r
g
m
i
n
α
m
,
G
m
∑
i
=
1
N
L
(
y
i
,
f
m
−
1
(
x
i
)
+
α
m
G
m
(
x
i
)
)
⇒
a
r
g
m
i
n
α
m
,
G
m
∑
i
=
1
N
e
x
p
[
−
y
i
(
f
m
−
1
(
x
i
)
+
α
m
G
m
(
x
i
)
)
]
⇒
a
r
g
m
i
n
α
m
,
G
m
∑
i
=
1
N
e
x
p
[
−
y
i
f
m
−
1
(
x
i
)
]
e
x
p
[
−
y
i
α
m
G
m
(
x
i
)
]
argmin_{\alpha_m,G_m}\sum_{i=1}^{N}L(y_i,f_{m-1}(x_i)+\alpha_m G_m(x_i))\\\Rarr argmin_{\alpha_m,G_m}\sum_{i=1}^{N}exp[-y_i(f_{m-1}(x_i)+\alpha_m G_m(x_i))]\\\Rarr argmin_{\alpha_m,G_m}\sum_{i=1}^{N}exp[-y_if_{m-1}(x_i)]exp[-y_i\alpha_m G_m(x_i)]
argminαm,Gmi=1∑NL(yi,fm−1(xi)+αmGm(xi))⇒argminαm,Gmi=1∑Nexp[−yi(fm−1(xi)+αmGm(xi))]⇒argminαm,Gmi=1∑Nexp[−yifm−1(xi)]exp[−yiαmGm(xi)]
因為
y
i
y_i
yi和
f
m
−
1
(
x
)
f_{m-1}(x)
fm−1(x)已經得到,所以可以令
w
m
,
i
=
e
x
p
[
−
y
i
f
m
−
1
(
x
i
)
]
w_{m,i}=exp[-y_if_{m-1}(x_i)]
wm,i=exp[−yifm−1(xi)],然後上面的優化目標變成如下形式:
a
r
g
m
i
n
α
m
,
G
m
∑
i
=
1
N
w
m
,
i
e
x
p
[
−
y
i
α
m
G
m
(
x
i
)
]
⇒
a
r
g
m
i
n
α
m
,
G
m
∑
y
i
=
G
m
(
x
i
)
w
m
,
i
e
−
α
m
+
∑
y
i
≠
G
m
(
x
i
)
w
m
,
i
e
α
m
⇒
a
r
g
m
i
n
α
m
,
G
m
(
e
α
m
−
a
−
α
m
)
∑
i
=
1
N
w
m
,
i
I
(
y
i
≠
G
m
(
x
i
)
)
+
e
−
α
m
∑
i
=
1
N
w
m
,
i
argmin_{\alpha_m,G_m}\sum_{i=1}^{N}w_{m,i}exp[-y_i\alpha_m G_m(x_i)]\\\Rarr argmin_{\alpha_m,G_m}\sum_{y_i=G_m(x_i)}w_{m,i}e^{-\alpha_m}+\sum_{y_i\neq G_m(x_i)}w_{m,i}e^{\alpha_m}\\\Rarr argmin_{\alpha_m,G_m}(e^{\alpha_m}-a^{-\alpha_m})\sum_{i=1}^Nw_{m,i}I(y_i\neq G_m(x_i))+e^{-\alpha_m}\sum_{i=1}^Nw_{m,i}
argminαm,Gmi=1∑Nwm,iexp[−yiαmGm(xi)]⇒argminαm,Gmyi=Gm(xi)∑wm,ie−αm+yi=Gm(xi)∑wm,ieαm⇒argminαm,Gm(eαm−a−αm)i=1∑Nwm,iI(yi=Gm(xi))+e−αmi=1∑Nwm,i
然後上式關於
α
m
\alpha_m
αm求導,並令其為0:
(
e
α
m
+
a
−
α
m
)
∑
i
=
1
N
w
m
,
i
I
(
y
i
≠
G
m
(
x
i
)
)
−
e
−
α
m
∑
i
=
1
N
w
m
,
i
=
0
⇒
∑
i
=
1
N
w
m
,
i
I
(
y
i
≠
G
m
(
x
i
)
)
∑
i
=
1
N
w
m
,
i
=
e
−
α
m
(
e
α
m
+
a
−
α
m
)
(e^{\alpha_m}+a^{-\alpha_m})\sum_{i=1}^Nw_{m,i}I(y_i\neq G_m(x_i))-e^{-\alpha_m}\sum_{i=1}^Nw_{m,i}=0\\\Rarr \frac{\sum_{i=1}^Nw_{m,i}I(y_i\neq G_m(x_i))}{\sum_{i=1}^Nw_{m,i}}=\frac{e^{-\alpha_m}}{(e^{\alpha_m}+a^{-\alpha_m})}
(eαm+a−αm)i=1∑Nwm,iI(yi=Gm(xi))−e−αmi=1∑Nwm,i=0⇒∑i=1Nwm,i∑i=1Nwm,iI(yi=Gm(xi))=(eαm+a−αm)e−αm
可以看到上式左邊部分就是我們的當前第m輪模型的誤差率,所以令
e
m
=
∑
i
=
1
N
w
m
,
i
I
(
y
i
≠
G
m
(
x
i
)
)
∑
i
=
1
N
w
m
,
i
e_m=\frac{\sum_{i=1}^Nw_{m,i}I(y_i\neq G_m(x_i))}{\sum_{i=1}^Nw_{m,i}}
em=∑i=1Nwm,i∑i=1Nwm,iI(yi=Gm(xi)),這裡的e時誤差的意思,和上式右半部分的e的不同,然後將其帶入上式可得到:
α
m
=
1
2
l
o
g
1
−
e
m
e
m
\alpha_m=\frac{1}{2}log\frac{1-e_m}{e_m}
αm=21logem1−em
然後結合
w
m
,
i
=
e
x
p
[
−
y
i
f
m
−
1
(
x
i
)
]
w_{m,i}=exp[-y_if_{m-1}(x_i)]
wm,i=exp[−yifm−1(xi)]和
f
m
(
x
)
=
f
m
−
1
(
x
)
+
α
m
G
m
(
x
)
f_m(x)=f_{m-1}(x)+\alpha_mG_m(x)
fm(x)=fm−1(x)+αmGm(x)得出權值更新的公式:
f
m
(
x
i
)
=
f
m
−
1
(
x
i
)
+
α
m
G
m
(
x
i
)
⇒
−
y
i
f
m
(
x
i
)
=
−
y
i
f
m
−
1
(
x
i
)
−
y
i
α
m
G
m
(
x
i
)
⇒
e
−
y
i
f
m
(
x
i
)
=
e
−
y
i
f
m
−
1
(
x
i
)
e
−
y
i
α
m
G
m
(
x
i
)
⇒
w
m
+
1
,
i
=
w
m
,
i
e
−
y
i
α
m
G
m
(
x
i
)
f_m(x_i)=f_{m-1}(x_i)+\alpha_mG_m(x_i)\\\Rarr -y_if_m(x_i)=-y_if_{m-1}(x_i)-y_i\alpha_mG_m(x_i)\\\Rarr e^{-y_if_m(x_i)}=e^{-y_if_{m-1}(x_i)}e^{-y_i\alpha_mG_m(x_i)}\\\Rarr w_{m+1,i}=w_{m,i}e^{-y_i\alpha_mG_m(x_i)}
fm(xi)=fm−1(xi)+αmGm(xi)⇒−yifm(xi)=−yifm−1(xi)−yiαmGm(xi)⇒e−yifm(xi)=e−yifm−1(xi)e−yiαmGm(xi)⇒wm+1,i=wm,ie−yiαmGm(xi)
然後對權值繼續規範化,使其之和為1,然後對應的誤差
e
m
e_m
em中的分母也就為1。
1.5python實現
這裡實現的一個簡易版的,基學習器使用一個根節點的決策樹,資料集採用西瓜書對應章節的資料進行簡單測試。
import numpy as np
import pandas as pd
#構建單層決策樹為基分類器的提升模型
def load_data():
df = pd.DataFrame()
df['密度'] = [0.697, 0.774, 0.634, 0.608, 0.556, 0.403, 0.481, 0.437, 0.666, 0.243, 0.245, 0.343, 0.639, 0.657,
0.360, 0.593, 0.719]
df['含糖量'] = [0.460, 0.376, 0.264, 0.318, 0.215, 0.237, 0.149, 0.211, 0.091, 0.267, 0.057, 0.099, 0.161, 0.198,
0.370, 0.042, 0.103]
df["好瓜"] = ["是", "是", "是", "是", "是", "是", "是", "是", "否", "否", "否", "否", "否", "否", "否", "否", "否"]
df.to_csv('data/watermelon45.csv', index=0)
#計算更新樣本的權重
def cal_sample_weight(weight_list:[],y_true:[],y_pred:[],am):
weight_list = np.array(weight_list)*np.exp(-am*(y_true*y_pred))
Zm = np.sum(weight_list)
return list(weight_list/Zm)
#計算第m輪模型的權重
def cal_tree_weight(em):
return np.log((1 - em) / em) / 2
def cal_em(feat_value_list:[], threshold, y_true:[], weight_list:[], flag='l'):
:param feat_value_list: 劃分特徵的所有取值
:param threshold: 閾值
:param y_true: 樣本的真實標籤列表
:param weight_list: 樣本當前的權重
:return: 誤差率
y_pred = np.ones(len(y_true))
if flag == 'l':
y_pred[np.array(feat_value_list)>threshold] = -1 #大於閾值的預測為-1,小於閾值的預測為1
elif flag == 'r':
y_pred[np.array(feat_value_list) < threshold] = -1 #大於閾值的預測為1,小於閾值的預測為-1
em = np.sum(np.array(weight_list)[y_pred != y_true])
return em,y_pred
#構建單層決策樹
def build_stump(data:pd.DataFrame, weight_list:[], label:[]):
:param data: 訓練資料
:param weight_list: 訓練樣本的權重
:param label: 資料的真實標籤
:return:
min_em = np.inf #找到使得當前權重下誤差率最小的分類器
tree = {} #返回的單層決策樹
best_feat = '' #最優劃分特徵
best_threshold = -1 #最優劃分特徵下產生的最優化閾值
ret_y_pred = [] #最優劃分下決策樹的預測結果
best_flag = ''
for feat in data.columns.values:
feat_value_list = list(data[feat]) #該屬性下的取值
sorted_feat_value_list = sorted(list(set(feat_value_list)))
threshold_list = [(sorted_feat_value_list[i]+sorted_feat_value_list[i+1])/2 for i in np.arange(len(sorted_feat_value_list)-1)]
for threshold in threshold_list:
for flag in ['l','r']:
cur_em, y_pred = cal_em(feat_value_list, threshold, label, weight_list, flag) #計算誤差率
if cur_em < min_em:
min_em = cur_em
best_feat = feat
best_threshold = threshold
ret_y_pred = y_pred
best_flag = flag
return best_feat, best_threshold, min_em, ret_y_pred, best_flag
#構建提升樹分類模型
def build_adaboost_classifier(data:pd.DataFrame, n=5):
:param data: 訓練資料集
:param n: 指定基分類器的數量
:return: 返回整合分類器
train_features = np.array(data.columns)[:-1]
label_feature = np.array(data.columns)[-1]
train_data = data[train_features]
label = data[label_feature]
weight_list = np.ones(len(label))/len(label) #初始化權重
adaboost_clf = []
for _ in np.arange(n):
best_feat, best_threshold, min_em, y_pred,best_flag = build_stump(train_data, weight_list, label)
am = cal_tree_weight(min_em)
weight_list = cal_sample_weight(weight_list,label,y_pred,am)
adaboost_clf.append((am,best_feat,best_threshold,best_flag))
print(weight_list)
print('誤差率:.{} 閾值:.{} flag:.{}'.format(min_em, best_threshold, best_flag))
return adaboost_clf
#分類器預測
def predict(data:pd.DataFrame, clf_list:[]):
y_pred = np.zeros(len(data))
for (am,best_feat,best_threshold,best_flag) in clf_list:
y_pred_tmp = np.ones(len(data))
if best_flag == 'l':
y_pred_tmp[data[best_feat]>best_threshold] = -1
elif best_flag == 'r':
y_pred_tmp[data[best_feat] < best_threshold] = -1
y_pred += am*y_pred_tmp
y_pred[y_pred>0] = 1
y_pred[y_pred<=0] = -1
return y_pred
if __name__ == '__main__':
watermelon = pd.read_csv('data/watermelon45.csv')
watermelon['好瓜'] = watermelon['好瓜'].map({'是':1,'否':-1})
print(watermelon)
# feat_value_list = [0,1,2,3,4,5,6,7,8,9]
# df = pd.DataFrame(columns=['feat1','feat2'])
# y_true = [1, 1, 1, -1, -1, -1, 1, 1, 1, -1]
# df['feat1'] = feat_value_list
# df['feat2'] = feat_value_list
# df['label'] = y_true
# weight_list = [0.1,0.1,0.1,0.1,0.1,0.1,0.1,0.1,0.1,0.1]
# print(build_stump(df,weight_list,y_true))
clf_list = build_adaboost_classifier(watermelon, n=11)
y_pred = predict(watermelon, clf_list)
print(list(watermelon['好瓜']))
print(y_pred)
print(np.sum(np.ones(len(y_pred))[y_pred!=list(watermelon['好瓜'])]))
2.AdaBoost迴歸
2.1基本思想
AdaBoost用於迴歸問題時也是採用前向分步演算法的思想,基函式使用迴歸樹
T
(
x
)
T(x)
T(x)(迴歸樹的原理可以參考機器學習決策樹DecisionTree以及python程式碼實現),損失函式使用平方誤差損失
L
(
y
,
f
(
x
)
)
=
(
y
−
f
(
x
)
)
2
L(y,f(x))=(y-f(x))^2
L(y,f(x))=(y−f(x))2,根據前向分步演算法的思想,我們當前m輪的加法模型就是
f
m
(
x
)
=
f
m
−
1
(
x
)
+
T
m
(
x
)
f_{m}(x)=f_{m-1}(x)+T_m(x)
fm(x)=fm−1(x)+Tm(x),假設我們已經經過m-1輪得到了
f
m
−
1
(
x
)
f_{m-1}(x)
fm−1(x),那麼我們第m輪的優化目標就變成如下形式:
a
r
g
m
i
n
T
m
∑
i
=
1
N
L
(
y
i
,
f
m
−
1
(
x
i
)
+
T
m
(
x
i
)
)
2
⇒
a
r
g
m
i
n
T
m
∑
i
=
1
N
(
y
i
−
f
m
−
1
(
x
i
)
−
T
m
(
x
i
)
)
2
⇒
a
r
g
m
i
n
T
m
∑
i
=
1
N
(
r
m
,
i
−
T
m
(
x
i
)
)
2
argmin_{T_m}\sum_{i=1}^{N}L(y_i,f_{m-1}(x_i)+T_m(x_i))^2\\\Rarr argmin_{T_m}\sum_{i=1}^{N}(y_i-f_{m-1}(x_i)-T_m(x_i))^2\\\Rarr argmin_{T_m}\sum_{i=1}^{N}(r_{m,i}-T_m(x_i))^2
argminTmi=1∑NL(yi,fm−1(xi)+Tm(xi))2⇒argminTmi=1∑N(yi−fm−1(xi)−Tm(xi))2⇒argminTmi=1∑N(rm,i−Tm(xi))2
其中,
r
m
,
i
=
y
i
−
f
m
−
1
(
x
i
)
r_{m,i}=y_i-f_{m-1}(x_i)
rm,i=yi−fm−1(xi)表示當前模型的殘差(即當前模型預測值和真實值的差),所以第m輪的優化目標就變成去擬合當前模型
f
m
−
1
(
x
)
f_{m-1}(x)
fm−1(x)的殘差,所以我們只需要每一輪使用一個迴歸樹去擬合殘差即可,最後將模型線性相加即可。
2.2演算法的具體步驟:
輸入:訓練資料集
T
=
{
(
x
1
,
y
1
)
,
(
x
2
,
y
2
)
,
.
.
.
,
(
x
N
,
y
N
)
}
T=\{(x_1,y_1),(x_2,y_2),...,(x_N,y_N)\}
T={(x1,y1),(x2,y2),...,(xN,yN)},
x
∈
R
n
,
y
∈
R
x\in R^n, y\in R
x∈Rn,y∈R
輸出:提升樹
- 初始化 f 0 ( x ) = 0 f_0(x)=0 f0(x)=0
- 對m=1,2,…,M。
(1)計算殘差: r m , i = y i − f m − 1 ( x i ) , i = 1 , 2 , . . . , N r_{m,i}=y_i-f_{m-1}(x_i), i=1,2,...,N rm,i=yi−fm−1(xi),i=1,2,...,N
(2)通過擬合 r m , i r_{m,i} rm,i構建一個迴歸樹 T m ( x ) T_m(x) Tm(x)
(3)更新: f m ( x ) = f m − 1 ( x ) + T m ( x ) f_m(x)=f_{m-1}(x)+T_{m}(x) fm(x)=fm−1(x)+Tm(x) - 得到迴歸提升樹: f M ( x ) = ∑ m = 1 M T m ( x ) f_M(x)=\sum_{m=1}^MT_m(x) fM(x)=∑m=1MTm(x)
2.3python實現
這裡我們呼叫的前面決策樹中實現的迴歸樹,來構建一個簡易版的提升樹。
import numpy as np
import pandas as pd
from DecisionTree import decisiontreeRegressor
'''構建迴歸樹為基模型的提升樹迴歸模型'''
def build_adaboost_regressor(data:pd.DataFrame, n=5):
'''
:param data: 訓練集
:param n: 基分類器的數量,基模型預設使用max_depth=1的迴歸樹
:return:
'''
adaboost_regressor = [] #整合模型
train_data = data[np.array(data.columns)[:-1]]
y_true = data[np.array(data.columns)[-1]]
base_model = decisiontreeRegressor.build_regressionTree(train_data, y_true, cur_depth=1,max_depth=1)
y_pred = decisiontreeRegressor.predict(base_model, train_data) #當前加法模型的預測結果
adaboost_regressor.append(base_model)
for _ in np.arange(n-1):
r = y_true - y_pred #當前模型和真實值的殘差
# print('mse:.{}'.format(np.sum(r**2)))
base_model = decisiontreeRegressor.build_regressionTree(train_data, r, cur_depth=1, max_depth=1)
r_pred = decisiontreeRegressor.predict(base_model, train_data)
y_pred = y_pred + r_pred # 模型相加的預測結果
adaboost_regressor.append(base_model)
return adaboost_regressor
def predict(data:pd.DataFrame, model:[]):
y_pred = np.zeros(len(data))
for base_model in model:
y_pred += decisiontreeRegressor.predict(base_model, data)
return y_pred
if __name__ == '__main__':
df = pd.DataFrame(columns=['x1'])
df['x1'] = [1, 2, 3, 4, 5, 6, 7, 8, 9, 10]
y_true = [5.56, 5.70, 5.91, 6.40, 6.80, 7.05, 8.90, 8.70, 9.00, 9.05]
df['y'] = y_true
tree_list = build_adaboost_regressor(df, 6)
for tree in tree_list:
print(tree)
y_pred = predict(df.loc[:,['x1']],tree_list)
# print(np.sum((y_pred-y_true)**2)/len(y_pred))
相關文章
- 《應用迴歸及分類》學習筆記1筆記
- 《機器學習Python實現_10_02_整合學習_boosting_adaboost分類器實現》機器學習Python
- 《機器學習Python實現_10_06_整合學習_boosting_gbdt分類實現》機器學習Python
- 分類演算法(1)-LR邏輯迴歸演算法邏輯迴歸
- 分類演算法-邏輯迴歸與二分類演算法邏輯迴歸
- 李巨集毅機器學習課程筆記-4.1分類簡介及其與迴歸的區別機器學習筆記
- 學習筆記——機器學習演算法(一): 基於邏輯迴歸的分類預測筆記機器學習演算法邏輯迴歸
- Mahout分類演算法學習之實現Naive Bayes分類示例演算法AI
- 教程 | 用Scikit-Learn實現多類別文字分類文字分類
- 遞迴和非遞迴分別實現求n的階乘遞迴
- 機器學習之分類迴歸樹(python實現CART)機器學習Python
- 邏輯迴歸求解二分類問題以及SPSS的實現邏輯迴歸SPSS
- Python學習筆記-StatsModels 統計迴歸(1)線性迴歸Python筆記
- 從零開始利用Python建立邏輯迴歸分類模型Python邏輯迴歸模型
- Java學習關於時間操作的應用類--Date類、Calendar類及其子類Java
- 用Python實現一個SVM分類器策略Python
- 【NLP】TensorFlow實現CNN用於文字分類(譯)CNN文字分類
- Andrew NG 深度學習課程筆記:二元分類與 Logistic 迴歸深度學習筆記
- 迴歸分析類別
- 乾貨 | 深度學習在文字分類中的應用深度學習文字分類
- 概率分類之樸素貝葉斯分類(垃圾郵件分類python實現)Python
- 【問題3】:Kaggle練習題《房價預測》----分別採用的嶺迴歸,隨機森林,bagging模型,AdaBoost,XgBoost等。隨機森林模型
- 統計學習方法——實現AdaBoost
- 通用mapper和分類實現APP
- 機器學習演算法(一): 基於邏輯迴歸的分類預測機器學習演算法邏輯迴歸
- python 採用pandas的DataFrame實現對數字型別用均值填補和分類型別用眾數填補Python型別
- 基於Pytorch實現貓狗分類PyTorch
- 線段樹差分及其應用
- 使用sklearn實現svm--用於機械故障分類
- 【NLP】TensorFlow實現CNN用於中文文字分類CNN文字分類
- Java學習--異常處理及其應用類Java
- 《機器學習Python實現_10_10_整合學習_xgboost_原理介紹及迴歸樹的簡單實現》機器學習Python
- 如何用 Python 和深度遷移學習做文字分類?Python遷移學習文字分類
- 採用線性迴歸實現訓練和預測(Python)Python
- 三、邏輯迴歸logistic regression——分類問題邏輯迴歸
- 機器學習(三):理解邏輯迴歸及二分類、多分類程式碼實踐機器學習邏輯迴歸
- python實現線性迴歸之簡單迴歸Python
- 強化學習分類強化學習