Хотите улучшить свой выбор функций? «Максимальная релевантность - минимальная избыточность» (он же MRMR) - это алгоритм, используемый платформой машинного обучения Uber для поиска «минимально-оптимального» подмножества функций.

MRMR (аббревиатура от Maximum Relevance - Minimum Redundancy) - это алгоритм выбора функций, который приобрел новую популярность после публикации в 2019 году этой статьи инженерами Uber:

Авторы показывают, как - благодаря MRMR - они достигли отличных результатов в автоматизации выбора функций в различных маркетинговых приложениях, среди которых:

  • привлечение пользователей,
  • кросс-продажи,
  • отток пользователей и повторная активация.

Однако MRMR - открытие не последнее время. Впервые это было предложено в этой статье, опубликованной в 2005 году двумя исследователями из Беркли:

Авторы утверждают, что из десятков тысяч генов выбора лишь нескольких из них (например, 50) достаточно для достижения максимального уровня точности для задачи (прогнозирования заболевания). Итак, вопрос в том, как нам найти 50 счастливчиков? Это именно то, для чего изначально был разработан MRMR.

Из этих первых двух примеров видно, насколько гибким является MRMR, который может оказаться полезным в совершенно разных областях, от маркетинга до геномики.

В этой статье мы увидим, как работает MRMR и чем он отличается от других популярных алгоритмов выбора функций, таких как Boruta (если вы хотите узнать больше о Boruta, я написал специальный пост: Борута объяснил, как именно ты хотел, чтобы тебе кто-то объяснил)

Минимально-оптимальное vs. все релевантное

Алгоритмы выбора функций можно в общих чертах разделить на две категории:

  • минимально-оптимальный (например, MRMR);
  • актуально для всех (например, Boruta).

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

Таким образом, если функция A и функция B релевантны, но они несут более или менее одинаковую информацию, всерелевантный метод выберет их обе, тогда как минимальный - оптимальный метод выберет только один из них и отбросит другой.

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

В примере, приведенном Дингом и Пэном, вы, вероятно, могли бы достичь такой же (или часто более высокой) точности с гораздо меньшей моделью, например с 50 функциями. Но как их выбрать? Взять 50 лучших функций Борута не работает. Фактически, многие из них могут быть сильно коррелированы друг с другом: они не добавят много информации.

MRMR был разработан для решения этой проблемы.

«Лучшие функции K - не лучшие функции K»

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

Давайте также представим, что мы знаем причинно-следственные связи между переменными (это привилегия, которой мы не часто пользуемся в реальной жизни, однако она полезна для понимания логики, лежащей в основе MRMR).

Знание причинно-следственной сети сделало бы выбор функции до смешного простым: мы бы выбрали {Возраст, IQ, Рост}, поскольку это только те, которые имеют прямую причинно-следственную связь с целевой переменной. Добавление любого из остальных вызовет ненужный шум.

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

Лучшие функции K - не лучшие функции K. (По материалам Т.М. Обложка).

Что это значит?

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

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

Мы хотим найти лучшие K-функции, а не K-лучшие функции!

В этом и заключается проблема Boruta: он дает индивидуальную оценку каждой функции. Действительно, в нашем примере Борута выбрал бы все 7 функций, поскольку все они имеют некоторую статистическую зависимость с доходом.

И это может иметь смысл в тех случаях, когда у нас не так много функций. Но в реальных приложениях часто бывает так:

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

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

Итак, теперь вопрос: как работает MRMR?

Под капотом MRMR

При использовании MRMR от вас в основном требуется сделать только один выбор: определить количество функций, которые вы хотите сохранить. Мы будем называть этот номер К. В нашем примере мы возьмем K = 3.

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

MRMR работает итеративно. На каждой итерации он определяет лучшую функцию (в соответствии с правилом) и добавляет ее в корзину выбранных функций. Как только функция попадает в корзину, она не может выйти наружу.

В нашем примере это результаты, которые мы получим в конце каждой итерации:

