На примере модели Random Forest

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

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

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

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

Передовой опыт расчета важности функций

Проблема с важностью функций по умолчанию

Мы собираемся использовать пример, чтобы показать проблему с важностью функций на основе примесей по умолчанию, предоставленную в Scikit-learn for Random Forest. Важность функции по умолчанию рассчитывается на основе среднего уменьшения примеси (или важности Джини), которая измеряет, насколько эффективно каждая функция снижает неопределенность. См. эту замечательную статью для более подробного объяснения математики, лежащей в основе расчета важности функции.

Давайте загрузим знаменитый набор данных Titanic с Kaggle. В наборе данных есть информация о 1309 пассажирах Титаника и о том, выжили ли они. Вот краткое описание включенных столбцов.

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

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

В-третьих, мы строим простую модель случайного леса.

RF train accuracy: 1.000.
RF test accuracy: 0.814

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

Из значений функций по умолчанию мы замечаем, что:

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

Значение перестановки для спасения

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

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

Здесь мы используем функцию permutation_importance, добавленную в пакет Scikit-learn в 2019 году. При вызове функции мы устанавливаем n_repeats = 20, что означает, что для каждой переменной мы случайным образом перемешиваем 20 раз и вычисляем снижение точности для создания ящичковой диаграммы.

Мы видим, что sex и pclass показаны как наиболее важные функции, а random_cat и random_num больше не имеют высоких оценок важности на основе важности перестановок в тестовом наборе. Коробчатая диаграмма показывает распределение снижения показателя точности при перестановке N повторов (в нашем случае N = 20).

Давайте также вычислим важность перестановок в обучающем наборе. Это показывает, что random_num и random_cat получают значительно более высокий рейтинг важности, чем при вычислении на тестовом наборе, и ранжирование функций сильно отличается от тестового набора. Как отмечалось ранее, это связано с переоснащением модели.

Вы можете задаться вопросом, почему Scikit-learn по-прежнему включает важность функции по умолчанию, если она не точна. Брейман и Катлер, изобретатели RF, указали, что этот метод суммирования коэффициентов Джини для каждой переменной по всем деревьям в лесу дает важность быстрой переменной, которая часто очень согласуется с мерой важности перестановки. Таким образом, значение по умолчанию должно быть прокси для важности перестановки. Однако, как Штробл и др. указали в Систематической ошибке в показателях важности переменных случайного леса, что меры переменной важности исходного метода случайного леса Бреймана… ненадежны в ситуациях, когда потенциальные переменные-предикторы различаются по своей шкале измерения или количеству значений. категории.

Надежная модель является предпосылкой для точных оценок важности

Мы видели, что когда режим переобучения, значения функций, сгенерированные из набора обучения и прогнозирования, могут сильно различаться. Давайте применим некоторый уровень регуляризации, установив min_samples_leaf = 20 вместо 1.

RF train accuracy: 0.810
RF test accuracy: 0.832

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

Альтернативный способ — вычислить важность перетаскиваемых столбцов. Это наиболее точный способ расчета важности функций. Идея состоит в том, чтобы рассчитать производительность модели со всеми предикторами, отбросить один предиктор и увидеть снижение производительности. Чем важнее функция, тем больше снижение производительности модели.

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

Ранжирование функций аналогично функциям перестановки, хотя величины различаются.

Передовая практика интерпретации важности функций

Проблема корреляции признаков

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

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

Чтобы проиллюстрировать это, давайте возьмем крайний пример и продублируем столбец пола, чтобы переобучить модель.

RF train accuracy: 0.794
RF test accuracy: 0.802

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

Теперь мы видим, что важность признаков пола теперь распределена между двумя дублированными столбцами пола. Что произойдет, если мы добавим немного шума в дублированный столбец?

Давайте попробуем добавить к полу случайный шум в диапазоне от 0 до 1.

sex_noisy теперь самая важная переменная. Что произойдет, если мы увеличим величину добавленного шума? Давайте увеличим диапазон случайной величины до 0–3.

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

Работа с коллинеарными функциями

Давайте посмотрим на корреляцию между признаками. Мы используем feature_corr_matrix из пакета rfpimp, который дает нам корреляцию Спирмена. Разница между корреляцией Спирмена и стандартной корреляцией Пирсона заключается в том, что корреляция Спирмена сначала преобразует две переменные в ранговые значения, а затем запускает корреляцию Пирсона для ранжированных переменных. Он не предполагает линейной зависимости между переменными.

feature_corr_matrix(X_train)

from rfpimp import plot_corr_heatmap
viz = plot_corr_heatmap(X_train, figsize=(7,5))
viz.view()

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

Стратегия 1. Объединение коллинеарных элементов

Один из способов решить эту проблему — объединить функции, которые сильно коллинеарны друг с другом, чтобы сформировать семейство функций, и мы можем сказать, что это семейство функций вместе считается X наиболее важным. Для этого мы будем использовать пакет rfpimp, который позволяет нам одновременно перемешивать две переменные.

Стратегия 2. Удаление сильно коллинеарных переменных

Если функция зависит от других функций, это означает, что функции могут быть точно предсказаны с использованием всех других функций в качестве независимых переменных. Чем выше R² модели, тем больше зависимая функция, и тем больше мы уверены, что удаление переменной не повлияет на точность.

Зависимость в первом столбце показывает оценку зависимости. Функция, которая полностью предсказуема с использованием других функций, будет иметь значение, близкое к 1. В этом случае мы, вероятно, можем отбросить один из pclass и fare, не сильно повлияв на точность.

В конце

Как только мы 1) получим надежную модель и реализуем правильную стратегию для расчета важности перестановки и 2) разберемся с корреляцией функций, мы можем начать создавать наше сообщение, чтобы поделиться с заинтересованными сторонами.

Что касается распространенного вопроса, который люди задают: «Является ли функция 1 в 10 раз более важной, чем функция 2?», вы можете понять в этот момент, что у нас есть уверенность, чтобы выдвигать аргумент только тогда, когда все функции независимы или имеют очень низкую корреляцию. Но в реальном мире это редкость. Рекомендуемая стратегия состоит в том, чтобы назначать функции уровням высокого, среднего и низкого воздействия, не слишком сосредотачиваясь на точной величине. Если нам нужно показать относительное сравнение между функциями, попробуйте сгруппировать коллинеарные функции (или отбросить их), чтобы они были знакомы, и интерпретируйте на основе группы, чтобы сделать аргумент более точным.

Вы можете найти код в этой статье на мой Github.

Ссылка

[1] Остерегайтесь важности случайного леса по умолчанию

[2] Важность перестановки против важности случайного леса (MDI)

[3] Важность функций для моделей машинного обучения Scikit-Learn

[4] Математика дерева решений, важность функций случайного леса в Scikit-learn и Spark

[5] Объяснение важности признаков на примере случайного леса

Все изображения, если не указано иное, принадлежат автору.