1 原理
SVR(Support Vector Regression)回归预测原理,基于支持向量机(SVM)的回归分支,其核心思想是通过寻找一个最优的超平面来进行回归预测,并处理非线性回归问题。以下是SVR回归预测原理的系统全面详细介绍:
1.1 基本原理:
1.SVR通过在线性函数两侧制造一个“间隔带”,该间距被称为容忍偏差(ϵ)。
2.对于所有落入间隔带内的样本,不计算损失。
3.只有支持向量会对函数模型产生影响。
4.最后,通过最小化总损失和最大化间隔来得出优化后的模型。
1.2 松弛变量与软间隔:
1.在现实任务中,很难直接确定合适的ϵ来确保大部分数据都能在间隔带内。
2.因此,SVR引入了松弛变量ξ,使函数的间隔要求变得放松,允许一些样本可以不在间隔带内。
3.引入松弛变量后,所有的样本数据都满足条件,这就是软间隔SVR。
1.3 核函数:
1.SVR预测还涉及到核函数的选择和应用。
2.核函数用于将输入空间映射到高维特征空间,以便解决非线性回归问题。
3.常见的核函数包括线性核函数、多项式核函数和RBF核函数等。
1.4 SVR计算公式:
1.SVR的计算公式旨在最小化总损失和最大化间隔。
2.公式如下:
1.5 算法步骤:
1.数据预处理:对输入特征进行标准化处理,使其均值为0,方差为1,以提高算法的收敛速度和精度。
2.核函数选择:选择适合的核函数,将数据映射到高维空间,以处理非线性回归问题。
1.6 SVR的特点:
1.不仅可以用于预测,还可以用于异常值检测。
2.通过最大化预测出错的容忍度(margin)来寻找最优解。
3.对于回归问题,支持向量回归(SVR)相比传统回归方法,具有更好的鲁棒性和泛化能力。
综上所述,SVR回归预测原理基于支持向量机的回归分支,通过在线性函数两侧制造“间隔带”,并利用松弛变量和核函数等技巧,实现了高效、准确的回归预测。
2 回归结果
图2-1 训练集测试结果
图2-2 测试集测试结果
由图2-1与图2-2可以看出真实值与拟合值非常接近,不存在偏差过大的数据点。
图2-3 训练集回归
图2-4 测试集回归
从图2-3与图2-4可以看出模型在训练集上训练效果很好,但在测试集上整体训练存在偏差。
图2-5 训练集残差图
图2-6 测试集残差图
基于图2-5与图2-6 中训练集和测试集的残差图,可以观察到模型的训练效果较好。在训练集中,残差值相对较小且稳定,这表明模型正在准确地拟合数据。而在测试集中,残差值稍大但仍在可接受的范围内,说明模型在未见过的数据上也有较好的表现。
本文在测试集数据量上划分了较大的比重,这是模型在测试集上由较好表现的重要原因之一。
3 代码
%% 清空环境变量
warning off % 关闭报警信息
close all % 关闭开启的图窗
clear % 清空变量
clc % 清空命令行
%% Import data
dataset = xlsread('data.xlsx');
%% Split data into training and testing sets
num_columns = size(dataset, 2);
num_rows = size(dataset, 1);
permutation_indices = randperm(num_rows);
split_ratio = 0.6; % 训练集、测试集划分比例为9:1
X_train = dataset(permutation_indices(1: round(num_rows*split_ratio)), 1: num_columns-1)';
Y_train = dataset(permutation_indices(1: round(num_rows*split_ratio)), num_columns)';
M = size(X_train, 2);
X_test = dataset(permutation_indices(round(num_rows*split_ratio): end), 1: num_columns-1)';
Y_test = dataset(permutation_indices(round(num_rows*split_ratio): end), num_columns)';
N = size(X_test, 2);
%% Normalize data
[x_train, ps_input] = mapminmax(X_train, 0, 1);
x_test = mapminmax('apply', X_test, ps_input);
[y_train, ps_output] = mapminmax(Y_train, 0, 1);
y_test = mapminmax('apply', Y_test, ps_output);
%% Transpose data to fit the model
x_train = x_train'; x_test = x_test';
y_train = y_train'; y_test = y_test';
%% Create SVM model
c_param = 4.0; % Penalty factor
g_param = 0.8; % RBF kernel parameter
cmd_params = [' -t 2',' -c ',num2str(c_param),' -g ',num2str(g_param),' -s 3 -p 0.01'];
svm_model = svmtrain(y_train, x_train, cmd_params);
%% Predict
[y_sim1, error_1] = svmpredict(y_train, x_train, svm_model);
[y_sim2, error_2] = svmpredict(y_test, x_test, svm_model);
%% Reverse normalize data
Y_sim1 = mapminmax('reverse', y_sim1, ps_output);
Y_sim2 = mapminmax('reverse', y_sim2, ps_output);
%% Calculate root mean square error (RMSE)
rmse_train = sqrt(mean((Y_sim1 - Y_train).^2));
rmse_test = sqrt(mean((Y_sim2 - Y_test).^2));
%% Plot training results
figure;
plot(1:M, Y_train, 'b-*', 1:M, Y_sim1, 'r-o', 'LineWidth', 1);
legend('Actual', 'Predicted');
xlabel('Sample');
ylabel('Value');
xlim([1, M]);
grid on;
figure;
plot(1:N, Y_test, 'y-*', 1:N, Y_sim2, 'r-o', 'LineWidth', 1);
legend('Actual', 'Predicted');
xlabel('Sample');
ylabel('Value');
xlim([1, N]);
grid on;
%% Plot scatter plot for training set
figure;
scatter(Y_train, Y_sim1, 25, 'green');
hold on;
plot(xlim, ylim, '--r');
xlabel('Actual (Training)');
ylabel('Predicted (Training)');
xlim([min(Y_train) max(Y_train)]);
ylim([min(Y_sim1) max(Y_sim1)]);
title('Predicted and Actual for Training Set');
grid on;
%% Plot scatter plot for test set
figure;
scatter(Y_test, Y_sim2, 25, 'green');
hold on;
plot(xlim, ylim, '--r');
xlabel('Actual (Test)');
ylabel('Predicted (Test)');
xlim([min(Y_test) max(Y_test)]);
ylim([min(Y_sim2) max(Y_sim2)]);
title('Predicted and Actual for Test Set');
grid on;
%% The residuals of the training set are calculated and saved as residuals train variables
residuals_train = Y_sim1 - Y_train;
%% Plot the residuals of the training set
figure;
plot(1:M, residuals_train, 'k', 'Marker', 'o');
xlabel('Sample (Training)');
ylabel('Residual');
title('Residuals for Training Set');
grid on;
%% If necessary, you can also calculate and plot the residuals of the test set
residuals_test = Y_sim2 - Y_test;
figure;
plot(1:N, residuals_test, 'k', 'Marker', 'o');
xlabel('Sample (Test)');
ylabel('Residual');
title('Residuals for Test Set');
grid on;