Машинное обучение в трейдинге: теория, модели, практика и алготорговля - страница 2952

Не получается вывод в МТ5 из ONNX-модели, обученной в LightGBM. Ошибки 5808 и 5805 при установке формы параметров. Но проблема вроде уже с определением размерностей параметров - получаются отрицательные значения (выделено в коде). Может просто чего-нибудь напутал. В питоне 3.10 всё вроде нормально.

Вывод MQL5:

void OnStart()
  {
   long h = OnnxCreate("model.onnx", FILE_COMMON);
   
   //Print(OnnxGetInputCount(h));
   //Print(OnnxGetOutputCount(h));
   //Print(OnnxGetInputName(h, 0));
   //Print(OnnxGetOutputName(h, 0));
   OnnxTypeInfo otype;
   OnnxGetInputTypeInfo(h, 0, otype);
   ArrayPrint(otype.dimensions);                   // -1 8
   //Print(otype.element_type, " ", otype.type);
   OnnxGetOutputTypeInfo(h, 0, otype);
   ArrayPrint(otype.dimensions);                   // -1 1
   //Print(otype.element_type, " ", otype.type);
   
   matrix mx={{8.32520000e+00, 4.10000000e+01, 6.98412698e+00, 1.02380952e+00,
               3.22000000e+02, 2.55555556e+00, 3.78800000e+01,-1.22230000e+02},
              {8.30140000e+00, 2.10000000e+01, 6.23813708e+00, 9.71880492e-01,
               2.40100000e+03, 2.10984183e+00, 3.78600000e+01,-1.22220000e+02},
              {7.25740000e+00, 5.20000000e+01, 8.28813559e+00, 1.07344633e+00,
               4.96000000e+02, 2.80225989e+00, 3.78500000e+01,-1.22240000e+02},
              {5.64310000e+00, 5.20000000e+01, 5.81735160e+00, 1.07305936e+00,
               5.58000000e+02, 2.54794521e+00, 3.78500000e+01,-1.22250000e+02},
              {3.84620000e+00, 5.20000000e+01, 6.28185328e+00, 1.08108108e+00,
               5.65000000e+02, 2.18146718e+00, 3.78500000e+01,-1.22250000e+02}};
   matrix my={{0.0},{0.0},{0.0},{0.0},{0.0}};   
   
   const long  ExtInputShape [] = {1,5,8};
   const long  ExtOutputShape[] = {1,5};
   Print(OnnxSetInputShape(h,0,ExtInputShape));
   Print(GetLastError());                            // 5808
   ResetLastError();
   Print(OnnxSetOutputShape(h,0,ExtOutputShape));
   Print(GetLastError());                            // 5805
   
   OnnxRun(h, ONNX_DEBUG_LOGS | ONNX_NO_CONVERSION, mx, my);
   //Print(mx);
   //Print(my);
   OnnxRelease(h);
  }

Обучение в питоне:

from lightgbm import LGBMRegressor
from sklearn.datasets import fetch_california_housing
import onnxmltools
from onnxconverter_common import *

housing = fetch_california_housing()
X, Y = housing.data, housing.target

model = LGBMRegressor()
model.fit(X, Y)
Yreal, Ypredict = Y[:5], model.predict(X[:5])
print(Yreal)
print(Ypredict)

initial_type = [('input', FloatTensorType([None, len(X[0])]))]
onnx_model = onnxmltools.convert_lightgbm(model, name='LightGBM', initial_types=initial_type)
onnxmltools.utils.save_model(onnx_model, 'model.onnx')

Вывод в питоне:

import numpy as np
import onnxruntime as ort
from sklearn.datasets import fetch_california_housing

housing = fetch_california_housing()
X, Y = housing.data, housing.target
Xtest, Yreal = X[:5], Y[:5]

sess = ort.InferenceSession("model.onnx", providers=ort.get_available_providers())
input_name = sess.get_inputs()[0].name
Ypredict = sess.run(None, {input_name: Xtest.astype(np.float32)})[0]

print(Xtest)
print(Yreal)
print(Ypredict)
Похоже, переходить на питон рановато. Лучше освоить CLI версию LightGBM и сохранять модели в формате if-else на C. Неуниверсально, зато дёшево и сердито)
Вспомнилось обсуждение цикличных признаков, вроде времени суток. ИМХО, надо переводить их в обычные, просто подбирая точку для начала отсчёта, в которой происходит наиболее сильная смена возможной закономерности. Можно пользоваться либо соображениями о рынке (расписание сессии, в данном случае), либо чем-то вроде этого, либо обучать древесную модель и брать точку первого сплита по этому признаку.
Один из методов псевдо-адаптации.
Один из методов псевдо-адаптации.
  • 2023.01.30
  • www.mql5.com
