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

 
СанСаныч Фоменко:

Доказательств, что НС с чем-то справилась я не вижу.

Переобучение - всемирное зло в науке и в частности при построении модели.

Поэтому необходима ошибка для трех наборов:

  • набора обучения. Вполне подойдет то, как это понимает rattle (OOB, test, validation)
  • набор, который находится вне, в смысле по датам, набора обучения.
  • еще один набор, который находится вне, в смысле по датам, набора обучения. 

Последние два набора без перемешивания, так как они поступают в терминале, баз за баром. 

На всех трех наборах должна быть примерно одинаковая ошибка. При этом Вам придется зафиксировать набор предикторов, которые Вы берете при обучении модели. 

Переобучение я в данной задаче сначала не учитывал, не было необходимости. Первый раз нейронка была с всего одним нейроном в внутреннем слое. Я сейчас проверил, ошибка при длительном обучении около 45%, и ниже не опускается. Сеть при обучении даёт тем входам 1,3,5,7,9,11 более высокие веса, но реально дообучиться она не может из-за нехватки нейронов. В этом и была идея, выжать из неё максимально правильный результат, в очень ограниченных условиях, и посмотреть каким входам она даст веса побольше.

Сейчас, имея валидационный файл, уже можно работать серьёзней. Сейчас я исходный файл поделил на 2 части (85% и 15%), обучал на первой части, иногда останавливал обучение и измерял ошибку на обоих частях. Те примеры из 15% файла не попадали в обучение, но ошибка в них уменьшалась примерно также как и в тренировочной части. Когда она стала 0% в обоих частях файла - остановил обучение, и проверил нейронку на втором файле, там ошибка вышла ~0%. Получается что для данной задачи переобучения даже не получилось добиться, забавно.


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

Были разные идеи как можно улучшить результат, например сглаживать результаты, или добавлять фильтр (<0.1 - продажа, >0.9 - покупка, а всё что между - период без торговли). Можно очень хорошо улучшить результат торговли добавив фильтр к результату нейронки и оптимизируя его тоже, но для фронттеста мне это совсем не помогло. Ещё была хорошая идея, что если нейронка обучалась на неком периоде истории, то оптимизировать фильтр можно на истории до этого периода. Ибо ошибка до периода оптимизации возможно связана с ошибкой после периода оптимизации. Но не прокатило, если есть три периода истории - "до обучения нейронки" - "обучение нейронки" - "после обучения нейронки", то у всех трёх будут свои оптимальные фильры, никак не связанные.

Я покачто для себя сделал вывод что модель должна иметь маленькую ошибку (<10%) на тренировочной и тестовой выборках. Фильтры на результат модели не применять, и никакого гадания типа "инвертировать результат каждую четвёртую неделю". Не опускаться в периоды мельче M15. Пробую разные новые идеи, хорошо если хоть одна из десяти улучшает результат. И как-то так должна получиться прибыльная модель.

 
Dr.Trader:

Переобучение я в данной задаче сначала не учитывал, не было необходимости. Первый раз нейронка была с всего одним нейроном в внутреннем слое. Я сейчас проверил, ошибка при длительном обучении около 45%, и ниже не опускается. Сеть при обучении даёт тем входам 1,3,5,7,9,11 более высокие веса, но реально дообучиться она не может из-за нехватки нейронов. В этом и была идея, выжать из неё максимально правильный результат, в очень ограниченных условиях, и посмотреть каким входам она даст веса побольше.

Сейчас, имея валидационный файл, уже можно работать серьёзней. Сейчас я исходный файл поделил на 2 части (85% и 15%), обучал на первой части, иногда останавливал обучение и измерял ошибку на обоих частях. Те примеры из 15% файла не попадали в обучение, но ошибка в них уменьшалась примерно также как и в тренировочной части. Когда она стала 0% в обоих частях файла - остановил обучение, и проверил нейронку на втором файле, там ошибка вышла ~0%. Получается что для данной задачи переобучения даже не получилось добиться, забавно.


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

