构建简单的梯度提升决策树(GBDT)模型:MATLAB 实现详解

梯度提升决策树(Gradient Boosting Decision Trees,GBDT)是一种强大的集成学习方法,广泛用于回归和分类任务。GBDT 的思想是通过串联多个弱学习器(通常是决策树),逐步优化预测残差,从而提高模型的准确性。在本文中,我们将使用 MATLAB 实现一个简化版的 GBDT 模型,并通过可视化工具来评估模型的效果。

数据准备

首先,我们从 Excel 文件中读取数据。特征位于前几列,而目标值(回归目标)位于最后一列。接下来,我们将数据划分为训练集和测试集,方便后续模型的训练与评估。

Matlab 复制代码
% 读取数据
data = readtable('data.xlsx');
X = data{:, 1:end-1};  % 前面所有列为特征
y = data{:, end};      % 最后一列为目标值

构建 GBDT 模型

在这段代码中,我们使用了 simpleGBDT 函数来实现梯度提升决策树。函数的核心思路是通过逐步拟合前一棵树的残差来建立多棵决策树模型。具体实现步骤如下:

超参数设定

我们首先定义了一些重要的超参数,包括树的数量、学习率、决策树的最大深度以及测试集的比例。

Matlab 复制代码
% 调用 GBDT 模型
num_trees = 35000;         % 迭代次数(树的数量)
learning_rate = 0.001;     % 学习率
max_depth = 25;            % 决策树的最大深度
test_ratio = 0.1;          % 测试集比例

核心 GBDT 训练过程

simpleGBDT 函数中,我们首先对数据进行训练集和测试集的划分。初始化时,预测值设为训练集的均值。每一轮迭代中,计算当前的残差,训练一棵新的决策树来拟合这些残差。然后,通过更新预测值来逐步提高模型的准确性。

Matlab 复制代码
function [model, metrics] = simpleGBDT(X, y, num_trees, learning_rate, max_depth, test_ratio)

    % 将数据集分为训练集和测试集
    n = size(X, 1);
    split_index = floor((1 - test_ratio) * n);
    X_train = X(1:split_index, :);
    y_train = y(1:split_index);
    X_test = X(split_index+1:end, :);
    y_test = y(split_index+1:end);

    % 初始化预测值为训练集的均值
    F_train = mean(y_train) * ones(size(y_train));
    F_test = mean(y_train) * ones(size(y_test));

    % 保存每棵树的结构
    model.trees = cell(num_trees, 1);

    % 梯度提升树的训练过程
    for t = 1:num_trees
        % 计算残差
        residual = y_train - F_train;

        % 训练一棵决策树以拟合残差
        tree = fitrtree(X_train, residual, 'MaxNumSplits', max_depth);

        % 记录这棵树
        model.trees{t} = tree;

        % 更新训练集预测值
        F_train = F_train + learning_rate * predict(tree, X_train);

        % 更新测试集预测值
        F_test = F_test + learning_rate * predict(tree, X_test);
    end
模型评价指标

我们使用多个常见的回归评价指标来评估模型的性能,包括平均绝对误差(MAE)、均方误差(MSE)、均方根误差(RMSE)、决定系数(R²)和平均绝对百分误差(MAPE)。

Matlab 复制代码
    % 评价指标
    MAE = mean(abs(y_test - F_test));
    MSE = mean((y_test - F_test).^2);
    RMSE = sqrt(MSE);
    R2 = 1 - sum((y_test - F_test).^2) / sum((y_test - mean(y_test)).^2);
    MAPE = mean(abs((y_test - F_test) ./ y_test)) * 100;

    % 输出评价指标
    metrics = struct('MAE', MAE, 'MSE', MSE, 'RMSE', RMSE, 'R2', R2, 'MAPE', MAPE);
    fprintf('MAE: %.4f\n', MAE);
    fprintf('MSE: %.4f\n', MSE);
    fprintf('RMSE: %.4f\n', RMSE);
    fprintf('R2: %.4f\n', R2);
    fprintf('MAPE: %.4f%%\n', MAPE);

可视化

为了更直观地理解模型的表现,我们绘制了两个图像。第一个图是预测值和真实值的对比,显示模型的拟合效果。第二个图是误差的柱状图,显示每个样本的预测误差。

Matlab 复制代码
    % 可视化:真实值与预测值对比
    figure;
    plot(y_test, '-o');
    hold on;
    plot(F_test, '-x');
    legend('真实值', '预测值');
    title('真实值与预测值对比');
    xlabel('样本');
    ylabel('值');
    grid on;

    % 可视化:误差值柱状图
    figure;
    bar(y_test - F_test);
    title('误差值柱状图');
    xlabel('样本');
    ylabel('误差');
    grid on;
end

结果与分析

运行此模型后,MATLAB 将输出各项评价指标以及生成可视化图表。通过这些图表,用户可以直观地了解模型的拟合情况,观察到哪些数据点误差较大,哪些数据点拟合得较好。

示例输出:
Matlab 复制代码
MAE: 0.1345
MSE: 0.0456
RMSE: 0.2137
R2: 0.9854
MAPE: 5.23%

如图所示,模型的平均绝对误差(MAE)较小,说明模型整体上预测的误差不大。同时,决定系数(R²)接近 1,表明模型对数据的拟合度非常高。误差柱状图也能够帮助我们识别那些误差较大的数据点。

总结

在这篇文章中,我们展示了如何在 MATLAB 中实现一个简单的 GBDT 模型。通过这种方法,模型能够逐步优化预测残差,从而实现更高的预测精度。尽管此实现相对简化,但它提供了梯度提升树的基本原理和流程。

如果你对机器学习算法有更多兴趣,欢迎继续探索 GBDT 的其他优化版本,如 XGBoost 或 LightGBM。

相关推荐
xiaoshiguang33 小时前
LeetCode:222.完全二叉树节点的数量
算法·leetcode
爱吃西瓜的小菜鸡3 小时前
【C语言】判断回文
c语言·学习·算法
别NULL3 小时前
机试题——疯长的草
数据结构·c++·算法
TT哇3 小时前
*【每日一题 提高题】[蓝桥杯 2022 国 A] 选素数
java·算法·蓝桥杯
我爱C编程4 小时前
基于Qlearning强化学习的机器人路线规划matlab仿真
matlab·机器人·强化学习·路线规划·qlearning·机器人路线规划
yuanbenshidiaos5 小时前
C++----------函数的调用机制
java·c++·算法
唐叔在学习5 小时前
【唐叔学算法】第21天:超越比较-计数排序、桶排序与基数排序的Java实践及性能剖析
数据结构·算法·排序算法
ALISHENGYA5 小时前
全国青少年信息学奥林匹克竞赛(信奥赛)备考实战之分支结构(switch语句)
数据结构·算法
chengooooooo5 小时前
代码随想录训练营第二十七天| 贪心理论基础 455.分发饼干 376. 摆动序列 53. 最大子序和
算法·leetcode·职场和发展
jackiendsc5 小时前
Java的垃圾回收机制介绍、工作原理、算法及分析调优
java·开发语言·算法