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.
%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.
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
hp = data["horsepower"].values
mpg = data["mpg"].values
plt.scatter(hp,mpg)
Verinin düz bir çizgiye uymadığı belli, ama biz yine de deneyelim.
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.
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");
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.
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.
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:
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
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_)
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.
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.
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.
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.
from sklearn.model_selection import train_test_split
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.
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?
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)))
)
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.
%matplotlib inline
import numpy as np
import pandas as pd
import matplotlib.pyplot as plt
import seaborn as sns
iris = sns.load_dataset("iris")
sns.pairplot(iris, hue="species")
iris.head()
Aynı veri kümesi scikit-learn
paketinde de mevcut. Oradan yükleyip eğitim ve sınama kümeleri hazırlayalım.
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.
from sklearn.neighbors import KNeighborsClassifier
knn = KNeighborsClassifier(n_neighbors = 3)
knn.fit(X_train, y_train);
Sınama kümesini kullanarak tahmin yapalım.
knn.predict(X_test)
Gerçek sonuçlarla karşılaştırarak, sınama kümesindeki başarı oranını çıkaralım.
np.mean(knn.predict(X_test)==y_test)
Eğitim kümesindeki başarı oranı:
np.mean(knn.predict(X_train)==y_train)
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?
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");