Были разные идеи как можно улучшить результат, например сглаживать результаты, или добавлять фильтр (<0.1 - продажа, >0.9 - покупка, а всё что между - период без торговли). Можно очень хорошо улучшить результат торговли добавив фильтр к результату нейронки и оптимизируя его тоже, но для фронттеста мне это совсем не помогло. Ещё была хорошая идея, что если нейронка обучалась на неком периоде истории, то оптимизировать фильтр можно на истории до этого периода. Ибо ошибка до периода оптимизации возможно связана с ошибкой после периода оптимизации. Но не прокатило, если есть три периода истории - "до обучения нейронки" - "обучение нейронки" - "после обучения нейронки", то у всех трёх будут свои оптимальные фильры, никак не связанные.

Я покачто для себя сделал вывод что модель должна иметь маленькую ошибку (<10%) на тренировочной и тестовой выборках. Фильтры на результат модели не применять, и никакого гадания типа "инвертировать результат каждую четвёртую неделю". Не опускаться в периоды мельче M15. Пробую разные новые идеи, хорошо если хоть одна из десяти улучшает результат. И как-то так должна получиться прибыльная модель.

Все дело в данных )

Данные во всех наборах должны содержать взаимно независииые наблюдения. Но даже в этом случае валидация даст худший результат.
 

Я попробовал ещё разные модели из Rattle, лес (forest) дал тоже хороший результат.

Шаг 1 - лес чему-то обучился, и в статистике входы 1,3,5,7,9,11 выглядят как-то обособленно. Ошибка на тренировочном файле 0%, на валидационном файле - 46%

 

Шаг 2 - оставил в файле только входы 1,3,5,7,9,11 и результат. Опять обучил лес на новом файле, теперь ошибка 0% и на тренировочном, и на валидационном файлах, всё круто. Единственный нюанс был что Rattle для второго шага выставил параметр "Number of variables" 2, наверное потому что файл меньше объёмом. Я изменил его на 4 как в первом шаге.

 

Dr.Trader

Приятно видеть брата по разуму на основе rattle. Во всяком случае имеем возможность сопоставлять результаты.

Итак и собственного опыта.

Берем rattle и модели из него.

На вкладке model учим, получая величину ООВ, а на вкладке Evaluate оцениваем на наборах Validation и Testing. Получаем три цифры.

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

На вкладке Evaluate, кроме получения перечисленных результатов, необходимо проставить набор в окно R Dataset. Очень важно, чтобы этот набор был получен механическим делением исходного файла, т.е. первый файл для всех трех цифр, например с 1 января 2014 по 1 января 2015, а вот файл в окне    

R Dataset обязательно после 1 января 2015 без всяких случайных выборок и прочих фишек, используемых в R. Просто тупо, механически.

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

 

Не могли бы Вы выложить все четыре цифры? Включая результат на файле из окна  R Dataset?

 
Dr.Trader:

Я попробовал ещё разные модели из Rattle, лес (forest) дал тоже хороший результат.

Шаг 1 - лес чему-то обучился, и в статистике входы 1,3,5,7,9,11 выглядят как-то обособленно. Ошибка на тренировочном файле 0%, на валидационном файле - 46%

 

Шаг 2 - оставил в файле только входы 1,3,5,7,9,11 и результат. Опять обучил лес на новом файле, теперь ошибка 0% и на тренировочном, и на валидационном файлах, всё круто. Единственный нюанс был что Rattle для второго шага выставил параметр "Number of variables" 2, наверное потому что файл меньше объёмом. Я изменил его на 4 как в первом шаге.

Интересно... Глубину надо ставить 6 переменных, чтобы все значимые подцепить.
 
Dr.Trader:

Я попробовал ещё разные модели из Rattle, лес (forest) дал тоже хороший результат.

