Обсуждение статьи "Python, ONNX и MetaTrader 5: Создаем модель RandomForest с предварительной обработкой данных RobustScaler и PolynomialFeatures"

 

Опубликована статья Python, ONNX и MetaTrader 5: Создаем модель RandomForest с предварительной обработкой данных RobustScaler и PolynomialFeatures:

В этой статье мы создадим модель случайного леса на языке Python, обучим модель и сохраним ее в виде конвейера ONNX с препроцессингом данных. Модель мы далее используем в терминале MetaTrader 5.

Случайный лес, или RandomForest, представляет собой мощный инструмент в арсенале машинного обучения. Для того чтобы лучше понять его принцип работы, давайте визуализируем его как огромную группу людей, собравшихся вместе и принимающих коллективные решения. Однако вместо реальных людей, каждый человек в этой группе является независимым классификатором или предсказателем текущей ситуации. Внутри этой группы, люди - это деревья решений, каждое из которых способно принимать решения на основе определенных признаков. Когда случайный лес принимает решение, он использует демократический принцип и голосование - каждое дерево выражает свое мнение, и решение принимается на основе множественных голосов.

Случайный лес широко применяется в множестве областей, и его гибкость делает его подходящим для задач как классификации, так и регрессии. При задаче классификации, модель решает, к какому из предопределенных классов отнести текущее состояние. Например, на финансовом рынке, это может означать решение о покупке (класс 1) или продаже (класс 0) актива, основываясь на множестве признаков.

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

Автор: Yevgeniy Koshtenko

 
Одна ошибка в коде, которую я нашел:

future_pr = dataset['<CLOSE>'].iloc[i + rand]
должно быть:

future_pr = dataset['close'].iloc[i + rand ]

В противном случае вы получите ошибку:

Файл "C:\Python39\lib\site-packages\pandas\core\indexes\base.py", строка 3812, in get_loc
raise KeyError(key) from err
KeyError: '<close> '

Неверная ссылка на столбец в вашей функции labelling_relabeling_regression. Я продолжал получать ошибки, потому что вы пытаетесь получить доступ к столбцу '<CLOSE>' в вашем наборе данных, но pandas не может найти его, потому что правильное имя столбца - 'close', а не '<CLOSE>'. Из-за чувствительности к регистру и дополнительных угловых скобок pandas выбрасывает ошибку KeyError.

Очень простая ошибка, но кто-то другой, идущий рядом, может запутаться и сдаться.

Поскольку остальная часть вашего кода использует <CLOSE> ... вероятно, лучше просто добавить строку, например:

dataset = dataset.rename(columns={'close': '<CLOSE>'})


def labelling_relabeling_regression(dataset, min_value=1, max_value=1):
dataset = dataset.rename(columns={'close': '<CLOSE>'}) //добавьте эту строку, чтобы остальная часть кода работала без сбоев
future_prices = [ ]

for i in range(dataset.shape[0] - max_value):
rand = random.randint(min_value, max_value )
future_pr = dataset['<CLOSE>'].iloc[i + rand ]
future_prices.append(future_pr )

набор данных = dataset.iloc[:len(future_prices)].copy( )
dataset['future_price'] = future_prices

return dataset


 
Shashank Rai #:
Одна ошибка в коде, которую я нашел:

должно быть:

future_pr = dataset['close'].iloc[i + rand ]

В противном случае вы получите ошибку:

Файл "C:\Python39\lib\site-packages\pandas\core\indexes\base.py", строка 3812, in get_loc
raise KeyError(key) from err
KeyError: '<close> '

Неверная ссылка на столбец в вашей функции labelling_relabeling_regression. Я продолжал получать ошибки, потому что вы пытаетесь получить доступ к столбцу '<CLOSE>' в вашем наборе данных, но pandas не может найти его, потому что правильное имя столбца - 'close', а не '<CLOSE>'. Из-за чувствительности к регистру и дополнительных угловых скобок pandas выбрасывает ошибку KeyError.

Очень простая ошибка, но кто-то другой, идущий рядом, может запутаться и сдаться.

Поскольку остальная часть вашего кода использует <CLOSE> ... вероятно, лучше просто добавить строку, например:

dataset = dataset.rename(columns={'close': '<CLOSE>'})


def labelling_relabeling_regression(dataset, min_value=1, max_value=1):
dataset = dataset.rename(columns={'close': '<CLOSE>'}) //добавьте эту строку, чтобы остальная часть кода работала без сбоев
future_prices = [ ]

for i in range(dataset.shape[0] - max_value):
rand = random.randint(min_value, max_value )
future_pr = dataset['<CLOSE>'].iloc[i + rand ]
future_prices.append(future_pr )

набор данных = dataset.iloc[:len(future_prices)].copy( )
dataset['future_price'] = future_prices

return dataset


