梯度提升决策树(Gradient Boosting Decision Trees,GBDT)是一种强大的集成学习方法,广泛用于回归和分类任务。GBDT 的思想是通过串联多个弱学习器(通常是决策树),逐步优化预测残差,从而提高模型的准确性。在本文中,我们将使用 MATLAB 实现一个简化版的 GBDT 模型,并通过可视化工具来评估模型的效果。
首先,我们从 Excel 文件中读取数据。特征位于前几列,而目标值(回归目标)位于最后一列。接下来,我们将数据划分为训练集和测试集,方便后续模型的训练与评估。
- % 读取数据
- data = readtable('data.xlsx');
- X = data{:, 1:end-1}; % 前面所有列为特征
- y = data{:, end}; % 最后一列为目标值
在这段代码中,我们使用了 simpleGBDT
函数来实现梯度提升决策树。函数的核心思路是通过逐步拟合前一棵树的残差来建立多棵决策树模型。具体实现步骤如下:
我们首先定义了一些重要的超参数,包括树的数量、学习率、决策树的最大深度以及测试集的比例。
- % 调用 GBDT 模型
- num_trees = 35000; % 迭代次数(树的数量)
- learning_rate = 0.001; % 学习率
- max_depth = 25; % 决策树的最大深度
- test_ratio = 0.1; % 测试集比例
在 simpleGBDT
函数中,我们首先对数据进行训练集和测试集的划分。初始化时,预测值设为训练集的均值。每一轮迭代中,计算当前的残差,训练一棵新的决策树来拟合这些残差。然后,通过更新预测值来逐步提高模型的准确性。
- 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)。
- % 评价指标
- 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);
为了更直观地理解模型的表现,我们绘制了两个图像。第一个图是预测值和真实值的对比,显示模型的拟合效果。第二个图是误差的柱状图,显示每个样本的预测误差。
- % 可视化:真实值与预测值对比
- 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 将输出各项评价指标以及生成可视化图表。通过这些图表,用户可以直观地了解模型的拟合情况,观察到哪些数据点误差较大,哪些数据点拟合得较好。
- MAE: 0.1345
- MSE: 0.0456
- RMSE: 0.2137
- R2: 0.9854
- MAPE: 5.23%
如图所示,模型的平均绝对误差(MAE)较小,说明模型整体上预测的误差不大。同时,决定系数(R²)接近 1,表明模型对数据的拟合度非常高。误差柱状图也能够帮助我们识别那些误差较大的数据点。
在这篇文章中,我们展示了如何在 MATLAB 中实现一个简单的 GBDT 模型。通过这种方法,模型能够逐步优化预测残差,从而实现更高的预测精度。尽管此实现相对简化,但它提供了梯度提升树的基本原理和流程。
如果你对机器学习算法有更多兴趣,欢迎继续探索 GBDT 的其他优化版本,如 XGBoost 或 LightGBM。