Merhabalar (uzun bir aradan sonra yeniden),
Bugün R üzerinde Neural Network (Sinir Ağları) kullanarak Boston Housing veri seti üzerinde fiyat tahminlerinde bulunacağız. Öncelikle “Yapay Sinir Ağları Nedir” hakkında daha önce yazmış yazılara göz atmanızda fayda var. Linkleri aşağıda paylaşıyorum.
Yapay Sinir Ağları (YSA) Nedir – Bölüm 1 ?
Yapay Sinir Ağları (YSA) Nedir – Bölüm 2 ?
Yapay Sinir Ağları (YSA) Nedir – Bölüm 3 ?
Neler Yapacağız?
- Kullanılacak Olan Kütüphaneleri İndirme ve Yükleme (Install & Load Use Library)
- Dataset Hakkında, İndirme ve Yükleme (Loading the dataset)
- Dataseti Özetleme (Summarizing the dataset)
- Dataseti Görselleştirme (Visualizing the dataset)
- Dataseti Normalleştirme (Normalization of Data)
- Model Kurma ve Tahmin (Making Model & Predictions)
- Değerlendirme (Conclusion)
R Ön Hazırlık
rm(list=ls()) # Sistemdeki değişkenleri temizler. cat("\014") # Konsolu temizler. set.seed(123) # Rasgele sayılar üretilirken kullanılan başlangıç değelerinin aynı olmasını sağlar.
-
Kullanılacak olan Kütüphaneleri İndirme ve Yükleme
# Install & Use Library --------------------------------------------------- if (require("MASS")==FALSE){ install.packages("MASS") library(MASS) } if (require("neuralnet")==FALSE){ install.packages("neuralnet") library(neuralnet) }
-
Dataset Hakkında, İndirme ve Yükleme (Loading the dataset)
Dataset Adı: Housing Values in Suburbs of Boston
Dataset Linki: https://archive.ics.uci.edu/ml/machine-learning-databases/housing/ ve https://www.kaggle.com/c/boston-housing
Yukarıda paylaştığım birinci linkte aşağıda açıklamalarını bahsettiğim dosyalar yer almaktadır. İkinci linkte ise dataset hakkında açıklayıcı bilgiler yer almaktadır.
housing.data: Ham datanın bulunduğu dosyadır
housing.names: Dataya ait metadata bilgisinin yer aldığı dosyadır.
Metadata Nedir: “Verinin verisi” ya da “Veri hakkında veri/bilgi” olarak ifade edilebilir. Kaynak: https://tr.wikipedia.org/wiki/Metadata
Not: Biz bu çalışmada dataseti R içerisinde MASS paketi içerisinde yer aldığı için indirmeye gerek kalmadan kullanacağız.
DataSet <- MASS::Boston # Mass library içerisindeki ‘Housing Values in Suburbs of Boston’ help(Boston) # Daha fazlası için str(DataSet) #Structure of Dataset 'data.frame': 506 obs. of 14 variables: $ crim : num 0.00632 0.02731 0.02729 0.03237 0.06905 ... $ zn : num 18 0 0 0 0 0 12.5 12.5 12.5 12.5 ... $ indus : num 2.31 7.07 7.07 2.18 2.18 2.18 7.87 7.87 7.87 7.87 ... $ chas : int 0 0 0 0 0 0 0 0 0 0 ... $ nox : num 0.538 0.469 0.469 0.458 0.458 0.458 0.524 0.524 0.524 0.524 ... $ rm : num 6.58 6.42 7.18 7 7.15 ... $ age : num 65.2 78.9 61.1 45.8 54.2 58.7 66.6 96.1 100 85.9 ... $ dis : num 4.09 4.97 4.97 6.06 6.06 ... $ rad : int 1 2 2 3 3 3 5 5 5 5 ... $ tax : num 296 242 242 222 222 222 311 311 311 311 ... $ ptratio: num 15.3 17.8 17.8 18.7 18.7 18.7 15.2 15.2 15.2 15.2 ... $ black : num 397 397 393 395 397 ... $ lstat : num 4.98 9.14 4.03 2.94 5.33 ... $ medv : num 24 21.6 34.7 33.4 36.2 28.7 22.9 27.1 16.5 18.9 ...
-
Dataseti Özetleme (Summarizing the dataset)
Dataseti incelediğimizde;
summary(DataSet) #Datasete ait descriptive bilgileri gösterir. crim zn indus chas nox Min. : 0.006320 Min. : 0.00000 Min. : 0.46000 Min. :0.00000000 Min. :0.3850000 1st Qu.: 0.082045 1st Qu.: 0.00000 1st Qu.: 5.19000 1st Qu.:0.00000000 1st Qu.:0.4490000 Median : 0.256510 Median : 0.00000 Median : 9.69000 Median :0.00000000 Median :0.5380000 Mean : 3.613524 Mean : 11.36364 Mean :11.13678 Mean :0.06916996 Mean :0.5546951 3rd Qu.: 3.677083 3rd Qu.: 12.50000 3rd Qu.:18.10000 3rd Qu.:0.00000000 3rd Qu.:0.6240000 Max. :88.976200 Max. :100.00000 Max. :27.74000 Max. :1.00000000 Max. :0.8710000 rm age dis rad tax Min. :3.561000 Min. : 2.9000 Min. : 1.129600 Min. : 1.000000 Min. :187.0000 1st Qu.:5.885500 1st Qu.: 45.0250 1st Qu.: 2.100175 1st Qu.: 4.000000 1st Qu.:279.0000 Median :6.208500 Median : 77.5000 Median : 3.207450 Median : 5.000000 Median :330.0000 Mean :6.284634 Mean : 68.5749 Mean : 3.795043 Mean : 9.549407 Mean :408.2372 3rd Qu.:6.623500 3rd Qu.: 94.0750 3rd Qu.: 5.188425 3rd Qu.:24.000000 3rd Qu.:666.0000 Max. :8.780000 Max. :100.0000 Max. :12.126500 Max. :24.000000 Max. :711.0000 ptratio black lstat medv Min. :12.60000 Min. : 0.3200 Min. : 1.73000 Min. : 5.00000 1st Qu.:17.40000 1st Qu.:375.3775 1st Qu.: 6.95000 1st Qu.:17.02500 Median :19.05000 Median :391.4400 Median :11.36000 Median :21.20000 Mean :18.45553 Mean :356.6740 Mean :12.65306 Mean :22.53281 3rd Qu.:20.20000 3rd Qu.:396.2250 3rd Qu.:16.95500 3rd Qu.:25.00000 Max. :22.00000 Max. :396.9000 Max. :37.97000 Max. :50.00000 dim(DataSet) #Datasete ait boyut bilgisini verir. Burada 506 satır, 14 sütun [1] 506 14 head(DataSet, 5) # Datasete ait ilk 5 satırı gösterir. crim zn indus chas nox rm age dis rad tax ptratio black lstat medv 1 0.00632 18 2.31 0 0.538 6.575 65.2 4.0900 1 296 15.3 396.90 4.98 24.0 2 0.02731 0 7.07 0 0.469 6.421 78.9 4.9671 2 242 17.8 396.90 9.14 21.6 3 0.02729 0 7.07 0 0.469 7.185 61.1 4.9671 2 242 17.8 392.83 4.03 34.7 4 0.03237 0 2.18 0 0.458 6.998 45.8 6.0622 3 222 18.7 394.63 2.94 33.4 5 0.06905 0 2.18 0 0.458 7.147 54.2 6.0622 3 222 18.7 396.90 5.33 36.2 tail(DataSet, 5) # Datasete ait son 5 satırı gösterir. crim zn indus chas nox rm age dis rad tax ptratio black lstat medv 502 0.06263 0 11.93 0 0.573 6.593 69.1 2.4786 1 273 21 391.99 9.67 22.4 503 0.04527 0 11.93 0 0.573 6.120 76.7 2.2875 1 273 21 396.90 9.08 20.6 504 0.06076 0 11.93 0 0.573 6.976 91.0 2.1675 1 273 21 396.90 5.64 23.9 505 0.10959 0 11.93 0 0.573 6.794 89.3 2.3889 1 273 21 393.45 6.48 22.0 506 0.04741 0 11.93 0 0.573 6.030 80.8 2.5050 1 273 21 396.90 7.88 11.9
-
Dataset Görselleştirme (Visualizing the dataset)
hist(DataSet$medv)
- Dataseti Normalleştirme (Normalization of Data)
Değişkenlerin(feature) ortalama ve varyansları birbirinden önemli ölçüde farklı olduğu takdirde ortalama ve varyansı büyük olan değişkenlerin diğer değişkenler üzerinde etkisi fazla olacağından diğerlerinin etkisini azaltacaktır. Bu neden ile bir data üzerinde normalleştirme(standartlaştırma) bu problemin önüne geçecektir. En çok kullanılan normalleştirmeler: Min-Max Normalleştirmesi ve Z-Score Normalleştirmesi’dir. Bu bu çalışmada Min-Max Normalleştirmesi kullanarak dataset üzerinden standartlaştırma yapacağız. Min-Max normalleştirmesi değerleri 0-1 aralığa dönüştürecektir.X* = (Xi – XMİN) / (XMAX – XMİN)
X*: Dönüştürülmüş değerleri,
Xi: Gözlem değelerini,
XMİN: En küçük gözlem değerini,
XMAX: En büyük gözlem değerini belirtir.Normalleştirme işlemi yapabilmemiz için oldukça kullanışlı olan apply() ve türevleri olan fonksiyonun kullanacağız. Veriseti içerisinde satır bazında veya sütun bazında bilgiler elde etmek istediğimizde kullandığımız fonksiyonlardır. Örnek verecek olusak; her satın/her sütun için min, max, mean, range vb. descriptive değerleri ile özel tanımlanan fonksiyonları kullanarak bu fonksiyon içerisinde değerleri elde edilebiliriz. Birbirine çok benzeyen bu 3 fonksiyonun kullanımı oldukça basittir. Aralarındaki fark çıktılarının veri tiplerinin farklı olmasından gelir.apply(): Matris içerisinde satır ve sütun bazında işlemler yapmamızı sağlar.
sapply ve lappy(): Vektör ve Listeler tipleriyle çalışırlar.
sapply() ‘ın çıktısı vektör, lapply() ‘ın çıktısı liste’dir.
Kullanımı:
apply(dataset, 2, mean) # Sütunları[2] ortalamasını verir. 1 parametresi satırları, 2 parametresi sürunları belirtir.
apply(dataset, 2, range) # Sütunları[2] ortalamasını verir. 1 parametresi satırları, 2 parametresi sürunları belirtir.
apply(DataSet, 2, mean) # Dataset içerisindeki sütunlara ait ortalama değerlerini verir. crim zn indus chas nox rm age 3.61352355731 11.36363636364 11.13677865613 0.06916996047 0.55469505929 6.28463438735 68.57490118577 dis rad tax ptratio black lstat medv 3.79504268775 9.54940711462 408.23715415020 18.45553359684 356.67403162055 12.65306324111 22.53280632411 apply(DataSet, 2, range) # Dataset içerisindeki sütunlara ait range(aralık) değerlerini verir. crim zn indus chas nox rm age dis rad tax ptratio black lstat medv [1,] 0.00632 0 0.46 0 0.385 3.561 2.9 1.1296 1 187 12.6 0.32 1.73 5 [2,] 88.97620 100 27.74 1 0.871 8.780 100.0 12.1265 24 711 22.0 396.90 37.97 50
Çalışmaya dönecek olursak;
MaxValue <- apply(DataSet, 2, max) # Dataset içerisindeki sütunlara ait max değerlerini verir. > MaxValue crim zn indus chas nox rm age dis rad tax ptratio black 88.9762 100.0000 27.7400 1.0000 0.8710 8.7800 100.0000 12.1265 24.0000 711.0000 22.0000 396.9000 lstat medv 37.9700 50.0000 MinValue <- apply(DataSet, 2, min) # Dataset içerisindeki sütunlara ait min değerlerini verir. MinValue crim zn indus chas nox rm age dis rad tax ptratio 0.00632 0.00000 0.46000 0.00000 0.38500 3.56100 2.90000 1.12960 1.00000 187.00000 12.60000 black lstat medv 0.32000 1.73000 5.00000 DataSetN <- as.data.frame(scale(DataSet, center = MinValue, scale = MaxValue-MinValue )) #DataSet verisini Min-Max Normalleştirmesi uyguluyoruz.
-
Model Kurma ve Tahmin (Making Model & Predictions)
Bu çalışmada Supervised(öğreticili/danışmalı/eğiticili) bir model (Neural Network) kullanacağımız için önce dataseti Train ve Test olarak iki ayrı parçaya ayırmamız gerekiyor. Burada Train verisi için 400 gözlem, Test verisi için 106 gözlem rastgele alınarak oluşturulacaktır. Literatürde %90 – %10 yada %80 – %20 oldukça yaygın olarak kullanılmaktadır.
ind <- sample(1:nrow(DataSet),400) # 1 ile 506 gözlem içerisinden rastgele 400 gözlem seçilir. TrainDF <- DataSetN[ind,] #Train datası için Dataset içerisindeki rastgele 400 gözlem seçilir. TestDF <- DataSetN[-ind,] #Test datası için Dataset içerisindeki rastgele 106 gözlem seçilir.
Dataset içerisinde 14 adet değişkenimiz (feature) bulunmaktadır. Burada bağımsız değişkenler ile bağımlı değişkeni tahmin etmeye çalışıyoruz. Bu sebeble
AllVars <- colnames(DataSet) PredictVars <- allVars[!allVars%in%"medv"] #PredictVars içerisinde yer alan bağımlı "medv" olan değişkeni çıkarıyoruz. PredictVars [1] "crim" "zn" "indus" "chas" "nox" "rm" "age" "dis" "rad" "tax" [11] "ptratio" "black" "lstat" PredictVars <- paste(PredictVars, collapse = "+") #Bağımsız değişkenler ile Bağımsız Değişkenleri Tahmin edeceğimiz üzere modeli formüle ediyoruz. PredictVars [1] "crim+zn+indus+chas+nox+rm+age+dis+rad+tax+ptratio+black+lstat" ModelFormula <-as.formula(paste("medv~", PredictVars, collapse = "+")) ModelFormula medv ~ crim + zn + indus + chas + nox + rm + age + dis + rad + tax + ptratio + black + lstat
NeuralNetwork modelimini kurmadan önce hatırlamamız gereken Temel Bileşenler var. Bunların belirlenmesi modelin başarısında oldukça belirleyici olduğunu hatırlatmakta fayda var. Eğer yukarıda paylaştığım yazımı okumadıysanız hala geç değil 🙂
Yapay Sinir Ağlarının Temel Bileşenleri
1. Mimari Yapı
2. Öğrenme Algoritması
3. Aktivasyon FonksiyonuModeli oluşturuyoruz ve grafiksel olarak çizdiriyoruz:
NNModel <- neuralnet(formula=ModelFormula, hidden=c(4,2), linear.output=T, data=TrainDF) #Neural Network Modelini GirdiKatmanı, GizliKatman1, GizliKatman2 ve ÇıktıKatmanı olarak oluşturuyoruz. plot(NNModel) #Neural Network Modelini çizdiriyoruz.
Mimari Yapı: Girdi, 1.GizliKatman, 2.GizliKatman ve Çıktı katmanı olmak üzere 4 katmandan oluşmaktadır. 1. Gizli Katmanda 4 nöron, 2. Gizli Katmanda 2 nöron bulunmaktadır.
Öğrenme Algoritması: Backpropagation Algorithm
Aktivasyon Fonksiyonu: Logistic (varsayılan)
PredictValues <- compute(NNModel, TestDF[,1:13]) #NNModel ile TestDF datasını PredictValues <- PredictValues$net.result ActualValues <- (TestDF$medv) Result <- data.frame(Actual=ActualValues, Predict=PredictValues, Diff=ActualValues-PredictValues) head(Result) Actual Predict Diff 6 0.5266666667 0.4434082115 0.08325845513 8 0.4911111111 0.2917075865 0.19940352464 9 0.2555555556 0.2435206581 0.01203489749 10 0.3088888889 0.2910989204 0.01778996848 18 0.2777777778 0.2933875774 -0.01560979964 26 0.1977777778 0.2684711768 -0.07069339904 tail(Result) Actual Predict Diff 486 0.36000000000 0.3995228085 -0.03952280853 490 0.04444444444 0.2208018159 -0.17635737148 495 0.43333333333 0.3165751666 0.11675816677 496 0.40222222222 0.2845141144 0.11770810779 497 0.32666666667 0.2549447216 0.07172194509 505 0.37777777778 0.4250194089 -0.04724163108
Result data frame’inde Actual yani TestDF değerleri(106 Gözlem), Predict yani Neural Network Modeli kurularak elde edilen değerler, ve Actual-Predict arasındaki fark olan Diffrence kolonundan oluşmaktadır. Burada head ve tail ile ilk 6 satır karşılaştırılması gözükmektedir.
ColMean <- apply(Result, 2, mean) #Actual, Predic ve Diff değişkenlerine ait ortalamalar ColMean Actual Predict Diff 0.3866037736 0.4006694639 -0.0140656903
Actual ile Predict kolonlarına ait ortalama değerlerinin (0.386 – 0.400) birbirine oldukça yakın olduğu görülmüştür. Şimdi Mean Square Error (MSE) değerlerini hesaplayıp görelim.
MSE <- sum((PredictValues - ActualValues)^2)/nrow(TestDF) #Mean Square Error MSE [1] 0.009414517716
MSE değeri 0.009 olduğu görülmüştür. Bir başka mimariye sahip Neural Network modeli ile ya da Regresyon gibi başka bir model ile karşılaştırarak model tercihinde bulunabilir. Son olarak
plot(ActualValues, PredictValues, col='blue', main='Actual vs Predicted', pch=1, cex=0.9, type = "p", xlab ="Frequency", ylab="Actual") abline(0,1,col="black")
Orjinden 45 derecelik açı ile geçen kırmızı çizgiye bitişik bir şekilde değerlerin yer aldığı görülmüştür.
-
Değerlendirme (Conclusion)
Bu çalışmada Boston Housing dataseti üzerinde Neural Network modeli kurularak fiyat tahmininde bunulmuştur. Dataset içerisinde 13 bağımsız değişken(feature) ile model kurularak 1 bağımlı(medv) değişken tahmini yapıldı. Neural Network mimari yapısında Girdi Katmanında 13 nöron, 1. Gizli Katmanda 4, 2. Gizli Katmanda 2 ve Çıktı Katmanında 1 nöron bulunmak üzere 13x4x2x1 modeli kurulmuştur. Modelin Mean Square Error (MSE) değerinin 0.009 olduğu görülmüştür.
Peki bundan sonra; Gizli Katman Sayısı ve bu katmanlardaki Nöron Sayısını nasıl belirleyeceğiz? Ben burada tamamen kendi isteğime göre mimari yapıyı oluşturdum. Daha fazla yada daha az da olabilirdi. Mimari yapının modelin başarısını etkileyen 3. önemli temel bileşenden biridir. Bu yazının 2 versiyonunda Gizli Katman Sayısı(1 ile 3 arasında) ve Gizli Katmandaki Nöron Sayısını(1 ile 3) parametrik yapıp en iyi mimari yapısını modelin performans ölçütü olan MSE değeri ile tespit edeceğiz.
Çok kısa süre içerisinde yukarıdaki kodları github üzerinde paylaşıyor olacağım. Konu hakkındaki görüş, öneri ve yorumlarınızı buradan ya da uslumetin@gmail.com üzerinden belirtebilirsiniz. Yeniden görüşmek üzere, selamlar. 🙂