Jaka jest najlepsza miara wydajności używana w równoważeniu zestawu danych przy użyciu techniki SMOTE

8

Użyłem techniki smote do nadpróbkowania mojego zestawu danych, a teraz mam zrównoważony zestaw danych. Problem, z którym się spotkałem, polega na tym, że wskaźniki wydajności; precyzja, przywołanie, pomiar F1, dokładność w niezrównoważonym zbiorze danych są lepiej wykonywane niż w zbalansowanym zbiorze danych.

Jakiego pomiaru mogę użyć, aby wykazać, że zestaw danych bilansujących może poprawić wydajność modelu?

Uwaga: roc_auc_score jest lepszy w zbalansowanym zestawie danych niż roc_auc_score z niezrównoważonym zestawem danych Czy można to uznać za dobry pomiar wydajności? po wyjaśnieniu zaimplementowałem kod i otrzymałem te wyniki

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')))

Wyniki:

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

Zrównoważony zestaw danych

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')))

Wyniki:

(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

Nie znalazłem żadnych skutecznych wyników. Czy powinienem wdrożyć model przy użyciu weryfikacji krzyżowej?

Rawia Sammout
źródło

Odpowiedzi:

8

Przede wszystkim, dla jasności, nie powinieneś oceniać wydajności swoich modeli na zbalansowanym zbiorze danych. To, co powinieneś zrobić, to podzielić zestaw danych na pociąg i zestaw testów z idealnie takim samym stopniem nierównowagi. Ocena powinna być wykonywana wyłącznie na zestawie testowym, a równoważenie na zestawie szkoleniowym.

Jeśli chodzi o twoje pytanie, każda metryka uśredniona dla makr powinna dobrze działać, aby udowodnić, że twoja technika bilansowania jest skuteczna. Aby obliczyć taką metrykę (powiedzmy dokładność dla uproszczenia), wystarczy obliczyć dokładności każdej klasy indywidualnie, a następnie je uśrednić .

Przykład :
Przeszkoliliśmy dwa modele m1im2 pierwszy bez zrównoważenia zestawu danych, a drugi po użyciu bili do zrównoważenia zestawu danych.

Rzeczywiste wartości: 0, 0, 0, 0, 0, 0, 0, 0, 1, 1
Przewidywane m1: 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 <- przewiduje tylko klasę większości
Przewidywane m2:1, 0, 0, 1, 0, 1, 0, 0, 1, 1

Jak normalnie obliczalibyśmy dokładność?

zadodo=doorrmidotprmirejadotjaonstotzalprmirejadotjaons

Jak nasze dwa modele radzą sobie z tym wskaźnikiem?

zadodo1=810=80%
zadodo2)=710=70%

Zgodnie z tym wskaźnikiem wydajności m2jest lepszy niż m1. Jednak niekoniecznie tak jest, ponieważ m1tylko przewiduje się większość klasy! Aby pokazać, jak m2jest lepszy m1, potrzebujemy metryki, która traktuje dwie klauzule jako równe.

Spróbujemy teraz obliczyć dokładność uśrednioną na poziomie makro. W jaki sposób? Najpierw obliczymy dokładność dla każdej klasy osobno, a następnie uśrednimy je:

  • m1
    zadodo10=88=100%m10
    zadodo11=02)=0% <- m1dokładność w klasie1
    mzadoro_zadodo1=zadodo10+zadodo112)=100%+0%2)=50%

  • Dla m2:
    zadodo2)0=58=62,5%<- m2dokładność w klasie0
    zadodo2)1=2)2)=100% <- m2dokładność w klasie1
    mzadoro_zadodo2)=zadodo2)0+zadodo2)12)=62,5%+100%2)=81,25%

Uwagi :

  • Uśrednianie makr można zastosować do dowolnej metryki, którą jednak chcesz, jednak jest to najczęściej w metrach macierzy pomieszania (np. Precyzja, przywołanie, f1).

  • Nie musisz tego samodzielnie wdrażać, wiele bibliotek już go ma (np. F1_score sklearn ma parametr o nazwie average, który można ustawić na "macro")

Djib2011
źródło
Bardzo dziękuję za twoje wspaniałe wyjaśnienie, jest jasne, zwięzłe. Czy możesz zaproponować kilka artykułów naukowych naprawdę?
Rawia Sammout,
4
Kilka artykułów na ten temat: 1 , 2 , 3 . Artykuły, które zasadniczo omawiają te metody, to metody walki z nierównowagą klas (nadmierne / niedostateczne próbkowanie, wagi klas itp.) Oraz mierniki, które można zastosować w takich sytuacjach (ROC, średnia g, kwadratowa kappa itp.)
Djib2011,
czy mógłbyś
rzucić
3
Z tego, co mogę powiedzieć, sądząc po macierzach zamieszania, twój pierwszy model (bez równoważenia) przewiduje tylko klasę większości, podczas gdy drugi (z smote) przewiduje drugą klasę. Poleciłbym może wypróbowanie innego klasyfikatora, ponieważ maszyny SVM wymagają dużej modyfikacji tuningu parametrów (tj. Ciągłego uruchamiania modelu w celu znalezienia najlepszego C, gamma, jądra itp.).
Djib2011,
dzięki za ciebie. myślę, że zmiana klasyfikatora jest lepsza, ponieważ używam parametru dostrajania gridsearch i trenowałem oba modele na najlepszych hiperparametrach znalezionych przez algorytm gridsearch
Rawia Sammout