梯度提升树GBDT-XGBoost

目录

    主要根据贪心科技李文哲老师直播视频记录

一、构造目标函数:

 二、目标函数的近似

三、把树的结构引入目标函数(参数化)

1.参数化

2.参数化

3.利用定义的变量整合目标函数

四、生成树的过程,利用贪心算法

余下部分引自简书:作者:ghostdogss 链接:https://www.jianshu.com/p/2e07e4186cfe

五、Shrinkage and Column Subsampling(XGBoost两种防止过拟合的方法) 

六、近似算法

七、针对稀疏数据的算法(缺失值处理)

八、python实现



    主要根据贪心科技李文哲老师直播视频记录

Bagging与Boosting二者都是由weak learner 组合而成,但有所区别:

Bagging:Leverages unstable base learners that are weak because of Overfitting

----可以理解为‘’多个专家‘’组的组合因过拟合而变弱

Boosting: Leverages stable base learners that are weak because of Underfitting

----多个‘’普通人‘’的组合本身是弱的而欠拟合

Boosting:是基于残差的训练,即以和的形式不断地弥补模型的预测误差。

即预测模型是按照一定顺序迭代生成的(Additive Training)。

给定Model1,但它的预测效果不怎么好,误差比较大,如果我们不能对Model1做任何改变,那么只能在此模型基础上加上新的Model2去拟合Model1预测的残差(真实值-Model1预测值);以此类推,直到Modelk能够达到较好的预测效果(残差较小);

那么,最终预测=Model1预测+Model2预测+...

XGBoost的优点:

算法可以并行,训练效率高;实际效果相对较好;超参数多,可以灵活调整

下面引出理解XGBoost的四个主要部分

1.怎样构造目标函数呢?

2.目标函数难以直接优化,如何近似?

3.如何把树的结构引入到目标函数(参数化)

4.仍然难以优化,使用贪心算法

首先假设我们已经有K棵树

一、构造目标函数:

如前述最终预测等于各个模型预测的加和:

那么,我们有:

\hat{y}_i=\sum_{k=1}^Kf_k(x_i)=\hat{y}_i^{(k-1)}+f_k(x_i), \ f_k\in F                                (1)

其中记\hat{y}_i^{(k-1)}为前k-1颗树的预测值的加和(显然,为已知项)

那么目标(损失)函数为:

Obj=\sum_{i=1}^nl(y_i,\hat{y}_i) \ \ + \ \ \sum_{k=1}^K \Omega (f_k), 即损失函数+正则化项/惩罚项(控制模型复杂度,防止过拟合) (2)

那么,(训练第K棵树时)目标函数可以修改为:

Obj=\sum_{i=1}^nl\left(y_i\ \mathbf{,} \ \hat{y}_i^{(k-1)}+f_k(x_i)\right) \ \ + \ \ \sum_{j=1}^{K-1} \Omega (f_{j})+\Omega(f_k)   (3)

其中第二项\sum_{j=1}^{K-1} \Omega (f_{j})为常数

那么最终目标函数化简为最小化下式

     Obj=\sum_{i=1}^nl\left(y_i\ \mathbf{,} \ \hat{y}_i^{(k-1)}+f_k(x_i)\right) \ \ + \ \ \Omega(f_k)         (4)

 二、目标函数的近似

这里主要利用Taylor(泰勒的二阶展开式来近似目标函数)

Taylor展开式形式如下:

f(x+\Delta x)=f(x)+f'(x)\Delta x+\frac{f''(x)}{2}\Delta^2 x+o(x)

令(4)式中 l\left(y_i,\hat{y}_i^{(k-1)}\right),f_k(x_i)分别记为f(x)\Delta x;那么目标函数可以近似为:\boldsymbol{Obj=\sum_{i=1}^n \left[l\left(y_i,\hat{y}_i^{(k-1)}\right)+\partial_{\hat{y}_i^{(k-1)}}l\left(y_i, \hat{y}_i^{(k-1)}\right)f_k(x_i)+\frac{1}{2}\partial_{\hat{y}_i^{(k-1)}}^2l\left(y_i, \hat{y}_i^{(k-1)}\right)f_k^2(x_i) \right]+ \Omega(f_k)}   (5)

