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

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

  • Что подразумевается под несбалансированным набором данных?
  • Почему это важно, если набор данных несбалансирован?
  • Различные способы справиться с несбалансированным набором данных.
  • Различные инструменты для работы с несбалансированным набором данных.

Что подразумевается под несбалансированным набором данных?

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

Почему это имеет значение, если набор данных искажен?

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

Различные способы справиться с несбалансированным набором данных

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

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

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

Различные инструменты для работы с несбалансированным набором данных

Пакет sklearn.utils.resample от Scikit Learn позволяет выполнять повторную выборку данных. Он принимает массивы в качестве входных данных и последовательно пересчитывает их.

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

X = df.drop(‘diagnosis’,axis=1)
y = df[‘diagnosis’]
from sklearn.model_selection import train_test_split
from sklearn.utils import resample
#split data into test and training sets
X_train, X_test, y_train, y_test = train_test_split( X, y, test_size=0.33, random_state=42)
#combine them back for resampling
train_data = pd.concat([X_train, y_train], axis=1)
# separate minority and majority classes
negative = train_data[train_data.diagnosis==0]
positive = train_data[train_data.diagnosis==1]
# upsample minority
pos_upsampled = resample(positive,
 replace=True, # sample with replacement
 n_samples=len(negative), # match number in majority class
 random_state=27) # reproducible results
# combine majority and upsampled minority
upsampled = pd.concat([negative, pos_upsampled])
# check new class counts
upsampled.diagnosis.value_counts()
1    139
0    139
Name: diagnosis, dtype: int64

Теперь у нас одинаковое количество экземпляров обоих классов в данных поезда.

Давайте теперь посмотрим на подвыборку.

# downsample majority
neg_downsampled = resample(negative,
 replace=True, # sample with replacement
 n_samples=len(positive), # match number in minority class
 random_state=27) # reproducible results
# combine minority and downsampled majority
downsampled = pd.concat([positive, neg_downsampled])
# check new class counts
downsampled.diagnosis.value_counts()
1    41
0    41
Name: diagnosis, dtype: int64

У обоих классов по 41 экземпляру.

В библиотеке imblearn есть класс imblearn.over_sampling.SMOTE, который выполняет передискретизацию с помощью SMOTE. Это реализация SMOTE или техники передискретизации синтетического меньшинства. Давайте посмотрим на реализацию ниже.

from imblearn.over_sampling import SMOTE
# Separate input features and target
X = df.drop(‘diagnosis’,axis=1)
y = df[‘diagnosis’]
# setting up testing and training sets
X_train, X_test, y_train, y_test = train_test_split(X, y, test_size=0.25, random_state=27)
sm = SMOTE(random_state=27, ratio=1.0)
X_train, y_train = sm.fit_sample(X_train, y_train)
X_train.shape, y_train.shape
((314, 5), (314,)) #We now have 314 data items in our training set
y_train = pd.DataFrame(y_train, columns = ['diagnosis'])
y_train.diagnosis.value_counts()
1    157
0    157
Name: diagnosis, dtype: int64

SMOTE создал достаточно синтетических данных для обоих классов, чтобы каждый из них содержал по 157 элементов данных.

Мы только что рассмотрели самый популярный способ пересэмплирования. В Imblearn есть множество других методов недостаточной и избыточной выборки, определенных в классах imblearn.under_sampling и imblearn.over_sampling, а также методы, которые объединяют эти два метода в классе imblearn.combine.

Вы можете узнать о них больше на странице https://imbalanced-learn.readthedocs.io/en/stable/api.html#module-imblearn.over_sampling.