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

8

Я использовал технику smote для пересчета моего набора данных, и теперь у меня есть сбалансированный набор данных. Проблема, с которой я столкнулся, заключается в том, что показатели производительности; точность, напоминание, измерение f1, точность в несбалансированном наборе данных выполняются лучше, чем при сбалансированном наборе данных.

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

Примечание: roc_auc_score лучше в сбалансированном наборе данных, чем roc_auc_score с несбалансированным набором данных. Можно ли это считать хорошим измерением производительности? после объяснения я реализовал код, и я получил этот результат

import pandas as pd
import numpy as np
from sklearn import preprocessing
import matplotlib.pyplot as plt 
plt.rc("font", size=14)
from sklearn.svm import LinearSVC
from sklearn.svm import SVC
from sklearn.cross_validation import train_test_split,StratifiedShuffleSplit,cross_val_score
import seaborn as sns
from scipy import interp
from time import *
from sklearn import metrics
X=dataCAD.iloc[:,0:71]
y= dataCAD['Cardio1']
# Split the dataset in two equal parts
X_train, X_test, y_train, y_test = train_test_split(
    X, y, test_size=0.3, random_state=0)
print(y_test.value_counts())
model=SVC(C=0.001, kernel="rbf",gamma=0.01, probability=True)
t0 = time()
clf = model.fit(X_train,y_train)
y_pred = clf.predict(X_test)
t = time() - t0
print("=" * 52)
print("time cost: {}".format(t))
print()
print("confusion matrix\n", metrics.confusion_matrix( y_test, y_pred))
cf=metrics.confusion_matrix(y_test, y_pred)
accuracy=(cf.item((0,0))/50)+(cf.item((1,1))/14)
print("model accuracy \n",accuracy/2)
print()
print("\t\tprecision_score: {}".format(metrics.precision_score( y_test, y_pred, average='macro')))
print()
print("\t\trecall_score: {}".format(metrics.recall_score(y_test, y_pred, average='macro')))
print()
print("\t\tf1_score: {}".format(metrics.f1_score(y_test, y_pred, average='macro')))
print()
print("\t\troc_auc_score: {}".format(metrics.roc_auc_score( y_test, y_pred, average='macro')))

Результаты:

Name: Cardio1, dtype: int64
====================================================
time cost: 0.012008905410766602

confusion matrix
 [[50  0]
 [14  0]]
model accuracy 
 0.5

        precision_score: 0.390625

        recall_score: 0.5

        f1_score: 0.43859649122807015

        roc_auc_score: 0.5

Для сбалансированного набора данных

X_train1,y_train1 = sm.fit_sample(X_train, y_train.ravel())
df= pd.DataFrame({'Cardio1': y_train1})
df.groupby('Cardio1').Cardio1.count().plot.bar(ylim=0)
plt.show()
print(X_train1.shape)
print(y_train1.shape)
#model=SVC(C=0.001, kernel="rbf",gamma=0.01, probability=True)
model=SVC(C=10, kernel="sigmoid",gamma=0.001, probability=True)
t0 = time()
clf = model.fit(X_train1,y_train1)
y_pred = clf.predict(X_test)
t = time() - t0
print("=" * 52)
print("time cost: {}".format(t))
print()
print("confusion matrix\n", metrics.confusion_matrix(y_test, y_pred))
cf=metrics.confusion_matrix(y_test, y_pred)
accuracy=(cf.item((0,0))/50)+(cf.item((1,1))/14)
print("model accuracy \n",accuracy/2)
print()
#print("\t\taccuracy: {}".format(metrics.accuracy_score( y_test, y_pred)))
print()
print("\t\tprecision_score: {}".format(metrics.precision_score( y_test, y_pred, average='macro')))
print()
print("\t\trecall_score: {}".format(metrics.recall_score(y_test, y_pred, average='macro')))
print()
print("\t\tf1_score: {}".format(metrics.f1_score(y_test, y_pred, average='macro')))
print()
print("\t\troc_auc_score: {}".format(metrics.roc_auc_score( y_test, y_pred, average='macro')))