这里在训练第k颗树时,l\left(y_i,\hat{y}_i^{(k-1)}\right),以及前k-1颗树对应的一阶偏导,二阶偏导都是已知(已经计算出来)的。

那么,目标函数就转化为最小化下式:

\boldsymbol{Obj=\sum_{i=1}^n \left[g_if_k(x_i)+\frac{1}{2}h_if_k^2(x_i) \right]+ \Omega(f_k)}               (6)

\boldsymbol{g_i\boldsymbol{}=\partial_{\hat{y}_i^{(k-1)}}l\left(y_i, \hat{y}_i^{(k-1)}\right)}                                                   (7)

\boldsymbol{h_i=\partial_{\hat{y}_i^{(k-1)}}^2l\left(y_i, \hat{y}_i^{(k-1)}\right)}                                                   (8)

然后,我们怎么去定义(参数化)f_k(x_i) 以及 惩罚项\Omega(f_k)

三、把树的结构引入目标函数(参数化)

1.参数化\large \boldsymbol{f_k(x_i)}

首先引入三个变量:

如上图所示

1)叶节点的值(leaf value)的向量\large w:如上图从左到右将叶节点排序那么得到,\large w=\left\{ w1,w2,w3 \right\}=\left \{ 15,12,20 \right \}

2)样本x的位置(sample position)\large q(x):

           ,假设第一个叶节点上有样本{1,3};第二个叶节点上有样本{4};第三个叶节点上有样本{2,5}

    ------那么, 如图所示,\large q(x_1)=1(第一个样本所在的位置)

最后,我们可以得到

                           \large \boldsymbol{f_k(x_i)=w_{q(x_i)}}                                 (9)

但是,对于这种复合函数\large w_{q(x_i)}依然难以去求解和处理

因此,这里又定义了第三个变量:

3)叶节点含有的样本集合\large I_j=\left \{ i|q(x_i)=j \right \},即哪些样本落在第j个叶节点上

           如上图中,\large I_1=\left \{ 1,3 \right \};\large I_2=\left \{ 4\right \};\large I_3=\left \{ 2,5 \right \}

2.参数化\large \boldsymbol{\Omega(f_k)}

树的复杂度通常可以通过两个方面表示:

树的深度/叶结点个数: T

叶节点的值: \large \frac{1}{2}\sum_{j=1}^Tw_j^2

那么我们得到参数化的惩罚项,

\large \Omega(f_k)=\gamma T+\frac{1}{2}\lambda \sum_{j=1}^Tw_j^2                           (10)

3.利用定义的变量\large I整合目标函数

 经过1,2步骤我们可以得到参数化后的目标函数为:

\boldsymbol{Obj=\sum_{i=1}^n \left[g_iw_{q(x_i)}+\frac{1}{2}h_iw_{q(x_i)}^2 \right]+ \gamma T + \frac{1}{2}\lambda \sum_{j=1}^Tw_j^2}   (11)

之前说到,对于w下标含有自变量难以求解,那么我们利用之前定义的I去简化上式:

      因为一个叶节点可能有多个样本,那么这些同一叶节点的样本的值\large \boldsymbol{w_{q(x_i)}}是相等的只有\large \boldsymbol{g_i}不同

  那么,上式可以被化简为:

    \boldsymbol{Obj=\sum_{j=1}^T \left[\left(\sum_{i\in I_j}g_i\right)w_j+\frac{1}{2}\left(\lambda+\sum_{i\in I_j}h_i\right)w_j^2 \right]+ \gamma T }        (12)

不难发现,上式是一个二次优化:ax^2+bx+c的形式:

     那么,目标函数的取得最优的点为:

                    \boldsymbol{w_j^*=-\frac{b}{2a}=-\frac{G_j}{H_j+\lambda}}                                   (13)

                    \boldsymbol{Obj^*=-\frac{1}{2}\sum_{j=1}^T\frac{G_j}{H_j+\lambda}\ + \ \gamma T}                    (14)

                  G_j=\sum_{i\in I_j}g_i     ,    H_j=\sum_{i\in I_j}h_i                                (15)

