30-часовой хакатон Яндекс.Погоды, или как предсказать осадки по сигналам от пользователей

Leono 13 декабря 2017 в 16:21 4,2k
Недавно мы провели хакатон, посвящённый использованию сигналов от пользователей в предсказании погоды. Сегодня я расскажу читателям Хабра, почему устроить такое соревнование — едва ли не более сложная задача, чем удачно в нём выступить, какие методы за 30 часов успели придумать участники, и как мы используем результаты хакатона.



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

Почему бы не задействовать показания домашних метеостанций (разумеется, анонимизированные)? Или можно использовать показания датчика давления в смартфонах. Или начать учитывать в реальном времени сообщения об ошибках, которые пользователи отправляют из приложения. Я привёл несколько самых очевидных примеров — прибавьте к ним массу косвенных признаков того, какая вокруг погода. Взять хотя бы силу сотового сигнала: когда телефон плохо ловит сеть, одной из причин порой является повышенная влажность воздуха. Пару недель назад один стартап даже привлёк раунд инвестиций, продвигая эту идею.

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

Поучаствовать в хакатоне мог любой data scientist, в том числе из Яндекса (не из команды Погоды) — но с условием, что решения от яндексоидов в общий зачёт не попадут.

Подготовка


Концепцию хакатона мы придумали весной, но провести его решили осенью: во-первых — чтобы предоставить командам сведения, собранные за летние месяцы, а во-вторых — чтобы все потенциальные участники успели вернуться из отпусков. Поскольку до тех пор мы в постоянном режиме не использовали пользовательские сигналы, пришлось сначала их раздобыть. Мы, как всегда, дошли до всех поставщиков (внутри и снаружи Яндекса) — и, как всегда, столкнулись с некоторыми проблемами. Показания датчиков давления удалось выгрузить, но не за весь нужный интервал времени. Сообщения от пользователей мы тоже решили командам не предоставлять: данные оказались слишком «грязными». Неподготовленный data scientist, как мы считали, не сумел бы за 30 часов заложить их в основу серьёзного алгоритма, а только потратил бы своё время.

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

Для соревнования использовались цифры, собранные в Москве, Санкт-Петербурге и Казани. В перечисленных городах есть радары, показания которых стали отличной целевой метрикой хакатона.

Задача

Каждый город разбивается на квадраты. Задача команды — определить, шёл ли дождь, для каждого квадрата и каждого часа. В обучающей выборке для каждого квадрата известно precipitation — количество осадков в миллиметрах, выпавших на конец часа. Считается, что дождь шёл, если precipitation > 0,25.
Обратите внимание: в задаче требовалось спрогнозировать осадки, в то время как метеостанции Netatmo осадки регистрировать не умеют — они фиксируют только температуру, давление, влажность и т. д.

Наше baseline-решение


Чтобы упростить жизнь участникам, мы предоставили им базовое решение, извлекающее признаки из всех имеющихся данных. В частности, мы показали, как добавить значения с метеостанций к данным с телефонов и обучить модель, не потратив слишком много памяти. Коротко о самом решении:
Ради экономии ресурсов построим отдельный классификатор для каждого из трёх городов. На основе данных с телефонов в каждом квадрате посчитаем простые признаки: число пользователей, среднее значение и дисперсию уровня сигнала. Дисперсия тут выступает как наиболее простой вариант оценки изменения сигнала по времени. 

Добавим к этим признакам усреднённые погодные данные с десяти ближайших метеостанций. Поскольку станции есть не в каждом квадрате, используем k-мерное дерево (k-d tree) для быстрого поиска ближайших соседей. Поверх всех признаков обучим классификатор на CatBoost с параметрами по умолчанию и посмотрим на полученные метрики.
Вот неплохое видео про принцип k-d tree:



На написание baseline у нас ушло меньше суток, но затем мы поняли, что задействовали лишние данные: в обучающую выборку случайно попали предсказанные значения «из будущего». Пришлось срочно устроить себе ночной мини-хакатон перед основным хакатоном — итоговая версия базового решения, где мы не нарушаем наши собственные правила, была готова за считанные часы до соревнования. В сумме двое сотрудников Яндекс.Погоды потратили на подготовку данных и разработку baseline около двух полных рабочих недель.

Решения участников


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

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

Идея яндексоидов


Решение, предложенное моими коллегами из проекта YT, сводилось к генерации хороших признаков и обучению классическим методом (градиентный бустинг над решающими деревьями). Ребята использовали CatBoost — возможно, из-за патриотизма к Яндексу, но по их словам, наша библиотека показывала «значительно более» удачные результаты, чем другие.

Самыми лучшими признаками были данные с любительских метеостанций. На их основе считались различные статистики: среднее, максимум, минимум, дисперсия и т. п. Стоит отметить, что использовались показания ближайших станций и ещё нескольких — распределённых вокруг целевого квадрата. Это распределение не было по-настоящему равномерным: в России и так не очень много устройств Netatmo, а таких, которые всегда в онлайне и с разрешения пользователя транслируют показания в интернет, ещё меньше.

Пользовательские признаки, например средняя скорость движения людей в целевом квадрате, тоже сыграли свою роль, хоть и не очень большую. Суммарно получилось около 7 тысяч признаков — которые, конечно, можно было отфильтровать, не потеряв в качестве модели. Но у команды хватило ресурсов на обучение с таким количеством, поэтому оптимизация толком не требовалась. Сам CatBoost обучали практически на дефолтных параметрах: тюнинг приводил к совсем незначительным изменениям в качестве, а времени отнимал порядочно.

Идеи победителей


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

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



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



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

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

Затем по законам жанра следовало попробовать несколько библиотек и поиграть с настройками гиперпараметров. Помимо традиционного XGBoost команды решили использовать LightGBM от Microsoft. Мнение участников: CatBoost работает не хуже, но несколько медленнее конкурентов. Зато многие отметили, что модель на основе CatBoost менее склонна к переобучению: результат на скрытой тестовой выборке практически не отличался от результата на отладочной выборке.


Слайд из презентации участников

Командам совсем не хватило времени на стекинг (то есть на построение ансамбля из алгоритмов) — хотя обладатель четвёртого места задействовал полученные градиентным бустингом предсказания, чтобы обучить модель, похожую на свёрточную нейросеть (!).

* * *

Все обладатели призовых мест отлично поработали с факторами и особенно с показаниями любительских метеостанций Netatmo. Это было непросто: две соседние станции, одна из которых расположена под прямыми солнечными лучами, а другая – в тени, могут показывать температуру с разницей в 15–20 градусов. Раз участники за короткое время разобрались в подобных данных, значит, задачу можно было усложнить — и, например, вовсе исключить из обучающей выборки показания Netatmo.

Что касается использования результатов — признаки, полученные командами, станут первыми кандидатами на признаки в самом сервисе. И конечно, нам очень помог опыт подготовки базового решения. Оно объединяло данные нескольких типов, собранные вокруг нужного района, по принципу k-d tree. Именно так и нужно агрегировать разные сигналы, которые прямо или косвенно указывают на развитие погодной ситуации.

Нам понравилось проводить соревнование по data science в погоде. Возможная тема для следующего соревнования (не обязательно хакатона) — долгосрочные прогнозы. У нас есть информация о погодных условиях во всём мире за последние 40 лет. В этих данных стоит поискать закономерности: кажется, совсем скоро система сможет вам сказать, что через полтора месяца температура опустится ниже нормы и будет идти снег.

Проголосовать:
+37
Сохранить: