Итоги

25.07.2018, 18:34:42
Всем привет!
Поздравляю победителей и благодарю организаторов за интересный датасет и качественную площадку (быстрый сервер, мгновенный расчёт рейтинга) ;-)
Я впервые участвую в подобном конкурсе, было очень интересно и полезно. Хотя я и начал работать с задачей только за десять дней до финала, я не уверен, что смог бы найти лучшее решение, даже если бы работал месяц – и без того перепробовал много подходов и идей.
Позволю себе поделиться впечатлениями.
Некоторые вещи сработали не как ожидалось, некоторые открытия вызвали недоумение.
Я изучаю машинное обучение уже около года, прочитал много книжек и статей, кое-что пытался применить на практике. Для себя я выбрал в качестве основного стек Python/scikit-learn, потому что R вызвал отторжение своим странным синтаксисом и (на первый взгляд?) неуклюжей R-Studio. К питону и его создателям у меня тоже много претензий, не зря ван Россум остаил корабль, видно ) Однако ближе к теме.
Мне хотелось попробовать при участии в конкурсе некоторые новые инструменты и технологии, про которые раньше слышал только краем уха, об этом тоже расскажу. Вот мои открытия.
Обнаруженные недостатки пакетов/технологий
Feature Engineering
Очень надеялся на Featuretools для генерации базовых фич (а в идеале и достаточно сложных). Набор примитивов там оказался более чем скромный, а вот при этом время работы просто обескуражило. Медленный однопоток. Есть возможность поднять dask кластер, но я не нашёл возможности сделать это в рамках родительского процесса. А каждый рабочий процесс dask делает полную копию всей таблицы, нам оно надо при размере 20Гб? Концепция cutoff times показалась искусственной – объяснена в доках плохо, подходит не для всех случаев. В нашем оказалась неприменима. В итоге заменил на агрегацию с помощью pandas, заработало на порядок быстрее.
25.07.2018, 18:35:06
Sklearn
RandomizedSearchCV реализован очень в лоб. Может бесконечно продолжать сэмплировать комбинации параметров, которые несовместимы и генерят ошибки. Я уже не говорю о направленном поиске, кажется, даже простые эвристики уже сильно помогут – пореже выдавай варианты, которые долго считаются, почаще выдавай близкие в N мерном пространстве к текущим оптимальным, иногда исследуй наименее изученные области пространства поиска.
Модели считались некоторые много часов, в зрелой библиотеке удивляет отсутствие автосохранений (или хотя бы периодических сохранений лучшей модели).
Skopt прельстил в этом плане своей полной совместимостью с sklearn. Однако попытка тестирования привела к странному – решения находит плохие, а работает в 50 раз дольше. Детали тут https://github.com/scikit-optimize/scikit-optimize/issues/703#issuecomment-407182220
Hyperopt отпугнул невнятной документацией и на первый взгляд невозможностью использовать родные оценщики sklearn. Что вы используете, коллеги?
Далее, мне кажется, сама идея обучения в этом фреймворке без ранней остановки порочна (авторы добавили её в один или два класса, не более). Ведь по сути нам предлагают на train уходить в переобучение, а по факту вложенной кроссвалидации оценивать среднюю степень переобучения таких оверфитнутых моделей (и выбирать «меньшее из зол»). Но если я не хочу использовать оверфитнутые? Не лучше ли добавить early stopping повсеместно? Что если вовремя остановленные модели будут на out-of-sample лучше, чем лучшие из предельно оверфитнутых, выбранных по текущим официальным рекомендациям? Кто думал о том же? )
XGboost как-то разочаровал. Впервые его попробовал, ожидал большего. Он постоянно у меня переобучался, на CV почти всегда он был отстающим, хотя я и всегда добавлял early stopping, и не забывал включать его гамму в сетку поиска. Как вы его готовите? что я делал не так?
Keras опечалил отсутствием поддержки sparse матриц. Ну, ладно, думаю, можно подавать кусками данные с помощью генератора. Однако дефолтная метрика для классификации accuracy, вы серьёзно??? и нет возможности из коробки задать roc_auc. Вот такое отношение у разработчиков. Видно и по докам – сухо, голое техническое описание, ни примеров, ни best practices. Удалось подсунуть самодельную метрику, сделанную на коленке из streaming_auc, сеточка даже заобучалась, но метрики ошибок выдавала в не полностью совместимом с sklearn формате, в итоге бросил разбираться из-за нехватки времени. Обёртка KerasClassifier жутко тормозила (только у меня так?)
Tensorflow “порадовал” молчаливым отказом работать с GPU (v1.9, cuda 9.2, Win. хотя Cuda 8 работала). GPU из-под TF виден, почему Keras и TF его не грузили – узнать невозможно, никакого контродя не предусмотрено. В сети полно подобных вопросов, разработчиков не волнует.
Питон:
Однопоточность. в 21м-то веке!
Отсутствие типизации ведёт к глупым ошибкам, (которые вообще-то элементарно могли быть пойманы), которые могут проявится через много часов вычислений и угробить долгую работу. Или просто потребуют вмешательства, будут отрывать от работы.
Неудобная отладка, как правило, это print() и перезапуск процедуры. отладчик старого доброго Visual Basic 6 на несколько порядков удобнее. Плюс там можно править любой (99,9%) код прямо во время выполнения, и не надо перезапускать процедуру. тут об этом нельзя и мечтать, хотя язык интерпретируемый.
Очень медленный.
Отсутствует нормальный компилятор. Чем сообщество занимается при таких глобальных проблемах, понять сложно. И как раз попалась статья недавно https://metarabbit.wordpress.com/2018/02/05/pythons-weak-performance-matters/, не я один так думаю, оказывается.
Метаобучение.
Сабмитнул несколько простеньких тестовых моделей, лучшие усреднил, скор улучшился. Захотел обучить на выходах модели и правильных метках метамодель – ничего не вышло, лучше арифм. среднего никто на CV не поднялся, даже XGBoost  Либо модели оказались слишком коррелированы, либо я что-то не так делал. Михаэлидис бы посмеялся.
Позитив
Перечитал за неделю аж 3.5 книжки по Machine learning
Поработал с разреженными матрицами
На практике познакомился с tf-idf, он очень сильно помогал моделям.
Впервые попробовал ансамбли.
Если кто-то захочет поработать вместе над следующим проектом, буду рад!
С уважением,
Анатолий


Зарегистрируйтесь или войдите, чтобы оставить сообщение.