日韩性视频-久久久蜜桃-www中文字幕-在线中文字幕av-亚洲欧美一区二区三区四区-撸久久-香蕉视频一区-久久无码精品丰满人妻-国产高潮av-激情福利社-日韩av网址大全-国产精品久久999-日本五十路在线-性欧美在线-久久99精品波多结衣一区-男女午夜免费视频-黑人极品ⅴideos精品欧美棵-人人妻人人澡人人爽精品欧美一区-日韩一区在线看-欧美a级在线免费观看

歡迎訪問 生活随笔!

生活随笔

當前位置: 首頁 > 编程语言 > python >内容正文

python

【机器学习基础】数学推导+纯Python实现机器学习算法17:XGBoost

發布時間:2025/3/8 python 21 豆豆
生活随笔 收集整理的這篇文章主要介紹了 【机器学习基础】数学推导+纯Python实现机器学习算法17:XGBoost 小編覺得挺不錯的,現在分享給大家,幫大家做個參考.

Python機器學習算法實現

Author:louwill

Machine Learning Lab

? ? ?

???? 自從陳天奇于2015年提出XGBoost以來,該模型就一直在各大數據競賽中當作大殺器被頻繁祭出。速度快、效果好是XGBoost的最大優點。XGBoost與GBDT同出一脈,都屬于boosting集成學習算法,但XGBoost相較于GBDT要青出于藍而勝于藍。

???? XGBoost的全程為eXtreme Gradient Boosting,即極端梯度提升樹。要深入理解整個XGBoost模型系統,建議還是要認真研讀陳天奇的 XGBoost: A Scalable Tree Boosting System 論文,深入損失函數的推導,這樣才能更好的掌握XGBoost。本文僅對模型最重要的部分,即XGBoost損失函數的數學推導過程和結點分裂的增益計算方式進行闡述。

XGBoost原理推導

???? 既然XGBoost整體上仍然屬于GBDT系統,那么XGBoost也一定是由多個基模型組成的一個加法模型,所以XGBoost可表示為:

???? 假設?第??次迭代要訓練的樹模型是??,可得:

???? 下面進入正題,推導XGBoost損失函數:

???? 損失函數原始形式可表示為:

???? 其中,??為損失函數的正則化項,表示全部??棵樹的復雜度之和,旨在防止模型過擬合。

???? XGBoost來自于GBDT,同樣也適用前向分步算法,以第??步的模型為例,模型對第??個樣本??的預測值為:

???? 其中,??是由第 ?? 步的模型給出的預測值,作為一個已知常數存在, ?? 是第??步樹模型的預測值。所以,目標函數可以改寫為:

???? 同時也可以對正則化項進行拆分,由于前?棵樹的結構已經確定,因此前?? 棵樹的復雜度之和也可以表示為常數:

???? 然后我們使用二階泰勒公式(這里需要大家回顧微積分相關知識),可以將損失函數改寫為:

???? 其中,??為損失函數的一階導,??為損失函數的二階導,需要注意的是這里是對??求導。XGBoost相較于GBDT而言用到了二階導數信息,所以如果要自定義損失函數,首要的要求是其二階可導。

???? 以平方損失函數為例:

???? 則有:

???? 將該二階泰勒展開式帶入前述推導的XGBoost損失函數中,可得損失函數的近似表達式:

???? 對上式去除相關常數項,簡化后的損失函數為:

???? 所以只需要求出每一步損失函數的一階導和二階導的值,然后最優化目標函數,就可以得到每一步的??,最后根據加法模型得到一個boosting模型。

???? 然后重新定義一棵決策樹,其包括兩個部分:葉子結點的權重向量??和實例(樣本)到葉子結點的映射關系??(本質是樹的分支結構);

???? 所以一顆樹的數學表達為:

???? 再來看定義模型復雜度的正則化項。模型復雜度??可由單棵樹的葉子結點數 ???和葉子權重 ?? ,具體來說損失函數的復雜度由所有樹的葉子結點數和葉子權重所決定。數學表達如下式所示:

???? 然后我們對所有葉子結點進行重新歸組。將屬于第??個葉子結點的所有樣本??劃入到一個葉子結點的樣本集合中,即:??,從而XGBoost的目標函數可以改寫為:

定義??,??簡化一下表達,含義如下:

  • ?:葉子結點 ?? 所包含樣本的一階偏導數累加之和,是一個常量;

  • ?:葉子結點 ?? 所包含樣本的二階偏導數累加之和,是一個常量;

