Прогнозирование временного ряда методом скользящего окна с помощью нейронной сети в MATLAB

Задача
Прогнозировать временной ряд методом скользящего окна с помощью нейронной сети в системе MATLAB.

Дано
Функция: cos(x - 0.5) * abs(x)
Число точек: n = 1000
Вектор X: linspace(0.001, 10, n)
Вектор Y: cos(X - 0.5) .* abs(X) + rand(size(X)) * 0.2 (шуманизация)

Также есть алгоритм решения задачи, который я не совсем понимаю (но он обязателен):

  1. Построить выборку для обучения. Для этого на основании временного ряда строится 5 рядов с задержкой от 1 до 5. Для построения ряда с задержкой 5 берутся от 1 до n-5 элементы выборки, с задержкой 4 берутся от 2 до n-4 элементы выборки, с задержкой 3 берутся от 3 до n-3 элементы выборки, с задержкой 2 берутся от 4 до n-2 элементы выборки, с задержкой 1 берутся от 5 до n-1 элементы выборки.
    Как я понял:
x1=X(5:n-1); y1=Y(5:n-1);
x2=X(4:n-2); y2=Y(4:n-2);
x3=X(3:n-3); y3=Y(3:n-3);
x4=X(2:n-4); y4=Y(2:n-4);
x5=X(1:n-5); y5=Y(1:n-5);
  1. Построить проверочную выборку. Поскольку длина выборки для обучения на 5 элементов меньше длины исходного временного ряда, для построения взять элементы от 6 до n-го.
    Как я понял:
ytest=Y(6:n);
  1. Временной ряд разбить на 2 части: использующиеся для обучения сети и для проверки. Размеры массивов должны относиться друг к другу приблизительно как 3:1.
    И тут уже вопросы:
    1) Обучающая и проверочная выборки были созданы на пред. двух шагах. Что значит разбить на 2 части?
    2) Что значит разбить на 2 части вкупе с отношением массивов друг к другу как 3:1.
  2. Построить feedforward neural network для прогнозирования. Число слоев – 2. Активационная функция первого слоя – гиперболический тангенс, второго – линейная. Число нейронов первого слоя взять достаточным для удовлетворительного прогнозирования (10-100), число нейронов второго слоя – 1.
    Может ли такая feedforward neural network в MATLAB прогнозировать временной ряд?
  3. Произвести обучение сети на обучающем множестве, привести график исходного ряда и спрогнозированного, а также погрешности прогнозирования.
    Это кажется понятным.

Ответы (1 шт):

Автор решения: user51515151

Кажется, я определился с решением.

% Для MATLAB R2018b (9.5.0.944444) Pro
% Программа, написанная с использованием функций Neural Network Toolbox
clear all; close all; clc;
% === Исходные данные ===
% Число точек
n = 100;
% Число лагов (5 -- согласно задаче)
b = 5;
% Генерация вектора X
X = linspace(0.001, 10, n);
% Генерация вектора Y на основе вектора X
Y = cos(X - 0.5) .* abs(X) + rand(size(X)) * 0.2; % "Шуманизация"
% Обучающая выборка
k = fix(n * 3 / 4);
Xt = X(1, 1:k);
Yt = Y(1, 1:k);
% Проверочная выборка
Xv = X(1, k+1:n);
Yv = Y(1, k+1:n);
vs = size(Xv, 2);
% Глубина прогноза
m = k - b;
% Горизонт прогноза (по умолчанию 1)
g = 1;
% Минимальные и максимальные значения координат
min_x = min(X);
max_x = max(X);
min_y = min(Y);
max_y = max(Y);

% === Прогнозирование временного ряда с помощью NNT ===
% Построение обучающих "подвыборок"
km = k - m;
if (m <= g)
    error('Горизонт прогноза слишком большой.');
elseif (g ~= 1 && isprime(km))
    error('Измените значение глубины прогноза (либо горизонта прогноза в 1).');
elseif (mod(km, g) ~= 0)
    error('Горизонт прогноза указан неверно.\n(%d mod g) должно быть равно 0.', km);
end
q = fix(km / g + 1);
Yq = zeros(m, q);
for i=1:q
    Yq(:, i) = Yt(1, 1+g*(i-1):m+g*(i-1));
end
% Настройка минимальных и максимальных значений
mmx = zeros(size(Yq, 1), 2);
mmx(:, 1) = min_y - min_y;
mmx(:, 2) = max_y + max_y;
% Создание нейронной сети обратного распространения с прямой связью
% 2 скрытых слоя
% Передаточные функции: гиперболический тангенс и линейная функция
net = newff(mmx, [100 1], {'tansig' 'purelin'});
% Скорость обучения
net.trainParam.lr = 0.01;
% Максимальное число эпох
net.trainParam.epochs = 10;
% Цель (всегда не меньше 1e-3, чтобы не было переобучения)
net.trainParam.goal = 1e-1;
% Обучение сети
fprintf('> Обучение сети началось\n');
[net, TR, T, E] = train(net, Yq(:, 1:q-1), Yq(end, 2:q));
train_mse = max(E);
fprintf('> Обучение сети закончилось\n');
% Моделирование работы сети
fprintf('> Моделирование работы сети началось\n');
Yp = Yq(:, q);
Yr = zeros(1, vs);
forecast_mse = 0;
for i=1:vs
    Yr(1, i) = sim(net, Yp);
    Yp = vertcat(Yp(2:size(Yp, 1), 1), Yr(1, i));
    forecast_mse = max(forecast_mse, (Yr(1, i)-Yv(1, i)).^2);
end
fprintf('> Моделирование работы сети закончилось\n');
% Построение графика
plot(Xt, Yt, 'b*'); % Построение обучающей выборки
hold on;
plot(Xv, Yv, 'gs'); % Построение проверочной выборки
plot(Xv, Yr, 'rx'); % Построение прогноза
tx = (max_x - min_x) / 20; ty = (max_y - min_y) / 20;
text(min_x + tx, min_y + ty, sprintf("Train MSE: %s", train_mse));
text(min_x + tx, min_y + ty * 2, sprintf("Forecast MSE: %s", forecast_mse));
xlim([min_x max_x]); % Установка границы по X
ylim([min_y max_y]); % Установка границы по Y
xlabel('X'); % Метка оси X
ylabel('Y'); % Метка оси Y
grid on; % Сетка
→ Ссылка