Как повысить производительность модели машинного обучения по сравнению с несбалансированными наборами данных.

Введение

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

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

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

Как передискретизация, так и недостаточная выборка могут быть реализованы с использованием различных алгоритмов. Однако я хочу сосредоточиться на двух подходах, которые я недавно использовал в Proof Of Concept для клиента: ADASYN и Правило отредактированного ближайшего соседа (ENN).

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

ADASYN

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

Алгоритм

📥 Ввод:

Набор данных Dᵣ с m выборками с {xᵢ, yᵢ}, от 1 до m, где xᵢ - это n-мерный вектор в пространстве признаков, а yᵢ - соответствующий класс. Пусть mᵣ и mₓ будет количество выборок меньшинства и большинства соответственно, так что mᵣ ⪯ mₓ и mᵣ + mₓ = m .

⚙️ Процедура:

я. Рассчитайте степень дисбаланса, d = mᵣ / mₓ

II. Если d ‹dₓ (где dₓ - предустановленный порог максимально допустимого дисбаланса), то:

a) Рассчитайте количество синтетических образцов, которые должны быть сгенерированы из класса меньшинства: G = (mₓ - mᵣ) × β, β - уровень баланса созданных синтетических образцов. β = 1 означает, что существует полный баланс между двумя классами.

б) Для каждого xᵢ ∈ выборки меньшинства найдите k-ближайших соседей на основе евклидова расстояния и вычислите отношение rᵢ, rᵢ = Δᵢ / K.

c) Нормализовать rₓ ← rᵢ / ∑ rᵢ, так, чтобы теперь rₓ было распределением плотности.

г) Расчет синтетической выборки, созданной для каждой точки данных меньшинства gᵢ = rₓ × G,, где G - общее количество наблюдений с синтетическими данными, которые необходимы должны быть созданы для класса меньшинства, как определено в (а).

e) Для каждого примера данных xᵢ класса меньшинства сгенерируйте gᵢ примеры синтетических данных в соответствии со следующими шагами:

Выполните цикл от 1 до gᵢ:

(i) Случайным образом выберите один пример данных меньшинства, xᵤ, из K ближайших соседей для данных xᵢ.

(ii) Создайте пример синтетических данных: sᵢ = xᵢ + (xᵤ - xᵢ) × λ

где (xᵤ− xᵢ) - вектор разностей в n-мерных пространствах, а λ - случайное число: λ ∈ [0, 1].

👍🏼 Плюсы:

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

👎🏼 Минусы:

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

ENN

Метод ENN удаляет экземпляры большинства классов, чей прогноз, сделанный методом KNN, отличается от большинства классов. Следовательно, если у экземпляра xᵢ ∈ N больше соседей из другого класса, xᵢ будет удален.

Алгоритм

ENN работает следующим образом:

1. Получите k ближайших соседей xᵢ, xᵢ ∈ N

2. xᵢ будет удален, если количество соседей из другого класса преобладает.

3. Процесс повторяется для каждого мажоритарного экземпляра подмножества N.

👍🏼 Плюсы:

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

👎🏼 Минусы:

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

ADASYN и ENN с Python

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

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

Все алгоритмы передискретизации / недостаточной выборки реализованы в модуле Python imbalanced-learn.

from imblearn.over_sampling import ADASYN
from imblearn.under_sampling import EditedNearestNeighbours

Детали подхода:

  • Данные разделены на обучающий набор (80%) и набор проверки (20%)
from sklearn.model_selection import train_test_split
train, valid, y_train, y_valid = train_test_split(data, y, test_size=0.2, random_state=42)
  • 🌳 🌳 Модель случайного леса. Я буду использовать scikit-learn RandomForestClassifier, используя исключения параметров по умолчанию для параметра min_samples_leaf, для которого будет установлено значение 5.
from sklearn.ensemble import RandomForestClassifier
  • Модели будут оцениваться с использованием метрики отзыва в наборе для проверки.
from sklearn.metrics import recall_score

Контрольная модель

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

model = RandomForestClassifier(min_samples_leaf=5 ,random_state=123)
model.fit(train, y_train)
print('Validation set Recall: ', 
      recall_score(y_valid, base_model.predict(valid)))

Отзыв набора для проверки: 0,6435643564356436

ADASYN

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

ada = ADASYN(random_state=42)
X_ada, y_ada = ada.fit_resample(train, y_train)
print('Resampled dataset after ADASYN shape %s' % Counter(y_ada))

Набор данных с повторной выборкой после формы ADASYN: {False: 2284, True: 2333}

ada_model = RandomForestClassifier(min_samples_leaf=5,
                                   random_state=123)
ada_model.fit(X_ada, y_ada)
print('Validation set Recall: ', 
      recall_score(y_valid, ada_model.predict(valid)))

Отзыв набора для проверки: 0,7920792079207921

ENN

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

enn = EditedNearestNeighbours(random_state = 42)
X_enn, y_enn = enn.fit_resample(train, y_train)
print('Resampled dataset after ENN shape %s' % Counter(y_enn))

Набор данных с повторной выборкой после формы ENN: {False: 1667, True: 382}

enn_model = RandomForestClassifier(min_samples_leaf=5,
                                   random_state=123)
enn_model.fit(X_enn, y_enn)
print('Validation set Recall: ', 
      recall_score(y_valid, enn_model.predict(valid)))

Отзыв набора для проверки: 0,7722772277227723

Заключение

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

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

Надеюсь, вам понравился этот пост. Если вы хотите прочитать другие интересные материалы, написанные моими коллегами из Quantyca, подписывайтесь на нас в Medium и LinkedIn.