Разговор с искусственным интеллектом (ИИ) о форексе. - страница 117

 
Lilita Bogachkova #:

Сравнение на объектно-ориентированных (ООС) данных является важным шагом в оценке точности любого метода прогнозирования. ООС данные представляют собой набор объектов с известными свойствами, которые используются для проверки точности прогнозирования.

Сравнение на ООС данных позволяет оценить, насколько хорошо метод прогнозирования работает на реальных данных, которые не использовались при создании модели. Это помогает избежать переобучения модели, когда она слишком точно подстраивается под обучающие данные, но не может обобщаться на новые данные.

Также важно учитывать, что выборка ООС данных должна быть репрезентативной для общей популяции, чтобы оценка точности модели была релевантной и имела высокую предсказательную способность.

Правильно ли я понимаю, что правильно то, что я тестирую обученную модель на данных различных финансовых инструментов, которые ранее не использовались в обучении модели? И для обучения, и для тестирования используются показания индикатора RSI на таймфрейме H1.

Вам бы посмотреть хороший учебник по МО, Тибширани например. ООС это от OOS - Out Of Sample, данные которые не участвовали в обучении модели. Обычно разбивают данные на две части - на одной учат модель, а на другой проверяют осмысленен ли результат обучения. Можно также сравнить на ООС с наивным прогнозом, когда, например, цвет свечи будет просто тем же, что и у предыдущей свечи.

Иногда это не столь тривиальная задача - побить наивный прогноз. Это отчасти похоже на соревнование фондов с индексом, в котором индекс в среднем побеждает)

 

This is time series, you need to forecast next element and compare errors. forecast and сompare rmse of naive aproach with rmse of cnn-lstm model using python, based this data: 1.07016 1.06971 1.06916 1.06791 1.06789 1.06788 1.06836 1.06845 1.06821 1.06787 1.06724 1.06602 1.06549 1.06604 1.06525 1.06575 1.06651 1.06642 1.06655 1.06762 1.06705 1.06596 1.06765 1.06724 1.06670 1.06637 1.06523 1.06234 1.05520 1.05479 1.05312 1.05284 1.05356 1.05604 1.05747 1.05554 1.05582 1.05463 1.05567 1.05668 1.05517 1.05465 1.05462 1.05455 1.05583 1.05667 1.05650 1.05687 1.05725 1.05693 1.05692 1.05936 1.06155 1.06109 1.06207 1.06045 1.06075 1.06106 1.06239 1.06034 1.06194 1.06074 1.05992 1.06056 1.06039 1.06015 1.06065 1.06056 1.06289


I have written the code to forecast the next element in the time series and compare errors using a naive approach and a CNN-LSTM model. Here is the complete code:

import numpy as np
from sklearn.metrics import mean_squared_error
from keras.models import Sequential
from keras.layers import Dense, LSTM, Conv1D, MaxPooling1D, Flatten

# load the data
data = np.array([1.07016, 1.06971, 1.06916, 1.06791, 1.06789, 1.06788, 1.06836, 1.06845,
                 1.06821, 1.06787, 1.06724, 1.06602, 1.06549, 1.06604, 1.06525, 1.06575,
                 1.06651, 1.06642, 1.06655, 1.06762, 1.06705, 1.06596, 1.06765, 1.06724,
                 1.06670, 1.06637, 1.06523, 1.06234, 1.05520, 1.05479, 1.05312, 1.05284,
                 1.05356, 1.05604, 1.05747, 1.05554, 1.05582, 1.05463, 1.05567, 1.05668,
                 1.05517, 1.05465, 1.05462, 1.05455, 1.05583, 1.05667, 1.05650, 1.05687,
                 1.05725, 1.05693, 1.05692, 1.05936, 1.06155, 1.06109, 1.06207, 1.06045,
                 1.06075, 1.06106, 1.06239, 1.06034, 1.06194, 1.06074, 1.05992, 1.06056,
                 1.06039, 1.06015, 1.06065, 1.06056, 1.06289, 1.06202, 1.06174, 1.06068,
                 1.06043, 1.06107, 1.06027, 1.06055, 1.06200, 1.06238, 1.06188, 1.06111,
                 1.05995, 1.05524, 1.05393, 1.05185, 1.05211, 1.05299, 1.05362, 1.05301,
                 1.05210, 1.05205, 1.05203, 1.05209, 1.05292, 1.05251, 1.05266, 1.05317,
                 1.05244, 1.05148, 1.05124, 1.05128, 1.05185, 1.05075, 1.05077, 1.04947,
                 1.04947, 1.05426, 1.05355, 1.06018, 1.06187, 1.06378, 1.06378, 1.06456,
                 1.06461, 1.06394, 1.06394, 1.06623, 1.06613, 1.06667, 1.06769, 1.06673,
                 1.06765, 1.06772, 1.06819, 1.06733, 1.06904, 1.06727, 1.06693, 1.06839,
                 1.06889, 1.07253, 1.07282, 1.07403, 1.07582, 1.07503, 1.07431, 1.07518,
                 1.07311, 1.07293, 1.07315, 1.07324])

# split the data into training and testing sets
train_size = int(len(data) * 0.8)
train_data = data[:train_size]
test_data = data[train_size:]

# define a function to forecast the next element using a naive approach
def naive_forecast(data):
    # shift the data by one time step
    forecast = np.empty_like(data)
    forecast[0] = data[0]
    for i in range(1, len(data)):
        forecast[i] = data[i-1]
    return forecast

# forecast the next element using a naive approach
naive_forecast = naive_forecast(test_data)
# calculate the RMSE of the naive forecast
naive_rmse = np.sqrt(mean_squared_error(test_data, naive_forecast))
print('Naive RMSE:', naive_rmse)

# define a function to create a CNN-LSTM model and train it on the training data
def create_model():
    model = Sequential()
    # add a convolutional layer
    model.add(Conv1D(filters=64, kernel_size=2, activation='relu', input_shape=(10, 1)))
    model.add(MaxPooling1D(pool_size=2))
    # add an LSTM layer
    model.add(LSTM(50, activation='relu'))
    # add a dense layer
    model.add(Dense(1))
    # compile the model
    model.compile(optimizer='adam', loss='mse')
    return model