將??和??帶入前述XGBoost損失函數,可得最終的損失函數表達式為:

根據一元二次方程的求解公式,可得:

代入到XGBoost的最終損失函數,可得損失為:

對于每個葉子結點 ??將其從目標函數中拆解出來,有:

???? 由前述推導可知,??和??相對于第??棵樹來說是可以計算出來的。所以該式就是一個只包含一個變量葉子結點權重??的一元二次函數,可根據最值公式求其最值點。當相互獨立的每棵樹的葉子結點都達到最優值時,整個損失函數也相應的達到最優。

???? 當樹結構固定的情況下,對上式求導并令其為0,可得最優點和最優值為:

???? 以上就是XGBoost完整的損失函數推導過程。基本框架仍然是GBDT框架,但XGBoost的最大特色是用到了損失函數的二階導數信息,目的就在于能夠更加準確的逼近真實損失。

???? 下圖是XGBoost論文中給出的葉子結點權重計算:

???? 根據二階導信息把XGBoost的優化推到了極為逼近真實損失的狀態,其結點分裂方式就跟CART樹的結點分裂方式本質上并沒有太大區別,但信息增益的計算方式有所不同。

???? 假設模型在某一節點完成特征分裂,分裂前的目標函數可以寫為:

???? 分裂后的目標函數為:

???? 則對于目標函數來說,分裂后的收益為:

???? 如果增益Gain>0,即分裂為兩個葉子節點后,目標函數下降了,則考慮此次分裂的結果。實際處理時需要遍歷所有特征尋找最佳分裂特征。

???? 以上就是XGBoost模型核心數學推導部分。完整的XGBoost模型還有很多工程上的細節,這里不做過多闡述,各位讀者最好把XGBoost論文認真研讀一遍。完整的XGBoost推導示意圖如下所示。

XGBoost算法實現

???? 有了GBDT的算法實現經驗,XGBoost實現起來就并沒有太多困難了,大多數底層代碼都較為類似,主要是在信息增益計算、葉子得分計算和損失函數的二階導信息上做一些變動。同樣先列出代碼框架:

???? 底層的決策樹結點和樹模型定義基本差別不大,具體這里不再列出,可參考第15講GBDT實現方式。主要是繼承底層的樹結點和樹來定義XGBoost單棵樹和XGBoost樹模型擬合方式。

???? 定義XGBoost單棵樹模型如下:

class XGBoostTree(Tree):# 結點分裂def _split(self, y):col = int(np.shape(y)[1]/2)y, y_pred = y[:, :col], y[:, col:]return y, y_pred# 信息增益計算公式def _gain(self, y, y_pred):Gradient = np.power((y * self.loss.gradient(y, y_pred)).sum(), 2)Hessian = self.loss.hess(y, y_pred).sum()return 0.5 * (Gradient / Hessian)# 樹分裂增益計算def _gain_by_taylor(self, y, y1, y2):# 結點分裂y, y_pred = self._split(y)y1, y1_pred = self._split(y1)y2, y2_pred = self._split(y2)true_gain = self._gain(y1, y1_pred)false_gain = self._gain(y2, y2_pred)gain = self._gain(y, y_pred)return true_gain + false_gain - gain# 葉子結點最優權重def _approximate_update(self, y):# y split into y, y_predy, y_pred = self._split(y)# Newton's Methodgradient = np.sum(y * self.loss.gradient(y, y_pred), axis=0)hessian = np.sum(self.loss.hess(y, y_pred), axis=0)update_approximation = gradient / hessianreturn update_approximation# 樹擬合方法def fit(self, X, y):self._impurity_calculation = self._gain_by_taylorself._leaf_value_calculation = self._approximate_updatesuper(XGBoostTree, self).fit(X, y)

???? 然后根據前向分步算法定義XGBoost模型:

