Каков правильный способ выборки сильно несбалансированного набора данных, который имеет низкое значение между корреляцией признаков и низкое значение между дисперсией класса? - PullRequest
0 голосов
/ 07 января 2020

У меня есть набор данных с 23 функциями с очень низкой корреляцией. Два класса имеют низкую дисперсию между классами.

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

1 Ответ

0 голосов
/ 07 января 2020

Спасибо, что пришли на ТАК, чтобы задать свой вопрос!

Работа с несбалансированными данными (определяемыми, как правило, как данные, в которых число случаев для одного или нескольких классов очень отличается от других - асимметричное распределение какого-либо рода) является постоянной проблемой, которая побудило много онлайн писать. Мне нравится эта статья в качестве отправной точки. Я приведу примеры в Python, хотя аналогичные идеи применимы и в R.

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

Для ясности, скажем, есть два случая для переменной X: X = 0 и X = 1. И давайте назовем X = 1 случай, когда происходит какое-то событие, присутствует некоторая характеристика c, наблюдается некоторый отклик и т. Д. c. Мы назовем это «позитивным классом». Наконец, допустим, у вас есть 100 000 наблюдений, из которых только 1000 случаев X = 1, остальные - X = 0. Таким образом, ваш класс меньшинства является положительным классом, а ваш дисбаланс (положительный к отрицательному) составляет 1/100.

Если вы рисуете 50 000 случайных выборок и хотите, чтобы доля составляла примерно 50/50 положительного и отрицательного классов, вы можете сделать пару вещей.

  1. Пересмотреть класс меньшинства

Этот метод позволяет вам получить больше примеров из данных, где X = 1. Чтобы достичь баланса 50/50, вам нужно (случайным образом) вытянуть из положительного класса больше, чтобы получить 25 000 примеров.

Чтобы сделать это с sci-kit learn, вы можете сделать что-то вроде следующего.

Предполагая, что X - это фрейм данных с вашими данными:

from sklearn.utils import resample

# make two dataframes, each with only one class 
majority_df = X[X['outcome']==0]
minority_df = X[X['outcome']==1]

# Oversampling the minority
oversampled_minority_df = resample(minority_df,
                          replace=True, 
                          n_samples=len(majority_df), 
                          random_state=123)

Несколько комментариев:

  • "Resampling" - это обработка извлечения данных из установить снова и снова
  • replace говорит о том, что вы хотите, чтобы процесс «отложил» наблюдение, которое он извлек; в этом случае это просто означает, что система может захватывать одно и то же наблюдение несколько раз во время повторной выборки (как будто ее кладут обратно в сумку, которую кто-то может захватить)
  • n_samples - это то же самое длина в качестве большинства класса данных, чтобы конечный результат имел равномерный баланс между примерами большинства / меньшинства

  • Демонстрация мажоритарного класса

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

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

# Oversampling the minority
undersampled_majority_df = resample(majority_df,
                           replace=False, 
                           n_samples=len(minority_df), 
                           random_state=123)

Пара замечаний:

  • Это все еще "повторная выборка", только берется меньше образцов
  • replace теперь ложно, так как вы не хотите повторять данные, если вам не нужно (что вам пришлось делать для передискретизации)
  • n_samples теперь соответствует длине minority_df так что имеется одинаковое количество примеров

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

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

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

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

from imblearn.over_sampling import SMOTE
from sklearn.model_selection import train_test_split

y = base_df['outcome']
X = base_df.drop('outcome', axis=1)

# setting up testing and training sets
X_train, X_test, y_train, y_test = train_test_split(X,
                                                    y,
                                                    test_size=0.20,
                                                    random_state=123)

sm = SMOTE(random_state=123, ratio=1.0)
X_train, y_train = sm.fit_sample(X_train, y_train)

Вы заметите, что у объекта sm есть метод fit_sample, и что вы устанавливаете соотношение положительного / отрицательного (до ratio) при его создании. Результатом являются кадры данных, которые сбалансированы и могут использоваться при подгонке модели.

...