数学建模_基于支持回归向量机SVR的回归预测之预测新数据+Matlab代码包教会 ...

打印 上一主题 下一主题

主题 985|帖子 985|积分 2955

马上注册,结交更多好友,享用更多功能,让你轻松玩转社区。

您需要 登录 才可以下载或查看,没有账号?立即注册

x
支持向量回归 (SVR) 模型预测

支持向量回归(Support Vector Regression, SVR)是支持向量机(SVM)的扩展,用于办理回归问题。SVM本身是一个二分类模型,但通过适当的调整和优化,SVM也能用于回归任务。SVR的目标是找到一个最佳的回归平面,使得预测值与实际值之间的误差最小化。
SVR的焦点头脑如下:

  • 目标函数:

    • 在SVR中,我们希望找到一个函数 f(x)来近似输入数据 x 和输出数据 y 之间的关系。与传统的回归模型差别,SVR并不是通过最小化误差的总和来寻找最优解,而是通过容忍某个范围内的误差(由 ε-带决定)来确保模型在复杂度和正确性之间取得平衡。

  • ε-带(ε-insensitive loss):

    • SVR的损失函数不是传统的平方误差损失函数。它只对预测误差超出 ε 的部分进行处罚,误差小于 ε 时不计入损失。这种方法有用地处理了噪声和过拟合问题,使得模型更具鲁棒性。

  • 核函数:

    • 与支持向量机一样,SVR也可以使用核函数来处理非线性数据。通过使用核函数,SVR可以在更高维度的特性空间中找到一个线性回归模型。常用的核函数包括线性核、高斯核(RBF核)等。

  • 优化目标:

    • SVR通过一个优化问题来寻找回归函数。它的优化目标是:

      • 最大化隔断(margin),即支持向量的距离。
      • 在一定容忍范围内最小化误差。


通过这些方法,SVR可以或许在数据维度较高、噪声较大的环境下,提供一个具有良好泛化能力的回归模型。
本文将通过一个SVR模型来预测数据,过程包括数据预处理、模型训练、预测与评估。本文中使用MATLAB语言来实现这一过程,下面是完整的代码息争释分析。
1. 初始化环境

  1. close all               % 关闭所有图窗
  2. clear                   % 清空工作空间变量
  3. clc                     % 清空命令行窗口
  4. % 设置随机数种子,以确保实验结果可重复
  5. rng(2222)
复制代码
解释:


  • close all:关闭所有已经打开的图窗。
  • clear:清空工作空间中的所有变量,确保不会有遗留变量影响程序运行。
  • clc:清空下令行窗口,使得输出更加清晰。
  • rng(2222):设置随机数种子,确保每次运行结果同等。
2. 导入数据

  1. % 导入回归数据
  2. res = readmatrix('回归数据.xlsx');  % 读取Excel文件中的数据
复制代码
解释:


  • 使用 readmatrix 从 Excel 文件中读取数据并存储在变量 res 中。假设数据文件名为 回归数据.xlsx。
