Apa metrik kinerja terbaik yang digunakan dalam menyeimbangkan dataset menggunakan teknik SMOTE


8

Saya menggunakan teknik smote untuk mengecualikan dataset saya dan sekarang saya memiliki dataset yang seimbang. Masalah yang saya hadapi adalah metrik kinerja; presisi, recall, ukuran f1, akurasi dalam dataset tidak seimbang lebih baik dilakukan daripada dengan dataset seimbang.

Pengukuran mana yang dapat saya gunakan untuk menunjukkan bahwa menyeimbangkan dataset dapat meningkatkan kinerja model?

NB: roc_auc_score lebih baik di datset seimbang daripada roc_auc_score dengan dataset tidak seimbang. Apakah ini dapat dianggap sebagai pengukuran kinerja yang baik? setelah penjelasan saya menerapkan kode dan saya mendapat hasil ini

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

Hasil:

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

Untuk dataset seimbang

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

Hasil:

(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

Saya tidak menemukan hasil yang efisien. Haruskah saya menerapkan model menggunakan validasi silang?

Jawaban:


8

Pertama-tama, hanya untuk menjadi jelas, Anda tidak harus mengevaluasi kinerja model Anda pada set data yang seimbang. Apa yang harus Anda lakukan adalah membagi dataset Anda menjadi kereta api dan set tes dengan tingkat ketidakseimbangan yang sama. Evaluasi harus dilakukan secara eksklusif pada set tes, sementara keseimbangan pada set pelatihan.

Sedangkan untuk pertanyaan Anda, setiap metrik makro rata-rata harus bekerja dengan baik untuk membuktikan bahwa teknik penyeimbangan Anda efektif. Untuk menghitung metrik seperti itu (katakanlah akurasi untuk kesederhanaan), Anda hanya perlu menghitung akurasi masing-masing kelas secara individu lalu rata - rata .

Contoh :
Kami melatih dua model m1dan m2, yang pertama tanpa menyeimbangkan dataset dan yang kedua setelah menggunakan SMOTE untuk menyeimbangkan dataset.

Nilai aktual: 0, 0, 0, 0, 0, 0, 0, 0, 1, 1
Diprediksi m1: 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 <- hanya memprediksi kelas mayoritas
Diprediksi m2:1, 0, 0, 1, 0, 1, 0, 0, 1, 1

Bagaimana kita biasanya menghitung akurasi?

Sebuahcc=cHairrecthalredsayactsayaHainstHaitSebuahlhalredsayactsayaHains

Bagaimana kinerja dua model kami pada metrik ini?

Sebuahcc1=810=80%
Sebuahcc2=710=70%

Menurut metrik kinerja ini, m2lebih baik daripada m1. Namun, ini tidak selalu terjadi karena m1hanya memprediksi kelas mayoritas! Untuk menunjukkan bagaimana m2lebih baik daripada m1, kita membutuhkan metrik yang memperlakukan kedua klausa itu sama.

Kami sekarang akan mencoba menghitung akurasi rata-rata makro. Bagaimana? Pertama-tama kita akan menghitung akurasi untuk setiap kelas secara terpisah, dan kemudian kita akan membuat rata-rata mereka:

  • m1
    Sebuahcc10=88=100%m10
    Sebuahcc11=02=0%m11
    mSebuahcrHai_Sebuahcc1=Sebuahcc10+Sebuahcc112=100%+0%2=50%

  • m2
    Sebuahcc20=58=62.5%m20
    Sebuahcc21=22=100%m21
    mSebuahcrHai_Sebuahcc2=Sebuahcc20+Sebuahcc212=62.5%+100%2=81.25%

Catatan :

  • Rata-rata makro dapat diterapkan ke metrik apa pun yang Anda inginkan, namun paling umum dalam metrik matriks kebingungan (misalnya presisi, penarikan, f1).

  • Anda tidak perlu mengimplementasikan ini sendiri, banyak perpustakaan sudah memilikinya (mis. Sklearn's f1_score memiliki parameter bernama average, yang dapat diatur ke "macro")


Terima kasih banyak atas penjelasan hebatnya, jelas ringkas. Bisakah Anda mengusulkan beberapa artikel ilmiah menjadi nyata ??
Rawia Sammout

4
Beberapa artikel tentang masalah ini: 1 , 2 , 3 . Apa yang pada dasarnya ditinjau oleh artikel-artikel ini adalah metode untuk memerangi imbalace kelas (pengambilan sampel berlebihan / kurang, bobot kelas, dll.) Dan metrik yang dapat digunakan dalam situasi ini (ROC, g-mean, kappa kuadratik, dll.)
Djib2011

bisa Anda lihat pada kode bersama saya menemukan hasil membingungkan bukan od meningkatkan kinerja model menggunakan lalu memukul saya mendapat kontras
Rawia Sammout

3
Dari apa yang bisa saya katakan menilai dari matriks kebingungan, model pertama Anda (tanpa balancing) hanya memprediksi kelas mayoritas, sedangkan yang kedua (dengan smote) memprediksi kelas lain. Saya akan merekomendasikan mungkin mencoba classifier lain, karena SVM memerlukan banyak penyetelan hyper-parameter (yaitu menjalankan model Anda lagi dan lagi untuk mengetahui C, gamma, tipe kernel, dll.) Terbaik.
Djib2011

terima kasih untuk Anda. saya pikir mengubah classifier lebih baik karena saya menggunakan parameter tuning gridsearch dan saya melatih kedua model pada hyperparameters terbaik yang ditemukan oleh algoritma
gridsearch
Dengan menggunakan situs kami, Anda mengakui telah membaca dan memahami Kebijakan Cookie dan Kebijakan Privasi kami.
Licensed under cc by-sa 3.0 with attribution required.