【Python機器學習】之 Boosting算法

 2023-12-25 阅读 33 评论 0

摘要:Boosting 1、Boosting 1.1、Boosting算法 ? Boosting算法核心思想: 1.2、Boosting實例 ? 使用Boosting進行年齡預測: 2、XGBoosting ? XGBoost 是 GBDT 的一種改進形式,具有很好的性能。 2.1、XGBoosting 推導 ? 經過 k 輪迭代后,GBDT/GBRT 的損失

Boosting

1、Boosting

1.1、Boosting算法

? Boosting算法核心思想:

在這里插入圖片描述

1.2、Boosting實例

? 使用Boosting進行年齡預測:

在這里插入圖片描述
在這里插入圖片描述
在這里插入圖片描述
在這里插入圖片描述

2、XGBoosting

? XGBoost 是 GBDT 的一種改進形式,具有很好的性能。

在這里插入圖片描述

2.1、XGBoosting 推導

? 經過 k 輪迭代后,GBDT/GBRT 的損失函數可以寫成 L(y,fk(x))L(y, f_k(x))L(y,fk?(x)),將fk(x)f_k(x)fk?(x)視為遍歷(是一個復合型變量),對 L(y,fk(x))L(y, f_k(x))L(y,fk?(x))fk?1(x)f_{k-1}(x)fk?1?(x) 處進行二階泰勒展開,可得:
L(y,fk(x))≈L(y,fk?1(x))+?L(y,fk?1(x))?fk(x)[fk(x)?fk?1(x)]+12×?2L(y,fk?1(x))?2fk?1(x)[fk(x)?fk?1(x)]2L(y, f_k(x)) \\ ≈ L(y, f_{k-1}(x) ) + \frac{\partial L(y, f_{k-1}(x) )}{\partial f_{k}(x)}[f_k(x) \ - f_{k-1}(x) ] \ + \ \frac{1}{2} × \frac{\partial ^2 L(y, f_{k-1}(x) )}{\partial ^2 f_{k-1}(x)}[f_k(x) \ - f_{k-1}(x) ]^2 L(y,fk?(x))L(y,fk?1?(x))+?fk?(x)?L(y,fk?1?(x))?[fk?(x)??fk?1?(x)]?+?21?×?2fk?1?(x)?2L(y,fk?1?(x))?[fk?(x)??fk?1?(x)]2
? 然后取 g=?L(y,fk?1(x))?fk(x)g = \frac{\partial L(y, f_{k-1}(x) )}{\partial f_{k}(x)}g=?fk?(x)?L(y,fk?1?(x))?h=?2L(y,fk?1(x))?2fk(x)h = \frac{\partial ^2L(y, f_{k-1}(x) )}{\partial ^2f_{k}(x)}h=?2fk?(x)?2L(y,fk?1?(x))? ,即 ggghhh 分別代表一階導數和二階導數,所以,展開式可以變形得:
L(y,fk(x))≈L(y,fk?1(x))+g[fk(x)?fk?1(x)]+12h[fk(x)?fk?1(x)]2L(y, f_k(x)) ≈ L(y, f_{k-1}(x) ) + g[f_k(x) \ - f_{k-1}(x) ] \ + \ \frac{1}{2}h[f_k(x) \ - f_{k-1}(x) ]^2 L(y,fk?(x))L(y,fk?1?(x))+g[fk?(x)??fk?1?(x)]?+?21?h[fk?(x)??fk?1?(x)]2
? 又因為在 GBDT 中,利用前向分布算法,有 fk(x)=fk?1(x)+Tk(x)f_k(x) \ = f_{k-1}(x) + T_k(x)fk?(x)?=fk?1?(x)+Tk?(x),即:
fk(x)?fk?1(x)=Tk(x)f_k(x) \ - f_{k-1}(x) \ = T_k(x) fk?(x)??fk?1?(x)?=Tk?(x)
? 代入上式,可得:
L(y,fk(x))≈L(y,fk?1(x))+g?Tk(x)+12h?Tk2(x)L(y, f_k(x)) ≈ L(y, f_{k-1}(x) ) + g \cdot T_k(x) \ + \ \frac{1}{2}h \cdot T^2_k(x) L(y,fk?(x))L(y,fk?1?(x))+g?Tk?(x)?+?21?h?Tk2?(x)
? 上面的損失函數還是對于一個樣本數據而言,對于整體樣本數據,損失函數可得:
L=∑i=1NL(y,fk(x))≈∑i=1N[L(y,fk?1(x))+g?Tk(x)+12h?Tk2(x)]L = \sum\limits^N_{i=1} L(y, f_k(x)) ≈ \sum\limits^N_{i=1} [ L(y, f_{k-1}(x) ) + g \cdot T_k(x) \ + \ \frac{1}{2}h \cdot T^2_k(x) ] L=i=1N?L(y,fk?(x))i=1N?[L(y,fk?1?(x))+g?Tk?(x)?+?21?h?Tk2?(x)]
? 等式右邊中的第一項 L(y,fk?1(x))L(y, f_{k-1}(x) )L(y,fk?1?(x)) 只與前 k-1 輪有關,第 k 輪優化中可將該項視為常數。在 GBDT 中的損失函數上再加上一項與第 k 輪的基學習器 CART 決策樹相關的正則化項 Ω(Tk(x))\Omega (T_k(x))Ω(Tk?(x)) 防止過擬合,可得到新的第 k 輪迭代時的等價損失函數:
Lk=∑i=1N[gi?Tk(xi)+12hi?Tk2(xi)]+Ω(Tk(x))L_k = \sum\limits^N_{i=1} [ \ g_i \cdot T_k(x_i) \ + \ \frac{1}{2}h_i \cdot T^2_k(x_i) \ ] \ + \Omega (T_k(x)) Lk?=i=1N?[?gi??Tk?(xi?)?+?21?hi??Tk2?(xi?)?]?+Ω(Tk?(x))
? 所以,LkL_kLk? 就是 XGBoost 模型的損失函數。

