İris Veri Seti Projesi

Bugünkü yazımızda ilk yapay sinir ağları projemizi gerçekleştireceğiz. Şu ana kadar öğrendiğimiz teorik bilgileri pratiğe dökme fırsatı bulacağız. Bu projemizde ünlü bir veri seti olan iris veri setini kullanacağız. Bu veri seti 3 farklı yaprak çeşidi olan setosa, versicolor ve virginica için farklı özellikleri barındırıyor.

Projemize başlamadan önce Kütüphane Kurulumları yazımızda kurduğumuz kütüphanelere ek olarak sklearn kütüphanesi de yüklemeliyiz. Bu kütüphaneyi kullanarak verilerimizi yapay sinir ağlarının işleyebileceği bir forma getiriyoruz. Anaconda Navigator üzerinden veya Anaconda terminali üzerinden conda install -c anaconda sckit-learn komutunu çalıştırarak indirebilirsiniz. Projemizi veri önişleme, yapay sinir ağı modelinin yapısını oluşturma ve modelin eğitimi olacak şekilde 3 bölümde gerçekleştireceğiz.

Veri Önişleme

İlk olarak verilerimizin bulunduğu csv dosyasını https://gist.github.com/netj/8836201 bu link üzerinden indirip zip içerisindeki iris.csv dosyasını çalışma yaptığımız klasörün içine atıyoruz. Artık kod yazmak için hazırız. İlk olarak gerekli kütüphaneleri import ettikten sonra csv dosyamızı pandas kütüphanesi yardımı ile okuyoruz. Aşağıdaki kod bloğunu spyder üzerinde seçip F9 ile çalıştırıyoruz.

import pandas as pd
import numpy as np
from sklearn import preprocessing
from sklearn.model_selection import train_test_split
from keras.models import Sequential
from keras.layers import Dense

# csv dosyamızı okuyoruz.
dataset = pd.read_csv("iris.csv")

Bu kod bloğunu çalıştırdıktan sonra variable explorer kısmında dataset verisinin üstüne çift tıklayarak verimizi inceleyebiliriz.

iris veri seti
Veri Seti

Veri setimizde 150 tane örnek bulunmaktadır. Her bir örneğin çanak yaprağının(sepal) uzunluğu ve genişliği, taç yaprağının(petal) uzunluğu ve genişliği ve hangi sınıfa ait olduğuna dair bilgiler yer almaktadır. Daha sonra veri setinde girdilerimizi(x) ve çıktılarımızı(y) ayırıyoruz. Bu ayırma işlemini iloc ile gerçekleştiriyoruz. iloc ile ayırma yaparken [ , ] virgülün sol kısmı satırları sağ kısmı ise sütunlarımızı ifade ediyor. “:” ile bütün satırları almamız gerektiğini söylüyoruz, “[0,1,2,3]” ile de birinci, ikinci, üçüncü ve dördüncü sütunları almamızı söylüyoruz. Böylelikle girdi değerlerimizi elde etmiş oluyoruz. [:,4] bu gösterim ile de beşinci sütunun hepsini alıyoruz yani çıktı değerlerimizi ayırıyoruz. Aşağıdaki kod bloğunu çalıştırdıktan sonra yine variable explorer üzerinden x ve y değişkenlerini inceleyebilirsiniz.

# girdileri ve çıktıları ayırıyoruz.
x = dataset.iloc[:,[0,1,2,3]]
y = dataset.iloc[:,4]

Görüldüğü gibi çıktılarımız bizim yapay sinir ağımızın işleyebileceği türden bir veri değil. Bu verilerimiz sayısal verilere dönüştürmeliyiz ve çoklu sınıflandırma yapacağımız için one-hot encoded formunda tutmalıyız. Örnek olarak [1,0,0] setosa sınıfını göstermektedir. İlk olarak verimizi sayısal veriye dönüştürmeliyiz. Bu işlemi yaparken sklearn kütüphanesinin preprocessing modülünden LabelEncoder sınıfını kullanıyoruz. Öncelikle bu sınıftan bir obje oluşturuyoruz ve bu objenin fit_transform fonksiyonu ile çıktılarımızı sayısal değerlere dönüştürüyoruz. Aşağıdaki kod bloğunu çalıştırdıktan sonra y değişkenini variable explorer üzerinde inceleyebilirisiniz.

