31 место в Telecom Data Cup… Not bad?

Недавно принял участие в соревновании по Machine Learning от Mail.ru https://mlbootcamp.ru/round/15/rating/. Это был мой первый подобный опыт, и я думаю попробовать свои силы дальше на Kaggle.

Задача состояла в том чтобы выявить клиентов неудовлетворённых качеством сотовой связи имея обезличенные данные по клиентам, статистику их звонков и потребления трафика, и технические данные о работе оборудования сети. Задача настоящая, все данные взяты у Мегафона, но был нюанс, чтобы получить данные для обучения необходимо обзвонить пользователей и спросить у них, довольны ли они качеством связи, работа ручная соответственно в исходных данных было 9443 пользователей, и больше половины из них (5221) ушло в тестовую выборку. Тут у меня и возникло первое подозрение, для машинного обучения данных маловато.

Начал я с простого: просеял немного данные из таблицах о пользователях и их звонках и начал обучать random forest’ы. Машинное обучение (когда данные уже собраны) состоит из двух основных этапов:

  • Feature engineering
  • Подбор модели и гиперпараметров для неё

С моделями я решил особо не заморачиватся на данном этапе. Джереми Ховард в своём курсе по машинному обучению на fast.ai (кстати очень рекомендую для начинающих) говорит, что по сути сейчас на практике можно использовать два типа моделей:

  • Random forest и разные их разновидности (XGBM, LightGBM и т.д.)
  • Многослойные нейронные сети (deeplearing)

А вот с feature engineering хотелось разобраться, поэтому я смотрел курс и параллельно пытался всё это применить на практике. На этом этапе моим лучшим достижением был ROCAUC где-то около 0.55 на паблике, а чтобы дотянутся до заветных 0.6 (где в то время находился лидер) нужно было больше крутых фич. И я взялся за данные с оборудования, CSV’шки с этими данными весили уже по несколько гигабайт и немного потыкавшись в Python ноутбуке я понял, что не смогу там быстро реализовать идею и получить результат обработки за приемлемое время. Было запилено Rails приложение с базой на Postgres в которую были залиты все эти данные, и уже внутри я мог реализовать любую идею по агрегации и фильтрации данных, да это дольше чем сделать это в ноутбуке, но зато результат обработки получался очень быстро, полный pipeline по всем таблицам для train и test занимал около 20 минут.

Т.к. пользователи звонили и пользовались интернетом в разное время и из разных мест, то на каждого пользователя приходилось большое количество сот, плюс данные по каждой соте имелись за каждый день, поэтому из всей этой массы решено было фильтровать для каждого пользователя только те временные промежутки в которые пользователь совершал звонки либо пользовался интернетом, а среди них выбирать значения с самыми худшими значениями (с точки зрения качества связи). Т.е. если это процент разрывов соединения то берём максимум, а если успешность установления пакетных сессий то минимум. Тут мой score был в районе 0.58.

Время шло, а максимальный score на паблике был в районе 0.63, и тут начали появляться подозрения, что задача всё не таки не для машинного обучения. Как я упоминал выше данных для обучения очень мало, как выяснилось ни одна из фич не коррелировала с целевой переменной больше чем на несколько сотых. Результат опроса также можно оценивать как весьма субъективный, почему пользователь сказал что его не устраивает качество связи? Может ему в салоне Мегафона нахамили, или за роуминг в прошлом месяце слишком много заплатил, или просто настроение плохое было, а ему тут звонят с вопросами.

Времени оставалось всё меньше, а подняться хотелось повыше… И тут пришла идея с тем что сами соты могут быть проблемными, и если есть одна жалоба у пользователя связанного с этой сотой, то может быть и другая. Количество используемых сот и train и test наборах пересекалось на 50%, поэтому я добавил пару новых фич по сотам на которых были замечены недовольные пользователи, на валидационном наборе это подняло мой результат, на результат был не стабилен, но я старался верить в валидацию ) В итоге после нескольких дней подбора гиперпараметров мне удалось добиться результата в 0.5997915, не заветные 0.6, но всё же близко: 12-е место на паблике. Правда к тому времени лидеры утопали уже к 0.7.

Последние дни соревнования я уже не видел путей улучшения решения, а в чате бурлили шутки про рандом, переобучение и чувствовалась некая разочарованность, что задача то не про ML. Итог на private 31 место, я съехал, в следующий раз надо больше внимания уделить валидации. Надо отдать должное побудителю, хоть финальный ROCAUC съехал у всех, но Сергей Старицын с 3-го места переместился на 1-е, как я понял два лидера паблика специально переобучали свои модели чтобы выиграть в специальной номинации за самое сильное падение на private. Т.е. это более чем уверенный результат, итого лучший score 0.5853939. Теперь вопрос: может ли бизнес из такого результата получить профит?

После окончания всех из топ-200 пригласили в офис Мегафона на спец. мероприятие, очень здорово что они выложили запись и хоть качество звука ужасное, но завеса тайны была приоткрыта. Самым важным мне показалось выступление Дмитрия Белякова из Ipsos Comcon, он рассказал как решают подобные задачи по настоящему. ML там не используется, а используются некие методы разложения объяснённой дисперсии, самое сложное — выяснить как параметры влияют друг на друга и на целевую переменную и для этого используется подход из теории игр.

Также про субъективность оценки было тоже упомянуто, это называется Гало-эффект когда клиент не может различить, что конкретно ему не нравится в качестве услуг и ориентируется на некое общее впечатление (т.е. либо всё устраивает либо всё плохо).

Из выступлений лидеров топ-3 мне больше всех понравилось 3-е место, Сергей Лавриков высказал то что меня терзало, любой запуск модели с новыми гиперпараметрами должен быть зафиксирован в Git, ситуация с потерянной моделью возникала у меня несколько раз, я помнил что было лучше , но не помнил что я при этом делал. Сразу вспоминается шутка про рандомный подбор:

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

На самом деле я так до конца и не понял есть ли смысл решать задачи подобного рода с использованием ML подхода, или нет. ROCAUC = 0.6 кажется очень маленьким, возможно ли бизнесу превратить это в прибыль? С другой стороны не было упомянуто какой точности можно добиться используя методы разложения объяснённой дисперсии.

Метки: