Çalışma 1: Doğrusal Bağlanım

Bu çalışmada, çeşitli araç modellerinin verilerini kullanarak, motor gücü ile yakıt sarfiyatı arasındaki ilişkiyi yakalayan bir model kuracağız.

In [0]:
%matplotlib inline
import numpy as np
import pandas as pd
import matplotlib.pyplot as plt

Verimiz Auto.csv isimli bir dosyada CSV formatında GitHub Gist'te kayıtlı halde.

pandas kütüphanesindeki fonksiyonlarla bu dosyayı internet üzerinden yükleyebiliriz.

In [0]:
data_url = "https://gist.githubusercontent.com/mkozturk/34aefae02254b610184d1e4f26c8caf9/raw/d415f48a5e206166b621dca385a5b339b31ded75/Auto.csv"
data = pd.read_csv(data_url,sep=",", usecols=(0,3), na_values="?").dropna()
data.head()

Grafiğini çizelim

In [0]:
hp = data["horsepower"].values
mpg = data["mpg"].values
plt.scatter(hp,mpg)

Verinin düz bir çizgiye uymadığı belli, ama biz yine de deneyelim.

In [0]:
from sklearn.linear_model import LinearRegression
from sklearn.metrics import r2_score

linmodel = LinearRegression()
linmodel.fit(hp.reshape(-1,1), mpg)

r2_score(mpg, linmodel.predict(hp.reshape(-1,1)))

Modelden elde ettiğimiz eğriyi orijinal veriyle beraber çizelim.

In [0]:
x_fit = np.linspace(0,250)
y_fit = linmodel.intercept_ + linmodel.coef_[0]*x_fit
plt.plot(x_fit, y_fit,"r")
plt.scatter(hp, mpg, alpha=0.5)
plt.xlabel("horsepower")
plt.ylabel("mpg");

Polinom bağlanımı

Düz bir çizginin veriye iyi uymadığı belli. Bunun yerine, ikinci derece bir polinom modeli varsayalım. $$\mathrm{mpg} = \beta_0 + \beta_1\cdot\mathrm{hp} + \beta_2 \cdot \mathrm{hp}^2$$

Bunun için $\mathrm{hp}$ ve $\mathrm{hp}^2$ değerlerini içeren iki sütunlu bir matris kurmalıyız.

In [0]:
deg2model = LinearRegression()
deg2model.fit(np.c_[hp, hp**2], mpg)

r2_score(mpg, deg2model.predict(np.c_[hp, hp**2]))

Yine oluşturulan model eğrisiyle verinin grafiğini çizelim.

In [0]:
x_fit = np.linspace(0,250)
y_fit = deg2model.intercept_ + deg2model.coef_[0]*x_fit + deg2model.coef_[1]*x_fit**2
plt.plot(x_fit, y_fit, "r")
plt.scatter(hp, mpg, alpha=0.5)
plt.xlabel("horsepower")
plt.ylabel("mpg");

İkinci derece polinom daha iyi uyuyor. Üçüncü derece daha mı iyi uyar? Dördüncü derece? Onbeşinci derece?

Her yeni kuvvet derecesi için veri matrisine yeni bir sütun eklememiz gerekir. Bu eklemeyi yukarıdaki gibi de yapabiliriz; ama scikit-learn bize daha zahmetsiz bir yol sunuyor:

In [0]:
from sklearn.preprocessing import PolynomialFeatures

derece = 2
poly = PolynomialFeatures(degree = derece, include_bias=False)
X = poly.fit_transform(hp.reshape(-1,1))
X[:5,:] # ilk beş satırı göster
In [0]:
linreg = LinearRegression()
linreg.fit(X, mpg)
print("R^2 =", r2_score(mpg, linreg.predict(X)))
print("Sabit parametre =", linreg.intercept_)
print("Katsayılar =", linreg.coef_)

Çalışma

Polinom derecesi olarak 3-9 kullanarak modeli yedi kere daha tekrar eğitin. RMSE değeri en yüksek olan modelin derecesi kaç?

Kod satırlarını kopyalayıp yeni bir hücreye yapıştırabilirsiniz, veya yukarıdaki hücreleri, derece değerini değiştirerek tekrar tekrar çalıştırabilirsiniz.


Çözüm

In [0]:
for derece in range(3,10):
    poly = PolynomialFeatures(degree = derece, include_bias=False)
    X = poly.fit_transform(hp.reshape(-1,1))
    linreg.fit(X, mpg)
    print("derece =",derece,"R^2 =", r2_score(mpg, linreg.predict(X)))

Altıncı derece polinomdaki RMSE değeri diğerlerinden az daha yüksek. Bu polinomu veriyle beraber çizelim.

In [0]:
linreg = LinearRegression()
poly = PolynomialFeatures(degree=6, include_bias=False)
X = poly.fit_transform(hp.reshape(-1,1))

linreg.fit(X, mpg)

x_fit = np.linspace(0,250)
y_fit = linreg.intercept_
for i,coef in enumerate(linreg.coef_):
    y_fit += coef*x_fit**(i+1)

plt.scatter(hp, mpg, alpha=0.5)
plt.plot(x_fit, y_fit, "r")
plt.xlabel("horsepower")
plt.ylabel("mpg")
plt.ylim([10,50]);