四、生成树的过程,利用贪心算法

之前的决策树已经知道,树的形状选择(特征划分)是利用信息熵或基尼系数(ID3,C4.5,CART),选择使得不确定性减少最大的那个特征(信息增益最大):

                min[ 不确定性(old) -不确定性(new)]      --------即 选择使得信息不确定性最小(信息增益最大)的特征

那么,对于XGBoost也是类似,只是将信息增益替换为Obj,即按照使得目标函数最小的特征划分:

                max[Obj(old)-Obj(new)]        ---------即选择差值最大的那个特征(表明新的目标函数 Obj(new)最小)

余下部分引自简书:作者:ghostdogss 链接:https://www.jianshu.com/p/2e07e4186cfe

 

五、Shrinkage and Column Subsampling(XGBoost两种防止过拟合的方法) 

XGBoost还提出了两种防止过拟合的方法:Shrinkage and Column Subsampling。

Shrinkage方法就是在每次迭代中对树的每个叶子结点的分数乘上一个缩减权重η,这可以使得每一棵树的影响力不会太大,留下更大的空间给后面生成的树去优化模型。

Column Subsampling类似于随机森林中的选取部分特征进行建树。

      Column Subsampling可分为两种,

一种是按层随机采样,在对同一层内每个结点分裂之前,先随机选择一部分特征,然后只需要遍历这部分的特征,来确定最优的分割点。

另一种是随机选择特征,则建树前随机选择一部分特征然后分裂就只遍历这些特征。

一般情况下前者效果更好。

六、近似算法

对于连续型特征值,当样本数量非常大,该特征取值过多时,遍历所有取值会花费很多时间,且容易过拟合。

因此XGBoost思想是对特征进行分桶,即找到l个划分点,将位于相邻分位点之间的样本分在一个桶中。在遍历该特征的时候,只需要遍历各个分位点,从而计算最优划分。

从算法伪代码中该流程还可以分为两种,全局的近似是在新生成一棵树之前就对各个特征计算分位点并划分样本,之后在每次分裂过程中都采用近似划分,而局部近似就是在具体的某一次分裂节点的过程中采用近似算法。

七、针对稀疏数据的算法(缺失值处理)

当样本的第i个特征值缺失时,无法利用该特征进行划分时,

XGBoost的想法是将该样本分别划分到左结点和右结点,然后计算其增益,哪个大就划分到哪边。

八、python实现

from sklearn import datasets
from sklearn.model_selection import train_test_split
import xgboost as xgb
from sklearn import metrics

# 导入鸢尾花的数据
iris = datasets.load_iris()
# 特征数据
data = iris.data[:100] # 有4个特征
# 标签
label = iris.target[:100]

# 提取训练集和测试集
# random_state:是随机数的种子。
train_x, test_x, train_y, test_y = train_test_split(data, label, random_state=0)

dtrain = xgb.DMatrix(train_x, label = train_y)
dtest = xgb.DMatrix(test_x)

# 参数设置
params={'booster':'gbtree',
    'objective': 'binary:logistic',
    'eval_metric': 'auc',
    'max_depth':4,
    'lambda':10,
    'subsample':0.75,
    'colsample_bytree':0.75,
    'min_child_weight':2,
    'eta': 0.025,
    'seed':0,
    'nthread':8,
     'silent':1}

watchlist = [(dtrain,'train')]

bst=xgb.train(params,dtrain,num_boost_round=100,evals=watchlist)
ypred=bst.predict(dtest)

# 设置阈值, 输出一些评价指标
# 0.5为阈值,ypred >= 0.5输出0或1
y_pred = (ypred >= 0.5)*1

# ROC曲线下与坐标轴围成的面积
print ('AUC: %.4f' % metrics.roc_auc_score(test_y,ypred))
# 准确率
print ('ACC: %.4f' % metrics.accuracy_score(test_y,y_pred))
print ('Recall: %.4f' % metrics.recall_score(test_y,y_pred))
# 精确率和召回率的调和平均数
print ('F1-score: %.4f' %metrics.f1_score(test_y,y_pred))
print ('Precesion: %.4f' %metrics.precision_score(test_y,y_pred))
metrics.confusion_matrix(test_y,y_pred)

 