label_encoder = preprocessing.LabelEncoder()
y = label_encoder.fit_transform(y)

y değişkeninin incelediğimizde setosa sınıfının 0, versicolor sınıfın 1 ve virginica sınıfının 2 değerini aldığını görüyoruz. Bu bizim için yeterli bir sonuç değil ek olarak one-hot encoding işlemini de gerçekleştirmeliyiz. Bu sefer de OneHotEncoder sınıfından objemizi oluşturuyoruz ve fit_transform fonksiyonu yardımı ile one-hot encoding işlemini de gerçekleştiriyoruz.

onehot_encoder = preprocessing.OneHotEncoder()
y = onehot_encoder.fit_transform(y[:,np.newaxis]).toarray()

Sonuç olarak çıktı değerlerimizi istediğimiz forma getirmiş oluyoruz.

iris veri seti
One-hot encoded Çıktılar

Bir sonraki adımımız ise girdi değerlerimizi ölçeklendirmek olacak. Ölçeklendirme işlemi ile girdi verilerimizi aynı değer aralıkları arasında sıkıştırıyoruz ve bu işlem bizim modelimizin minimum noktasına ulaşma işlemini hızlandırıyor. Örnek olarak elimizde bir araba veri seti olsun ve arabanın beygir gücü ve ağırlığından arabanın markasını tahmin edelim. Arabaların ağırlık değerleri 1500 kg ve 4000 kg aralığında değer alsın ve beygir gücü ise 50 ile 180 aralığında değer alsın. Aşağıda verilerimizin ve yitim fonksiyonumuzun grafiğini inceleyebilirsiniz.

iris veri seti
Ölçeklendirilmemiş Veri

Grafiği incelediğimizde verimizin düzensiz bir şekilde dağıldığını fark ediyoruz. Burada yitim fonksiyonumuzu geniş bir tabağa benzetebiliriz, biz ise daha çok kase şeklinde düzgün bir yitim fonksiyonu tercih ederiz ki minimum değerine ulaşmak daha kolay olsun. Aşağıdaki ise ölçeklendirilmiş, düzgün veri dağılımlı grafiği inceleyebilirsiniz.

iris veri seti
Ölçeklendirilmiş Veri

Ölçeklendirme işlemini gerçekleştirirken de sklearn kütüphanesinin StandardScaler sınıfından bir obje oluşturuyoruz ve fit_transform fonksiyonu ile ölçeklendirme işlemini gerçekleştiriyoruz.

scaler = preprocessing.StandardScaler()
scaler.fit_transform(x)
iris veri seti
Ölçeklendirilmiş Değerler

Veri önişleme işleminin son adımı olarak hazırladığımız verileri eğitim ve test kümesi olmak üzere ikiye ayıracağız. Bu sayede eğitilmiş olan modelimizin daha önce hiç görmediği test kümelerindeki başarısını değerlendirebileceğiz. Ek olarak eğitim ve test kümelerinin başarı değerlerini karşılaştırarak modelimiz hakkında bazı sonuçlara varabiliriz. Örnek olarak eğitim kümesinde çok iyi başarı sağlayan bir model test kümesinde çok başarısız ise burada aşırı öğrenme(overfitting) olduğuna kanaat getirip bu problemi çözmek üzerine uğraşabiliriz. İlerleyen yazılarımızda bu konulara detaylı bir şekilde değineceğiz. Veri kümesini ayırma işlemini gerçekleştirirken sklearn kütüphanesinin train_test_split fonksiyonundan yaralanıyoruz. Parametre olarak x değerimizi, y değerimizi, test_size olarak 0.3(test kümesi için veri setinin %30′ luk kısmını ayır) değerini ve random_state için ise 2 değerini veriyoruz. Ayırma işlemleri rastgele yapıldığı için random_state parametresi sayesinde her seferinde aynı sonucu alabiliyoruz. Sonuç olarak eğitim kümemizde 105 örnek, test kümemizde ise 45 örnek bulunuyor.