Kırmızı çizgi veriye gayet iyi (fazla iyi!) uysa da, düşük beygir gücünde verimsizlik öngörme gibi bir garipliği var. Ayrıca, modelin henüz görmediğimiz verilerdeki performansının nasıl olacağını göz önüne almadık. Modelimiz aşırı öğrenmiş olabilir.

Eğitme ve sınama kümeleri

Aşırı öğrenmeden kaçınmak için, önce orijinal veri kümesinden bazı noktaları rastgele olarak kenara ayırırız. Bu test kümesi en sonunda modelleri sınamak için kullanılacak.

In [0]:
from sklearn.model_selection import train_test_split
In [0]:
derece = 6
poly = PolynomialFeatures(degree = derece, include_bias=False)
X = poly.fit_transform(hp.reshape(-1,1))

X_train, X_test, y_train, y_test = train_test_split(X, mpg, random_state=11)

linreg = LinearRegression()
linreg.fit(X_train, y_train) # Eğitim kümesiyle eğit
print("eğitim R^2 =", r2_score(y_train, linreg.predict(X_train)))
print("sınama R^2 =", r2_score(y_test, linreg.predict(X_test))) # Sınama 

Altıncı derece polinom modelin test kümesi başarısı, eğitim kümesi başarısından düşük. Bu, aşırı öğrenmeye tekabül ediyor.

Eğitme-sınama kümeleri rastgele belirlendiği için, şansa bağlı olarak bu sayılar değişecektir (random_state parametre değeriyle oynayarak yeni değerler bulabilirsiniz). Bu yüzden çapraz doğrulama (cross validation) yöntemleri kullanmak daha sağlam bir yaklaşımdır, ama buradaki zamanımız bu ayrıntıya girmeye elvermiyor.

Çalışma

Eğitim-sınama kümeleri ayırarak 2-9 arasındaki derecelerde polinom modelleri eğitin. Her polinom derecesi için eğitim kümesi ve test kümesi başarı puanlarını ayrı ayrı hesaplayın. Bu puanlara bakarak, hangi modeli kullanmayı tercih edersiniz?


Çözüm

In [0]:
for derece in range(2,10):
    poly = PolynomialFeatures(degree = derece, include_bias=False)
    X = poly.fit_transform(hp.reshape(-1,1))

    X_train, X_test, y_train, y_test = train_test_split(X, mpg, random_state=11)

    linreg = LinearRegression()
    linreg.fit(X_train, y_train) # Eğitim kümesiyle eğit
    print("derece = {}, eğitim R^2 = {:.3f}, sınama R^2 = {:.3f}".format(
          derece,
          r2_score(y_train, linreg.predict(X_train)),
          r2_score(y_test, linreg.predict(X_test)))
         )

Çalışma 2: Sınıflandırma

Bu kısımda bir sınıflandırma algoritması eğiteceğiz. Klasik "iris" (süsen) veri kümesini ve k-NN algoritmasını kullanacağız.

Bu veri kümesinin yapısını görmek için seaborn kütüphanesinin pairplot fonksiyonunu kullanabiliriz.

In [0]:
%matplotlib inline
import numpy as np
import pandas as pd
import matplotlib.pyplot as plt
In [0]:
import seaborn as sns
iris = sns.load_dataset("iris")
sns.pairplot(iris, hue="species")
In [0]:
iris.head()

Aynı veri kümesi scikit-learn paketinde de mevcut. Oradan yükleyip eğitim ve sınama kümeleri hazırlayalım.

In [0]:
from sklearn.datasets import load_iris
iris = load_iris()

from sklearn.model_selection import train_test_split
X_train, X_test, y_train, y_test = train_test_split(iris["data"], iris["target"], random_state=121324)

En yakın üç komşuyla kNN modeli oluşturalım ve eğitim kümesiyle eğitelim.

In [0]:
from sklearn.neighbors import KNeighborsClassifier
knn = KNeighborsClassifier(n_neighbors = 3)
knn.fit(X_train, y_train);

Sınama kümesini kullanarak tahmin yapalım.

In [0]:
knn.predict(X_test)

Gerçek sonuçlarla karşılaştırarak, sınama kümesindeki başarı oranını çıkaralım.

In [0]:
np.mean(knn.predict(X_test)==y_test)

Eğitim kümesindeki başarı oranı:

In [0]:
np.mean(knn.predict(X_train)==y_train)

Çalışma

Veri kümesini eğitim ve sınama kümelerine ayırın. k-NN algoritmasını 1-10 arasında sayıda komşular kullanarak eğitin. Her model (komşu sayısı) için eğitim kümesi başarı oranını ve sınama kümesi başarı oranını kaydedin. Kaç komşu kullanmak sizce en uygundur?


Çözüm

In [0]:
train_scores = []
test_scores = []
X_train, X_test, y_train, y_test = train_test_split(iris["data"], iris["target"], random_state=76845)
for k in range(1,20):
    knn = KNeighborsClassifier(n_neighbors = k)
    knn.fit(X_train, y_train)
    train_scores.append( knn.score(X_train, y_train))
    test_scores.append( knn.score(X_test, y_test))

plt.plot(range(1,20), train_scores, range(1,20),test_scores)
plt.legend(["Training","Testing"])
plt.ylabel("Accuracy score")
plt.xlabel("k");