Support Vector Regression (SVR): Python ile Uygulama
Bu yazımızda polinom regresyonda kullandığımız veri seti üzerinde SVR uygulayacağız. Dilimiz Python olacak.
Kütüphaneleri İndirme, Çalışma Diznini Ayarlama ve Veri Setini İndirme
Veriyi buradan indirebilirsiniz.
import numpy as np import matplotlib.pyplot as plt import pandas as pd import os os.chdir('Sizin_Calisma_Dizniniz') dataset = pd.read_csv('PozisyonSeviyeMaas.csv')
Veriyi Anlamak
Yukarıdaki tabloda niteliklerimizi görüyoruz:
Pozisyon: İş Ünvanı. Nitelik türü kategorik.
Seviye: İş ünvanlarını birbiri arasında maaş, astlık-üstlük vb. sıralayan nitelik. Nitelik türü nümerik.
Maas: Her bir pozisyondaki personelin yıllık maaşı. Nitelik türü nümerik.
Bu veri seti ve kuracağımız polinom model ile çözmeye çalışacağımız problem seviyesine göre bir personelin maaşını tahmin etmek olacak. Böylelikle y hedef değişkenimizin Maas, bağımsız değişken Seviye olduğunu çıkarabiliyoruz. Pozisyon seviye ile yakından ilgili bir nitelik ve seviyenin adlandırması gibi bir fonksiyonu olduğu için bu niteliği veri setinden çıkarıyoruz.
Veri seti çok az bir kayıttan (10 adet) oluştuğu için eğitim ve test olarak ayırmıyoruz.
Bağımlı ve Bağımsız Değişkenleri Oluşturmak
X = dataset.iloc[:, 1:2].values y = dataset.iloc[:, 2].values
Değişkenlerin ayrılmış halini yukarıdaki resimde görüyoruz.
SVR ile Modeli Eğitmek
SVR scikit-learn kütüphanesi Support Vector Machine modülünün bir sınıfı olarak tanımlanmış. SVR’da asıl işi yapacak olan SVR sınıfının nesnesi, yani regressör, makine. Modelimizi eğitmek için öncelikle bu sınıftan regressor
adında bir nesne yaratıyoruz. Daha sonra bu nesnenin fit()
metoduna X, y değişkenlerimizi parametre olarak veriyoruz. Böylelikle makinemizi kurmuş oluyoruz.
from sklearn.svm import SVR regressor = SVR(kernel='rbf')
burada kullandığımız kernel parametresinin karşılığı ‘rbf’ zaten varsayılan çekirdek. Bu şu demek: değişkenler arasındaki ilişki durumuna göre bir çekirdek seçilmeli. Makinemizi eğitelim.
regressor.fit(X, y)
Modelimizi de eğittik şimdi bir tahmin yapalım. Seviye 6.5 için bir tahmin yapalım bakalım sonuç ne olacak?
y_pred = regressor.predict(np.array([6.5]).reshape(-1,1)) print(y_pred) array([130001.55760156])
Sonuç 130 bin gibi bir rakam. Gerçek değerlere baktığımızda seviye 6 150 bin seviye 7 200 bin TL idi. 130 6.5 için kötü bir tahmin. Bir de grafiğe bakalım bir yerde yanlışlık mı var?
plt.scatter(X, y, color = 'red') plt.plot(X, regressor.predict(X), color = 'blue') plt.title('SVR Model') plt.xlabel('Pozisyon') plt.ylabel('Maas') plt.show()
Aaa! Bir tuhaflık var grafikte.6.5’u bile iyi tahmin etmiş tesadüf. 9.5’i tahmin etmeye çalışsaydık facia olacakmış. Sorun şu: birçok regresyon sınıfı feature scaling için tedbir alırken az kullanılan SVR sınıfında böyle bir tedbir yok. Dolayısıyla kullanıcı SVR’dan önce feature scaling yapmak durumunda.
Feature Scaling
Feature scaling için scikit-learn
kütüphanesi preprocessing
modülü StandardScaler sınıfını kullanacağız. Bağımsız değişken için sc_X
, bağımlı değişken için sc_y
adında bu sınıftan iki nesne yaratalım:
from sklearn.preprocessing import StandardScaler sc_X = StandardScaler() sc_y = StandardScaler()
Şimdi bu nesneleri ve fit_transform()
metodlarını kullanarak değişkenlerimizi standartlaştıralım.
X = sc_X.fit_transform(X) y = sc_y.fit_transform(y.reshape(-1,1))
Gördüğümüz gibi feature scaling uyguladığımız yeni değişkenlerimiz yukarıda görülüyor. Bu işlemi kabaca km ile mm’yi işleme sokmadan önce ikisini de metreye çevirmek olarak düşünebiliriz. Buraya kadar tüm kodlarımızı toplayıp yeniden çalıştıralım:
# Kütüphaneleri indirme import numpy as np import matplotlib.pyplot as plt import pandas as pd import os # Dizin ayarlama os.chdir("Sizin_Calisma_Dizniniz") # Veri setini indirme, bağımlı&bağımsız değişkenleri ayırma dataset = pd.read_csv('PozisyonSeviyeMaas.csv') X = dataset.iloc[:, 1:2].values y = dataset.iloc[:, 2].values # Feature Scaling from sklearn.preprocessing import StandardScaler sc_X = StandardScaler() sc_y = StandardScaler() X = sc_X.fit_transform(X) y = sc_y.fit_transform(y.reshape(-1,1)) # SVR modeli eğitme from sklearn.svm import SVR regressor = SVR(kernel='rbf') regressor.fit(X, y)
Bu sefer 6.5’i tahmin etmeden önce bir grafik çizelim bakalım model veri ile ne derece uyumlu görünüyor. Hiç alakasız birşey ise boşa tırmalamanın alemi yok.
plt.scatter(X, y, color = 'red') plt.plot(X, regressor.predict(X), color = 'blue') plt.title('SVR Model') plt.xlabel('Pozisyon') plt.ylabel('Maas') plt.show()
İşte bu! Bakın feature scaling sonrası model donunu topladı ve veriyi daha iyi temsil etmeye başladı. Dikkatinizi çekti ise model ilk dokuz seviyemize çok iyi uyum gösterirken 10. seviyedeki (son) poziyonu atladı. Bunun nedeni bu veri noktasını sıra dışı olarak kabul etti. Yani sen bunlar gibi Karamanın koyunu değilsin sonradan çıkmasın oyunu, sen farklısın o sebeple uzak dur benden dedi. Şimdi 6.5’lik derecemizi tekrar tahmin edelim bakalım yeni model ne kadarlık bir maaş öngörüyor.
py_pred = regressor.predict(np.array([6.5]).reshape(-1,1)) print(py_pred) array([0.01158103])
Sonuç: 0.01158103 gibi abuk bir rakam çıkıyor. Sebebini tahmin edeceksiniz hemen: feature scaling. Evet feature scaling yaptığımız için X ve y verileri orijinal halinden çok uzaklaşmıştı. Şimdi bu değerlerle de tahmin yapınca haliyle alakasız sonuçlar elde ettik. Bunun için feature scaling işlemini biraz tersine almamız lazım. Madem X değerlerini sc_X.fit_transform(X)
ile dönüştürdük o halde 6.5 değerine de bunu uygulamalıyız:
py_pred = regressor.predict(sc_X.fit_transform(6.5))
TypeError: Singleton array array(6.5) cannot be considered a valid collection
hatasını aldık. Yani Türkçesi: “kardeş ben parametre olarak tek rakam değil bir dizi alıyorum, tek rakam da olsa bana diziyle gel” demek istiyor. Verelim:
py_pred = regressor.predict(sc_X.fit_transform(np.array([6.5]).reshape(-1,1))) print(py_pred) [-0.41686141]
Sonuç: -0.41686141. Yine olmadı. Peki neden? Çünkü burada elde ettiğimiz tahmin değeri ölçeklenmiş tahmin değeri bunu da orijinal y (maaş) değerine çevirmemiz lazım. Dert etmeyin StandartScaler
sınıfını yazanlar bunu da düşünüp bir metod yazmışlar. Metodumuz inverse_transform()
. Bu metod ölçeklendirilmiş değerleri alıp gerçek değerlere geri dönüştürüyor. Bu metodu da daha önce oluşturduğumuz ve y değerleriyle eğittiğimiz sc_y
nesnesinde çağıracağız. Şimdi yapmamız gereken şey -0.41686141 değerini veya bu değeri veren kodları bu metoda parametre vermek.
py_pred = sc_y.inverse_transform(regressor.predict(sc_X.transform(np.array([[6.5]])))) print(py_pred) [131106.77303274]
Sonuç: 131106.77303274. Evet şimdi oldu. Güzel bir tahmin ortaya koydu. Bravo!