### 实现CEEMDAN-GBDT-LSTM-XGBoost组合模型 #### 数据预处理与分解阶段 为了构建一个有效的CEEMDAN-GBDT-LSTM-XGBoost混合模型,首先需要利用Complementary Ensemble Empirical Mode Decomposition with Adaptive Noise (CEEMDAN) 对原始时间序列数据进行分解。这一步骤能够帮助提取出信号的不同频率成分,从而使得后续建模更加精准。 ```python import numpy as np from PyEMD import CEEMDAN def decompose_series(time_series_data): ceemdan = CEEMDAN() imfs = ceemdan.ceemdan(np.array(time_series_data)) return imfs.T.tolist() # 转置并转换为列表形式以便于进一步操作 ``` 此函数接收一维的时间序列作为输入,并返回多个内部模式函数(IMFs),这些IMF代表了原序列的不同振荡特性[^1]。 #### 构建GBDT预测组件 Gradient Boosting Decision Tree (GBDT) 是一种强大的机器学习方法,在回归和分类任务上表现优异。对于每一个由CEEMDAN产生的子序列,可以单独训练一个GBDT模型来进行短期趋势的学习: ```python from sklearn.ensemble import GradientBoostingRegressor gbdt_models = [] for i, sub_sequence in enumerate(decompose_series(your_time_series)): gbdt_model = GradientBoostingRegressor(n_estimators=100, learning_rate=0.1, max_depth=3, random_state=i) train_X, test_X, train_y, test_y = prepare_train_test(sub_sequence) # 假设有一个准备训练集的方法 gbdt_model.fit(train_X, train_y) gbdt_models.append(gbdt_model) def predict_gbdt(models, new_input): predictions = [model.predict([new_input]) for model in models] return sum(predictions)/len(predictions) # 平均化各个GBDT的结果 ``` 这段代码展示了如何针对每个IMF创建独立的GBDT实例,并最终通过平均法集成它们的输出以获得整体估计值。 #### LSTM网络设计 Long Short-Term Memory networks (LSTMs) 特别适合捕捉长时间跨度内的依赖关系,非常适合用于金融市场的波动性分析等场景。这里展示了一个简单的Keras/TensorFlow实现方式来定义LSTM架构: ```python from tensorflow.keras.models import Sequential from tensorflow.keras.layers import Dense, LSTM, Dropout lstm_model = Sequential([ LSTM(units=50, return_sequences=True, input_shape=(X.shape[1], 1)), Dropout(0.2), LSTM(units=50), Dropout(0.2), Dense(units=1)]) lstm_model.compile(optimizer='adam', loss='mean_squared_error') history = lstm_model.fit(X_train, y_train, epochs=epochs_num, batch_size=batch_sz) ``` 请注意,实际应用中可能还需要调整超参数以及加入正则化措施防止过拟合等问题的发生。 #### XGBoost增强器配置 Extreme Gradient Boosting (XGBoost) 提供了一种高效的梯度提升框架,它不仅速度快而且性能优越。当与其他技术相结合时,往往能取得更好的效果。下面是如何设置基本的XGBoost回归器的例子: ```python import xgboost as xgb xgb_regressor = xgb.XGBRegressor(objective="reg:squarederror", n_estimators=100, seed=123) xgb_regressor.fit(training_features, target_values) predicted_results = xgb_regressor.predict(testing_features) ``` 在这个过程中,`training_features` 和 `target_values` 应该是从之前步骤得到的数据集中分离出来的特征矩阵和标签向量;而 `testing_features` 则是用来评估模型泛化能力的新样本集合。 最后,将上述三个部分结合起来形成完整的CEEMDAN-GBDT-LSTM-XGBoost体系结构,可以通过加权求和或者其他高级融合策略(比如堆叠)完成最终决策层的设计。具体权重分配可以根据交叉验证结果动态调整优化。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值