Спасибо большое, посмотрю, возможно упустил при редактировании кода!(
 
Yevgeniy Koshtenko #:
Спасибо большое, я посмотрю, возможно, я пропустил это при редактировании кода!(

Нет проблем, сэр. Еще одна рекомендация - для тех, кто не использует google colab и просто работает на своей машине или на AWS, им не нужно импортировать gdown

Вместо этого используйте следующее:

Во-первых:

import os #добавьте эту строку в область импорта вместо import gdown
.


Второе:

замените следующий раздел


# Save the pipeline
joblib.dump(pipeline, 'rf_pipeline.joblib')

# Convert pipeline to ONNX
onnx_model = convert_sklearn(pipeline, initial_types=initial_type)

# Save the model in ONNX format
model_onnx_path = "rf_pipeline.onnx"
onnx.save_model(onnx_model, model_onnx_path)

# Save the model in ONNX format
model_onnx_path = "rf_pipeline.onnx"
onnx.save_model(onnx_model, model_onnx_path)

# Connect Google Drive (if you work in Colab and this is necessary)
from google.colab import drive
drive.mount('/content/drive')

# Specify the path to Google Drive where you want to move the model
drive_path = '/content/drive/My Drive/'  # Make sure the path is correct
rf_pipeline_onnx_drive_path = os.path.join(drive_path, 'rf_pipeline.onnx')

# Move ONNX model to Google Drive
shutil.move(model_onnx_path, rf_pipeline_onnx_drive_path)

print('The rf_pipeline model is saved in the ONNX format on Google Drive:', rf_pipeline_onnx_drive_path)

на:

# Сохраните трубопровод в формате Joblib
joblib_model_path = 'rf_pipeline.joblib '
joblib.dump(pipeline, joblib_model_path)

# Преобразование трубопровода в формат ONNX
initial_type = [('float_input', FloatTensorType([None, n_features]))]
onnx_model = convert_sklearn(pipeline, initial_types=initial_type )

# Сохраните модель ONNX
model_onnx_path = "rf_pipeline.onnx "
onnx.save_model(onnx_model, model_onnx_path)

# Укажите локальную папку в текущем каталоге для сохранения модели
local_folder_path = './models/'# Настройте этот путь по мере необходимости.

# Создайте каталог, если он не существует
if not os.path.exists(local_folder_path):
os.makedirs(local_folder_path )

# Укажите полные пути к моделям в локальной папке
local_joblib_path = os.path.join(local_folder_path, 'rf_pipeline.joblib' )
local_onnx_path = os.path.join(local_folder_path, 'rf_pipeline.onnx' )

# Переместите модели в указанную локальную папку
shutil.move(joblib_model_path, local_joblib_path)
shutil.move(model_onnx_path, local_onnx_path)

print(f'Модель rf_pipeline в формате Joblib сохранена локально по адресу: {local_joblib_path}')

print(f'Модель rf_pipeline в формате ONNX сохранена локально по адресу: {local_onnx_path}')


модель будет храниться в подкаталоге /model. Здесь же будет храниться модель в виде файла jplotlib, если она понадобится вам во время выполнения. Кроме того, обе модели можно запускать непосредственно из python для получения прогнозов.

 
Спасибо за статью. После того, как я сделал reinforcement learning для своего проекта в университете, я задался вопросом, возможно ли это.
 
Shashank Rai #:

Нет проблем, сэр. Еще одна рекомендация - для тех, кто не использует google colab и просто работает на своей машине или на AWS, им не нужно импортировать gdown

Вместо этого используйте следующее:

Во-первых:

import os #добавьте эту строку в область импорта вместо import gdown
.


Второе:

замените следующий раздел


на:

# Сохраните трубопровод в формате Joblib
joblib_model_path = 'rf_pipeline.joblib '
joblib.dump(pipeline, joblib_model_path)

# Преобразование трубопровода в формат ONNX
initial_type = [('float_input', FloatTensorType([None, n_features]))]
onnx_model = convert_sklearn(pipeline, initial_types=initial_type )

# Сохраните модель ONNX
model_onnx_path = "rf_pipeline.onnx "
onnx.save_model(onnx_model, model_onnx_path)

# Укажите локальную папку в текущем каталоге для сохранения модели
local_folder_path = './models/'# Настройте этот путь по мере необходимости.

# Создайте каталог, если он не существует
if not os.path.exists(local_folder_path):
os.makedirs(local_folder_path )

# Укажите полные пути к моделям в локальной папке
local_joblib_path = os.path.join(local_folder_path, 'rf_pipeline.joblib' )
local_onnx_path = os.path.join(local_folder_path, 'rf_pipeline.onnx' )

# Переместите модели в указанную локальную папку
shutil.move(joblib_model_path, local_joblib_path)
shutil.move(model_onnx_path, local_onnx_path)

print(f'Модель rf_pipeline в формате Joblib сохранена локально по адресу: {local_joblib_path}')

print(f'Модель rf_pipeline в формате ONNX сохранена локально по адресу: {local_onnx_path}')


модель будет храниться в подкаталоге /model. Здесь же будет храниться модель в виде файла jplotlib, если она понадобится вам во время выполнения. Кроме того, обе модели можно запускать непосредственно из python для получения прогнозов.

Исправил, забросил версию обучающего файла на утверждение модератору.

 
Adrian Page #:
Спасибо за статью. После того, как я сделал reinforcement learning для своего проекта в университете, я задался вопросом, возможно ли это.

Да, до обучения с подкреплением я еще не добрался)))

 
22.04.2024 - поменял данные датасета из формата Excel в формат библиотеки Python MetaTrader5. Плюс, сделал сохранение модели локально (ранее было сохранение на Гугл Диск)
 
Yevgeniy Koshtenko #:

Почему не использовался градинтный бустинг, как более свежий алгоритм (раз уж сетуете что случайный лес уже старый)? Просто так получилось или были какие-то причины? Вроде бы бустинг есть в sklearn.

 
Aleksey Nikolayev #:

Почему не был использован градиентный бустинг как более современный алгоритм (раз уж вы жалуетесь, что random forest уже устарел)? Это просто произошло или была какая-то причина? Я думаю, что бустинг есть в sklearn.

Просто лес был выбран в качестве простого примера)Бустинг в следующей статье, сейчас я его немного дорабатываю)

 
Yevgeniy Koshtenko #:

Просто лес был выбран в качестве простого примера)Бустинг в следующей статье, сейчас я его немного дорабатываю)

Хорошо)