Несколько лет назад я разработал модель выявления мошеннических транзакций для двусторонней торговой площадки в Интернете. Моя первоначальная модель была основана на характеристиках транзакции и ее контексте. Эта модель была неплохой, но я хотел сделать ее лучше. Я уже использовал Gradient Boosted Tree, и дополнительная настройка гиперпараметров не привела к значительному увеличению производительности. Я снова обратился к особенностям.

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

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

Важность функций

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

Из графика видно, что во всех наборах данных первые 1–3 функции имеют чрезмерную важность по сравнению с другими. Еще более отчетливо это видно на следующих графиках. Слева показано распределение значимости функций, а справа - совокупная сумма значимости функций для каждого набора данных. Распределение важности функций показывает, что большинство функций находятся в нижней части шкалы важности (например, менее 0,1). График совокупной важности функций на правом графике показывает, что в большинстве случаев после нескольких функций (в зависимости от того, сколько функций находится в модели) наблюдается убывающая отдача. Это не означает, что следует отбрасывать менее важные функции - в совокупности они очень важны - но по отдельности они не вносят значительного улучшения в прогностическую эффективность модели.

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

В поисках фантастических возможностей

  1. Думайте о проблеме, а не о данных .. Что касается проблемы обнаружения мошенничества, которую я обсуждал в начале сообщения, у меня были все данные, доступные мне с самого начала. Проблема в том, что я действительно не думал о том, как мошенник может вести себя при взаимодействии с покупателем. Когда я начал обдумывать это - даже на довольно базовом уровне - стало очевидно, что скорость передачи данных потенциально может иметь значение, но первоначальная модель не могла этого обнаружить. Обдумывая проблему и тонкие поведенческие нюансы, которые могут отличать одну группу от других, вы часто можете придумать гораздо больше интересных идей, чем просто играя с различными комбинациями и преобразованиями данных в ноутбук.
  2. Поговорите с людьми. Как специалистам по обработке данных, нам легко уйти от дел, пока мы работаем над процессом построения модели. Это большая ошибка. Не только слегка высокомерно думать, что мы можем просто взять набор данных и построить прогнозную модель в контексте, с которым мы * возможно * * не знакомы, но также терять ценную информацию о том, что должно иметь значение и на что ваше внимание должны быть сфокусированы. При запуске нового проекта - особенно если он находится в незнакомом вам контексте - вам следует попытаться сотрудничать с экспертом в предметной области. Это не означает, что вы не можете обнаружить новые, очень важные особенности, изучая данные. Вы определенно можете это сделать, но эксперт в предметной области часто может увидеть, проходят ли идеи новых функций «нюхательный тест», прежде чем вы потратите значительное время на их разработку.
  3. Встаньте на плечи гигантов: наука о данных прошла долгий путь за последние несколько лет. Существует так много описаний того, как разные команды и компании подходили к различным задачам прогнозного моделирования. Мне очень нравится читать интервью с победителями конкурса Kaggle, и одна из моих любимых рецензий о поиске фанатичных функций - это от победителей анализа рыночной корзины Instacart. Есть много интересных фактов о том, как они подошли к проблеме, продумывая временные зависимости, а также пытаясь определить закономерности действий, которые клиенты не предпринимали. Эта и другие статьи стоят вашего времени. Как и любая проблема, над которой вы работаете, скорее всего, вы не первый, кто ее решает. Посмотрите вокруг, чтобы увидеть, что сделали другие, и вы, вероятно, найдете отличные идеи для функций, которые вы можете внести в свою проблему.

Извлечение фантастических возможностей

  1. Группирование функций с древовидной структурой. Группирование как категориальных, так и непрерывных входных данных часто является хорошим приемом для удаления шума, выделения сигнала и выявления нелинейностей между функциями и целью. Но сделать это наиболее оптимальным способом с сохранением информации может быть непросто. Конечно, вы можете сделать это вручную, например, исключив непрерывные объекты или свернув аналогичные категориальные объекты в общую группу. В обоих случаях есть риск, что вы действительно удаляете или сокращаете ценную информацию из набора функций. Один из хороших способов эффективно объединить функции - это использовать древовидную модель. Впервые я узнал об этой технике в этой статье Facebook. Древовидная модель может использоваться для эффективного объединения непрерывных и категориальных переменных в группы с максимизацией информации. Хотя это действительно уместно только тогда, когда вы хотите использовать линейную модель, есть много случаев, когда это очень желательно! Я обсуждаю ключевое практическое преимущество этого в своем посте о менее известных методах обработки и анализа данных.
  2. Встраивание сущностей с помощью нейронных сетей: использование нейронных сетей для преобразования категориальных переменных в векторы с действительными значениями изменило правила игры. Основная идея состоит в том, чтобы использовать нейронную сеть для изучения числового представления категориальных данных во время обучения. Это похоже на то, как нейронные сети можно использовать для изучения векторов слов. Изучая вещественное представление категориального признака, похожие значения более точно отображаются в пространстве встраивания, таким образом выявляя скрытые характеристики данных, которые в противном случае были бы потеряны. Отличной, хорошо задокументированной иллюстрацией этого подхода является его применение в конкурсе Rossman Store Sales, который проводился на Kaggle. Несмотря на минимальную функциональную инженерию, команда смогла занять 3-е место в конкурсе. Это было в значительной степени из-за очень ценных репрезентаций, извлеченных из категориальных особенностей.
  3. Удалите шум из ваших функций. Часть искусства специалиста по обработке данных - это обнаружение сигнала в шуме. Этот общий образ мышления следует применять к функциям, которые вы вкладываете в модели. Если функция беспорядочная, отсутствуют данные, есть случайные экстремальные значения или выбросы или другие источники случайных отклонений, все это может скрыть ее истинное значение. Я часто пытаюсь подходить к задачам прогнозного моделирования с мыслью, что я хочу максимально упростить для моей модели изучение взаимосвязи между функциями и целью. Хотя это большая тема, существует несколько алгоритмов шумоподавления, которые можно применить к данным непрерывного временного ряда, которые помогут минимизировать шум и выделить сигнал - например, фильтры Калмана и быстрое преобразование Фурье. Этот блокнот Kaggle обсуждает некоторые из этих алгоритмов шумоподавления и предоставляет их реализации на Python.

Резюме

Поиск фантастических черт - это одновременно искусство и наука. Это также действительно творческое занятие, которое я лично считаю забавным и полезным. Приятно находить новую функцию, особенно такую, которая приводит к значительному повышению производительности вашей модели. Это также непросто и может привести к множеству кроличьих нор. Мне нравится эта цитата из статьи Instacart, на которую я ссылался ранее:

«Обычно функции, на создание которых уходит много времени, в конечном итоге ничего не делают. Но мы не сможем узнать результат, если ничего не сделаем. Так что самое главное - участвовать в заблуждении, будто вы получите лучший результат, если попробуете! »

Надеюсь, эта статья поможет вам попробовать немного лучше.

Спасибо за прочтение!

P.S. Код для этого поста можно найти здесь.