Шаг 1 - лес чему-то обучился, и в статистике входы 1,3,5,7,9,11 выглядят как-то обособленно. Ошибка на тренировочном файле 0%, на валидационном файле - 46%

 

Шаг 2 - оставил в файле только входы 1,3,5,7,9,11 и результат. Опять обучил лес на новом файле, теперь ошибка 0% и на тренировочном, и на валидационном файлах, всё круто. Единственный нюанс был что Rattle для второго шага выставил параметр "Number of variables" 2, наверное потому что файл меньше объёмом. Я изменил его на 4 как в первом шаге.

В первом случае лес использовал шумы для обучения, что не очень хорошо.
 
СанСаныч Фоменко:

Не могли бы Вы выложить все четыре цифры? Включая результат на файле из окна  R Dataset?

Сделал так с нейронкой - dummy_set_features.csv поделен стандартно на 3 части 70%/15%/15%; dummy_set_validation.csv использовал на вкладке evaluate как "csv file" (это по сути тоже самое что и R Dataset, просто формат файла другой).

Взял лог из Rattle, убрал те два ограничения из вызова нейронки о которых писал раньше, запустил просто в R, модель всё равно получилась недообученной (ошибка 35% на тренировочной выборке). Так бывает, что если уменьшить обучающую выборку, то и результат обучения хуже. Но можно увеличить количество нейронов во внутреннем слое, это должно улучшить обучение.

Поменял число нейронов с 10 на 20, запустил обучение ещё раз, теперь ошибка на обучающей выборке стала 0%. Ошибка на валидационной выборке - 0.6%, на тестовой выборке - 0.1%. Ошибка на файле dummy_set_validation.csv - 0.3%. Всё хорошо, R в приложении.

 

Интересно, получается что проблемы обучения нейронки сильно отличаются от проблем деревьев. Для меня проблема с нн в том чтобы взять нужное количество внутренних нейронов, и приостановить обучение до того как сеть начнёт переобучаться. В принципе чем больше нейронов тем лучше, но это сильно влияет на требуемую оперативную память и время обучения. Лишние предикторы особо не мешают для обучения, нейронка обычно обучается с ними не хуже, но они увеличивают время обучения, и желательно от них отказываться чтобы было просто быстрее.

Когда-то я использовал самописную сеть в mt4, советник мог сразу обучаться и торговать. Там были проблемы со скоростью обучения, инициализацией весов, алгоритмами обучения. Было слишком много мелких проблем, добиться хорошего результата сложно даже на обучающей выборке, в итоге я всё бросил и теперь работаю в R. Пакет nnet умеет обучаться по bfgs алгоритму, это убирает все те мелкие проблемы. Но у пакета лимит в всего 1 внутренний слой. Хочется иметь хотя бы 3 внутренних слоя, но вместе с bfgs алгоритмом, иначе опять будет куча проблем с обучением. 

Файлы:
r_nnet2.txt  10 kb
 
Dr.Trader:

Сделал так с нейронкой - dummy_set_features.csv поделен стандартно на 3 части 70%/15%/15%; dummy_set_validation.csv использовал на вкладке evaluate как "csv file" (это по сути тоже самое что и R Dataset, просто формат файла другой).

 

Нет, не то же самое.

Удивительная вещь, со многими обсуждаю этот вопрос и НИКТО  НЕ ДЕЛАЕТ КАК ПИШУ. А я знаю, что пишу, так как на упражнения подобные Вашим убил полгода, причем вне rattle(). Что не подставлю в тестер - совсем другая ошибка. А потом сделал так, как описал выше, ошибка в тестере практически совпала с ошибкой на файле R Dataset.

 Я Алексею передавал три файла, которые получены механическим делением одно большого на три части. На первой части упражняемся, учим,оцениваем... А на двух других проверяем те цифры,которые получили на первом. Если на всех трех файлах ошибка более 20%(!), а точнее, ближе 40% - значит модель не переобучена и с ней можно работать.