Результаты:

(246, 71)
(246,)
====================================================
time cost: 0.05353999137878418

confusion matrix
 [[ 0 50]
 [ 0 14]]
model accuracy 
 0.5


        precision_score: 0.109375

        recall_score: 0.5

        f1_score: 0.1794871794871795

        roc_auc_score: 0.5

Я не нашел эффективных результатов. Должен ли я реализовать модель с использованием перекрестной проверки?

Равия Саммут
источник

Ответы:

8

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

Что касается вашего вопроса, то любая метрика, усредненная по макросам, должна хорошо доказать, что ваша техника балансировки эффективна. Чтобы рассчитать такую ​​метрику (скажем, точность для простоты), вам просто нужно вычислить точность каждого класса в отдельности, а затем усреднить их.

Пример :
Мы тренировались две моделей m1и m2первые без балансирования набора данных , а второго после использования поражало , чтобы сбалансировать набор данных.

Фактические значения: 0, 0, 0, 0, 0, 0, 0, 0, 1, 1
Предсказано m1: 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 <- только прогнозирует класс большинства
Предсказано m2:1, 0, 0, 1, 0, 1, 0, 0, 1, 1

Как бы мы обычно рассчитывали точность?

aссзнак равносорресTпреdясTяоNsTоTaLпреdясTяоNs

Как наши две модели работают по этому показателю?

aсс1знак равно810знак равно80%
aсс2знак равно710знак равно70%

Согласно этой метрике производительности, m2лучше, чем m1. Однако, это не обязательно так, как m1предсказывает класс большинства! Чтобы показать, как m2лучше m1, нам нужна метрика, которая рассматривает два предложения как равные.

Теперь попробуем вычислить макро-усредненную точность. Как? Сначала мы рассчитаем точность для каждого класса в отдельности, а затем усредним их:

  • m1
    aсс10знак равно88знак равно100%m10
    aсс11знак равно02знак равно0%m11
    мaсро_aсс1знак равноaсс10+aсс112знак равно100%+0%2знак равно50%

  • m2
    aсс20знак равно58знак равно62,5%m20
    aсс21знак равно22знак равно100%m21
    мaсро_aсс2знак равноaсс20+aсс212знак равно62,5%+100%2знак равно81,25%

Примечания :

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

  • Вам не нужно реализовывать это самостоятельно, во многих библиотеках это уже есть (например, у fle_score у sklearn есть параметр с именем average, который можно установить на "macro")

Djib2011
источник
Большое спасибо за ваше великолепное объяснение, это ясно, кратко. Можете ли вы предложить некоторые научные статьи в реальность?
Равия Саммут
4
Несколько статей по этому вопросу: 1 , 2 , 3 . По сути, эти статьи представляют собой методы борьбы с дисбалансом классов (избыточная / недостаточная выборка, веса классов и т. Д.) И метрики, которые можно использовать в этих ситуациях (ROC, g-mean, квадратичная каппа и т. Д.)
Djib2011
не могли бы вы взглянуть на общий код, я нашел противоречивые результаты вместо повышения производительности модели, используя smote, я получил контраст
Rawia Sammout
3
Из того, что я могу сказать, судя по матрицам путаницы, ваша первая модель (без балансировки) предсказывает только класс большинства, а вторая (с ударением) предсказывает другой класс. Я бы порекомендовал попробовать другой классификатор, так как SVM требует большой настройки гиперпараметров (то есть, запускает вашу модель снова и снова, чтобы определить лучший C, гамму, тип ядра и т. Д.).
Djib2011
спасибо за тебя я думаю, что изменение классификатора лучше, потому что я использую параметр настройки gridsearch и обучил обе модели лучшим гиперпараметрам, найденным алгоритмом
gridsearch