? 假設第 k 棵 CART 回歸樹其對一個的葉子區域樣本子集為 Dk1,Dk2,...,DkTD_{k1}, D_{k2}, ... ,D_{kT}Dk1?,Dk2?,...,DkT?,且第 jjj 個小單元 DkjD_{kj}Dkj? 中仍然包含 NkjN_{kj}Nkj? 個樣本數據,則計算每個小單元里面的樣本的輸出均值為:
c ̄kj=1Nkj∑xi∈Dkjyi\overline c_{kj} = \frac{1}{N_{kj}}\sum\limits_{x_i \in D_{kj}} y_i ckj?=Nkj?1?xi?Dkj??yi?
? 得到:
Tk(x)=∑j=1Tc ̄kj?I(xi∈Dkj)T_k(x) = \sum\limits_{j=1}^T \overline c_{kj} \cdot I( x_i \in D_{kj} ) Tk?(x)=j=1T?ckj??I(xi?Dkj?)
? 正則化項 Ω(Tk(x))\Omega (T_k(x))Ω(Tk?(x)) 的構造如下:
Ω(Tk(x))=γT+12γ∑j=1Tc ̄kj2\Omega (T_k(x)) = \gamma \ T + \frac{1}{2}\gamma \sum\limits_{j=1}^T \overline c_{kj}^2 Ω(Tk?(x))=γ?T+21?γj=1T?ckj2?
? 其中, 參數 TTTTk(x)T_k(x)Tk?(x) 決策樹的葉子節點的個數,參數 c ̄kj,j=1,2,...,T\overline c_{kj} ,j=1,2,...,Tckj?j=1,2,...,T,是第 jjj 個葉子節點的輸出均值;γ\gammaγλ\lambdaλ 是兩個權衡因子。葉子節點的數量及權重因子一起用來控制決策樹模型的復雜度。

? 將 Tk(x)T_k(x)Tk?(x)Ω(Tk(x))\Omega (T_k(x))Ω(Tk?(x)) 一起帶入 LkL_{k}Lk? ,可得:
Lk=∑i=1N[gi?Tk(xi)+12hi?Tk2(xi)]+Ω(Tk(x))=∑i=1N[gi?Tk(xi)+12hi?Tk2(xi)]+γT+12γ∑j=1Tc ̄kj2=∑i=1N[(∑xi∈Dkjgi)?c ̄kj+12(∑xi∈Dkjhi+λ)(c ̄kj)2]+γTL_k = \sum\limits^N_{i=1} [ \ g_i \cdot T_k(x_i) \ + \ \frac{1}{2}h_i \cdot T^2_k(x_i) \ ] \ + \Omega (T_k(x)) \\ = \sum\limits^N_{i=1} [ \ g_i \cdot T_k(x_i) \ + \ \frac{1}{2}h_i \cdot T^2_k(x_i) \ ] \ +\gamma \ T + \frac{1}{2}\gamma \sum\limits_{j=1}^T \overline c_{kj}^2 \\ = \sum\limits^N_{i=1}[ (\sum\limits_{x_i \in D_{kj}}g_i)\cdot \overline c_{kj} + \frac{1}{2}(\sum\limits_{x_i \in D_{kj}} h_i + \lambda) (\overline c_{kj})^2] + \gamma \ T Lk?=i=1N?[?gi??Tk?(xi?)?+?21?hi??Tk2?(xi?)?]?+Ω(Tk?(x))=i=1N?[?gi??Tk?(xi?)?+?21?hi??Tk2?(xi?)?]?+γ?T+21?γj=1T?ckj2?=i=1N?[(xi?Dkj??gi?)?ckj?+21?(xi?Dkj??hi?+λ)(ckj?)2]+γ?T