x_egitim, x_test, y_egitim, y_test = train_test_split(x, y, test_size = 0.3, random_state=2)

Yapay Sinir Ağı Modelini Oluşturma

Yapay sinir ağı modelimizi keras kütüphanesinin yardımı ile çok kolay bir şekilde oluşturacağız. Girdilerimizde 4 farklı özellik olduğu için 4 nöronlu bir girdi katmanımız olacak. Gizli katmanımız 8 nörondan oluşacak ve aktivasyon fonksiyonu olarak ReLU kullanacağız. Çıktı katmanımız ise 3 sınıfımız olduğu için 3 nörondan oluşacak ve çoklu sınıflandırma yaptığımız için softmax fonksiyonunu kullanacağız. Aşağıdaki resimde oluşturacağımız modelin yapısını inceleyebilirsiniz.

iris veri seti
Yapay Sinir Ağı Modelinin Yapısı

Öncelikle girdi katmanımızın nöron sayılarını ve çıktı katmanımızın nöron sayılarını belirliyoruz.

girdi_sayisi = x_egitim.shape[1]
sinif_sayisi = y_egitim.shape[1]

Daha sonra modelimizin temelini oluşturacak Sequential sınıfında bir obje üretiyoruz. Katmanlarımızı bu temel üzerinde kuracağız.

model = Sequential()

model.add(Dense(8,input_dim = girdi_sayisi, activation = 'relu'))
model.add(Dense(sinif_sayisi, activation = 'softmax'))

model.summary()

add fonksiyonu ile katmanlarımızı sırası ile ekliyoruz. Girdi katmanımızı eklerken bağlanacağı gizli katmandaki nöronların sayısını, girdi katmanındaki nöronların sayısını, ve gizli katmanda kullanılacak olan aktivasyon fonksiyonunu Dense objesine parametre olarak veriyoruz ve bu Dense obejsini ise add fonksiyonumuza veriyoruz. Girdi ve gizli katanımızı eklediğimize göre çıktı katmanımızı da ekliyoruz. Nöron sayısı olarak sınıf sayısını ve aktivasyon fonksiyonu olarak da softmax değerini veriyoruz. Son olarak ise summary fonksiyonu ile modelimizin özetini çıktı olarak alıyoruz.

iris veri seti
Model Özeti

Modelimizde eğitilecek toplamda 67 adet parametre olduğunu görüyoruz. Bunların 56 tanesi nöronların ağırlık değerleri geri kalan 11 tanesi ise nöronların eşik değerleridir.

Modelin Eğitimi ve Testi

Modelimizin eğitimine başlamadan önce modelimizin kullanacağı yitim fonksiyonunu ve bu yitim fonksiyonunu minimize ederken kullanacağımız optimizasyon tekniğini belirlemeliyiz. Çoklu sınıflandırma yaptığımız için yitim fonksiyonu olarak kategorik çapraz yitim(categorical cross entropy) fonksiyonunu seçiyoruz. Optimizasyon tekniği için ise parçalı gradyan inişi(mini-batch gradient descent) seçiyoruz. Ekstra olarak modelimizin başarısının bir diğer ölçüsü olan doğruluk(accuracy) değerini metrik olarak seçiyoruz. Doğruluk dışında daha farklı değerlerimiz de var bunları ilerleyen yazılarımızda daha detaylı bir şekilde inceleyeceğiz. compile fonksiyonuna bu seçtiğimiz değerleri veriyoruz. Modelimimizin eğitimini ise fit fonksiyonu ile gerçekleştiriyoruz. Fonksiyona parametre olarak eğitim için ayırdığımız x ve y değerlerini veriyoruz. Modelimizi kaç yineleme(epoch) için eğiteceğimizi veriyoruz ve bu değeri 70 olarak seçiyoruz. Son olarak ise bathc_size yani modelin eğitim sırasında kaç örneği işledikten sonra optimizasyon yapacağının değerini veriyoruz. Bunu ise 16 olarak seçtik.

