马上注册,结交更多好友,享用更多功能,让你轻松玩转社区。
您需要 登录 才可以下载或查看,没有账号?立即注册
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. 初始化环境
- close all % 关闭所有图窗
- clear % 清空工作空间变量
- clc % 清空命令行窗口
- % 设置随机数种子,以确保实验结果可重复
- rng(2222)
复制代码 解释:
- close all:关闭所有已经打开的图窗。
- clear:清空工作空间中的所有变量,确保不会有遗留变量影响程序运行。
- clc:清空下令行窗口,使得输出更加清晰。
- rng(2222):设置随机数种子,确保每次运行结果同等。
2. 导入数据
- % 导入回归数据
- res = readmatrix('回归数据.xlsx'); % 读取Excel文件中的数据
复制代码 解释:
- 使用 readmatrix 从 Excel 文件中读取数据并存储在变量 res 中。假设数据文件名为 回归数据.xlsx。
3. 数据归一化
- % 将特征变量 X 和目标变量 Y 进行归一化处理
- X = res(:,1:end-1); % 提取特征变量
- Y = res(:,end); % 提取目标变量
- [x, psin] = mapminmax(X', 0, 1); % 特征归一化
- [y, psout] = mapminmax(Y', 0, 1); % 目标归一化
复制代码 解释:
- 从数据中分离出特性变量 X 和目标变量 Y。
- 使用 mapminmax 将数据归一化到 [0, 1] 范围,X 和 Y 都进行归一化,得到归一化后的 x 和 y,并生存归一化的参数(psin 和 psout),以便后续反归一化使用。
4. 划分训练集与测试集
- num = size(res, 1); % 获取样本数量
- k = input('是否打乱样本(是:1,否:0):'); % 用户选择是否打乱样本
- if k == 0
- state = 1:num; % 不打乱样本
- else
- state = randperm(num); % 打乱样本
- end
- ratio = 0.8; % 训练集占比
- train_num = floor(num * ratio); % 计算训练集大小
- % 划分训练集和测试集
- x_train = x(:, state(1:train_num))'; % 训练集特征
- y_train = y(state(1:train_num))'; % 训练集目标
- x_test = x(:, state(train_num+1:end))'; % 测试集特征
- y_test = y(state(train_num+1:end))'; % 测试集目标
复制代码 解释:
- num = size(res, 1) 获取数据的总样本数。
- k = input(...) 提示用户是否必要打乱样本。如果 k 为 0,则数据按次序划分;如果 k 为 1,则数据被随机打乱。
- 根据设置的 ratio(80%用于训练集),我们计算训练集的样本数 train_num,然后将数据划分为训练集和测试集。
5. 构建 SVR 模型
- % 使用高斯核函数训练支持向量回归模型
- model = fitrsvm(x_train, y_train, "KernelFunction", "gaussian", ... % 高斯核函数
- "Solver", "ISDA", ... % 使用 ISDA 优化算法
- "KernelScale", "auto"); % 核尺度参数自动调整
复制代码 解释:
- fitrsvm 函数用于训练支持向量回归模型。我们选择了高斯核函数 "KernelFunction", "gaussian",并使用 "Solver", "ISDA" 优化算法。
- KernelScale 设置为 "auto",这意味着MATLAB将自动选择一个得当的核尺度。
6. 模型预测
- % 使用训练好的模型对训练集和测试集进行预测
- re1 = predict(model, x_train); % 训练集预测
- re2 = predict(model, x_test); % 测试集预测
复制代码 解释:
- 使用训练好的模型 model 对训练集 x_train 和测试集 x_test 进行预测,分别得到 re1 和 re2,即训练集和测试集的预测结果。
7. 数据反归一化
- % 将预测值从归一化空间反转为原始数据空间
- Y_train = Y(state(1:train_num)); % 实际训练集目标
- Y_test = Y(state(train_num+1:end)); % 实际测试集目标
- % 反归一化预测值
- pre1 = mapminmax('reverse', re1, psout);
- pre2 = mapminmax('reverse', re2, psout);
复制代码 解释:
- 使用 mapminmax('reverse', ...) 将归一化后的预测值 re1 和 re2 反归一化为原始数据空间,得到 pre1 和 pre2。
- Y_train 和 Y_test 为实际的目标值(训练集和测试集的原始目标)。
8. 计算误差与评估指标
- % 计算均方根误差 (RMSE)
- error1 = sqrt(mean((pre1 - Y_train).^2));
- error2 = sqrt(mean((pre2 - Y_test).^2));
- % 计算 R2 和 MAE
- R1 = 1 - norm(Y_train - pre1)^2 / norm(Y_train - mean(Y_train))^2;
- R2 = 1 - norm(Y_test - pre2)^2 / norm(Y_test - mean(Y_test))^2;
- mae1 = mean(abs(Y_train - pre1 ));
- mae2 = mean(abs(pre2 - Y_test ));
- disp('训练集预测精度指标如下:')
- disp(['训练集数据的R2为:', num2str(R1)])
- disp(['训练集数据的MAE为:', num2str(mae1)])
- disp(['训练集数据的RMSE为:', num2str(error1)])
- disp('测试集预测精度指标如下:')
- disp(['测试集数据的R2为:', num2str(R2)])
- disp(['测试集数据的MAE为:', num2str(mae2)])
- disp(['测试集数据的RMSE为:', num2str(error2)])
复制代码 解释:
- 计算训练集和测试集的均方根误差(RMSE)、R2 值和匀称绝对误差(MAE)。这些是常用的回归模型评估指标。
- 使用 disp 函数输出这些指标的值。
9. 结果可视化
- % 绘制训练集预测结果对比
- figure
- plot(1:train_num, Y_train, 'r-^', 1:train_num, pre1, 'b-+', 'LineWidth', 1)
- legend('真实值', '预测值')
- xlabel('样本点')
- ylabel('预测值')
- title('训练集预测结果对比')
- % 绘制测试集预测结果对比
- figure
- plot(1:num-train_num, Y_test, 'r-^', 1:num-train_num, pre2, 'b-+', 'LineWidth', 1)
- legend('真实值', '预测值')
- xlabel('样本点')
- ylabel('预测值')
- title('测试集预测结果对比')
- % 绘制训练集百分比误差图
- figure
- plot((pre1 - Y_train)./Y_train, 'b-o', 'LineWidth', 1)
- legend('百分比误差')
- xlabel('样本点')
- ylabel('误差')
- title('训练集百分比误差曲线')
- % 绘制测试集百分比误差图
- figure
- plot((pre2 - Y_test)./Y_test, 'b-o', 'LineWidth', 1)
- legend('百分比误差')
- xlabel('样本点')
- ylabel('误差')
- title('测试集百分比误差曲线')
复制代码 解释:
- 绘制多个图窗以可视化预测结果:
- 训练集和测试集的预测结果与实际结果对比。
- 训练集和测试集的百分比误差图。
10. 拟合度图
- % 绘制拟合度图
- figure;
- plotregression(Y_train, pre1, '训练集', ... Y_test, pre2, '测试集'); set(gcf, 'Toolbar', 'figure');
复制代码 解释:
- 使用 plotregression 绘制训练集和测试集的回归拟合图,显示预测值与实际值的拟合环境。
11. 新数据预测
- % 新数据预测
- newdata = xlsread("新的多输入.xlsx");
- newy = newpre(newdata, psin, psout, model);
- figure
- plot(newy)
- xlabel('样本点')
- ylabel('预测值')
- % 保存预测结果
- xlswrite("新的输出.xlsx", newy)
- % 定义新数据预测函数
- function y = newpre(newdata, psin, psout, model)
- % 归一化新数据
- x = mapminmax('apply', newdata', psin);
- % 使用模型进行预测
- pre = predict(model, x');
- % 反归一化预测结果
- y = mapminmax('reverse', pre, psout);
- end
复制代码 解释:
- 读取新数据(新的多输入.xlsx),并进行归一化处理。
- 使用训练好的模型对新数据进行预测,并将结果反归一化。
- 将预测结果生存到一个新的Excel文件(新的输出.xlsx)中。
Matlab代码手把手教运行
为了资助更多的萌新更快上手数学建模建等竞赛,这里有本文中的完整Matlab代码:
- close all % 关闭开启的图窗
- clear % 清空变量
- clc % 清空命令行
- %随机数种子固定结果
- rng(2222)
- %% 导入数据
- res = readmatrix('回归数据.xlsx');
- %% 数据归一化 索引
- X = res(:,1:end-1);
- Y = res(:,end);
- [x,psin] = mapminmax(X', 0, 1);
- %保留归一化后相关参数
- [y, psout] = mapminmax(Y', 0, 1);
- %% 划分训练集和测试集
- num = size(res,1);%总样本数
- k = input('是否打乱样本(是:1,否:0):');
- if k == 0
- state = 1:num; %不打乱样本
- else
- state = randperm(num); %打乱样本
- end
- ratio = 0.8; %训练集占比
- train_num = floor(num*ratio);
- x_train = x(:,state(1: train_num))';
- y_train = y(state(1: train_num))';
- x_test = x(:,state(train_num+1: end))';
- y_test = y(state(train_num+1: end))';
- %% svr模型
- %核尺度参数(KernelScale)
- % 这个参数用于调整数据点的尺度,
- % 以便在计算Gram矩阵(一种用于核方法的矩阵)时获得更好的性能。
- % 如果设置为'auto',软件会自动选择一个合适的尺度因子。
- % 但由于这个过程涉及到子采样,所以每次的估计值可能会有所不同。
- % 为了确保结果的可重复性,建议在训练之前设置一个随机数种子
- model = fitrsvm(x_train, y_train, "KernelFunction","gaussian",... %高斯函数,用于计算 Gram 矩阵的核函数,指定 oKernelFunctiond
- "Solver","ISDA",... %ISDA优化,支持训练过程中的动态结构调整,并可以降低计算资源需求,减少过拟合风险。
- "KernelScale","auto"); %核尺度参数(KernelScale)
- %% 仿真测试
- re1 = predict(model, x_train);
- re2 = predict(model, x_test );
- %% 数据反归一化
- %实际值
- Y_train = Y(state(1: train_num));
- Y_test = Y(state(train_num+1:end));
- %预测值
- pre1 = mapminmax('reverse', re1, psout);
- pre2 = mapminmax('reverse', re2, psout);
- %% 均方根误差
- error1 = sqrt(mean((pre1 - Y_train).^2));
- error2 = sqrt(mean((pre2 - Y_test).^2));
- %% 相关指标计算
- % R2
- R1 = 1 - norm(Y_train - pre1)^2 / norm(Y_train - mean(Y_train))^2;
- R2 = 1 - norm(Y_test - pre2)^2 / norm(Y_test - mean(Y_test ))^2;
- % MAE
- mae1 = mean(abs(Y_train - pre1 ));
- mae2 = mean(abs(pre2 - Y_test ));
- disp('训练集预测精度指标如下:')
- disp(['训练集数据的R2为:', num2str(R1)])
- disp(['训练集数据的MAE为:', num2str(mae1)])
- disp(['训练集数据的RMSE为:', num2str(error1)])
- disp('测试集预测精度指标如下:')
- disp(['测试集数据的R2为:', num2str(R2)])
- disp(['测试集数据的MAE为:', num2str(mae2)])
- disp(['测试集数据的RMSE为:', num2str(error2)])
- figure
- plot(1: train_num, Y_train, 'r-^', 1: train_num, pre1, 'b-+', 'LineWidth', 1)
- legend('真实值','预测值')
- xlabel('样本点')
- ylabel('预测值')
- title('训练集预测结果对比')
- %%画图
- figure
- plot(1: num-train_num, Y_test, 'r-^', 1: num-train_num, pre2, 'b-+', 'LineWidth', 1)
- legend('真实值','预测值')
- xlabel('样本点')
- ylabel('预测值')
- title('测试集预测结果对比')
- %% 训练集百分比误差图
- figure
- plot((pre1 - Y_train )./Y_train, 'b-o', 'LineWidth', 1)
- legend('百分比误差')
- xlabel('样本点')
- ylabel('误差')
- title('训练集百分比误差曲线')
- %% 测试集百分比误差图
- figure
- plot((pre2 - Y_test )./Y_test, 'b-o', 'LineWidth', 1)
- legend('百分比误差')
- xlabel('样本点')
- ylabel('误差')
- title('测试集百分比误差曲线')
- %% 拟合图
- figure;
- plotregression(Y_train, pre1, '训练集', ...
- Y_test, pre2, '测试集');
- set(gcf,'Toolbar','figure');
- %% 新数据预测
- newdata = xlsread("新的多输入.xlsx");
- newy = newpre(newdata,psin,psout,model);
- figure
- plot(newy)
- xlabel('样本点')
- ylabel('预测值')
- %保存数据
- xlswrite("新的输出.xlsx",newy)
- function y = newpre(newdata,psin,psout,model)
- %归一化
- x= mapminmax('apply',newdata',psin);
- %预测
- pre = predict(model,x');
- %反归一化
- y = mapminmax('reverse',pre,psout);
- 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企服之家,中国第一个企服评测及商务社交产业平台。 |