? 由上公式可知,XGBoost 模型對應的損失函數 LkL_kLk? 主要與原損失函數的一階、二階梯度在當前模型的值 gi、hig_i 、h_igi?hi? 及第 kkk 棵 CART 樹的葉子節點參數值 c ̄kj\overline c_{kj}ckj? 有關,而 gi、hig_i 、h_igi?hi? 與第 kkk 輪迭代無關,所以將其當做常數,在要訓練第 kkk 棵 CART 樹,只需要考慮 c ̄kj\overline c_{kj}ckj? 參數。

? 對 ckjc_{kj}ckj? 求導并令其導數等于 0 ,可得:
?Lk?c ̄kj=∑j=1T[(∑xi∈Dkjgi)+(∑xi∈Dkjhi+λ)?c ̄kj]=0\frac{\partial L_k}{\partial \overline c_{kj}} = \sum\limits^T_{j=1}[ (\sum\limits_{x_i \in D_{kj}}g_i) + (\sum\limits_{x_i \in D_{kj}} h_i + \lambda) \cdot \overline c_{kj}] = 0 \\ ?ckj??Lk??=j=1T?[(xi?Dkj??gi?)+(xi?Dkj??hi?+λ)?ckj?]=0

c ̄kj=?∑xi∈Dkjgi∑xi∈Dkjhi+λ\overline c_{kj} = -\frac{\sum\limits_{x_i \in D_{kj}}g_i}{\sum\limits_{x_i \in D_{kj}} h_i + \lambda} ckj?=?xi?Dkj??hi?+λxi?Dkj??gi??

? 將其帶入上式可得第 kkk 輪迭代時等價的損失函數為:
Lk=?12∑j=1T[(∑xi∈Dkjgi)2(∑xi∈Dkjhi+λ)]+λTL_k = - \frac{1}{2}\sum\limits^T_{j=1}[ \frac{(\sum\limits_{x_i \in D_{kj}}g_i)^2}{(\sum\limits_{x_i \in D_{kj}} h_i + \lambda)} ] + \lambda T Lk?=?21?j=1T?[(xi?Dkj??hi?+λ)(xi?Dkj??gi?)2?]+λT
? 實際上,第 kkk 輪迭代的損失函數的優化過程對應的就是第 kkk 棵樹的分裂過程:每次分裂對應于將屬于某個葉子結點下的訓練樣本分配到兩個新的葉子節點上;而損失函數滿足樣本之間的累積性,所以可以通過將分裂前葉子節點上所有樣本的損失函數與分裂之后兩個新葉子節點上的樣本的損失函數進行比較,以此作為各個特征分裂點的打分標準;最后選擇一個生成該樹的最佳分裂方案。

