构建简单的梯度提升决策树(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。

相关推荐
Swift社区2 小时前
LeetCode - #139 单词拆分
算法·leetcode·职场和发展
Kent_J_Truman3 小时前
greater<>() 、less<>()及运算符 < 重载在排序和堆中的使用
算法
IT 青年3 小时前
数据结构 (1)基本概念和术语
数据结构·算法
Dong雨3 小时前
力扣hot100-->栈/单调栈
算法·leetcode·职场和发展
SoraLuna4 小时前
「Mac玩转仓颉内测版24」基础篇4 - 浮点类型详解
开发语言·算法·macos·cangjie
liujjjiyun4 小时前
小R的随机播放顺序
数据结构·c++·算法
¥ 多多¥4 小时前
c++中mystring运算符重载
开发语言·c++·算法
trueEve5 小时前
SQL,力扣题目1369,获取最近第二次的活动
算法·leetcode·职场和发展
Evand J5 小时前
集合卡尔曼滤波(Ensemble Kalman Filter),用于二维滤波(模拟平面上的目标跟踪),MATLAB代码
matlab·平面·目标跟踪
天若有情6735 小时前
c++框架设计展示---提高开发效率!
java·c++·算法