Любой скальпер знает, что круглосуточная торговля - глупость. Есть интервалы, где достигается высокая и стабильная прибыльность, поэтому различными способами находят эти интервалы. Например, при
[Удален]
Aleksey Nikolayev #:
Вспомнилось обсуждение цикличных признаков, вроде времени суток. ИМХО, надо переводить их в обычные, просто подбирая точку для начала отсчёта, в которой происходит наиболее сильная смена возможной закономерности. Можно пользоваться либо соображениями о рынке (расписание сессии, в данном случае), либо чем-то вроде этого, либо обучать древесную модель и брать точку первого сплита по этому признаку.
Можно взять волатильность вместо приращений, она точно отражает рыночные циклы. И прогнать через 2 модели, одна из которых фильтрует плохие случаи (как в последней статье делал). Результаты иногда приличные, нужно несколько раз попереобучать. Потенциально подобный подход даст больше, чем bestinterval.

ЗЫ onnx на маке завелся из примера, что круто, бустинги не проверял еще 
Там на вход точно матрицу 2-мерную нужно, как в вашем примере? Логичнее одномерный массив с признаками, кажется. Может ругаться на неправильную форму матрицы. Например, вместо одномерного нужно давать 2-мерный, где каждая запись во 2-м измерении, т.е вложенные массивы, содержащие по 1 значению.

Ну и для катбуста есть пример перевода в mql из питона, lgbm вроде ничем не лучше 
Maxim Dmitrievsky #:
ЗЫ onnx на маке завелся из примера, что круто, бустинги не проверял еще 
Там на вход точно матрицу 2-мерную нужно, как в вашем примере? Логичнее одномерный массив с признаками, кажется. Может ругаться на неправильную форму матрицы. Например, вместо одномерного нужно давать 2-мерный, где каждая запись во 2-м измерении, т.е вложенные массивы, содержащие по 1 значению.

Ну, при обучении в питоне тестил модель на первых пяти строках датасета. Потом при запуске ONNX в питоне тоже проверил вывод на тех же первых пяти строках. Как ни крути, всё же это матрица. В МТ5 варианте просто скопипастил эти же пять строк в виде матрицы. Да и в примере Рената на вход подаётся тоже матрица из десяти строк и четырёх столбцов.

Проблема там, ИМХО, уже при загрузке модели, поскольку выдаются отрицательные числа в размерностях. Кстати, надо посмотреть что будет выдавать в примере Рената.

OnnxTypeInfo otype;
OnnxGetInputTypeInfo(h, 0, otype);
ArrayPrint(otype.dimensions);                   // -1 8
OnnxGetOutputTypeInfo(h, 0, otype);
ArrayPrint(otype.dimensions);                   // -1 1
Maxim Dmitrievsky #:
Можно взять волатильность вместо приращений, она точно отражает рыночные циклы. И прогнать через 2 модели, одна из которых фильтрует плохие случаи (как в последней статье делал). Результаты иногда приличные, нужно несколько раз попереобучать. Потенциально подобный подход даст больше, чем bestinterval.

Не, я просто про общий подход к цикличным переменным. Их надо "разрезать" для превращения в обычные. Но можно же делать это по разному, не обязательно в формальном нуле.

Помимо суточного времени, циклические переменные возникают, например, когда ищутся веса для портфеля из двух символов.

Aleksey Nikolayev #:
Похоже, переходить на питон рановато. Лучше освоить CLI версию LightGBM и сохранять модели в формате if-else на C. Неуниверсально, зато дёшево и сердито)
Есть ещё пакет  intrees, там можно правила тянуть с многих деревняных моделей.
Форесты, бусты... 
Maxim Dmitrievsky #:
Ну и для катбуста есть пример перевода в mql из питона, lgbm вроде ничем не лучше 

Есть лёгкие сомнения в будущем Яндекса)

Ещё, по идее, lgbm должен лучше интегрироваться с сишарпом и прочими поделками микрософта, если вдруг это станет актуальным)

mytarmailS #:
Есть ещё пакет  intrees, там можно правила тянуть с многих деревняных моделей.
Форесты, бусты... 

Можете скрипт с таким функционалом продемонстрировать?

Aleksey Nikolayev #:

Есть лёгкие сомнения в будущем Яндекса)

На чем они основаны?