Destek Vektör Makinesi (SVM)
SVM'ye Giriş
Destek vektör makineleri (SVM'ler), hem sınıflandırma hem de regresyon için kullanılan güçlü ancak esnek denetlenen makine öğrenme algoritmalarıdır. Ancak genellikle sınıflandırma problemlerinde kullanılırlar. 1960'larda, SVM'ler ilk olarak tanıtıldı, ancak daha sonra 1990'da rafine edildi. SVM'ler, diğer makine öğrenimi algoritmalarına kıyasla benzersiz uygulama yöntemlerine sahiptir. Son zamanlarda, birden çok sürekli ve kategorik değişkeni işleme yetenekleri nedeniyle son derece popülerdirler.
SVM'nin Çalışması
Bir SVM modeli, temelde çok boyutlu uzayda bir hiper düzlemdeki farklı sınıfların bir temsilidir. Hatanın en aza indirilmesi için hiper düzlem, SVM tarafından yinelemeli bir şekilde oluşturulacaktır. SVM'nin amacı, bir maksimum marjinal hiper düzlem (MMH) bulmak için veri setlerini sınıflara bölmektir.
Aşağıdakiler, SVM'de önemli kavramlardır -
Support Vectors- Hiper düzleme en yakın olan veri noktalarına destek vektörleri denir. Bu veri noktaları yardımıyla ayırma çizgisi tanımlanacaktır.
Hyperplane - Yukarıdaki diyagramda da görebileceğimiz gibi, farklı sınıflara sahip bir dizi nesne arasında bölünmüş bir karar düzlemi veya uzaydır.
Margin- Farklı sınıfların gizli veri noktalarında iki satır arasındaki boşluk olarak tanımlanabilir. Hattan destek vektörlerine dikey mesafe olarak hesaplanabilir. Büyük marj iyi bir marj olarak kabul edilir ve küçük marj kötü bir marj olarak kabul edilir.
SVM'nin temel amacı, maksimum marjinal hiper düzlem (MMH) bulmak için veri kümelerini sınıflara bölmektir ve aşağıdaki iki adımda yapılabilir -
İlk olarak, SVM, sınıfları en iyi şekilde ayıran yinelemeli olarak hiper düzlemler oluşturacaktır.
Ardından, sınıfları doğru şekilde ayıran alt düzlemi seçecektir.
Python'da SVM'yi Uygulama
SVM'yi Python'da uygulamak için, aşağıdaki gibi standart kitaplık içe aktarmasıyla başlayacağız -
import numpy as np
import matplotlib.pyplot as plt
from scipy import stats
import seaborn as sns; sns.set()
Daha sonra, SVM kullanarak sınıflandırma için sklearn.dataset.sample_generator'dan doğrusal olarak ayrılabilir verilere sahip örnek bir veri kümesi oluşturuyoruz -
from sklearn.datasets.samples_generator import make_blobs
X, y = make_blobs(n_samples=100, centers=2, random_state=0, cluster_std=0.50)
plt.scatter(X[:, 0], X[:, 1], c=y, s=50, cmap='summer');
Aşağıdakiler, 100 örnek ve 2 küme içeren örnek veri kümesi oluşturulduktan sonra çıktı olacaktır -
SVM'nin ayrımcı sınıflandırmayı desteklediğini biliyoruz. iki boyut olması durumunda bir çizgi veya birden fazla boyut olması durumunda çok katlı bir çizgi bularak sınıfları birbirinden ayırır. Yukarıdaki veri kümesinde aşağıdaki şekilde uygulanır -
xfit = np.linspace(-1, 3.5)
plt.scatter(X[:, 0], X[:, 1], c=y, s=50, cmap='summer')
plt.plot([0.6], [2.1], 'x', color='black', markeredgewidth=4, markersize=12)
for m, b in [(1, 0.65), (0.5, 1.6), (-0.2, 2.9)]:
plt.plot(xfit, m * xfit + b, '-k')
plt.xlim(-1, 3.5);
Çıktı aşağıdaki gibidir -
Yukarıdaki çıktıdan, yukarıdaki örnekleri mükemmel şekilde ayırt eden üç farklı ayırıcı olduğunu görebiliriz.
Tartışıldığı gibi, SVM'nin ana amacı, bir maksimum marjinal hiper düzlem (MMH) bulmak için veri setlerini sınıflara bölmektir, dolayısıyla sınıflar arasında sıfır çizgisi çizmek yerine, her çizginin etrafına en yakın noktaya kadar bir genişlikte bir kenar boşluğu çizebiliriz. Aşağıdaki gibi yapılabilir -
xfit = np.linspace(-1, 3.5)
plt.scatter(X[:, 0], X[:, 1], c=y, s=50, cmap='summer')
for m, b, d in [(1, 0.65, 0.33), (0.5, 1.6, 0.55), (-0.2, 2.9, 0.2)]:
yfit = m * xfit + b
plt.plot(xfit, yfit, '-k')
plt.fill_between(xfit, yfit - d, yfit + d, edgecolor='none',
color='#AAAAAA', alpha=0.4)
plt.xlim(-1, 3.5);
Çıktıdaki yukarıdaki görüntüden, ayırt edici sınıflandırıcılar içindeki "marjları" kolayca gözlemleyebiliriz. SVM, marjı maksimize eden çizgiyi seçecektir.
Daha sonra, bu veriler üzerinde bir SVM modeli eğitmek için Scikit-Learn'ün destek vektör sınıflandırıcısını kullanacağız. Burada, SVM'ye uyması için aşağıdaki gibi doğrusal çekirdek kullanıyoruz -
from sklearn.svm import SVC # "Support vector classifier"
model = SVC(kernel='linear', C=1E10)
model.fit(X, y)
Çıktı aşağıdaki gibidir -
SVC(C=10000000000.0, cache_size=200, class_weight=None, coef0=0.0,
decision_function_shape='ovr', degree=3, gamma='auto_deprecated',
kernel='linear', max_iter=-1, probability=False, random_state=None,
shrinking=True, tol=0.001, verbose=False)
Şimdi, daha iyi bir anlayış için, aşağıdakiler 2D SVC için karar işlevlerini çizecektir -
def decision_function(model, ax=None, plot_support=True):
if ax is None:
ax = plt.gca()
xlim = ax.get_xlim()
ylim = ax.get_ylim()
Modeli değerlendirmek için aşağıdaki gibi grid oluşturmamız gerekiyor -
x = np.linspace(xlim[0], xlim[1], 30)
y = np.linspace(ylim[0], ylim[1], 30)
Y, X = np.meshgrid(y, x)
xy = np.vstack([X.ravel(), Y.ravel()]).T
P = model.decision_function(xy).reshape(X.shape)
Ardından, karar sınırlarını ve marjlarını aşağıdaki gibi çizmemiz gerekiyor -
ax.contour(X, Y, P, colors='k',
levels=[-1, 0, 1], alpha=0.5,
linestyles=['--', '-', '--'])
Şimdi, benzer şekilde destek vektörlerini aşağıdaki gibi çizin -
if plot_support:
ax.scatter(model.support_vectors_[:, 0],
model.support_vectors_[:, 1],
s=300, linewidth=1, facecolors='none');
ax.set_xlim(xlim)
ax.set_ylim(ylim)
Şimdi, modellerimizi aşağıdaki gibi uydurmak için bu işlevi kullanın -
plt.scatter(X[:, 0], X[:, 1], c=y, s=50, cmap='summer')
decision_function(model);
Yukarıdaki çıktıdan, bir SVM sınıflandırıcısının verilere kenar boşluklarıyla, yani kesikli çizgilerle ve destek vektörleriyle, bu uyumun temel öğeleri, kesikli çizgiye dokunarak sığdığını gözlemleyebiliriz. Bu destek vektör noktaları, sınıflandırıcının support_vectors_ özniteliğinde aşağıdaki gibi saklanır -
model.support_vectors_
Çıktı aşağıdaki gibidir -
array([[0.5323772 , 3.31338909],
[2.11114739, 3.57660449],
[1.46870582, 1.86947425]])
SVM Çekirdekleri
Uygulamada, SVM algoritması, bir girdi veri alanını gerekli forma dönüştüren çekirdek ile uygulanır. SVM, çekirdeğin düşük boyutlu bir girdi alanı alıp onu daha yüksek boyutlu bir alana dönüştürdüğü çekirdek numarası adı verilen bir teknik kullanır. Basit bir deyişle, çekirdek, bölünemeyen sorunları, ona daha fazla boyut ekleyerek ayrılabilir sorunlara dönüştürür. SVM'yi daha güçlü, esnek ve doğru hale getirir. Aşağıda SVM tarafından kullanılan bazı çekirdek türleri verilmiştir -
Doğrusal Çekirdek
Herhangi iki gözlem arasında iç çarpım olarak kullanılabilir. Doğrusal çekirdeğin formülü aşağıdaki gibidir -
k (x, x ben ) = toplam (x * x ben )
Yukarıdaki formülden, iki vektör arasındaki çarpımın her girdi değeri çiftinin çarpımının toplamı olduğunu söylediğini görebiliriz.
Polinom Çekirdeği
Doğrusal çekirdeğin daha genelleştirilmiş şeklidir ve eğri veya doğrusal olmayan girdi uzayını ayırt eder. Polinom çekirdeğin formülü aşağıdadır -
K (x, xi) = 1 + toplam (x * xi) ^ d
Burada d, öğrenme algoritmasında manuel olarak belirtmemiz gereken polinom derecesidir.
Radyal Temel Fonksiyonu (RBF) Kernel
Çoğunlukla SVM sınıflandırmasında kullanılan RBF çekirdeği, belirsiz boyutlu uzayda girdi uzayını eşler. Aşağıdaki formül matematiksel olarak açıklıyor -
K (x, xi) = exp (-gamma * toplamı ((x - xi ^ 2))
Burada gama 0 ile 1 arasındadır. Öğrenme algoritmasında bunu manuel olarak belirtmemiz gerekir. İyi bir varsayılan gama değeri 0.1'dir.
Doğrusal olarak ayrılabilir veriler için SVM uyguladığımız için, doğrusal olarak ayrılamayan veriler için Python'da uygulayabiliriz. Çekirdekler kullanılarak yapılabilir.
Misal
Aşağıda, çekirdekleri kullanarak bir SVM sınıflandırıcısı oluşturmaya yönelik bir örnek verilmiştir. Scikit-learn'ün iris veri kümesini kullanacağız -
Aşağıdaki paketleri içe aktararak başlayacağız -
import pandas as pd
import numpy as np
from sklearn import svm, datasets
import matplotlib.pyplot as plt
Şimdi, giriş verilerini yüklememiz gerekiyor -
iris = datasets.load_iris()
Bu veri kümesinden ilk iki özelliği şu şekilde alıyoruz -
X = iris.data[:, :2]
y = iris.target
Ardından, SVM sınırlarını orijinal verilerle aşağıdaki gibi çizeceğiz -
x_min, x_max = X[:, 0].min() - 1, X[:, 0].max() + 1
y_min, y_max = X[:, 1].min() - 1, X[:, 1].max() + 1
h = (x_max / x_min)/100
xx, yy = np.meshgrid(np.arange(x_min, x_max, h),
np.arange(y_min, y_max, h))
X_plot = np.c_[xx.ravel(), yy.ravel()]
Şimdi, düzenlileştirme parametresinin değerini aşağıdaki gibi sağlamamız gerekiyor -
C = 1.0
Ardından, SVM sınıflandırıcı nesnesi aşağıdaki gibi oluşturulabilir -
Svc_classifier = svm.SVC (çekirdek = 'doğrusal', C = C) .fit (X, y)
Z = svc_classifier.predict(X_plot)
Z = Z.reshape(xx.shape)
plt.figure(figsize=(15, 5))
plt.subplot(121)
plt.contourf(xx, yy, Z, cmap=plt.cm.tab10, alpha=0.3)
plt.scatter(X[:, 0], X[:, 1], c=y, cmap=plt.cm.Set1)
plt.xlabel('Sepal length')
plt.ylabel('Sepal width')
plt.xlim(xx.min(), xx.max())
plt.title('Support Vector Classifier with linear kernel')
Çıktı
Text(0.5, 1.0, 'Support Vector Classifier with linear kernel')
SVM sınıflandırıcı oluşturmak için rbf çekirdek, çekirdeği şu şekilde değiştirebiliriz: rbf aşağıdaki gibi -
Svc_classifier = svm.SVC(kernel='rbf', gamma =‘auto’,C=C).fit(X, y)
Z = svc_classifier.predict(X_plot)
Z = Z.reshape(xx.shape)
plt.figure(figsize=(15, 5))
plt.subplot(121)
plt.contourf(xx, yy, Z, cmap=plt.cm.tab10, alpha=0.3)
plt.scatter(X[:, 0], X[:, 1], c=y, cmap=plt.cm.Set1)
plt.xlabel('Sepal length')
plt.ylabel('Sepal width')
plt.xlim(xx.min(), xx.max())
plt.title('Support Vector Classifier with rbf kernel')
Çıktı
Text(0.5, 1.0, 'Support Vector Classifier with rbf kernel')
Gama değerini 'otomatik' olarak koyarız ancak değerini 0 ile 1 arasında da sağlayabilirsiniz.
SVM Sınıflandırıcılarının Artıları ve Eksileri
SVM sınıflandırıcılarının artıları
SVM sınıflandırıcılar büyük bir doğruluk sunar ve yüksek boyutsal alanla iyi çalışır. SVM sınıflandırıcılar temelde eğitim noktalarının bir alt kümesini kullanır, bu nedenle sonuçta çok daha az bellek kullanır.
SVM sınıflandırıcılarının eksileri
Eğitim süreleri yüksektir, bu nedenle pratikte büyük veri kümeleri için uygun değildir. Diğer bir dezavantaj, SVM sınıflandırıcılarının çakışan sınıflarla iyi çalışmamasıdır.