Какое правило определяет выбор «Лучшей» функции на каждой итерации, а именно: IQ на шаге 1, Возраст на шаге 2 и Рост на шаге 3? Это ядро ​​MRMR.

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

На практике на каждой итерации i вычисляется балл для каждой оцениваемой характеристики (f):

Лучшая функция на итерации i - это функция, имеющая наивысший балл. Так просто.

Вопрос только в том, как вычислить числитель и знаменатель. На основании этого решения авторы статьи Uber идентифицируют множество вариантов MRMR, таких как MID, MIQ, FCD , FCQ, FRQ, RFCQ и RFRQ. Тем не мение:

Поскольку FCQ поразительно прост и быстр и в целом работает лучше, чем другие алгоритмы, я сосредоточусь на этом варианте (кстати, распространить его на другие варианты несложно).

Релевантность функции f на i -й итерации (числитель) вычисляется как F-статистика между функцией и целевой переменной (Здесь, чтобы узнать больше о F-тесте). Избыточность (знаменатель) вычисляется как средняя корреляция (Пирсона) между функцией и всеми функциями, выбранными на предыдущих итерациях. Итак, формула принимает следующий вид:

где i - это i -я итерация, f - оцениваемая функция, F - F- statistic и corr - корреляция Пирсона. Обратите внимание, что корреляция берется по абсолютной величине. Фактически, если две функции имеют корреляцию .9 или -.9, это не имеет значения: в обоих случаях они очень избыточны.

Чтобы сделать вещи еще более ясными, представьте, что мы находимся на третьей итерации. Вот что произошло раньше:

  • IQ был выбран на 1-й итерации;
  • Возраст был выбран на второй итерации.

Какую функцию мы должны выбрать следующей?

Все, что нам нужно для вычисления оценки каждой функции, - это F-статистика и корреляции:

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

Реализация Python с нуля

Итерационный процесс, который мы описали выше, легко реализовать на Python:

Эту реализацию очень легко понять. Однако это неоптимально. Вы можете понять почему?

В приведенном выше коде мы вычисляем множество корреляций, которые никогда не будем использовать. Фактически, в строке 6 мы обрабатываем все возможные пары функций. Это означает F * (F - 1) / 2 пары. Для F = 10 000 это будет означать 50 миллионов корреляций!

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

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

  • 1-я итерация: корреляции не требуются. Фактически, функция еще не выбрана: достаточно выбрать функцию, имеющую наивысший балл (то есть наивысшую F-статистику).
  • 2-я итерация: требуется F - 1 корреляция.
  • 3-я итерация: F - требуется 2 корреляции.
  • K -я итерация: требуется F - K + 1 корреляция.

Теперь выполнить вычисления очень просто: эта процедура требует вычисления корреляций менее F * (K - 1). Если F = 10 000 и K = 50, это приводит к гораздо более разумному числу: менее 500 тысяч корреляций.

Эта улучшенная версия будет выглядеть так:

Это почти эквивалентно предыдущей версии, за исключением строк 11 и 21–23.

Просто дайте мне "pip install"

Вы можете найти готовую версию MRMR для задач классификации в моем Github. Его можно установить через:

pip install git+https://github.com/smazzanti/mrmr

Это отрывок того, как вы можете его использовать:

from mrmr import mrmr_classif
from sklearn.datasets import make_classification

# create some data
X, y = make_classification(n_samples = 1000, n_features = 50, n_informative = 10, n_redundant = 40)
X = pd.DataFrame(X)
y = pd.Series(y)

# use mrmr classification
selected_features = mrmr_classif(X, y, K = 10)

Выводы

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

MRMR ценен не только потому, что он эффективен (как было доказано в статье Uber), но и потому, что его простота позволяет быстро и легко реализовать его в любом конвейере.

Спасибо за чтение! Надеюсь, этот пост был вам полезен.

Я ценю отзывы и конструктивную критику. Если вы хотите поговорить об этой статье или о других связанных темах, вы можете написать мне на мой контакт в Linkedin.