model.compile(optimizer='sgd',loss="categorical_crossentropy",metrics=['accuracy'])
model.fit(x_egitim, y_egitim, batch_size=16, epochs=70)

Bu kod bloğunu çalıştırdıktan sonra eğitim işlemimiz başlıyor. Modelin zaman ile gelişimini konsolda çıktı olarak takip edebilirsiniz. İlk yinelemede modelimizin yitimi değeri 1.2774 ve eğitim kümesindeki doğruluk değeri 0.20. Gayet başarısız bir model. 70. yinelemede ise modelimizin yitim değeri 0.4834′ e kadar düşmüş ve doğruluk değeri ise 0.9238′ e kadar çıkmış. %92′ lik bir doğruluk değeri ile modelimiz eğitim kümesinde gayet başarılı.

iris veri seti
Eğitim Süreci

Modelimizin daha önce hiç görmediği veriler üzerinde de başarılı bir performans ortaya koyması gerekir. Bunun için ise test verilerimizi ayırmıştık. Son olarak modelimizin test kümesinde başarısını ölçebiliriz.

sonuc = model.evaluate(x_test, y_test, verbose=0)
print("Test yitim değeri : ", sonuc[0])
print("Test doğruluk değeri : ",sonuc[1])

Modelimiz test verisinde de %923′ lük bir doğruluk oranı ile gayet başarılı.

iris veri seti
Test Sonuçları

İlk yapay sinir ağları projemizi başarılı bir şekilde tamamladık. Yazdığımız kodu tek parça halinde aşağıda bulabilirsiniz.

import pandas as pd
import numpy as np
from sklearn import preprocessing
from sklearn.model_selection import train_test_split
from keras.models import Sequential
from keras.layers import Dense

# csv dosyamızı okuyoruz.
dataset = pd.read_csv("iris_veriseti.csv")

# girdileri ve çıktıları ayırıyoruz.
x = dataset.iloc[:,[0,1,2,3]]
y = dataset.iloc[:,4]

# çıktılarımızı sayısal değerlere dönüştüryoruz.

label_encoder = preprocessing.LabelEncoder()
y = label_encoder.fit_transform(y)

# one-hot encoding işlemini gerekleştiriyoruz.
onehot_encoder = preprocessing.OneHotEncoder()
y = onehot_encoder.fit_transform(y[:,np.newaxis]).toarray()


# ölçeklendirme işlmeni gerçekleştiriyoruz.
scaler = preprocessing.StandardScaler()
x = scaler.fit_transform(x)

# eğitim ve test kümelerine ayırma işlemi
x_egitim, x_test, y_egitim, y_test = train_test_split(x, y, test_size = 0.3, random_state=2)


girdi_sayisi = x_egitim.shape[1]
sinif_sayisi = y_egitim.shape[1]

# modelimizi oluşturuyoruz. 
model = Sequential()

model.add(Dense(8,input_dim = girdi_sayisi, activation = 'relu'))
model.add(Dense(sinif_sayisi, activation = 'softmax'))

model.summary()


# eğitimi gerçekleştiriyoruz.
model.compile(optimizer='sgd',loss="categorical_crossentropy",metrics=['accuracy'])
model.fit(x_egitim, y_egitim, batch_size=16, epochs=70)


# test işlemi
sonuc = model.evaluate(x_test, y_test, verbose=0)
print("Test yitim değeri : ", sonuc[0])
print("Test doğruluk değeri : ",sonuc[1])