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

 
Aleksey Vyazmikin:

Метрику я предоставил - выглядит хуже. Причина - большая вероятность попадания в случайный набор предикторов для построения сплита дерева предиктора связанного со временем.


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

В случайном лесу - да. Задается например по

max_features{“auto”, “sqrt”, “log2”}, int or float, default=”auto”

The number of features to consider when looking for the best split:


Aleksey Vyazmikin:

Да, я не использовал у себя минуты в старой версии.

Может они и ухудшили результат? Попробуйте в новой версии их удалить.

Вот так, должна быть полная аналогия вашему старому варианту

if(nameInd[nInd]=="Hour")        {CopyTime        (sim,per,startDt,n_bar+1,dtm);TimeToStruct(dtm[0],dts);ArrayResize(tmp,1);tmp[0]=(double)(dts.hour)*360.0/24.0;tmp[0]=(buf==0?MathSin(tmp[0]*pi/180.0):MathCos(tmp[0]*pi/180.0));}

if(nameInd[nInd]=="WeekDay")     {CopyTime        (sim,per,startDt,n_bar+1,dtm);TimeToStruct(dtm[0],dts);ArrayResize(tmp,1);tmp[0]=(double)(dts.day_of_week)*360.0/7.0;tmp[0]=(buf==0?MathSin(tmp[0]*pi/180.0):MathCos(tmp[0]*pi/180.0));}


 
elibrarius:

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

В случайном лесу - да. Задается например по


Может они и ухудшили результат? Попробуйте в новой версии их удалить.

Вот так, должна быть полная аналогия вашему старому варианту

if(nameInd[nInd]=="Hour")        {CopyTime        (sim,per,startDt,n_bar+1,dtm);TimeToStruct(dtm[0],dts);ArrayResize(tmp,1);tmp[0]=(double)(dts.hour)*360.0/24.0;tmp[0]=(buf==0?MathSin(tmp[0]*pi/180.0):MathCos(tmp[0]*pi/180.0));}

if(nameInd[nInd]=="WeekDay")     {CopyTime        (sim,per,startDt,n_bar+1,dtm);TimeToStruct(dtm[0],dts);ArrayResize(tmp,1);tmp[0]=(double)(dts.day_of_week)*360.0/7.0;tmp[0]=(buf==0?MathSin(tmp[0]*pi/180.0):MathCos(tmp[0]*pi/180.0));}


По поводу рандома - там его достаточно.

Вас не удивило, что у меня отдельно время и с синусом и с косинусом, а как я сейчас понимаю, должно быть одно, но использоваться то синус то косинус?

Отсюда вопрос, что такое  buf, и почему когда он равен нулю, то берем косинус?

 
Aleksey Vyazmikin:

По поводу рандома - там его достаточно.

Вас не удивило, что у меня отдельно время и с синусом и с косинусом, а как я сейчас понимаю, должно быть одно, но использоваться то синус то косинус?

Отсюда вопрос, что такое  buf, и почему когда он равен нулю, то берем косинус?

buf номер буфера.
Для времени их 2.Есть индикаторы с 1 буфером, есть и больше 2.

Я у себя в цикле перебираю количество буферов при составлении столбцов для обучающего набора.

Нужно обязательно подавать и синус и косинус,  а не что-то одно. Объяснение почему - тут https://megaobuchalka.ru/9/5905.html

Числовые данные, казалось бы, не надо кодировать. Но в ряде случаев целесообразно кодировать и числовые данные [22]. При кодировании числовых данных необходимо учитывать содержательное значение данных, расположение значений в интервале значений, точность измерения данных. Продемонстрируем это на примерах. Например, кодирование позволяет учесть содержательное значение данных. Если входными данными сети является угол между двумя направлениями, например, направление ветра, то ни в коем случае не следует подавать на вход сети значение угла (не важно, в градусах или радианах). Такая подача приведет к необходимости "уяснения" сетью того факта, что 0 градусов и 360 градусов одно и тоже. Разумнее выглядит подача в качестве входных данных синуса и косинуса этого угла. Число входных сигналов сети увеличивается, но зато близкие значения входа кодируются близкими входными сигналами.

Виды трансформации данных — Мегаобучалка
Виды трансформации данных — Мегаобучалка
  • megaobuchalka
  • megaobuchalka.ru
Трансформация данных — это преобразование данных к определенному представлению, формату или виду, оптимальному с точки зрения конкретного метода анализа [6]. Для разных задач анализа могут потребоваться разные методы трансформации. Типичными средствами трансформации данных являются следующие. Преобразование временны́х данных . Оптимизация...
 
elibrarius:

buf номер буфера.
Для времени их 2.Есть индикаторы с 1 буфером, есть и больше 2.

Я у себя в цикле перебираю количество буферов при составлении столбцов для обучающего набора.

Нужно обязательно подавать и синус и косинус,  а не что-то одно. Объяснение почему - тут https://megaobuchalka.ru/9/5905.html