class XGBoost(object):def __init__(self, n_estimators=200, learning_rate=0.001, min_samples_split=2,min_impurity=1e-7, max_depth=2):self.n_estimators = n_estimators # Number of treesself.learning_rate = learning_rate # Step size for weight updateself.min_samples_split = min_samples_split # The minimum n of sampels to justify splitself.min_impurity = min_impurity # Minimum variance reduction to continueself.max_depth = max_depth # Maximum depth for tree# 交叉熵損失self.loss = LogisticLoss()# 初始化模型self.estimators = []# 前向分步訓練for _ in range(n_estimators):tree = XGBoostTree(min_samples_split=self.min_samples_split,min_impurity=min_impurity,max_depth=self.max_depth,loss=self.loss)self.estimators.append(tree)def fit(self, X, y):y = to_categorical(y)y_pred = np.zeros(np.shape(y))for?i?in?range(self.n_estimators):tree = self.trees[i]y_and_pred = np.concatenate((y, y_pred), axis=1)tree.fit(X, y_and_pred)update_pred?=?tree.predict(X)y_pred -= np.multiply(self.learning_rate, update_pred)def predict(self, X):y_pred = None# 預測for tree in self.estimators:update_pred = tree.predict(X)if y_pred is None:y_pred = np.zeros_like(update_pred)y_pred -= np.multiply(self.learning_rate, update_pred)y_pred = np.exp(y_pred) / np.sum(np.exp(y_pred), axis=1, keepdims=True)# 將概率預測轉換為標簽y_pred = np.argmax(y_pred, axis=1)return y_pred

???? 使用sklearn數據作為示例:

from?sklearn?import?datasets data = datasets.load_iris() X = data.data y = data.targetX_train,?X_test,?y_train,?y_test?=?train_test_split(X,?y,?test_size=0.4,?seed=2)??clf = XGBoost() clf.fit(X_train, y_train) y_pred = clf.predict(X_test)accuracy?=?accuracy_score(y_test,?y_pred) print ("Accuracy:", accuracy) Accuracy: 0.9666666666666667


???? XGBoost也提供了原生的模型庫可供我們調用。pip安裝xgboost即可:

pip install xgboost

???? 同樣使用sklearn數據集進行測試:

import xgboost as xgb from xgboost import plot_importance from matplotlib import pyplot as plt# 設置模型參數 params = {'booster': 'gbtree','objective': 'multi:softmax', 'num_class': 3, 'gamma': 0.1,'max_depth': 2,'lambda': 2,'subsample': 0.7,'colsample_bytree': 0.7,'min_child_weight': 3,'silent': 1,'eta': 0.001,'seed': 1000,'nthread': 4, }plst = params.items()dtrain = xgb.DMatrix(X_train, y_train) num_rounds = 200 model = xgb.train(plst, dtrain, num_rounds)# 對測試集進行預測 dtest = xgb.DMatrix(X_test) y_pred = model.predict(dtest)# 計算準確率 accuracy = accuracy_score(y_test, y_pred) print ("Accuracy:", accuracy) # 繪制特征重要性 plot_importance(model) plt.show(); Accuracy: 0.9166666666666666

參考資料:

XGBoost: A Scalable Tree Boosting System

https://www.jianshu.com/p/ac1c12f3fba1

往期精彩:

數學推導+純Python實現機器學習算法16:Adaboost

數學推導+純Python實現機器學習算法15:GBDT

數學推導+純Python實現機器學習算法14:Ridge嶺回歸

數學推導+純Python實現機器學習算法13:Lasso回歸

數學推導+純Python實現機器學習算法12:貝葉斯網絡

數學推導+純Python實現機器學習算法11:樸素貝葉斯

數學推導+純Python實現機器學習算法10:線性不可分支持向量機

數學推導+純Python實現機器學習算法8-9:線性可分支持向量機和線性支持向量機

數學推導+純Python實現機器學習算法7:神經網絡

數學推導+純Python實現機器學習算法6:感知機

數學推導+純Python實現機器學習算法5:決策樹之CART算法

數學推導+純Python實現機器學習算法4:決策樹之ID3算法

數學推導+純Python實現機器學習算法3:k近鄰

數學推導+純Python實現機器學習算法2:邏輯回歸

數學推導+純Python實現機器學習算法1:線性回歸

往期精彩回顧適合初學者入門人工智能的路線及資料下載機器學習及深度學習筆記等資料打印機器學習在線手冊深度學習筆記專輯《統計學習方法》的代碼復現專輯 AI基礎下載機器學習的數學基礎專輯獲取一折本站知識星球優惠券,復制鏈接直接打開:https://t.zsxq.com/yFQV7am本站qq群1003271085。加入微信群請掃碼進群: 與50位技術專家面對面20年技術見證,附贈技術全景圖

總結

以上是生活随笔為你收集整理的【机器学习基础】数学推导+纯Python实现机器学习算法17:XGBoost的全部內容,希望文章能夠幫你解決所遇到的問題。

如果覺得生活随笔網站內容還不錯,歡迎將生活随笔推薦給好友。