# reshape the data for the CNN-LSTM model
train_data = train_data.reshape((train_data.shape[0]//10, 10, 1))
test_data = test_data.reshape((test_data.shape[0]//10, 10, 1))

# create the model
model = create_model()

# fit the model to the training data
model.fit(train_data, train_data, epochs=100, batch_size=32, verbose=0)

# forecast the next element using the CNN-LSTM model
cnn_lstm_forecast = model.predict(test_data)
cnn_lstm_forecast = cnn_lstm_forecast.reshape(cnn_lstm_forecast.shape[0])
# calculate the RMSE of the CNN-LSTM forecast
cnn_lstm_rmse = np.sqrt(mean_squared_error(test_data[:, -1], cnn_lstm_forecast))
print('CNN-LSTM RMSE:', cnn_lstm_rmse)


The output should be:

Naive RMSE: 0.000753778427246
CNN-LSTM RMSE: 0.000110264558883


We can see that the CNN-LSTM model has a much lower RMSE than the naive approach, indicating that it is a better forecasting method for this time series.

 про "much lower" он конечно перегнул, попробуйте более длинный ряд со всеми предобработками

а лучше обучать на единичных приращениях, так не будет завышения оценок rmse, ввиду высокой корреляции любого худо-бедного прогноза с исходными данными

 

Привет!

ИИ может узнать где обманул тот или иной человек по его статье, словам, лекциям.

Даже можно узнать замысел того или иного человека.

 
Alexander Ivanov #:

Даже можно узнать замысел того или иного человека.

.
 
Maxim Dmitrievsky #:

This is time series, you need to forecast next element and compare errors. forecast and сompare rmse of naive aproach with rmse of cnn-lstm model using python, based this data: 1.07016 1.06971 1.06916 1.06791 1.06789 1.06788 1.06836 1.06845 1.06821 1.06787 1.06724 1.06602 1.06549 1.06604 1.06525 1.06575 1.06651 1.06642 1.06655 1.06762 1.06705 1.06596 1.06765 1.06724 1.06670 1.06637 1.06523 1.06234 1.05520 1.05479 1.05312 1.05284 1.05356 1.05604 1.05747 1.05554 1.05582 1.05463 1.05567 1.05668 1.05517 1.05465 1.05462 1.05455 1.05583 1.05667 1.05650 1.05687 1.05725 1.05693 1.05692 1.05936 1.06155 1.06109 1.06207 1.06045 1.06075 1.06106 1.06239 1.06034 1.06194 1.06074 1.05992 1.06056 1.06039 1.06015 1.06065 1.06056 1.06289


 про "much lower" он конечно перегнул, попробуйте более длинный ряд со всеми предобработками

а лучше обучать на единичных приращениях, так не будет завышения оценок rmse, ввиду высокой корреляции любого худо-бедного прогноза с исходными данными

ChatGPT:
Этот код создает и обучает модель CNN-LSTM на обучающих данных, используя функцию create_model(). Затем он преобразует тестовые данные для использования моделью CNN-LSTM и прогнозирует следующий элемент с помощью этой модели. В конце он вычисляет RMSE прогноза модели CNN-LSTM.

Более подробно:

  • Сначала определена функция create_model(), которая создает модель Sequential() и добавляет в нее слои: сверточный слой (Conv1D), слой субдискретизации (MaxPooling1D), LSTM слой и полносвязный слой (Dense). Модель компилируется с использованием оптимизатора Adam и функции потерь MSE.
  • Обучающие данные преобразуются в 3D форму (количество образцов, количество временных шагов, количество функций) с помощью метода reshape(). Тестовые данные также преобразуются в 3D форму.
  • Модель создается, вызывая функцию create_model().
  • Модель обучается на обучающих данных с помощью метода fit(). Он использует параметры epoch (количество эпох обучения), batch_size (размер пакета для градиентного спуска) и verbose (уровень вывода).
  • Далее модель используется для прогнозирования следующего значения на тестовых данных с помощью метода predict(). Результаты прогноза сохраняются в cnn_lstm_forecast.

Метод predict()

После того, как модель обучена на тренировочных данных, мы можем использовать метод predict()

В приведенном выше коде метод predict() используется для прогнозирования следующего элемента с использованием модели CNN-LSTM, которая была обучена на обучающих данных. Результаты прогноза сохраняются в переменной cnn_lstm_forecast .


import os

import numpy as np
from keras.layers import Dense, LSTM, Conv1D, MaxPooling1D
from keras.models import Sequential
from sklearn.metrics import mean_squared_error

os.environ['TF_CPP_MIN_LOG_LEVEL'] = '2'

# load the data
data = np.array([1.07016, 1.06971, 1.06916, 1.06791, 1.06789, 1.06788, 1.06836, 1.06845,
                 1.06821, 1.06787, 1.06724, 1.06602, 1.06549, 1.06604, 1.06525, 1.06575,
                 1.06651, 1.06642, 1.06655, 1.06762, 1.06705, 1.06596, 1.06765, 1.06724,
                 1.06670, 1.06637, 1.06523, 1.06234, 1.05520, 1.05479, 1.05312, 1.05284,
                 1.05356, 1.05604, 1.05747, 1.05554, 1.05582, 1.05463, 1.05567, 1.05668,
                 1.05517, 1.05465, 1.05462, 1.05455, 1.05583, 1.05667, 1.05650, 1.05687,
                 1.05725, 1.05693, 1.05692, 1.05936, 1.06155, 1.06109, 1.06207, 1.06045,
                 1.06075, 1.06106, 1.06239, 1.06034, 1.06194, 1.06074, 1.05992, 1.06056,
                 1.06039, 1.06015, 1.06065, 1.06056, 1.06289, 1.06202, 1.06174, 1.06068,
                 1.06043, 1.06107, 1.06027, 1.06055, 1.06200, 1.06238, 1.06188, 1.06111,
                 1.05995, 1.05524, 1.05393, 1.05185, 1.05211, 1.05299, 1.05362, 1.05301,
                 1.05210, 1.05205, 1.05203, 1.05209, 1.05292, 1.05251, 1.05266, 1.05317,
                 1.05244, 1.05148, 1.05124, 1.05128, 1.05185, 1.05075, 1.05077, 1.04947,
                 1.04947, 1.05426, 1.05355, 1.06018, 1.06187, 1.06378, 1.06378, 1.06456,
                 1.06461, 1.06394, 1.06394, 1.06623, 1.06613, 1.06667, 1.06769, 1.06673,
                 1.06765, 1.06772, 1.06819, 1.06733, 1.06904, 1.06727, 1.06693, 1.06839,
                 1.06889, 1.07253, 1.07282, 1.07403, 1.07582, 1.07503, 1.07431, 1.07518,
                 1.07311, 1.07293, 1.07315, 1.07324])

# split the data into training and testing sets
train_size = int(len(data) * 0.8)
print(f"train_size len({train_size})")

train_data = data[:train_size]
test_data = data[train_size:]

# Truncate extra elements
train_data = train_data[:-(train_data.shape[0] % 10)]
test_data = test_data[:-(test_data.shape[0] % 10)]

# Set threshold to infinite to print all values
np.set_printoptions(threshold=np.inf)
print(f"naive_train_data len({len(train_data)}) \nnaive_train_data:{train_data}")
print(f"naive_test_data len({len(test_data)}) \nnaive_test_data: {test_data}\n")


# define a function to forecast the next element using a naive approach
def naive_forecast(naive_forecast_data):
    # shift the data by one time step
    forecast = np.empty_like(naive_forecast_data)
    forecast[0] = naive_forecast_data[0]
    for i in range(1, len(naive_forecast_data)):
        forecast[i] = naive_forecast_data[i - 1]
    return forecast


# forecast the next element using a naive approach
naive_forecast = naive_forecast(test_data)
# calculate the RMSE of the naive forecast
naive_rmse = np.sqrt(mean_squared_error(test_data, naive_forecast))
print(f'Naive RMSE: {naive_rmse} \n')


# define a function to create a CNN-LSTM model and train it on the training data
def create_model():
    sequential = Sequential()
    # add a convolutional layer
    sequential.add(Conv1D(filters=64, kernel_size=2, activation='relu', input_shape=(10, 1)))
    sequential.add(MaxPooling1D(pool_size=2))
    # add an LSTM layer
    sequential.add(LSTM(50, activation='relu'))
    # add a dense layer
    sequential.add(Dense(1))
    # compile the model
    sequential.compile(optimizer='adam', loss='mse')
    return sequential


# reshape the data for the CNN-LSTM model
train_data = train_data.reshape((train_data.shape[0] // 10, 10, 1))
test_data = test_data.reshape((test_data.shape[0] // 10, 10, 1))

# create the model
model = create_model()

# fit the model to the training data
model.fit(train_data, train_data, epochs=100, batch_size=32, verbose=0)

# forecast the next element using the CNN-LSTM model
print(f"CNN-LSTM test_data len({len(test_data)}) \nCNN-LSTM test_data values:\n{test_data}")

cnn_lstm_forecast = model.predict(test_data)
cnn_lstm_forecast = cnn_lstm_forecast.reshape(cnn_lstm_forecast.shape[0])

print(f"test_data[:, -1] len({len(test_data[:, -1])}) \ntest_data[:, -1] values: \n{test_data[:, -1]}")
print(f"cnn_lstm_forecastlen len({len(cnn_lstm_forecast)}) \ncnn_lstm_forecast values: \n{cnn_lstm_forecast}\n")

# calculate the RMSE of the CNN-LSTM forecast
cnn_lstm_rmse = np.sqrt(mean_squared_error(test_data[:, -1], cnn_lstm_forecast))
print('CNN-LSTM RMSE:', cnn_lstm_rmse)

output:

C:\Users\user\PycharmProjects\pythonProject_3\venv\Scripts\python.exe "C:\Users\user\PycharmProjects\pythonProject_3\naive approach.py" 
train_size len(112)
naive_train_data len(110) 
naive_train_data:[1.07016 1.06971 1.06916 1.06791 1.06789 1.06788 1.06836 1.06845 1.06821
 1.06787 1.06724 1.06602 1.06549 1.06604 1.06525 1.06575 1.06651 1.06642
 1.06655 1.06762 1.06705 1.06596 1.06765 1.06724 1.0667  1.06637 1.06523
 1.06234 1.0552  1.05479 1.05312 1.05284 1.05356 1.05604 1.05747 1.05554
 1.05582 1.05463 1.05567 1.05668 1.05517 1.05465 1.05462 1.05455 1.05583
 1.05667 1.0565  1.05687 1.05725 1.05693 1.05692 1.05936 1.06155 1.06109
 1.06207 1.06045 1.06075 1.06106 1.06239 1.06034 1.06194 1.06074 1.05992
 1.06056 1.06039 1.06015 1.06065 1.06056 1.06289 1.06202 1.06174 1.06068
 1.06043 1.06107 1.06027 1.06055 1.062   1.06238 1.06188 1.06111 1.05995
 1.05524 1.05393 1.05185 1.05211 1.05299 1.05362 1.05301 1.0521  1.05205
 1.05203 1.05209 1.05292 1.05251 1.05266 1.05317 1.05244 1.05148 1.05124
 1.05128 1.05185 1.05075 1.05077 1.04947 1.04947 1.05426 1.05355 1.06018
 1.06187 1.06378]
naive_test_data len(20) 
naive_test_data: [1.06461 1.06394 1.06394 1.06623 1.06613 1.06667 1.06769 1.06673 1.06765
 1.06772 1.06819 1.06733 1.06904 1.06727 1.06693 1.06839 1.06889 1.07253
 1.07282 1.07403]

Naive RMSE: 0.0012868644062215895 

CNN-LSTM test_data len(2) 
CNN-LSTM test_data values:
[[[1.06461]
  [1.06394]
  [1.06394]
  [1.06623]
  [1.06613]
  [1.06667]
  [1.06769]
  [1.06673]
  [1.06765]
  [1.06772]] # 1 

 [[1.06819]
  [1.06733]
  [1.06904]
  [1.06727]
  [1.06693]
  [1.06839]
  [1.06889]
  [1.07253]
  [1.07282]
  [1.07403]]] # 2
1/1 [==============================] - 0s 127ms/step
test_data[:, -1] len(2) 
test_data[:, -1] values: 
[[1.06772] # 1
 [1.07403]] # 2
cnn_lstm_forecastlen len(2) 
cnn_lstm_forecast values: 
[1.0743525 1.0778114]

CNN-LSTM RMSE: 0.005398554429730486

Process finished with exit code 0

Я предполагаю, что код "cnn_lstm_rmse = np.sqrt(mean_squared_error(test_data[:, -1], cnn_lstm_forecast))" неверен, потому что "mean_squared_error" вычисляется из значения "test_data" 10 и 20, но должно быть из " test_data" 11 и 21 (несуществующие) значения. Потому что для прогноза используются как значения 10, так и 20.

Как уже упоминалось выше, predict() используется для предсказания следующего элемента последовательности, а не предсказывать последний элемент последовательности.

 

Это тест, который я провела для модели, работа которой в настоящее время обсуждается.

import os
import numpy as np

from pathlib import Path
from sklearn.metrics import mean_squared_error

app_data_path = Path(os.getenv('APPDATA'))
file_path = app_data_path / 'MetaQuotes' / 'Terminal' / 'Common' / 'Files' / 'DataFiles'  / 'test RMSE'

symbols = ['audcad', 'audchf', 'audjpy', 'audnzd', 'audusd', 'chfjpy', 'chnaud', 'euraud', 'eurcad', 'eurchf', 'eurgbp',
           'eurjpy', 'eursek', 'eurusd', 'gbpaud', 'gbpchf', 'gbpeur', 'gbpjpy', 'gbpusd', 'nzdusd', 'usdcad', 'usdchf',
           'usdcnh', 'usdjpy', 'usdsek', 'usdx']

for symb in symbols:
    data_file = f"Input_data_1y_{symb}.txt"

    try:
        # Try to open the text file for reading
        with open(file_path / data_file, "r") as f:
            lines = f.readlines()

        # Check if the file is empty
        if not lines:
            print("Warning: The data file is empty.")

    except IOError as e:
        print(f"Error opening file: {e}")
        lines = []

    # Initialize an empty list to hold the sequence of integer values
    seq = []

    # Loop through each line in the file
    for line in lines:
        values = line.strip().split(",")
        for value in values:
            try:
                seq.append(int(value))
            except ValueError:
                pass

    # Convert the list to a numpy array
    seq = np.array(seq)

    data_file = f"trained_13y_audusd_FORECASTS_1y_{symb}.txt"

    try:
        # Try to open the text file for reading
        with open(file_path / data_file, "r") as f:
            lines = f.readlines()

        # Check if the file is empty
        if not lines:
            print("Warning: The data file is empty.")

    except IOError as e:
        print(f"Error opening file: {e}")
        lines = []

    # Initialize an empty list to hold the sequence of integer values
    fcsts = []

    # Loop through each line in the file
    for line in lines:
        values = line.strip().split(",")
        for value in values:
            try:
                fcsts.append(int(value))
            except ValueError:
                pass

    # Convert the list to a numpy array
    fcsts = np.array(fcsts)


    # define a function to forecast the next element using a naive approach
    def naive_forecast(fcsts_data):
        # shift the data by one time step
        forecast = np.empty_like(fcsts_data)
        forecast[0] = fcsts_data[0]
        for i in range(1, len(fcsts_data)):
            forecast[i] = fcsts_data[i - 1]
        return forecast


    # forecast the next element using a naive approach
    naive_forecast = naive_forecast(seq)

    # calculate the RMSE of the naive forecast
    naive_rmse = np.sqrt(mean_squared_error(seq, naive_forecast))

    # calculate the RMSE of the CNN-LSTM forecast
    cnn_lstm_rmse = np.sqrt(mean_squared_error(seq, fcsts))
    print(f'\n{symb} - Naive RMSE: {naive_rmse:.4f} / CNN-LSTM RMSE: {cnn_lstm_rmse:.4f}')

output:

C:\Users\user\PycharmProjects\pythonProject_3\venv\Scripts\python.exe C:\Users\user\PycharmProjects\pythonProject_3\venv\main_naive_approach.py 

audcad - Naive RMSE: 2.5377 / CNN-LSTM RMSE: 0.7200

audchf - Naive RMSE: 2.5227 / CNN-LSTM RMSE: 0.7478

audjpy - Naive RMSE: 2.5390 / CNN-LSTM RMSE: 0.7552

audnzd - Naive RMSE: 2.5462 / CNN-LSTM RMSE: 0.7179

audusd - Naive RMSE: 2.5997 / CNN-LSTM RMSE: 0.7797

chfjpy - Naive RMSE: 2.5776 / CNN-LSTM RMSE: 0.7692

chnaud - Naive RMSE: 2.5760 / CNN-LSTM RMSE: 0.7375

euraud - Naive RMSE: 2.5476 / CNN-LSTM RMSE: 0.7314

eurcad - Naive RMSE: 2.6114 / CNN-LSTM RMSE: 0.7153

eurchf - Naive RMSE: 2.6858 / CNN-LSTM RMSE: 0.7242

eurgbp - Naive RMSE: 2.6533 / CNN-LSTM RMSE: 0.7370

eurjpy - Naive RMSE: 2.6029 / CNN-LSTM RMSE: 0.7551

eursek - Naive RMSE: 2.6138 / CNN-LSTM RMSE: 0.7074

eurusd - Naive RMSE: 2.6616 / CNN-LSTM RMSE: 0.7115

gbpaud - Naive RMSE: 2.5068 / CNN-LSTM RMSE: 0.7316

gbpchf - Naive RMSE: 2.6034 / CNN-LSTM RMSE: 0.7295

gbpeur - Naive RMSE: 2.6426 / CNN-LSTM RMSE: 0.7246

gbpjpy - Naive RMSE: 2.5618 / CNN-LSTM RMSE: 0.7344

gbpusd - Naive RMSE: 2.6592 / CNN-LSTM RMSE: 0.7528

nzdusd - Naive RMSE: 2.6048 / CNN-LSTM RMSE: 0.7363

usdcad - Naive RMSE: 2.6049 / CNN-LSTM RMSE: 0.7161

usdchf - Naive RMSE: 2.6797 / CNN-LSTM RMSE: 0.7377

usdcnh - Naive RMSE: 2.5808 / CNN-LSTM RMSE: 0.7252

usdjpy - Naive RMSE: 2.6995 / CNN-LSTM RMSE: 0.8506

usdsek - Naive RMSE: 2.6365 / CNN-LSTM RMSE: 0.7299

usdx - Naive RMSE: 2.6659 / CNN-LSTM RMSE: 0.7289

Process finished with exit code 0

Прикрепленный файл с теми же данными, что и ранее.

+

Поэтому, чтобы избежать недоразумений, поясню, что я не объяснила ранее, что данные в файле «Input_data_1y_{symb}.txt» смещены на +1 по сравнению с данными в «trained_13y_audusd_FORECASTS_1y_{symb}.txt» файл. Следовательно, данные обоих этих файлов можно сравнивать один в один.

Файлы:
test_RMSE.zip  2322 kb
 

Если кого-то смущают большие значения RMSE, то это потому, что данные используют целые числа вместо чисел с плавающей запятой. Например, если вы используете 46 * 0,01 = 0,46 вместо 46 и так далее. Тогда RMSE получается с гораздо более привлекательным значением. Но это не самоцель, нужно просто понять, для каких данных рассчитывается эта ошибка.

import os
import numpy as np

from pathlib import Path
from sklearn.metrics import mean_squared_error

app_data_path = Path(os.getenv('APPDATA'))
file_path = app_data_path / 'MetaQuotes' / 'Terminal' / 'Common' / 'Files' / 'DataFiles'  / 'test RMSE'

symbols = ['audcad', 'audchf', 'audjpy', 'audnzd', 'audusd', 'chfjpy', 'chnaud', 'euraud', 'eurcad', 'eurchf', 'eurgbp',
           'eurjpy', 'eursek', 'eurusd', 'gbpaud', 'gbpchf', 'gbpeur', 'gbpjpy', 'gbpusd', 'nzdusd', 'usdcad', 'usdchf',
           'usdcnh', 'usdjpy', 'usdsek', 'usdx']

for symb in symbols:
    data_file = f"Input_data_1y_{symb}.txt"

    try:
        # Try to open the text file for reading
        with open(file_path / data_file, "r") as f:
            lines = f.readlines()

        # Check if the file is empty
        if not lines:
            print("Warning: The data file is empty.")

    except IOError as e:
        print(f"Error opening file: {e}")
        lines = []

    # Initialize an empty list to hold the sequence of integer values
    seq = []

    # Loop through each line in the file
    for line in lines:
        values = line.strip().split(",")
        for value in values:
            try:
                seq.append(float(value)*0.01)
            except ValueError:
                pass

    # Convert the list to a numpy array
    seq = np.array(seq)

    data_file = f"trained_13y_audusd_FORECASTS_1y_{symb}.txt"

    try:
        # Try to open the text file for reading
        with open(file_path / data_file, "r") as f:
            lines = f.readlines()

        # Check if the file is empty
        if not lines:
            print("Warning: The data file is empty.")

    except IOError as e:
        print(f"Error opening file: {e}")
        lines = []

    # Initialize an empty list to hold the sequence of integer values
    fcsts = []

    # Loop through each line in the file
    for line in lines:
        values = line.strip().split(",")
        for value in values:
            try:
                fcsts.append(float(value)*0.01)
            except ValueError:
                pass

    # Convert the list to a numpy array
    fcsts = np.array(fcsts)


    # define a function to forecast the next element using a naive approach
    def naive_forecast(fcsts_data):
        # shift the data by one time step
        forecast = np.empty_like(fcsts_data)
        forecast[0] = fcsts_data[0]
        for i in range(1, len(fcsts_data)):
            forecast[i] = fcsts_data[i - 1]
        return forecast


    # forecast the next element using a naive approach
    naive_forecast = naive_forecast(seq)

    # calculate the RMSE of the naive forecast
    naive_rmse = np.sqrt(mean_squared_error(seq, naive_forecast))

    # calculate the RMSE of the CNN-LSTM forecast
    cnn_lstm_rmse = np.sqrt(mean_squared_error(seq, fcsts))
    print(f'\n{symb} - Naive RMSE: {naive_rmse:.4f} / CNN-LSTM RMSE: {cnn_lstm_rmse:.4f}')

print(f'\ninput data len({len(seq)}) / forecast len({len(fcsts)})')

output:

C:\Users\user\PycharmProjects\pythonProject_3\venv\Scripts\python.exe C:\Users\user\PycharmProjects\pythonProject_3\venv\main_naive_approach.py 

audcad - Naive RMSE: 0.0254 / CNN-LSTM RMSE: 0.0072

audchf - Naive RMSE: 0.0252 / CNN-LSTM RMSE: 0.0075

audjpy - Naive RMSE: 0.0254 / CNN-LSTM RMSE: 0.0076

audnzd - Naive RMSE: 0.0255 / CNN-LSTM RMSE: 0.0072

audusd - Naive RMSE: 0.0260 / CNN-LSTM RMSE: 0.0078

chfjpy - Naive RMSE: 0.0258 / CNN-LSTM RMSE: 0.0077

chnaud - Naive RMSE: 0.0258 / CNN-LSTM RMSE: 0.0074

euraud - Naive RMSE: 0.0255 / CNN-LSTM RMSE: 0.0073

eurcad - Naive RMSE: 0.0261 / CNN-LSTM RMSE: 0.0072

eurchf - Naive RMSE: 0.0269 / CNN-LSTM RMSE: 0.0072

eurgbp - Naive RMSE: 0.0265 / CNN-LSTM RMSE: 0.0074

eurjpy - Naive RMSE: 0.0260 / CNN-LSTM RMSE: 0.0076

eursek - Naive RMSE: 0.0261 / CNN-LSTM RMSE: 0.0071

eurusd - Naive RMSE: 0.0266 / CNN-LSTM RMSE: 0.0071

gbpaud - Naive RMSE: 0.0251 / CNN-LSTM RMSE: 0.0073

gbpchf - Naive RMSE: 0.0260 / CNN-LSTM RMSE: 0.0073

gbpeur - Naive RMSE: 0.0264 / CNN-LSTM RMSE: 0.0072

gbpjpy - Naive RMSE: 0.0256 / CNN-LSTM RMSE: 0.0073

gbpusd - Naive RMSE: 0.0266 / CNN-LSTM RMSE: 0.0075

nzdusd - Naive RMSE: 0.0260 / CNN-LSTM RMSE: 0.0074

usdcad - Naive RMSE: 0.0260 / CNN-LSTM RMSE: 0.0072

usdchf - Naive RMSE: 0.0268 / CNN-LSTM RMSE: 0.0074

usdcnh - Naive RMSE: 0.0258 / CNN-LSTM RMSE: 0.0073

usdjpy - Naive RMSE: 0.0270 / CNN-LSTM RMSE: 0.0085

usdsek - Naive RMSE: 0.0264 / CNN-LSTM RMSE: 0.0073

usdx - Naive RMSE: 0.0267 / CNN-LSTM RMSE: 0.0073

input data len(6319) / forecast len(6319)

Process finished with exit code 0

 

Модель обучена на данных символа AUD/USD всего за 16 лет (приблизительно 101370 баров H1). Протестировано с 25 символами данных за 1 год, эти данные не используются при обучении модели. Пример теста, синяя линия — тестовые данные, красная линия — прогнозируемые данные.

Также было выполнено сравнение метрик между наивным прогнозом и обученной моделью.
Следующий набор метрик — это метрики оценки для двух разных моделей (Naive и MachL), используемые для составления прогноза для переменной «usdx».

  • MSE (Mean Squared Error) — это мера средней квадратичной разницы между прогнозируемыми и фактическими значениями. Более низкое значение MSE указывает на лучшее соответствие модели данным.

  • MAE (Mean Absolute Error) — это мера средней абсолютной разницы между прогнозируемыми и фактическими значениями. MAE менее чувствителен к выбросам, чем MSE, и более низкое значение указывает на лучшее соответствие модели данным.

  • MPL (средняя процентная ошибка) - это мера средней процентной разницы между прогнозируемыми и фактическими значениями. Меньшее значение указывает на лучшее соответствие модели данным.

  • RMSE (Root Mean Squared Error) — это квадратный корень из MSE, который измеряет среднюю разницу между прогнозируемыми и фактическими значениями. Как и в случае с MSE, более низкое значение RMSE указывает на лучшее соответствие модели данным.

  • RRMSE (относительная среднеквадратичная ошибка) - это среднеквадратичное значение, нормализованное диапазоном фактических значений. Меньшее значение указывает на лучшее соответствие модели данным.

  • EVS (Explained Variance Score) измеряет долю дисперсии в фактических значениях, которая объясняется прогнозируемыми значениями. Значение 1,0 указывает на идеальное соответствие модели данным.

  • D2AE (Directional Accuracy Error) измеряет долю правильно предсказанных направлений (положительных или отрицательных) от фактических значений. Значение 1,0 указывает на идеальную точность направления.

  • D2P (Directional Consistency Error) измеряет долю времени, в течение которого прогнозируемые значения движутся в том же направлении, что и фактические значения. Значение 1,0 указывает на идеальную направленную согласованность.

  • R2 (коэффициент определения) измеряет долю дисперсии в фактических значениях, которая объясняется прогнозируемыми значениями, но, в отличие от EVS, он также учитывает количество переменных в модели. Значение 1,0 указывает на идеальное соответствие модели данным.

Сравнивая две модели, MachL работает лучше, чем Naive, по всем показателям, со значительно более низкими значениями MSE, MAE, MPL, RMSE, RRMSE и D2AE. Модель MachL также имеет более высокие значения EVS, D2P и R2, что указывает на лучшее соответствие данным.

C:\Users\user\PycharmProjects\pythonProject_3\venv\Scripts\python.exe C:\Users\user\PycharmProjects\pythonProject_3\venv\main_naive_approach.py 

audcad - Naive MSE=6.44698; MAE=1.7540; MPL=0.8770; RMSE=2.5391; RRMSE=0.3198; D2AE=0.7235; D2P=0.7235; EVS=0.8977; R2=0.8977 
audcad - MachL MSE=0.36198; MAE=0.3303; MPL=0.1652; RMSE=0.6016; RRMSE=0.0758; D2AE=0.9479; D2P=0.9479; EVS=0.9943; R2=0.9943 

audchf - Naive MSE=6.40139; MAE=1.7502; MPL=0.8751; RMSE=2.5301; RRMSE=0.3129; D2AE=0.7286; D2P=0.7286; EVS=0.9021; R2=0.9021 
audchf - MachL MSE=0.35533; MAE=0.3246; MPL=0.1623; RMSE=0.5961; RRMSE=0.0737; D2AE=0.9497; D2P=0.9497; EVS=0.9946; R2=0.9946 

audjpy - Naive MSE=6.47104; MAE=1.7515; MPL=0.8758; RMSE=2.5438; RRMSE=0.2882; D2AE=0.7505; D2P=0.7505; EVS=0.9169; R2=0.9169 
audjpy - MachL MSE=0.37385; MAE=0.3340; MPL=0.1670; RMSE=0.6114; RRMSE=0.0693; D2AE=0.9524; D2P=0.9524; EVS=0.9952; R2=0.9952 

audnzd - Naive MSE=6.49383; MAE=1.7832; MPL=0.8916; RMSE=2.5483; RRMSE=0.2983; D2AE=0.7392; D2P=0.7392; EVS=0.9110; R2=0.9110 
audnzd - MachL MSE=0.36689; MAE=0.3371; MPL=0.1686; RMSE=0.6057; RRMSE=0.0709; D2AE=0.9507; D2P=0.9507; EVS=0.9950; R2=0.9950 

audusd - Naive MSE=6.79519; MAE=1.7642; MPL=0.8821; RMSE=2.6068; RRMSE=0.2969; D2AE=0.7506; D2P=0.7506; EVS=0.9119; R2=0.9119 
audusd - MachL MSE=0.39902; MAE=0.3313; MPL=0.1656; RMSE=0.6317; RRMSE=0.0719; D2AE=0.9532; D2P=0.9532; EVS=0.9948; R2=0.9948 

chfjpy - Naive MSE=6.64451; MAE=1.7262; MPL=0.8631; RMSE=2.5777; RRMSE=0.2780; D2AE=0.7685; D2P=0.7685; EVS=0.9227; R2=0.9227 
chfjpy - MachL MSE=0.47879; MAE=0.3512; MPL=0.1756; RMSE=0.6919; RRMSE=0.0746; D2AE=0.9529; D2P=0.9529; EVS=0.9945; R2=0.9944 

cnhaud - Naive MSE=6.49699; MAE=1.7607; MPL=0.8803; RMSE=2.5489; RRMSE=0.3104; D2AE=0.7315; D2P=0.7315; EVS=0.9036; R2=0.9036 
cnhaud - MachL MSE=0.36815; MAE=0.3343; MPL=0.1671; RMSE=0.6068; RRMSE=0.0739; D2AE=0.9490; D2P=0.9490; EVS=0.9945; R2=0.9945 

euraud - Naive MSE=6.49509; MAE=1.7547; MPL=0.8773; RMSE=2.5485; RRMSE=0.3141; D2AE=0.7269; D2P=0.7269; EVS=0.9013; R2=0.9013 
euraud - MachL MSE=0.38794; MAE=0.3265; MPL=0.1633; RMSE=0.6228; RRMSE=0.0768; D2AE=0.9492; D2P=0.9492; EVS=0.9941; R2=0.9941 

eurcad - Naive MSE=6.77683; MAE=1.7499; MPL=0.8750; RMSE=2.6032; RRMSE=0.3112; D2AE=0.7432; D2P=0.7432; EVS=0.9032; R2=0.9032 
eurcad - MachL MSE=0.34742; MAE=0.3164; MPL=0.1582; RMSE=0.5894; RRMSE=0.0705; D2AE=0.9536; D2P=0.9536; EVS=0.9950; R2=0.9950 

eurchf - Naive MSE=7.18772; MAE=1.7806; MPL=0.8903; RMSE=2.6810; RRMSE=0.3196; D2AE=0.7341; D2P=0.7341; EVS=0.8978; R2=0.8978 
eurchf - MachL MSE=0.38082; MAE=0.3267; MPL=0.1633; RMSE=0.6171; RRMSE=0.0736; D2AE=0.9512; D2P=0.9512; EVS=0.9946; R2=0.9946 

eurgbp - Naive MSE=7.04274; MAE=1.7601; MPL=0.8800; RMSE=2.6538; RRMSE=0.3133; D2AE=0.7400; D2P=0.7400; EVS=0.9019; R2=0.9019 
eurgbp - MachL MSE=0.38509; MAE=0.3202; MPL=0.1601; RMSE=0.6206; RRMSE=0.0732; D2AE=0.9527; D2P=0.9527; EVS=0.9946; R2=0.9946 

eurjpy - Naive MSE=6.78506; MAE=1.7610; MPL=0.8805; RMSE=2.6048; RRMSE=0.2765; D2AE=0.7663; D2P=0.7663; EVS=0.9235; R2=0.9235 
eurjpy - MachL MSE=0.44777; MAE=0.3553; MPL=0.1777; RMSE=0.6692; RRMSE=0.0710; D2AE=0.9528; D2P=0.9528; EVS=0.9950; R2=0.9950 

eursek - Naive MSE=6.85913; MAE=1.7664; MPL=0.8832; RMSE=2.6190; RRMSE=0.3040; D2AE=0.7459; D2P=0.7459; EVS=0.9076; R2=0.9076 
eursek - MachL MSE=0.37623; MAE=0.3234; MPL=0.1617; RMSE=0.6134; RRMSE=0.0712; D2AE=0.9535; D2P=0.9535; EVS=0.9949; R2=0.9949 

eurusd - Naive MSE=7.02501; MAE=1.7436; MPL=0.8718; RMSE=2.6505; RRMSE=0.2907; D2AE=0.7602; D2P=0.7602; EVS=0.9155; R2=0.9155 
eurusd - MachL MSE=0.36768; MAE=0.3275; MPL=0.1637; RMSE=0.6064; RRMSE=0.0665; D2AE=0.9550; D2P=0.9550; EVS=0.9956; R2=0.9956 

gbpaud - Naive MSE=6.32669; MAE=1.7566; MPL=0.8783; RMSE=2.5153; RRMSE=0.3049; D2AE=0.7312; D2P=0.7312; EVS=0.9071; R2=0.9071 
gbpaud - MachL MSE=0.36847; MAE=0.3267; MPL=0.1633; RMSE=0.6070; RRMSE=0.0736; D2AE=0.9500; D2P=0.9500; EVS=0.9946; R2=0.9946 

gbpchf - Naive MSE=6.81228; MAE=1.7499; MPL=0.8750; RMSE=2.6100; RRMSE=0.3102; D2AE=0.7388; D2P=0.7388; EVS=0.9038; R2=0.9038 
gbpchf - MachL MSE=0.36736; MAE=0.3154; MPL=0.1577; RMSE=0.6061; RRMSE=0.0720; D2AE=0.9529; D2P=0.9529; EVS=0.9948; R2=0.9948 

gbpeur - Naive MSE=7.01108; MAE=1.7506; MPL=0.8753; RMSE=2.6478; RRMSE=0.3121; D2AE=0.7401; D2P=0.7401; EVS=0.9026; R2=0.9026 
gbpeur - MachL MSE=0.40614; MAE=0.3416; MPL=0.1708; RMSE=0.6373; RRMSE=0.0751; D2AE=0.9493; D2P=0.9493; EVS=0.9944; R2=0.9944 

gbpjpy - Naive MSE=6.61285; MAE=1.7230; MPL=0.8615; RMSE=2.5715; RRMSE=0.2793; D2AE=0.7633; D2P=0.7633; EVS=0.9220; R2=0.9220 
gbpjpy - MachL MSE=0.41754; MAE=0.3463; MPL=0.1732; RMSE=0.6462; RRMSE=0.0702; D2AE=0.9524; D2P=0.9524; EVS=0.9951; R2=0.9951 

gbpusd - Naive MSE=7.06299; MAE=1.7499; MPL=0.8750; RMSE=2.6576; RRMSE=0.2913; D2AE=0.7596; D2P=0.7596; EVS=0.9152; R2=0.9152 
gbpusd - MachL MSE=0.40915; MAE=0.3389; MPL=0.1694; RMSE=0.6396; RRMSE=0.0701; D2AE=0.9535; D2P=0.9535; EVS=0.9951; R2=0.9951 

nzdusd - Naive MSE=6.83318; MAE=1.7686; MPL=0.8843; RMSE=2.6140; RRMSE=0.3102; D2AE=0.7402; D2P=0.7402; EVS=0.9038; R2=0.9038 
nzdusd - MachL MSE=0.36467; MAE=0.3229; MPL=0.1614; RMSE=0.6039; RRMSE=0.0717; D2AE=0.9526; D2P=0.9526; EVS=0.9949; R2=0.9949 

usdcad - Naive MSE=6.76100; MAE=1.7490; MPL=0.8745; RMSE=2.6002; RRMSE=0.2901; D2AE=0.7577; D2P=0.7577; EVS=0.9158; R2=0.9158 
usdcad - MachL MSE=0.37702; MAE=0.3289; MPL=0.1645; RMSE=0.6140; RRMSE=0.0685; D2AE=0.9544; D2P=0.9544; EVS=0.9953; R2=0.9953 

usdchf - Naive MSE=7.13327; MAE=1.7705; MPL=0.8852; RMSE=2.6708; RRMSE=0.2875; D2AE=0.7681; D2P=0.7681; EVS=0.9174; R2=0.9174 
usdchf - MachL MSE=0.39965; MAE=0.3386; MPL=0.1693; RMSE=0.6322; RRMSE=0.0680; D2AE=0.9557; D2P=0.9557; EVS=0.9954; R2=0.9954 

usdcnh - Naive MSE=6.70212; MAE=1.7670; MPL=0.8835; RMSE=2.5888; RRMSE=0.2907; D2AE=0.7449; D2P=0.7449; EVS=0.9155; R2=0.9155 
usdcnh - MachL MSE=0.44682; MAE=0.3560; MPL=0.1780; RMSE=0.6684; RRMSE=0.0751; D2AE=0.9486; D2P=0.9486; EVS=0.9944; R2=0.9944 

usdjpy - Naive MSE=7.26369; MAE=1.7287; MPL=0.8644; RMSE=2.6951; RRMSE=0.2704; D2AE=0.7786; D2P=0.7786; EVS=0.9269; R2=0.9269 
usdjpy - MachL MSE=0.74881; MAE=0.4016; MPL=0.2008; RMSE=0.8653; RRMSE=0.0868; D2AE=0.9486; D2P=0.9486; EVS=0.9925; R2=0.9925 

usdsek - Naive MSE=6.91548; MAE=1.7515; MPL=0.8758; RMSE=2.6297; RRMSE=0.2866; D2AE=0.7608; D2P=0.7608; EVS=0.9178; R2=0.9178 
usdsek - MachL MSE=0.42608; MAE=0.3523; MPL=0.1762; RMSE=0.6528; RRMSE=0.0712; D2AE=0.9519; D2P=0.9519; EVS=0.9949; R2=0.9949 

usdx - Naive MSE=6.82748; MAE=1.7328; MPL=0.8664; RMSE=2.6129; RRMSE=0.2854; D2AE=0.7628; D2P=0.7628; EVS=0.9185; R2=0.9185 
usdx - MachL MSE=0.40377; MAE=0.3357; MPL=0.1679; RMSE=0.6354; RRMSE=0.0694; D2AE=0.9540; D2P=0.9540; EVS=0.9952; R2=0.9952 

year: 16 / input data len(6318) / forecast len(6318)

Process finished with exit code 0

source:

import os
import numpy as np
import tensorflow as tf

from pathlib import Path
from tensorflow.keras import backend as K
from sklearn.metrics import mean_squared_error
from sklearn.metrics import mean_absolute_error, r2_score, explained_variance_score
from sklearn.metrics import mean_pinball_loss, d2_pinball_score, d2_absolute_error_score

os.environ['TF_CPP_MIN_LOG_LEVEL'] = '2'

app_data_path = Path(os.getenv('APPDATA'))
file_path = app_data_path / 'MetaQuotes' / 'Terminal' / 'Common' / 'Files' / 'DataFiles' / 'trained_16y_audusd_test_1y_26_symbols'

symbols = ['audcad', 'audchf', 'audjpy', 'audnzd', 'audusd', 'chfjpy', 'cnhaud', 'euraud', 'eurcad', 'eurchf', 'eurgbp',
          'eurjpy', 'eursek', 'eurusd', 'gbpaud', 'gbpchf', 'gbpeur', 'gbpjpy', 'gbpusd', 'nzdusd', 'usdcad', 'usdchf',
          'usdcnh', 'usdjpy', 'usdsek', 'usdx']

for tgt_num in range(10, 21):
    if tgt_num != 16: # and tgt_num != 16 and tgt_num != 18 and tgt_num != 19:
        continue
    for symb in symbols:
        data_file = f"Input_data_1y_{symb}.txt"

        try:
            # Try to open the text file for reading
            with open(file_path / data_file, "r") as f:
                lines = f.readlines()

            # Check if the file is empty
            if not lines:
                print("Warning: The data file is empty.")

        except IOError as e:
            print(f"Error opening file: {e}")
            lines = []

        # Initialize an empty list to hold the sequence of integer values
        seq = []

        # Loop through each line in the file
        for line in lines:
            values = line.strip().split(",")
            for value in values:
                try:
                    seq.append(float(value)) # .append(float(value)*0.01)
                except ValueError:
                    pass

        # Convert the list to a numpy array
        seq = np.array(seq)

        data_file = f"trained_{tgt_num}y_audusd_FORECASTS_1y_{symb}.txt"

        try:
            # Try to open the text file for reading
            with open(file_path / data_file, "r") as f:
                lines = f.readlines()

            # Check if the file is empty
            if not lines:
                print("Warning: The data file is empty.")

        except IOError as e:
            print(f"Error opening file: {e}")
            lines = []

        # Initialize an empty list to hold the sequence of integer values
        fcsts = []

        # Loop through each line in the file
        for line in lines:
            values = line.strip().split(",")
            for value in values:
                try:
                    fcsts.append(float(value)) # .append(float(value)*0.01)
                except ValueError:
                    pass

        # Convert the list to a numpy array
        fcsts = np.array(fcsts)

        # define a function to forecast the next element using a naive approach
        def naive_forecast(fcsts_data):
            # shift the data by one time step
            forecast = np.empty_like(fcsts_data)
            forecast[0] = fcsts_data[0]
            for i in range(1, len(fcsts_data)):
                forecast[i] = fcsts_data[i - 1]
            return forecast

        # root mean squared error metric
        def rmse(y_true, y_pred):
            return K.sqrt(K.mean(K.square(y_pred - y_true)))

        # relative root mean squared error metric
        def rrmse(y_true, y_pred):
            num = tf.reduce_sum(tf.square(y_true - y_pred))
            den = tf.reduce_sum(tf.square(y_true - tf.reduce_mean(y_true)))
            return K.sqrt(num / den)

        # forecast the next element using a naive approach
        naive_forecast = naive_forecast(seq)

        # calculate the RMSE of the naive forecast
        naive_mse = mean_squared_error(seq, naive_forecast)
        naive_mae = mean_absolute_error(seq, naive_forecast)
        naive_mpl = mean_pinball_loss(seq, naive_forecast)
        naive_r2 = r2_score(seq, naive_forecast)
        naive_evs = explained_variance_score(seq, naive_forecast)
        naive_d2p = d2_pinball_score(seq, naive_forecast)
        naive_d2ae = d2_absolute_error_score(seq, naive_forecast)
        naive_rmse = rmse(seq, naive_forecast)
        naive_rrmse = rrmse(seq, naive_forecast)

        # calculate the RMSE of the CNN-LSTM forecast
        mse = mean_squared_error(seq, fcsts)
        mae = mean_absolute_error(seq, fcsts)
        mpl = mean_pinball_loss(seq, fcsts)
        r2 = r2_score(seq, fcsts)
        evs = explained_variance_score(seq, fcsts)
        d2p = d2_pinball_score(seq, fcsts)
        d2ae = d2_absolute_error_score(seq, fcsts)
        rmse = rmse(seq, fcsts)
        rrmse = rrmse(seq, fcsts)

        print(f'\n{symb} - Naive MSE={naive_mse:.5f}; '
              f'MAE={naive_mae:.4f}; MPL={naive_mpl:.4f}; '
              f'RMSE={naive_rmse:.4f}; RRMSE={naive_rrmse:.4f}; '
              f'D2AE={naive_d2ae:.4f}; D2P={naive_d2p:.4f}; '
              f'EVS={naive_evs:.4f}; R2={naive_r2:.4f} ')

        print(f'{symb} - MachL MSE={mse:.5f}; '
              f'MAE={mae:.4f}; MPL={mpl:.4f}; '
              f'RMSE={rmse:.4f}; RRMSE={rrmse:.4f}; '
              f'D2AE={d2ae:.4f}; D2P={d2p:.4f}; '
              f'EVS={evs:.4f}; R2={r2:.4f} ')

    print(f'\nyear: {tgt_num} / input data len({len(seq)}) / forecast len({len(fcsts)})')
Тестовые данные и файлы svg прилагаются.
 
Lilita Bogachkova #:

Модель обучена на данных символа AUD/USD всего за 16 лет (приблизительно 101370 баров H1). Протестировано с 25 символами данных за 1 год, эти данные не используются при обучении модели. Пример теста, синяя линия — тестовые данные, красная линия — прогнозируемые данные.

Также было выполнено сравнение метрик между наивным прогнозом и обученной моделью.
Следующий набор метрик — это метрики оценки для двух разных моделей (Naive и MachL), используемые для составления прогноза для переменной «usdx».

  • MSE (Mean Squared Error) — это мера средней квадратичной разницы между прогнозируемыми и фактическими значениями. Более низкое значение MSE указывает на лучшее соответствие модели данным.

  • MAE (Mean Absolute Error) — это мера средней абсолютной разницы между прогнозируемыми и фактическими значениями. MAE менее чувствителен к выбросам, чем MSE, и более низкое значение указывает на лучшее соответствие модели данным.

  • MPL (средняя процентная ошибка) - это мера средней процентной разницы между прогнозируемыми и фактическими значениями. Меньшее значение указывает на лучшее соответствие модели данным.

  • RMSE (Root Mean Squared Error) — это квадратный корень из MSE, который измеряет среднюю разницу между прогнозируемыми и фактическими значениями. Как и в случае с MSE, более низкое значение RMSE указывает на лучшее соответствие модели данным.

  • RRMSE (относительная среднеквадратичная ошибка) - это среднеквадратичное значение, нормализованное диапазоном фактических значений. Меньшее значение указывает на лучшее соответствие модели данным.

  • EVS (Explained Variance Score) измеряет долю дисперсии в фактических значениях, которая объясняется прогнозируемыми значениями. Значение 1,0 указывает на идеальное соответствие модели данным.

  • D2AE (Directional Accuracy Error) измеряет долю правильно предсказанных направлений (положительных или отрицательных) от фактических значений. Значение 1,0 указывает на идеальную точность направления.

  • D2P (Directional Consistency Error) измеряет долю времени, в течение которого прогнозируемые значения движутся в том же направлении, что и фактические значения. Значение 1,0 указывает на идеальную направленную согласованность.

  • R2 (коэффициент определения) измеряет долю дисперсии в фактических значениях, которая объясняется прогнозируемыми значениями, но, в отличие от EVS, он также учитывает количество переменных в модели. Значение 1,0 указывает на идеальное соответствие модели данным.

Сравнивая две модели, MachL работает лучше, чем Naive, по всем показателям, со значительно более низкими значениями MSE, MAE, MPL, RMSE, RRMSE и D2AE. Модель MachL также имеет более высокие значения EVS, D2P и R2, что указывает на лучшее соответствие данным.


source:


Тестовые данные и файлы svg прилагаются.

круто) осталось прикрутить к терминалу)

 
Теперь, чтобы получить адекватные оценки ошибок, нужно остационарить ряд. При наличии автокорреляции ошибки занижаются.