1. 基础实现:使用 MATLAB 内置函数
代码示例
matlab
%% 1. 数据准备
% 生成示例数据(正弦波 + 噪声)
t = linspace(0, 20, 200)';
y = sin(2*pi*0.2*t) + 0.1*randn(size(t));
%% 2. 创建训练集和测试集
train_ratio = 0.8;
n_train = floor(length(y) * train_ratio);
% 训练集
X_train = t(1:n_train);
y_train = y(1:n_train);
% 测试集
X_test = t(n_train+1:end);
y_test = y(n_train+1:end);
%% 3. 训练 SVR 模型
% 使用 fitrsvm 函数
svr_model = fitrsvm(X_train, y_train, ...
'KernelFunction', 'gaussian', ... % RBF核函数
'Standardize', true, ...
'KernelScale', 'auto', ...
'BoxConstraint', 1, ... % 正则化参数C
'Epsilon', 0.1); % ε-不敏感区域参数
%% 4. 预测
% 测试集预测
y_pred = predict(svr_model, X_test);
% 预测未来时间点
future_time = linspace(t(end)+1, t(end)+10, 10)'; % 预测未来10个点
future_pred = predict(svr_model, future_time);
%% 5. 可视化结果
figure;
subplot(2,1,1);
plot(t, y, 'b-', 'LineWidth', 1.5); hold on;
plot(X_train, y_train, 'ro', 'MarkerSize', 5, 'DisplayName', '训练数据');
plot(X_test, y_pred, 'g-', 'LineWidth', 2, 'DisplayName', 'SVR预测');
plot(future_time, future_pred, 'm--', 'LineWidth', 2, 'DisplayName', '未来预测');
xline(t(n_train), 'k--', '训练结束');
legend('Location', 'best');
xlabel('时间'); ylabel('数值');
title('SVR 时间序列预测');
grid on;
subplot(2,1,2);
plot(X_test, y_test, 'b-', 'LineWidth', 1.5); hold on;
plot(X_test, y_pred, 'r-', 'LineWidth', 1.5);
legend('真实值', '预测值');
xlabel('时间'); ylabel('数值');
title('测试集预测对比');
grid on;
2. 多步超前预测实现
matlab
%% 多步超前预测函数
function [predictions] = svr_multi_step_predict(data, lookback, horizon)
% data: 输入时间序列
% lookback: 回看窗口大小
% horizon: 预测步数
n = length(data);
% 准备训练数据
X = zeros(n - lookback - horizon + 1, lookback);
y = zeros(n - lookback - horizon + 1, horizon);
for i = 1:(n - lookback - horizon + 1)
X(i, :) = data(i:i+lookback-1)';
y(i, :) = data(i+lookback:i+lookback+horizon-1)';
end
% 划分训练测试
train_size = floor(0.8 * size(X, 1));
X_train = X(1:train_size, :);
y_train = y(1:train_size, :);
X_test = X(train_size+1:end, :);
y_test = y(train_size+1:end, :);
% 训练多个SVR模型(每个预测步一个)
models = cell(horizon, 1);
predictions = zeros(size(y_test));
for h = 1:horizon
% 训练单个步长的SVR模型
model = fitrsvm(X_train, y_train(:, h), ...
'KernelFunction', 'gaussian', ...
'Standardize', true, ...
'KernelScale', 'auto', ...
'OptimizeHyperparameters', 'auto', ...
'HyperparameterOptimizationOptions', ...
struct('AcquisitionFunctionName', 'expected-improvement-plus'));
models{h} = model;
% 预测
predictions(:, h) = predict(model, X_test);
end
% 可视化结果
figure;
for h = 1:min(4, horizon) % 最多显示前4个预测步
subplot(2, 2, h);
plot(y_test(:, h), 'b-', 'LineWidth', 1.5); hold on;
plot(predictions(:, h), 'r--', 'LineWidth', 1.5);
title(sprintf('预测步长: %d', h));
xlabel('时间点'); ylabel('数值');
legend('真实值', '预测值');
grid on;
end
% 计算评估指标
mse = mean((predictions - y_test).^2, 1);
mae = mean(abs(predictions - y_test), 1);
rmse = sqrt(mse);
fprintf('各预测步长的性能指标:\n');
for h = 1:horizon
fprintf('步长 %d: RMSE=%.4f, MAE=%.4f\n', h, rmse(h), mae(h));
end
end
3. 自动超参数优化
matlab
%% 使用贝叶斯优化自动调参
function optimized_model = optimize_svr(X, y)
% 定义可调超参数范围
vars = [
optimizableVariable('BoxConstraint', [0.1, 100], 'Transform', 'log')
optimizableVariable('KernelScale', [0.1, 10], 'Transform', 'log')
optimizableVariable('Epsilon', [0.01, 1], 'Transform', 'log')
];
% 交叉验证函数
cv_fun = @(params) kfoldLoss(fitrsvm(X, y, ...
'KernelFunction', 'gaussian', ...
'Standardize', true, ...
'KFold', 5, ...
'BoxConstraint', params.BoxConstraint, ...
'KernelScale', params.KernelScale, ...
'Epsilon', params.Epsilon));
% 贝叶斯优化
results = bayesopt(cv_fun, vars, ...
'MaxObjectiveEvaluations', 30, ...
'AcquisitionFunctionName', 'expected-improvement-plus', ...
'PlotFcn', {@plotObjectiveModel, @plotMinObjective});
% 用最优参数训练最终模型
best_params = results.XAtMinObjective;
optimized_model = fitrsvm(X, y, ...
'KernelFunction', 'gaussian', ...
'Standardize', true, ...
'BoxConstraint', best_params.BoxConstraint, ...
'KernelScale', best_params.KernelScale, ...
'Epsilon', best_params.Epsilon);
fprintf('最优参数:\n');
fprintf('BoxConstraint (C): %.4f\n', best_params.BoxConstraint);
fprintf('KernelScale: %.4f\n', best_params.KernelScale);
fprintf('Epsilon: %.4f\n', best_params.Epsilon);
end
4. 完整应用示例:股票价格预测
matlab
%% 股票价格预测示例
function stock_price_prediction()
% 加载示例数据
load('Data_EquityIdx.mat'); % 假设有股票数据
% 使用价格和成交量作为特征
prices = USPrice;
volume = USVolume;
% 创建特征矩阵
n = length(prices);
lookback = 20; % 使用过去20天的数据
features = zeros(n - lookback, 5);
target = zeros(n - lookback, 1);
for i = lookback+1:n-1
% 特征工程
features(i-lookback, 1) = mean(prices(i-lookback:i-1)); % 过去20天均价
features(i-lookback, 2) = std(prices(i-lookback:i-1)); % 波动率
features(i-lookback, 3) = prices(i-1)/prices(i-lookback) - 1; % 收益率
features(i-lookback, 4) = mean(volume(i-lookback:i-1)); % 平均成交量
features(i-lookback, 5) = (prices(i-1) - min(prices(i-lookback:i-1))) / ...
(max(prices(i-lookback:i-1)) - min(prices(i-lookback:i-1))); % 相对位置
% 预测目标:未来1天的价格
target(i-lookback) = prices(i+1);
end
% 划分训练集和测试集
train_ratio = 0.8;
n_train = floor(size(features, 1) * train_ratio);
X_train = features(1:n_train, :);
y_train = target(1:n_train);
X_test = features(n_train+1:end, :);
y_test = target(n_train+1:end);
% 训练优化后的SVR模型
svr_model = optimize_svr(X_train, y_train);
% 预测
y_pred = predict(svr_model, X_test);
% 评估
mse = mean((y_pred - y_test).^2);
mae = mean(abs(y_pred - y_test));
rmse = sqrt(mse);
mape = mean(abs((y_pred - y_test) ./ y_test)) * 100;
fprintf('\n股票价格预测性能:\n');
fprintf('RMSE: %.4f\n', rmse);
fprintf('MAE: %.4f\n', mae);
fprintf('MAPE: %.2f%%\n', mape);
% 可视化
figure;
subplot(2,1,1);
plot(y_test, 'b-', 'LineWidth', 1.5); hold on;
plot(y_pred, 'r--', 'LineWidth', 1.5);
legend('实际价格', '预测价格');
xlabel('交易日'); ylabel('价格');
title('股票价格预测结果');
grid on;
subplot(2,1,2);
error = y_pred - y_test;
histogram(error, 50);
xlabel('预测误差'); ylabel('频数');
title('预测误差分布');
grid on;
% 计算方向准确性
direction_acc = sum(sign(y_pred(2:end) - y_pred(1:end-1)) == ...
sign(y_test(2:end) - y_test(1:end-1))) / (length(y_test)-1) * 100;
fprintf('方向准确性: %.2f%%\n', direction_acc);
end
5. 关键注意事项
-
数据预处理:
matlab% 标准化(推荐) [X_scaled, mu_X, sigma_X] = zscore(X); [y_scaled, mu_y, sigma_y] = zscore(y); % 反标准化预测结果 y_pred_original = y_pred_scaled * sigma_y + mu_y; -
特征工程:
- 添加滞后特征
- 添加移动平均
- 添加技术指标(RSI, MACD等)
- 季节性特征
-
模型选择:
- 线性核:适用于线性关系
- 多项式核:适用于多项式关系
- RBF核(高斯核):适用于复杂非线性关系
-
参数调优顺序:
- 先调 ε(Epsilon)
- 再调 C(BoxConstraint)
- 最后调核参数(KernelScale)
参考代码 通过实现支持向量回归可以预测未来数据 www.youwenfan.com/contentcsu/54902.html
6. 替代方案:使用深度学习工具箱
matlab
%% 使用深度学习工具箱的回归层
function svr_with_dl()
% 创建简单的SVR-like网络
layers = [
featureInputLayer(1)
fullyConnectedLayer(10)
reluLayer
fullyConnectedLayer(5)
reluLayer
fullyConnectedLayer(1)
huberRegressionLayer('HuberDelta', 0.1) % 类似SVR的ε不敏感损失
];
options = trainingOptions('adam', ...
'MaxEpochs', 50, ...
'MiniBatchSize', 32, ...
'Plots', 'training-progress');
% 训练网络
net = trainNetwork(X_train, y_train, layers, options);
end
这些代码示例展示了 MATLAB 中实现 SVR 进行时间序列预测的多种方法。关键是根据具体问题调整窗口大小、核函数和超参数。