Значит я правильно изначально всё сделал - просто уже не помню, что делал...

   double tmp[4];
   int nInd=0;
   MqlDateTime dts;
   double pi=3.1415926535897932384626433832795;
   for(int buf=0; buf<2; buf++)
   {
      TimeToStruct(iTime(Symbol(),PERIOD_CURRENT,0),dts);
      tmp[buf]=(double)(dts.hour*60+dts.min)*360.0/1440.0;
      //tmp[buf]=(double)(dts.hour*60+dts.min)*360.0/24.0;
      tmp[buf]=(buf==0?MathSin(tmp[0]*pi/180.0):MathCos(tmp[0]*pi/180.0));

      TimeToStruct(iTime(Symbol(),PERIOD_CURRENT,0),dts);
      tmp[buf+2]=(double)(dts.day_of_week*1440+dts.hour*60+dts.min)*360.0/10080.0;
      //tmp[buf+2]=(double)dts.day_of_week*360.0/7.0;
      tmp[buf+2]=(buf==0?MathSin(tmp[0]*pi/180.0):MathCos(tmp[0]*pi/180.0));
   }
 
А может вообще обойтись одним входом вместо 4-х?
Просто число минут с понедельника 0:00 =
dts.day_of_week*1440+dts.hour*60+dts.min
Хотя  - плохая идея. Чтобы добраться например до первых 10 минут каждого часа, придется очень много сплитов сделать.
Наверное лучше, как вы - просто дни, часы. Ну и может минуты.
 
elibrarius:
А может вообще обойтись одним входом вместо 4-х?
Просто число минут с понедельника 0:00 = Хотя  - плохая идея. Чтобы добраться например до первых 10 минут каждого часа, придется очень много сплитов сделать.
Наверное лучше, как вы - просто дни, часы. Ну и может минуты.

Запустил уже обучение без минут - посмотрим.

Я использую ещё время по типу 1/4 бара - часовки, 4часовки, дни.

 
Aleksey Vyazmikin:

Запустил уже обучение без минут - посмотрим.

Я использую ещё время по типу 1/4 бара - часовки, 4часовки, дни.

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

 
elibrarius:

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

Если делать самому квантование, то да, но там же ещё встроена автоматика.

Выше на гистограммах - это как раз разное число квантов на предиктор, видно, как они влияют на итоговый результат.

Если вытаскивать прожилки ценной информации в виде отдельного кванта предиктора, то можно эту прожилку закодировать в виде бинарного признака и подавать отдельно.

 
elibrarius:

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

Баланс - T1 с минутами и T2 без минут -  средний результат: 3384/3126/3890

Recall - средний результат: 0,0459/0,0424/0,0458


Precision - средний результат: 0,5216/0,5318/0,5389

По средним показателям в совокупности T2 худший вариант получился.

Открыл таблицу по значимости предикторов и тут удивился



Как то не понравились методу обучения последние изменения, может я не правильно что сделал?

//день недели, час = ввести через 2 предиктора sin и cos угла от полного цикла 360/7,  360/24
   double tmp[4];
   int nInd=0;
   MqlDateTime dts;
   double pi=3.1415926535897932384626433832795;
   for(int buf=0; buf<2; buf++)
   {
      TimeToStruct(iTime(Symbol(),PERIOD_CURRENT,0),dts);
      //tmp[buf]=(double)(dts.hour*60+dts.min)*360.0/1440.0;
      tmp[buf]=(double)(dts.hour*60+dts.min)*360.0/24.0;
      tmp[buf]=(buf==0?MathSin(tmp[0]*pi/180.0):MathCos(tmp[0]*pi/180.0));

      TimeToStruct(iTime(Symbol(),PERIOD_CURRENT,0),dts);
      //tmp[buf+2]=(double)(dts.day_of_week*1440+dts.hour*60+dts.min)*360.0/10080.0;
      tmp[buf+2]=(double)dts.day_of_week*360.0/7.0;
      tmp[buf+2]=(buf==0?MathSin(tmp[0]*pi/180.0):MathCos(tmp[0]*pi/180.0));
   }


 Открыл выборку



И увидел, что в столбце TimeHG - стоят часы - ошибка моя - надо переделывать все тесты.


 
Aleksey Vyazmikin:

Баланс - T1 с минутами и T2 без минут -  средний результат: 3384/3126/3890

Recall - средний результат: 0,0459/0,0424/0,0458


Precision - средний результат: 0,5216/0,5318/0,5389

По средним показателям в совокупности T2 худший вариант получился.

Открыл таблицу по значимости предикторов и тут удивился



Как то не понравились методу обучения последние изменения, может я не правильно что сделал?


 Открыл выборку



И увидел, что в столбце TimeHG - стоят часы - ошибка моя - надо переделывать все тесты.


И часы остались с минутами

 tmp[buf]=(double)(dts.hour*60+dts.min)*360.0/24.0;

Надо так

 tmp[buf]=(double)(dts.hour)*360.0/24.0;
TimeHG - видимо на себя все взял, потому остальные часы и не использовались.