"Enter"a basıp içeriğe geçin

Python ile ROC Curve ve AuC

Geçtiğimiz yazıda Sınıflandırma Modelleri İçin Performans Değerlendirme adlı yazıda öğrendiğimiz Doğruluk (Accuracy), Duyarlılık (Recall), Kesinlik (Precision), F-skor ve Matthews Correlation Coefficient (MCC) metriklerinin sklearn kütüphanesinin sağladığı iris veri seti için uygulamalarını yaptık.

Bu yazıda ise ROC Curve ve AuC adlı metriklerin uygulamasını yaparak daha iyi kavramaya çalışacağız.

Uygulama için yine iris veri setini kullanacağız. Veri setini yükleyerek başlayalım:

from sklearn.datasets import load_iris

dataset = load_iris()

Veri setine ilişkin özellik seti ile etiketleri için nesneleri tanımlayarak devam edelim:

features = dataset.data
labels = dataset.target

Bir önceki yazıdan da hatırladığınız gibi 4 ayrı özellik belirten features adlı 2 boyutlu dizi ile 3 farklı sınıf (class) belirten labels adlı tek boyutlu diziye sahip durumdayız. Her bir sınıf (class) için ayrı ayrı ROC eğrisini çizdirebilmemiz için labels adlı diziye one-hot encoding uygulayacağız. One-hot encoding birden fazla sınıf belirten kategorik dizilerin ikili (binary) olarak temsil edilmesini sağlar.

Aşağıdaki tabloda olduğu gibi şehir adlı bir dizi ve bu dizi altında İzmir, İstanbul ve Ankara adlarında 3 farklı sınıf olsun. One-hot encoding her İzmir, İstanbul ve Ankara için 3 farklı dizi yaratır. İzmir dizisinde yalnızca İzmir olanlara karşılık 1 değeri verilirken diğer hepsi için 0, İstanbul dizisinde sadece İstanbul olanlara karşılık 1, diğerleri için 0 ve Ankara dizisi için de aynı şekilde sadece Ankara değerine karşılık gelenler için 1 ve diğerleri için 0 değeri verilir.

ŞehirİzmirİstanbulAnkara
İzmir100
İstanbul010
İzmir100
Ankara001
İstanbul010
one-hot encoding

Bu yöntem veri önişleme (data pre-processing) adımlarından biridir ve sadece etiketlere değil özellik setlerindeki kategorik verilere de sıklıkla uygulanmaktadır. Zira makine öğrenmesi algoritmalarının büyük çoğunluğu kategorik verilerle çalışamadığı gibi, 0,1,2,3 gibi sayı ile ifade edilen kategorik verileri de numerik olduklarından ötürü numerik değerlerine göre hesaba kattığından yanılmaktadır. Bu sebeple çalıştığımız modelin inceliklerini tanıyarak, kategorik değişkenleri gerekli olduğu durumlarda one-hot encoding ile ikili yapılara dönüştürmemiz gerekmektedir.

Etiket (label) tarafında da her bir sınıf için ayrı ayrı değerlendirme yapmayı kolaylaştırmak için one-hot encoding uygulanmaktadır.

Sklearn ile labels değişkenimizi ikili (binary) hale getirmek (binarize) ve sınıf sayısını ileride kullanmak üzere kaydetmek için aşağıdaki kodları kullanıyoruz:

from sklearn.preprocessing import label_binarize

labels = label_binarize(labels, classes=[0, 1, 2])

n_classes = labels.shape[1]

Problemi bizim için daha zor hale getirmek üzere veri setinin bize sunduğu 4 özelliğe ek olarak yeni özellik kolonları ekleyerek bunlara rastgele değerler atanmasını sağlıyoruz. Elbette bu adım normalde yapılması beklenen bir şey değil 🙂

import numpy as np

random_state = np.random.RandomState(42)
n_samples, n_features = features.shape
features = np.c_[features, random_state.randn(n_samples,  10 * n_features)]

Veri setimizi eğitim (training) ve test seti olarak ikiye ayırıyoruz:

from sklearn.model_selection import train_test_split

X_train, X_test, y_train, y_test = train_test_split(features, labels, test_size = 0.5, shuffle = True)

Şimdi ise ROC Curve ve AuC adlı yazıda adım adım yaparak oluşturduğumuz fpr ve tpr değerlerini hesaplamak üzere aşağıdaki kodları çalıştırıyoruz. OneVsRestClassifier literatürde OneVsAll olarak da karşınıza çıkabilecek birine karşılık hepsi anlamına gelen bir sınıflandıma çeşidi. Aşağıdaki kodda Support Vector Machines modelini one-hot encoding uyguladığımız labels dizisinde yer alan tüm alt kolonlar için ayrı ayrı eğiterek desicion_function ile X_test dizisinde yer alan özelliklere göre tahmin edilen her bir y değerinin karar sınırına (decision boundary) uzaklığını elde ediyoruz. Bu da ROC eğrisini çizerken sınırı her kaydırdığımızda False Positive Rate (FPR) ve True Positive Rate (TPR) hesaplamamızı sağlıyor.

from sklearn.svm import SVC
from sklearn.multiclass import OneVsRestClassifier

classifier = OneVsRestClassifier(SVC(kernel='linear', probability=True))
y_score = classifier.fit(X_train, y_train).decision_function(X_test)

Aşağıdaki kod hücresi ile her bir sınıf için (Setosa, Versicolour ve Virginica) ayrı ayrı FPR, TPR ve AuC değerlerini hesaplıyoruz:

from sklearn.metrics import roc_curve, auc

fpr = dict()
tpr = dict()
roc_auc = dict()
for i in range(n_classes):
    fpr[i], tpr[i], _ = roc_curve(y_test[:, i], y_score[:, i])
    roc_auc[i] = auc(fpr[i], tpr[i])

Hatırlayacağımız gibi Setosa, Versicolour ve Virginica adındaki türler 0, 1 ve 2 olarak etiket setimizde yer alıyordu. Virginica yani 2 için ROC eğrisini çizdirmek istersek aşağıdaki kodu kullanıyoruz:

import matplotlib.pyplot as plt
plt.figure()
lw = 2
plt.plot(fpr[2], tpr[2], color='darkorange',
         lw=lw, label='ROC curve (area = %0.2f)' % roc_auc[2])
plt.plot([0, 1], [0, 1], color='navy', lw=lw, linestyle='--')
plt.xlim([0.0, 1.0])
plt.ylim([0.0, 1.05])
plt.xlabel('False Positive Rate')
plt.ylabel('True Positive Rate')
plt.title('Receiver operating characteristic example')
plt.legend(loc="lower right")
plt.show()

Sonuç olarak aşağıdaki grafiği elde ediyoruz. Elbetteki sizler farklı gürültüler eklediğiniz için ve eğittiğiniz modelin başlangıç değerleri farklı olacağından farklı sonuçlar elde etmeniz gayet doğal:

Uygulamaya ilişkin github repo’suna erişmek için tıklayın.

Bir sonraki yazımızda regresyon modelleri için performans değerlendirme yöntemlerini öğreneceğiz.

Keyifli Öğrenmeler 🙂

İlk Yorumu Siz Yapın

Bir Cevap Yazın

Translate »
%d blogcu bunu beğendi: