欢迎大家来到IT世界,在知识的湖畔探索吧!
对于决策树这个经典算法,前面介绍过随机森林,今天再介绍一个它的典型升级应用,叫做GBDT,它的全称是Gradient Boosting Decision Tree,即梯度提升决策树。它的思路其实很简单,核心思想就两部分:
第一个就是Boosting机制,它会串行的训练多个精度不高的弱模型,比如前面介绍的Cart树,但是每个新模型都会纠正前面的模型的残差(残差就是实际值和预测值之间的差值)。
第二个就是梯度下降,它把优化问题转化为梯度下降的过程,对于梯度下降和偏导数这部分内容就不过多的赘述了,没接触过的朋友可以去参考高等数学的内容。
举一个具体的例子吧,比如我有一堆Cart树用于处理回归问题,第一棵树算出来的残差是50.08,那么第二棵树就只用于优化这个残差部分,假设它算出来的残差是10.44,那么第三部分就再次用来优化这部分残差,假设它算出来的新的残差是2.97,然后这样依次进行下去。因为后续的树都是用来优化前面的残差,所以整体效果不会比优化前更差,这也是“提升”二字的价值所在。
这里给一个GBDT的伪代码实现吧,如下所示:
初始化: F_0(x) = argmin_p ΣL(y_i,p) for m in 1..M: 1. 计算伪残差: r_im = -[∂L(y_i,F(x_i))/∂F(x_i)]_{F(x)=F_{m-1}(x)} 2. 用(x_i,r_im)拟合回归树h_m(x)(叶子节点输出γ_jm) 3. 线搜索步长: ρ_m = argmin_ρ ΣL(y_i, F_{m-1}(x_i)+ρ*h_m(x_i)) 4. 更新模型: F_m(x) = F_{m-1}(x) + ν*ρ_m*h_m(x) # ν是学习率 最终模型: F(x) = F_M(x)
欢迎大家来到IT世界,在知识的湖畔探索吧!
然后来看一个具体的代码实现吧,代码如下所示:
欢迎大家来到IT世界,在知识的湖畔探索吧!import numpy as np import matplotlib.pyplot as plt from sklearn.ensemble import GradientBoostingRegressor from sklearn.model_selection import train_test_split from sklearn.datasets import make_regression from sklearn.metrics import mean_squared_error # 1. 生成示例数据 X, y = make_regression( n_samples=1000, # 样本数量 n_features=10, # 特征数量 noise=0.1, # 噪声比例 random_state=42) X_train, X_valid, y_train, y_valid = train_test_split(X, y, test_size=0.2, random_state=42) # 2. 初始化GBDT模型 model = GradientBoostingRegressor( n_estimators=200, # 树的数量 learning_rate=0.1, # 学习率 max_depth=3, # 每棵树的最大深度 validation_fraction=0.1, # 内部验证集比例 n_iter_no_change=10, # 早停轮数 tol=1e-4, # 早停阈值 random_state=42 ) # 3. 训练模型 model.fit(X_train, y_train) # 4. 获取训练过程中的损失值 # 训练损失 (可以直接从模型获取) train_loss = model.train_score_ # 计算验证集在每个阶段的损失 valid_loss = [] for i, y_pred in enumerate(model.staged_predict(X_valid)): valid_loss.append(mean_squared_error(y_valid, y_pred)) # 5. 可视化损失曲线 plt.figure(figsize=(10, 6)) plt.plot(train_loss, 'b-', label='Training Loss') plt.plot(valid_loss, 'r-', label='Validation Loss') # 标记最佳迭代次数 best_iter = np.argmin(valid_loss) plt.axvline(x=best_iter, color='k', linestyle='--', linewidth=1) plt.text(best_iter+5, max(valid_loss)*0.9, f'Best Iter: {best_iter}', fontsize=12) plt.xlabel('Boosting Iterations') plt.ylabel('Mean Squared Error') plt.title('Gradient Boosting Training Process') plt.legend() plt.grid(True) plt.show() # 6. 打印最佳模型信息 print(f"最佳迭代次数: {best_iter}") print(f"训练集最终MSE: {train_loss[-1]:.4f}") print(f"验证集最佳MSE: {min(valid_loss):.4f}") print(f"模型实际使用的树的数量: {model.n_estimators_}")
借助sklearn这个库,我们想实现这个功能还是很简单的,我们只需要使用GradientBoostingRegressor这个类就可以了,然后就是对整体训练和验证过程的可视化,来看一下整体效果吧:
欢迎大家来到IT世界,在知识的湖畔探索吧!
但是需要说明的是,这里我们选择了200棵树,也不是说我们无限的增加树就可以把损失值降低到无限小,这里可以看到损失也有一个极限,它不会无限减少,因为越到后面减小的越可以忽略不计了。然后看一下控制台的输出吧,如下所示:
对于更专业的比如XgBoost或者其他的Boost算法,通常都需要使用专门的类库,这里就不做演示了,推荐感兴趣的朋友们继续去深入了解,或者持续关注本系列教程。
免责声明:本站所有文章内容,图片,视频等均是来源于用户投稿和互联网及文摘转载整编而成,不代表本站观点,不承担相关法律责任。其著作权各归其原作者或其出版社所有。如发现本站有涉嫌抄袭侵权/违法违规的内容,侵犯到您的权益,请在线联系站长,一经查实,本站将立刻删除。 本文来自网络,若有侵权,请联系删除,如若转载,请注明出处:https://itzsg.com/137936.html