Изучите общие методы обработки несбалансированных наборов данных классификации для структурированных данных

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

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

Вы должны запустить алгоритм классификации, чтобы отличить доброкачественную опухоль от злокачественной. 20 000 наблюдений доброкачественных опухолей и всего 100 наблюдений злокачественных опухолей; это приводит к несбалансированности набора данных.

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

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

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

Общие методы обработки несбалансированных наборов данных

  1. Стоимость обучения учитывает ошибочную классификацию класса меньшинства, налагая штраф на алгоритмы машинного обучения. Идея состоит в том, чтобы минимизировать стоимость классификации.
  2. Недостаточная или понижающая выборка для большинства классов, когда наблюдения большинства классов случайным образом удаляются, чтобы уменьшить его влияние на алгоритм машинного обучения.
  3. Передискретизация или повышающая выборка, класс меньшинства, где наблюдения для класса меньшинства случайным образом дублируются, чтобы усилить влияние на алгоритм машинного обучения.
  4. Создание синтетических данных для класса меньшинства с помощью SMOTE (метод передискретизации синтетического меньшинства). SMOTE берет случайные выборки из класса меньшинства, находит его ближайших k соседей, а затем выбирает точку между случайно выбранной точкой данных и ее ближайшими k соседями для генерации синтетических данных.

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

Импорт необходимых библиотек и считывание данных во фрейм данных

import numpy as np
import pandas as pd
from sklearn.preprocessing import StandardScaler
from sklearn.model_selection import train_test_split
from sklearn.linear_model import LogisticRegression
from sklearn.metrics import confusion_matrix
from sklearn.metrics import plot_confusion_matrix
from sklearn.metrics import precision_score, recall_score, accuracy_score, f1_score
import matplotlib.pyplot as plt
import seaborn as sns
%matplotlib inline
#Reading the data from the csv file into a dataframe
data= pd.read_csv(r'\Insurance_data\train.csv')

Отображение информации о наборе данных

data.info()

Преобразование категориальных переменных в столбцы индикатора

У нас есть несколько категориальных переменных, таких как пол и повреждения транспортного средства, которые необходимо преобразовать в фиктивные или индикаторные переменные. Здесь мы удаляем первый уровень, чтобы получить k-1 манекенов из k категорийных уровней, установив для параметра drop_first значение True.

data_2 = pd.get_dummies(data,drop_first=True)

Просмотр данных

Создание функций и целевой переменной

X= data_2.iloc[:,[1,2,3,4,5,6,7,9,10,11,12]]
y=data_2.iloc[:,8]

Просмотр распределения целевой переменной

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

y.value_counts().plot(kind='bar',figsize=(3,3),title="Insurance sell")
plt.xlabel("Insurance Response")
plt.ylabel("Frequency")
y_pos=50000
x_pos=0
for i, v in enumerate(data_count):
    plt.text(i+x_pos, y_pos, v, horizontalalignment='center',      verticalalignment='center', fontsize=20)
plt.show()

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

Применение Standardscalar для стандартизации функций

# define standard scaler
scaler = StandardScaler()
X= pd.DataFrame(scaler.fit_transform(X))

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

X_train, X_test, y_train, y_test=  train_test_split(X,y,test_size=0.2)

Парадокс точности для несбалансированного набора данных

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

clf = LogisticRegression(random_state=0).fit(X_train, y_train)
y_pred=clf.predict(X_test)

Построение матрицы неточностей

plot_confusion_matrix(clf,X_test, y_test)

Проверка точности, точности, отзыва и F1-балла на несбалансированном наборе тестовых данных.

print("Accuracy",accuracy_score(y_test, y_pred))
print("Precision", precision_score(y_test, y_pred))
print("Recall",recall_score(y_test, y_pred))
print("F1 score",f1_score(y_test, y_pred))

Вы можете видеть, что у нас относительно хорошая точность, отзывчивость и оценка F1 очень плохие. Это демонстрирует парадокс точности, когда точность не является хорошим показателем производительности модели. Рекомендуется проверить точность, отзывчивость и оценку F1.

Применение экономичного обучения

Применение class_weight = ”balance” автоматически изменит веса в зависимости от частоты занятий. Веса классов обратно пропорциональны частотам классов во входных данных.

веса классов = Общее кол-во записей в наборе данных / (Общее количество классов * Количество образцов в классе)

clf_cw = LogisticRegression(random_state=0, class_weight='balanced').fit(X_train, y_train)
y_pred= clf_cw.predict(X_test)
print("Accuracy",accuracy_score(y_test, y_pred))
print("Precision", precision_score(y_test, y_pred))
print("Recall",recall_score(y_test, y_pred))
print("F1 score",f1_score(y_test, y_pred))

Вы можете видеть, что точность упала, но у нас лучший результат в F1.

Отображение матрицы путаницы после применения class_weights

plot_confusion_matrix(clf_cw, X_test, y_test)

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

pip install imblearn

Применение случайной недостаточной выборки

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

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

from imblearn.under_sampling import RandomUnderSampler
# create the train and test dataset
X_train, X_test, y_train, y_test= train_test_split(X, y, test_size=0.2)
# Create an instance of RandomUnderSampler, fit the training data #and apply Logistics regression
rus= RandomUnderSampler()
X_train, y_train = rus.fit_resample(X_train, y_train)
clf_rus=  LogisticRegression(random_state=0).fit(X_train, y_train)
# predict the test data
y_pred= clf_rus.predict(X_test)
# print the model performance metrics
print("Accurcay",accuracy_score(y_test, y_pred))
print("Precision", precision_score(y_test, y_pred))
print("Recall",recall_score(y_test, y_pred))
print("F1 score",f1_score(y_test, y_pred))
plot_confusion_matrix(clf_rus, X_test, y_test)

Применение случайной передискретизации

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

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

from imblearn.over_sampling import RandomOverSampler
# create the train and test dataset
X_train, X_test, y_train, y_test= train_test_split(X, y, test_size=0.2)
# Create an instance of RandomOverSampler, fit the training data #and apply Logistics regression
ros= RandomOverSampler(sampling_strategy='auto')
X_train, y_train = ros.fit_resample(X_train, y_train)
clf_ros=  LogisticRegression(random_state=0).fit(X_train, y_train)
# predict the test data
y_pred= clf_ros.predict(X_test)
# print the model performance metrics
print("Accurcay",accuracy_score(y_test, y_pred))
print("Precision", precision_score(y_test, y_pred))
print("Recall",recall_score(y_test, y_pred))
print("F1 score",f1_score(y_test, y_pred))
plot_confusion_matrix(clf_ros, X_test, y_test)

Применение метода передискретизации синтетических меньшинств (SMOTE)

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

Сравнение количества наблюдений между исходным набором данных и обучающим набором данных, созданным с помощью SMOTE.

from imblearn.over_sampling import SMOTE
# create the train and test dataset
X_train, X_test, y_train, y_test= train_test_split(X, y, test_size=0.2)
##Create an instance of SMOTE, fit the training data and apply #Logistics regression
sm = SMOTE(random_state=27, sampling_strategy='minority', k_neighbors=5)
X_train, y_train = sm.fit_resample(X_train, y_train)
clf_sm = LogisticRegression(random_state=0).fit(X_train, y_train)
# predict the test data
y_pred= clf_sm.predict(X_test)
# print the model performance metrics
print("Accurcay",accuracy_score(y_test, y_pred))
print("Precision", precision_score(y_test, y_pred))
print("Recall",recall_score(y_test, y_pred))
print("F1 score",f1_score(y_test, y_pred))
plot_confusion_matrix(clf_sm, X_test, y_test)

Заключение:

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