? 在實踐中,當訓練數據量較大時,不可能窮舉出每一棵樹進行打分來選擇最好的,因為這個過程計算量太大。所以,通常采用貪心算法的方式來進行逐層選擇最佳分裂點。假設一個葉子節點 III 分裂成兩個新的葉子節點 ILI_LIL?IRI_RIR? ,則該節點分裂產生的增益為:
Gsplit=12[(∑xi∈ILgi)2(∑xi∈ILhi+λ)+(∑xi∈IRgi)2(∑xi∈IRhi+λ)?(∑xi∈Igi)2(∑xi∈Ihi+λ)]?γG_{split} = \frac{1}{2}[ \frac{(\sum\limits_{x_i \in I_{L}}g_i)^2}{(\sum\limits_{x_i \in I_{L}} h_i + \lambda)} + \frac{(\sum\limits_{x_i \in I_{R}}g_i)^2}{(\sum\limits_{x_i \in I_{R}} h_i + \lambda)} - \frac{(\sum\limits_{x_i \in I}g_i)^2}{(\sum\limits_{x_i \in I} h_i + \lambda)} ] - \gamma Gsplit?=21?[(xi?IL??hi?+λ)(xi?IL??gi?)2?+(xi?IR??hi?+λ)(xi?IR??gi?)2??(xi?I?hi?+λ)(xi?I?gi?)2?]?γ
? 上面的 GsplitG_{split}Gsplit? 表示的就是一個葉子節點 III 按照某特征下的某分裂點分成兩個新的葉子節點 ILI_LIL?IRI_RIR? 后可以得到的“增益”,該增益值與模型的損失函數值成負相關關系(因為在損失函數的基礎上取了負號),即該值越大,就表示按照該分裂方式分裂可以使模型的整體損失減小得越多。

? 所以,XGBoost 采用的是解析解思維,即對損失函數進行二階泰勒展開,求得解析解,然后用這個解析解作為“增益”來輔助簡歷 CART 回歸樹,最終使得整體損失達到最優。

3、XGBoosting 實踐

  1. 讀取數據
import os
import pandas as pd
import numpy as npfrom sklearn.model_selection import train_test_split
from sklearn.ensemble import RandomForestClassifier
from sklearn.metrics import accuracy_score
import matplotlib.pyplot as plt
import seaborn as sns
%matplotlib inlineimport xgboost as xgbdf = pd.read_csv('LoanStats3a 2.csv',low_memory=False,skiprows=1)
print(df.shape)
df.head()
(42538, 144)

在這里插入圖片描述

  1. 數據預處理
df = df.iloc[:,2:111]  # 刪掉很多空的列
empty_cols = [i for i in range(45,72)]   # 刪除更多的列
df = df.drop(df.columns[empty_cols],axis=1)
df.shapedf = df[(df['loan_status']=="Fully Paid") | (df['loan_status']=="Charged Off")]
df['loan_status'] = df['loan_status'].map({'Fully Paid':0, 'Charged Off':1})
df=df.dropna(axis=1) #340000 is minimum number of non-NA values
df

在這里插入圖片描述

  1. 數據獨熱編碼
df_grade = df['grade'].str.get_dummies().add_prefix('grade: ')
# 把類型獨熱編碼
df_subgrad = df['sub_grade'].apply(str).str.get_dummies().add_prefix('sub_grade: ')
df_home = df['home_ownership'].apply(str).str.get_dummies().add_prefix('home_ownership: ')
df_addr = df['addr_state'].apply(str).str.get_dummies().add_prefix('addr_state: ')
df_term = df['term'].apply(str).str.get_dummies().add_prefix('term: ')# 添加獨熱編碼數據列
df = pd.concat([df, df_grade, df_subgrad, df_home, df_addr, df_term], axis=1)
# 去除獨熱編碼對應的原始列
df = df.drop(['grade', 'sub_grade', 'home_ownership', 'addr_state', 'int_rate', 'term', 'zip_code','purpose','initial_list_status','initial_list_status','pymnt_plan','issue_d','earliest_cr_line','verification_status'], axis=1)
  1. 準備數據
# 準備數據
X = df.drop('loan_status', axis=1)
y = df['loan_status']
print (X.shape, y.shape)
(39786, 122) (39786,)
  1. 預測的實現
X_train, X_test, y_train, y_test = train_test_split(X, y, test_size=0.2, random_state=123)
xg_classifier = xgb.XGBClassifier(objective ='binary:logistic', colsample_bytree = 0.3, learning_rate = 0.1,max_depth = 5, alpha = 10, n_estimators = 10)xg_classifier.fit(X_train,y_train)
xg_classifier.score(X_test, y_test)
0.9889419452123649

文中實例及參考:

  • 《機器學習基礎》
  • 貪心學院,https://www.greedyai.com

版权声明:本站所有资料均为网友推荐收集整理而来,仅供学习和研究交流使用。

原文链接:https://808629.com/196854.html

发表评论:

本站为非赢利网站,部分文章来源或改编自互联网及其他公众平台,主要目的在于分享信息,版权归原作者所有,内容仅供读者参考,如有侵权请联系我们删除!

Copyright © 2022 86后生记录生活 Inc. 保留所有权利。

底部版权信息