SMOTE手法を使用してデータセットのバランスをとるのに使用される最良のパフォーマンスメトリックは何ですか


8

スモートテクニックを使用してデータセットをオーバーサンプリングし、バランスのとれたデータセットを手に入れました。私が直面した問題は、パフォーマンスメトリックです。精度、再現率、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

まず最初に、明確にするために、バランスの取れたデータセットでモデルのパフォーマンスを評価しないでください。あなたがすべきことは、データセットを理想的には同じ程度の不均衡のトレインとテストセットに分割することです。評価は、トレーニングセットでバランスを取りながら、テストセットでのみ実行する必要があります。

あなたの質問については、平均化されたマクロのメトリックは、バランシング手法が効果的であることを証明するためにうまく機能するはずです。このようなメトリックを計算するには(単純化のために精度としましょう)、各クラスの精度を個別に計算し、それらを平均するだけです。


2つのモデルm1とをトレーニングしました。1つm2はデータセットのバランスをとらず、2つ目はSMOTEを使用してデータセットのバランスをとった後です。

実際の値: 0, 0, 0, 0, 0, 0, 0, 0, 1, 1
予測m10, 0, 0, 0, 0, 0, 0, 0, 0, 0 <-過半数クラスのみを予測
予測m21, 0, 0, 1, 0, 1, 0, 0, 1, 1

通常、精度をどのように計算しますか?

acc=correctpredictionstotalpredictions

2つのモデルはこのメトリックでどのように機能しますか?

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

このパフォーマンスメトリックによると、m2はより優れていm1ます。ただし、m1大多数のクラスを予測するだけなので、必ずしもそうであるとは限りません。がどのようm2に優れているかを示すためにm1、2つのクラスを等しいものとして扱うメトリックが必要です。

次に、マクロ平均の精度を計算してみましょう。どうやって?最初に、各クラスの精度を個別に計算し、次にそれらを平均します。

  • 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%

  • マクロ平均化は任意のメトリックに適用できますが、これは混同行列メトリック(精度、再現率、f1など)で最も一般的です。

  • これを自分で実装する必要はありません。多くのライブラリにすでに実装されています(たとえば、sklearnのf1_scoreにはと呼ばれるパラメーターがありaverage、これをに設定できます"macro")。


あなたの素晴らしい説明に感謝しますそれは明らかに簡潔ですいくつかの科学記事を実際に提案できますか?
Rawia Sammout 2018

4
問題のいくつかの記事:123。これらの記事は、基本的な概要このような状況で使用することができる戦闘クラスimbalace(オーバー/アンダーサンプリング、クラス重みなど)とメトリック(ROC、G-平均、二次カッパなど)への方法は何
Djib2011

共有コードを見てみてください。代わりに、
smote

3
混同行列から判断すると、最初のモデル(バランスなし)は過半数クラスのみを予測し、2番目のモデル(スモートあり)は他のクラスを予測します。SVMには大量のハイパーパラメーター調整が必要なため(つまり、最良のC、ガンマ、カーネルタイプなどを把握するためにモデルを何度も実行するため)、別の分類子を試すことをお勧めします。
Djib2011

ありがとう。グリッドサーチチューニングパラメーターを使用し、グリッドサーチアルゴリズムで見つかった最高のハイパーパラメーターで両方のモデルをトレーニングしたため、分類子を変更する方が良いと思います
Rawia Sammout
弊社のサイトを使用することにより、あなたは弊社のクッキーポリシーおよびプライバシーポリシーを読み、理解したものとみなされます。
Licensed under cc by-sa 3.0 with attribution required.