3. 数据归一化

  1. % 将特征变量 X 和目标变量 Y 进行归一化处理
  2. X = res(:,1:end-1);      % 提取特征变量
  3. Y = res(:,end);          % 提取目标变量
  4. [x, psin] = mapminmax(X', 0, 1);   % 特征归一化
  5. [y, psout] = mapminmax(Y', 0, 1);  % 目标归一化
复制代码
解释:


  • 从数据中分离出特性变量 X 和目标变量 Y。
  • 使用 mapminmax 将数据归一化到 [0, 1] 范围,X 和 Y 都进行归一化,得到归一化后的 x 和 y,并生存归一化的参数(psin 和 psout),以便后续反归一化使用。
4. 划分训练集与测试集

  1. num = size(res, 1);      % 获取样本数量
  2. k = input('是否打乱样本(是:1,否:0):');  % 用户选择是否打乱样本
  3. if k == 0
  4.    state = 1:num;        % 不打乱样本
  5. else
  6.    state = randperm(num);  % 打乱样本
  7. end
  8. ratio = 0.8;             % 训练集占比
  9. train_num = floor(num * ratio);  % 计算训练集大小
  10. % 划分训练集和测试集
  11. x_train = x(:, state(1:train_num))';  % 训练集特征
  12. y_train = y(state(1:train_num))';    % 训练集目标
  13. x_test = x(:, state(train_num+1:end))';  % 测试集特征
  14. y_test = y(state(train_num+1:end))';    % 测试集目标
复制代码
解释:


  • num = size(res, 1) 获取数据的总样本数。
  • k = input(...) 提示用户是否必要打乱样本。如果 k 为 0,则数据按次序划分;如果 k 为 1,则数据被随机打乱。
  • 根据设置的 ratio(80%用于训练集),我们计算训练集的样本数 train_num,然后将数据划分为训练集和测试集。
5. 构建 SVR 模型

  1. % 使用高斯核函数训练支持向量回归模型
  2. model = fitrsvm(x_train, y_train, "KernelFunction", "gaussian", ...  % 高斯核函数
  3.     "Solver", "ISDA", ...  % 使用 ISDA 优化算法
  4.     "KernelScale", "auto");  % 核尺度参数自动调整
复制代码
解释:


  • fitrsvm 函数用于训练支持向量回归模型。我们选择了高斯核函数 "KernelFunction", "gaussian",并使用 "Solver", "ISDA" 优化算法。
  • KernelScale 设置为 "auto",这意味着MATLAB将自动选择一个得当的核尺度。
6. 模型预测

  1. % 使用训练好的模型对训练集和测试集进行预测
  2. re1 = predict(model, x_train);  % 训练集预测
  3. re2 = predict(model, x_test);   % 测试集预测
复制代码
解释:


  • 使用训练好的模型 model 对训练集 x_train 和测试集 x_test 进行预测,分别得到 re1 和 re2,即训练集和测试集的预测结果。
7. 数据反归一化

  1. % 将预测值从归一化空间反转为原始数据空间
  2. Y_train = Y(state(1:train_num));  % 实际训练集目标
  3. Y_test = Y(state(train_num+1:end));  % 实际测试集目标
  4. % 反归一化预测值
  5. pre1 = mapminmax('reverse', re1, psout);
  6. pre2 = mapminmax('reverse', re2, psout);
复制代码
解释:


  • 使用 mapminmax('reverse', ...) 将归一化后的预测值 re1 和 re2 反归一化为原始数据空间,得到 pre1 和 pre2。
  • Y_train 和 Y_test 为实际的目标值(训练集和测试集的原始目标)。
8. 计算误差与评估指标

  1. % 计算均方根误差 (RMSE)
  2. error1 = sqrt(mean((pre1 - Y_train).^2));
  3. error2 = sqrt(mean((pre2 - Y_test).^2));
  4. % 计算 R2 和 MAE
  5. R1 = 1 - norm(Y_train - pre1)^2 / norm(Y_train - mean(Y_train))^2;
  6. R2 = 1 - norm(Y_test - pre2)^2 / norm(Y_test - mean(Y_test))^2;
  7. mae1 = mean(abs(Y_train - pre1 ));
  8. mae2 = mean(abs(pre2 - Y_test ));
  9. disp('训练集预测精度指标如下:')
  10. disp(['训练集数据的R2为:', num2str(R1)])
  11. disp(['训练集数据的MAE为:', num2str(mae1)])
  12. disp(['训练集数据的RMSE为:', num2str(error1)])
  13. disp('测试集预测精度指标如下:')
  14. disp(['测试集数据的R2为:', num2str(R2)])
  15. disp(['测试集数据的MAE为:', num2str(mae2)])
  16. disp(['测试集数据的RMSE为:', num2str(error2)])
复制代码
解释:


  • 计算训练集和测试集的均方根误差(RMSE)、R2 值和匀称绝对误差(MAE)。这些是常用的回归模型评估指标。
  • 使用 disp 函数输出这些指标的值。
9. 结果可视化

  1. % 绘制训练集预测结果对比
  2. figure
  3. plot(1:train_num, Y_train, 'r-^', 1:train_num, pre1, 'b-+', 'LineWidth', 1)
  4. legend('真实值', '预测值')
  5. xlabel('样本点')
  6. ylabel('预测值')
  7. title('训练集预测结果对比')
  8. % 绘制测试集预测结果对比
  9. figure
  10. plot(1:num-train_num, Y_test, 'r-^', 1:num-train_num, pre2, 'b-+', 'LineWidth', 1)
  11. legend('真实值', '预测值')
  12. xlabel('样本点')
  13. ylabel('预测值')
  14. title('测试集预测结果对比')
  15. % 绘制训练集百分比误差图
  16. figure
  17. plot((pre1 - Y_train)./Y_train, 'b-o', 'LineWidth', 1)
  18. legend('百分比误差')
  19. xlabel('样本点')
  20. ylabel('误差')
  21. title('训练集百分比误差曲线')
  22. % 绘制测试集百分比误差图
  23. figure
  24. plot((pre2 - Y_test)./Y_test, 'b-o', 'LineWidth', 1)
  25. legend('百分比误差')
  26. xlabel('样本点')
  27. ylabel('误差')
  28. title('测试集百分比误差曲线')
复制代码
解释:


  • 绘制多个图窗以可视化预测结果:

    • 训练集和测试集的预测结果与实际结果对比。
    • 训练集和测试集的百分比误差图。

10. 拟合度图

  1. % 绘制拟合度图
  2. figure;
  3. plotregression(Y_train, pre1, '训练集', ... Y_test, pre2, '测试集'); set(gcf, 'Toolbar', 'figure');
复制代码
解释:


  • 使用 plotregression 绘制训练集和测试集的回归拟合图,显示预测值与实际值的拟合环境。
11. 新数据预测

  1. % 新数据预测
  2. newdata = xlsread("新的多输入.xlsx");
  3. newy = newpre(newdata, psin, psout, model);
  4. figure
  5. plot(newy)
  6. xlabel('样本点')
  7. ylabel('预测值')
  8. % 保存预测结果
  9. xlswrite("新的输出.xlsx", newy)
  10. % 定义新数据预测函数
  11. function y = newpre(newdata, psin, psout, model)
  12.    % 归一化新数据
  13.    x = mapminmax('apply', newdata', psin);
  14.    % 使用模型进行预测
  15.    pre = predict(model, x');
  16.    % 反归一化预测结果
  17.    y = mapminmax('reverse', pre, psout);
  18. end
复制代码
解释:


  • 读取新数据(新的多输入.xlsx),并进行归一化处理。
  • 使用训练好的模型对新数据进行预测,并将结果反归一化。
  • 将预测结果生存到一个新的Excel文件(新的输出.xlsx)中。

Matlab代码手把手教运行

为了资助更多的萌新更快上手数学建模建等竞赛,这里有本文中的完整Matlab代码:
  1. close all               % 关闭开启的图窗
  2. clear                   % 清空变量
  3. clc                     % 清空命令行
  4. %随机数种子固定结果
  5. rng(2222)
  6. %%  导入数据
  7. res = readmatrix('回归数据.xlsx');
  8. %%  数据归一化 索引
  9. X = res(:,1:end-1);
  10. Y = res(:,end);
  11. [x,psin] = mapminmax(X', 0, 1);
  12. %保留归一化后相关参数
  13. [y, psout] = mapminmax(Y', 0, 1);
  14. %%  划分训练集和测试集
  15. num = size(res,1);%总样本数
  16. k = input('是否打乱样本(是:1,否:0):');
  17. if k == 0
  18.    state = 1:num; %不打乱样本
  19. else
  20.    state = randperm(num); %打乱样本
  21. end
  22. ratio = 0.8; %训练集占比
  23. train_num = floor(num*ratio);
  24. x_train = x(:,state(1: train_num))';
  25. y_train = y(state(1: train_num))';
  26. x_test = x(:,state(train_num+1: end))';
  27. y_test = y(state(train_num+1: end))';
  28. %%  svr模型
  29. %核尺度参数(KernelScale)
  30. % 这个参数用于调整数据点的尺度,
  31. % 以便在计算Gram矩阵(一种用于核方法的矩阵)时获得更好的性能。
  32. % 如果设置为'auto',软件会自动选择一个合适的尺度因子。
  33. % 但由于这个过程涉及到子采样,所以每次的估计值可能会有所不同。
  34. % 为了确保结果的可重复性,建议在训练之前设置一个随机数种子
  35. model = fitrsvm(x_train, y_train, "KernelFunction","gaussian",...  %高斯函数,用于计算 Gram 矩阵的核函数,指定 oKernelFunctiond
  36.     "Solver","ISDA",...  %ISDA优化,支持训练过程中的动态结构调整,并可以降低计算资源需求,减少过拟合风险。
  37.     "KernelScale","auto"); %核尺度参数(KernelScale)
  38. %%  仿真测试
  39. re1 = predict(model, x_train);
  40. re2 = predict(model, x_test );
  41. %%  数据反归一化
  42. %实际值
  43. Y_train = Y(state(1: train_num));
  44. Y_test = Y(state(train_num+1:end));
  45. %预测值
  46. pre1 = mapminmax('reverse', re1, psout);
  47. pre2 = mapminmax('reverse', re2, psout);
  48. %%  均方根误差
  49. error1 = sqrt(mean((pre1 - Y_train).^2));
  50. error2 = sqrt(mean((pre2 - Y_test).^2));
  51. %% 相关指标计算
  52. % R2
  53. R1 = 1 - norm(Y_train - pre1)^2 / norm(Y_train - mean(Y_train))^2;
  54. R2 = 1 - norm(Y_test -  pre2)^2 / norm(Y_test -  mean(Y_test ))^2;
  55. %  MAE
  56. mae1 = mean(abs(Y_train - pre1 ));
  57. mae2 = mean(abs(pre2 - Y_test ));
  58. disp('训练集预测精度指标如下:')
  59. disp(['训练集数据的R2为:', num2str(R1)])
  60. disp(['训练集数据的MAE为:', num2str(mae1)])
  61. disp(['训练集数据的RMSE为:', num2str(error1)])
  62. disp('测试集预测精度指标如下:')
  63. disp(['测试集数据的R2为:', num2str(R2)])
  64. disp(['测试集数据的MAE为:', num2str(mae2)])
  65. disp(['测试集数据的RMSE为:', num2str(error2)])
  66. figure
  67. plot(1: train_num, Y_train, 'r-^', 1: train_num, pre1, 'b-+', 'LineWidth', 1)
  68. legend('真实值','预测值')
  69. xlabel('样本点')
  70. ylabel('预测值')
  71. title('训练集预测结果对比')
  72. %%画图
  73. figure
  74. plot(1: num-train_num, Y_test, 'r-^', 1: num-train_num, pre2, 'b-+', 'LineWidth', 1)
  75. legend('真实值','预测值')
  76. xlabel('样本点')
  77. ylabel('预测值')
  78. title('测试集预测结果对比')
  79. %% 训练集百分比误差图
  80. figure
  81. plot((pre1 - Y_train )./Y_train, 'b-o', 'LineWidth', 1)
  82. legend('百分比误差')
  83. xlabel('样本点')
  84. ylabel('误差')
  85. title('训练集百分比误差曲线')
  86. %% 测试集百分比误差图
  87. figure
  88. plot((pre2 - Y_test )./Y_test, 'b-o', 'LineWidth', 1)
  89. legend('百分比误差')
  90. xlabel('样本点')
  91. ylabel('误差')
  92. title('测试集百分比误差曲线')
  93. %%  拟合图
  94. figure;
  95. plotregression(Y_train, pre1, '训练集', ...
  96.                Y_test, pre2, '测试集');
  97. set(gcf,'Toolbar','figure');
  98. %% 新数据预测
  99. newdata = xlsread("新的多输入.xlsx");
  100. newy = newpre(newdata,psin,psout,model);
  101. figure
  102. plot(newy)
  103. xlabel('样本点')
  104. ylabel('预测值')
  105. %保存数据
  106. xlswrite("新的输出.xlsx",newy)
  107. function y = newpre(newdata,psin,psout,model)
  108.    %归一化
  109.    x= mapminmax('apply',newdata',psin);
  110.    %预测
  111.    pre = predict(model,x');
  112.    %反归一化
  113.    y = mapminmax('reverse',pre,psout);
  114. end
复制代码
回归数据

x1x2x3x4x5y3.0362265613.881217.47568.4348316.8209348.479076124.3916588450.278231.623160.4768310.720564.121851855.2485978634.475232.985468.7401111.5485667.671487345.1212367253.694244.469265.3606114.3619159.327530574.6490218647.125268.305263.8013212.0485767.985703914.2672095445.033257.770161.689977.05562546.475065984.8045125848.875234.096867.144677.65613447.184425793.8258036583.543270.757561.4445316.6565454.04872964.7875349546.304225.827967.8935111.4366569.903723095.5807975481.803287.904362.2043211.2692747.320129573.6589199482.116278.809361.2021712.3741871.684296953.8299859128.034225.218764.8142316.7046168.187354275.2957856804.695282.694767.1343413.6187158.03093765.5543085340.983277.283369.394667.80435248.779318113.1595798717.524209.913366.7386216.30867.564109035.8447345505.52243.112465.762418.69319246.937703985.7373735589.905276.005662.248999.41583348.31135809
新的多输入数据

x1x2x3x4x53.03622575613.8808217.47497768.43482616.8209304.39165818450.2778231.62309060.47683210.7204984.19061229183.6836268.51010865.81807711.3141693.19240957145.7749204.27615968.23265316.1200575.1062376826.7186274.11765960.74799814.2069715.80909046765.6902222.18762467.6796809.2607454.77772247993.8317245.45518167.64599613.5895115.18440817506.1906298.05156464.2402207.0507054.53883128374.9062213.57692768.8806729.8182755.50861318046.1835215.52025666.19075111.4854523.65418797087.1249227.66560363.78074115.8688193.42772575338.8268282.41521863.8678858.9312084.37958767994.9283253.03953069.3920887.5237174.04685077794.6313233.16634264.14355013.9168373.74868336763.9297288.61193367.87215210.325529
数据表格模型这个放即可 无需修改代码!

免责声明:如果侵犯了您的权益,请联系站长,我们会及时删除侵权内容,谢谢合作!更多信息从访问主页:qidao123.com:ToB企服之家,中国第一个企服评测及商务社交产业平台。
回复

使用道具 举报

0 个回复

倒序浏览

快速回复

您需要登录后才可以回帖 登录 or 立即注册

本版积分规则

万万哇

金牌会员
这个人很懒什么都没写!
快速回复 返回顶部 返回列表