Was ist die beste Leistungsmetrik, die beim Ausgleichen von Datensätzen mithilfe der SMOTE-Technik verwendet wird?

8

Ich habe die Smote-Technik verwendet, um meinen Datensatz zu überabtasten, und jetzt habe ich einen ausgeglichenen Datensatz. Das Problem, mit dem ich konfrontiert war, ist, dass die Leistungsmetriken; Präzision, Rückruf, f1-Messung und Genauigkeit im unausgeglichenen Datensatz werden besser ausgeführt als bei einem ausgeglichenen Datensatz.

Mit welcher Messung kann ich zeigen, dass ein Ausgleichsdatensatz die Leistung des Modells verbessern kann?

NB: roc_auc_score ist in ausgeglichenen Datenmengen besser als roc_auc_score in unausgeglichenen Datenmengen. Kann dies als gute Leistungsmessung angesehen werden? Nach der Erklärung habe ich Code implementiert und diese Ergebnisse erhalten

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

Ergebnisse:

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

Für einen ausgeglichenen Datensatz

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

Ergebnisse:

(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

Ich habe keine effizienten Ergebnisse gefunden. Sollte ich das Modell mithilfe der Kreuzvalidierung implementieren?

Rawia Sammout
quelle

Antworten:

8

Um ganz klar zu sein, sollten Sie zunächst nicht die Leistung Ihrer Modelle anhand des ausgeglichenen Datensatzes bewerten. Was Sie tun sollten, ist, Ihren Datensatz in einen Zug und einen Testsatz mit idealerweise dem gleichen Grad an Ungleichgewicht aufzuteilen. Die Bewertung sollte ausschließlich am Testset durchgeführt werden, während das Balancieren am Trainingsset erfolgt.

Was Ihre Frage betrifft, sollte jede makro-gemittelte Metrik gut genug sein, um zu beweisen, dass Ihre Ausgleichstechnik effektiv ist. Zur Berechnung einer solchen Metrik (sagen wir mal Genauigkeit der Einfachheit halber), müssen Sie nur die Genauigkeit jeder Klasse berechnen einzeln und dann durchschnittlich ihnen.

Beispiel :
Wir haben zwei Modelle trainiert m1und m2das erste ohne Ausgleich des Datensatzes und das zweite nach Verwendung von SMOTE zum Ausgleichen des Datensatzes.

Istwerte: 0, 0, 0, 0, 0, 0, 0, 0, 1, 1
Vorausgesagt m1: 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 <- prognostiziert nur Mehrheitsklasse
Vorausgesagt m2:1, 0, 0, 1, 0, 1, 0, 0, 1, 1

Wie würden wir normalerweise die Genauigkeit berechnen?

acc=correctpredictionstotalpredictions

Wie verhalten sich unsere beiden Modelle mit dieser Metrik?

acc1=810=80%
acc2=710=70%

Nach dieser Leistungsmetrik m2ist besser als m1. Dies ist jedoch nicht unbedingt der Fall, da m1nur die Mehrheitsklasse vorhergesagt wird! Um zu zeigen, wie m2besser ist als m1, benötigen wir eine Metrik, die die beiden Klassen als gleich behandelt.

Wir werden nun versuchen, eine makrogemittelte Genauigkeit zu berechnen. Wie? Zuerst berechnen wir die Genauigkeit für jede Klasse separat und dann mitteln wir sie:

  • m1
    acc10=88=100%m10
    acc11=02=0%m11
    macro_acc1=acc10+acc112=100%+0%2=50%

  • m2
    acc20=58=62.5%m20
    acc21=22=100%m21
    macro_acc2=acc20+acc212=62.5%+100%2=81.25%

Anmerkungen :

  • Die Makro-Mittelung kann auf jede gewünschte Metrik angewendet werden, ist jedoch bei Verwirrungsmatrix-Metriken am häufigsten (z. B. Genauigkeit, Rückruf, f1).

  • Sie müssen dies nicht selbst implementieren, viele Bibliotheken haben es bereits (z. B. hat sklearns f1_score einen Parameter namens average, der auf gesetzt werden kann "macro").

Djib2011
quelle
Vielen Dank für Ihre großartige Erklärung. Es ist klar, prägnant. Könnten Sie einige wissenschaftliche Artikel für real vorschlagen?
Rawia Sammout
4
Einige Artikel zu diesem Thema: 1 , 2 , 3 . Was diese Artikel im Wesentlichen überblicken, sind Methoden zur Bekämpfung von Klassenungleichgewichten (Über- / Unterabtastung, Klassengewichte usw.) und Metriken, die in diesen Situationen verwendet werden können (ROC, g-Mittelwert, quadratischer Kappa usw.)
Djib2011
Könnten Sie einen Blick auf den gemeinsam genutzten Code
werfen?
3
Nach dem, was ich anhand der Verwirrungsmatrizen beurteilen kann, sagt Ihr erstes Modell (ohne Ausgleich) nur die Mehrheitsklasse voraus, während das zweite (mit Smote) die andere Klasse vorhersagt. Ich würde empfehlen, vielleicht einen anderen Klassifikator zu versuchen, da SVMs viel Hyperparameter-Tuning erfordern (dh Ihr Modell immer wieder ausführen, um den besten C-, Gamma-, Kerneltyp usw. herauszufinden).
Djib2011
Danke für dich. Ich denke, das Ändern des Klassifikators ist besser, weil ich Gridsearch-Tuning-Parameter verwende und beide Modelle auf die besten Hyperparameter trainiert habe, die vom Gridsearch-Algorithmus gefunden wurden
Rawia Sammout