Упомянутые 3 файла имеют 27 предикторов и 6 целевых переменных. 27 предикторов были отобраны из 170 предикторов по моим собственным алгоритмам. На сегодня эти 27 предикторов не приводят к переобученным моделям. А вот остальные 143 предиктора из моего набора - это шум и на этом шуме запросто можно получить ошибку, сравнимую с Вашей, но модель переобучается и не пригодна для дальнейшего использования.

Почему на шумовых предикторах ошибка меньше, чем на знАчимых предикторах?

По моим представлениям, так как алгоритм подгонки модели стремиться уменьшить ошибку подгонки, то он всегда среди шумовых, случайных значений способен отыскать нечто, что лучше, чем из знАчимых предикторов. В результате, чем меньше ошибка, тем меньше знАчимых предикторов участвует в построении модели! 

 

ПС 

Если судить по ошибке, то либо НС на 100% переобучена,либо заглядывает вперед. 

 

"CSV file" и "R dataset" на закладке evaluate это просто разные способы указать источник данных. Если в них подать одни и те же данные, то и результат при тестировании модели будет одинаковый.

Если перед запуском rattle выполнить

dataset_validate <- read.csv("file:///C:/dummy_set_validation.csv", na.strings=c(".", "NA", "", "?"), strip.white=TRUE, encoding="UTF-8")

, то этот самый dataset_validate теперь будет доступен на закладке evaluate как R dataset. Но результат проверки модели в итоге будет такой же самый как если просто выбрать опцию csv file и указать файл C:/dummy_set_validation.csv, данные для теста в обоих случаях будут идентичные.

Cамо обучение было на другом файле, dummy_set_features.csv, так что заглядывание в будущее тут невозможно, ибо данные в обоих файлах разные, и вообще не зависят от времени (а от формулы). Я считаю что нейронка отлично справилась и нашла 6 входов которые определяют результат, снизила воздействие остальных входов, и какой-то своей нейронной логикой описала нужную формулу.

Я на всякий случай сверил оба файла чтоб найти дубликаты строк, мало-ли они всётаки есть. Вот код на R:

#читаем данные из файлов для обучения и валидации
dataset_train <- read.csv("file:///C:/dummy_set_features.csv", na.strings=c(".", "NA", "", "?"), strip.white=TRUE, encoding="UTF-8")
dataset_validate <- read.csv("file:///C:/dummy_set_validation.csv", na.strings=c(".", "NA", "", "?"), strip.white=TRUE, encoding="UTF-8")

anyDuplicated(dataset_train) #количество повторных строк в первом файле - 567
anyDuplicated(dataset_validate) #количество повторных строк во втором файле - 202
# это покачто просто повторные строки в обоих файла по отдельности. Это не вредит, но и ничего не улучшает, лучше их убрать.
dataset_train <- unique(dataset_train)
dataset_validate <- unique(dataset_validate)

#Теперь можно узнать сколько строк из dataset_train повторяются в dataset_validate
dataset_combined <- rbind(dataset_train, dataset_validate) #Объединяем оба файла в один
nrow(dataset_combined) - nrow(dataset_combined[!duplicated(dataset_combined), ]) #количество повторенных строк - 23. Таких повторов быть не должно, их надо удалить.
#Удаление повторенных строк из dataset_validate
dataset_validate <- dataset_validate[!(tail(duplicated(dataset_combined), nrow(dataset_validate))), ]
#Удаление из памяти объединённого файла, он больше не нужен
rm(dataset_combined)

Если это выполнить до запуска rattle, то в нём будет доступен выбор обоих таблиц dataset_train и dataset_validate для обучения и проверки модели, повторов в них уже не будет. Слава R.

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

 
Это так и должно быть. Файл формируется случайными числами.

В общем, я переоценил сложность задачи . Она уже и лесом решается, по факту. Можно подумать , как такое возможно в свете того как работает лес.
Причина обращения: