Bir önceki bölümde Makine Öğrenmesinde hipotez, parametreler, öğrenme algoritması, maliyet fonksiyonu ve amaç kavramlarından bahsetmiştik. Kare hata fonksiyonunu maliyet fonksiyonumuzda kullanarak, lineer regresyon problemimizin hipotezini hesaplamıştık. Hatırlamak isterseniz:
Kaldığımız yerden devam edelim. Hipotezimizin basitleştirmeden önceki haline bir bakalım.
Hatırlarsanız, Makine Öğrenmesinde asıl yapmak istediğimiz, amacımız, verilere en uygun eğriyi bulmaktır. Verilerin bir dağılım grafiğini çizdiğimizde, veriler eğer düz bir çizgiye düşüyorsa, yukarıdaki hipotezi kullanabiliriz, çünkü hipotez fonksiyonumuz düz bir çizgiyi tanımlar, doğru denklemidir. Bunu biraz daha net anlayalım. değerlerini değiştirerek düzlem üzerine çizebileceğimiz sonsuz sayıda düz çizgi vardır. Ancak, dağılım grafiğimizde verilerin konumuna baktığımızda, verilerimize en iyi uyabilecek yalnızca bir düz çizgi vardır ve şimdi yapmak istediğimiz bu en iyi uyan çizgiyi çizebilmektir.
Maliyet fonksiyonu (J) bizim istediğimiz bu amaca algoritmik olarak hizmet eder. Eğer parametrelerinin doğru hipotezden çok uzakta olduğunu bulursak bize çok büyük bir maliyet verir. Ancak, doğru bir hipotezin maliyeti çok düşüktür. Bunu genelde,
‘ların maliyet fonksiyonunu en aza indirgeyerek yaparız.
Şimdi konuyu biraz daha rahat anlayabilmek için elimizdeki veri setine bir göz atalım.
Evin Büyüklüğü (metrekare) |
Evin Fiyatı (TL) |
100 |
150000 |
130 |
155000 |
170 |
200000 |
200 |
206000 |
235 |
340000 |
245 |
225000 |
280 |
250000 |
300 |
350000 |
345 |
250000 |
350 |
370000 |
400 |
450000 |
420 |
380000 |
450 |
560000 |
460 |
500000 |
500 |
550000 |
540 |
580000 |
540 |
660000 |
600 |
650000 |
Dağılım grafiğinde verilerimizi incelersek:
Eğer tetaları 800, 6000 olarak seçseydik, hipotezimiz şöyle olacaktı,
Bu hipotezin doğrusu da yandaki gibi olacaktı. Rastgele seçtiğimiz teta değerlerinin verilerimize mükemmel uymadığını görüyoruz.
Bunları zaten biliyoruz ancak sık sık tekrar etmenin bir sakıncası yok, tekrar hatırlamak gerekirse, hipotez (h) öğrenmeye çalıştığımız modeldir. Hipotez fonksiyonunu “öğrenmek” için θ’ları bulmamız gerekir.
Hatırlarsanız tek bir teta ile gerçekleştirdiğimiz bir önceki örnekte maliyet fonksiyonu ile teta arasında şöyle bir ilişki olduğunu görmüştük:
Ancak şu an elimizde iki tane parametre var, ve tahmin edersiniz ki bunların maliyet fonksiyonu ile aralarındaki ilişki tek bir parametreye sahip hipotezdeki gibi basit olmayacaktır. Burada daha rahat görselleştirebilmemiz için devreye kontur grafikleri giriyor. Kontur grafiğini bir önceki grafiğin üç boyutlu hali gibi düşünebilirsiniz. Tabi bu grafiği isterseniz iki boyutlu uzayda da temsil edebilirsiniz.Aşağıda bu grafiğe ait örnekler yer alıyor.
Bundan sonra yapacaklarımızı daha iyi anlamak için aşağıdaki görseli dikkatlice inceleyin.
Şimdi yukarıdaki görseli birlikte yorumlayalım.
- Sağ tarafta kontur grafiğinin iki boyutlu düzlemde temsili verilmiş. Ortaya doğru giderek küçülen halkaya doğru baktığımızda
değerleri ile hesaplanan maliyet fonksiyonunun değerinin 0’a doğru yaklaştığını görüyoruz.
- Maliyet fonksiyonunun sıfıra yaklaşması bize en iyi hipotezi verecektir. En iyi hipotez ise veri setimize uyan en iyi eğriyi verir.
- Sağ tarafta
değerlerini kırmızı ile seçiyor ve sıfıra doğru yaklaştırıyor.
- Bu sırada sol tarafta verilen verilerimizin dağılım grafiğine baktığımızda,
- Seçilen tetalara göre hesaplanan hipotezin, maliyet fonksiyonunu minimize ettiğimiz anda verilere en iyi uyum sağladığını görebiliyoruz.
Bundan sonra ne yapacağımızı kısaca anlamışsınızdır. Amaç bir önceki örnekte olduğu gibi ve az önceki görselde gözüktüğü gibi maliyet fonksiyonumuzu minimize eden en iyi değerlerini seçerek hipotezimizi oluşturacağız.
Burada Dereceli Azalma’yı kullanacağız. Dereceli azalmanın o meşhur karışık tanımlamalarından önce basitçe anlamaya çalışalım.
Gradient Descent ya da türkçe olarak Dereceli Azalma aslında bir algoritmadır. Sadece makine öğrenmesi problemlerinde değil, bir çok optimizasyon probleminde de kullanılır. Bizim makine öğrenmesinde kullanmamızın da aslında en temel sebebi optimizasyondur. Sanırım artık ezberlediniz ancak maliyet fonksiyonunu en aza indirmek de bir optimizasyon problemidir.
- Dereceli Azalma Algoritması : Bir fonksiyonun minimumunu bulmamızı sağlar. Fonksiyonun minimumunu bulmak için birinci dereceden yinelemeli bir optimizasyon algoritmasıdır.
Biz dereceli azalmayı maliyet fonksiyonunu en aza indirgemek için bize gereken değerlerini bulmak için kullanacağız.
- Dereceli azalmada kullanacağımız fonksiyon :
- Amacımız :
Dereceli Azalma Algoritmasının Basitçe Çalışma Şekli:
‘lara Herhangi Bir Değer Verin ( teta değerlerine başlangıç değeri olarak 0 verebiliriz. )
değerini minimuma indirgeyene kadar
değerlerini değiştirin.
Aşağıda maliyet fonksiyonunun kontur grafiğine baktığımızda iki ayrı minimum noktası görüyoruz. Başlangıç noktası seçtiğimiz yere göre farklı minimumlara gittiğine dikkat edin.
Dereceli Azalmanın algoritmasına bakalım.
Bildiklerimizden başlayalım. fonksiyonunun maliyet fonksiyonu olduğunu biliyoruz.
nin de sırayla j=0 ve j=1 için
değerlerini bize vereceğini biliyoruz.
: Öğrenme Oranı ( bir katsayı )
: Maliyet Fonksiyonunun türevi
=
: Parametreler (tetalar)
: eşzamanlı olarak güncellemek (
‘ları)
Eşzamanlı Olarak Tetaları güncellemek şu demek:
Yani, önce tetaları bulacağız, sonra teta değişkenine atayacağız. Fark ettiyseniz, maliyet fonksiyonunun türevini aldığımız kısımda her iki tetayı da kullanıyoruz. Önce‘ı bulup
‘a atarsak bir sonraki adımda
‘i hesaplarken kullanacağımız
değerini değiştirmiş olduğumuz halde görürüz.
Yanlış Şekilde Tetaları Güncellemek de aşağıdaki şekilde olur:
Şimdi öğrenme oranından, biraz bahsedelim.
- Öğrenme oranı, zamanın azalan bir fonksiyonudur. Bu parametre, optimum ağırlığa doğru ne kadar hızlı veya yavaş hareket edeceğimizi belirler.
çok büyükse optimal çözümü atlayacağız. Çok küçükse, en iyi değerleri birleştirmek için çok fazla yinelemeye ihtiyacımız olacaktır. Bu yüzden iyi bir
kullanmak çok önemlidir.
Görerek daha iyi anlarız. O yüzden dereceli azalma ile öğrenme oranı arasındaki ilişkiye bakalım. Sol tarafta alfayı çok küçük seçersek, sağ tarafta da alfayı çok büyük seçersek maliyeti nasıl minimize ettiğimize bakın.
Dereceli azalma(Gradyan inişi), öğrenme oranı α sabit olsa bile, yerel bir minimuma yaklaşabilir. Yerel bir minimuma yaklaştığımızda dereceli azalma otomatik olarak daha küçük adımlar atacaktır. Yani, zamanla α’nın azaltılmasına gerek yoktur. Yerel minimuma yaklaştıkça aslında grafiğimiz şöyle olacaktır:
Lineer Regresyonun amacı maliyet fonksiyonunu en aza indirmektir.
Hipotezi şöyle yazabiliriz:
Buradan sonra matematik işlemlerini yazdığımız program ile gerçekleştireceğiz.
Programımızda AndrewNG’nin hazırladığı Coursera’daki Machine Learning dersindeki ex1data1.txt veri setini kullanarak yararlanacağız.
veriseti, ex1data1.txt
6.1101,17.592 5.5277,9.1302 8.5186,13.662 7.0032,11.854 5.8598,6.8233 8.3829,11.886 7.4764,4.3483 8.5781,12 6.4862,6.5987 5.0546,3.8166 5.7107,3.2522 14.164,15.505 5.734,3.1551 8.4084,7.2258 5.6407,0.71618 5.3794,3.5129 6.3654,5.3048 5.1301,0.56077 6.4296,3.6518 7.0708,5.3893 6.1891,3.1386 20.27,21.767 5.4901,4.263 6.3261,5.1875 5.5649,3.0825 18.945,22.638 12.828,13.501 10.957,7.0467 13.176,14.692 22.203,24.147 5.2524,-1.22 6.5894,5.9966 9.2482,12.134 5.8918,1.8495 8.2111,6.5426 7.9334,4.5623 8.0959,4.1164 5.6063,3.3928 12.836,10.117 6.3534,5.4974 5.4069,0.55657 6.8825,3.9115 11.708,5.3854 5.7737,2.4406 7.8247,6.7318 7.0931,1.0463 5.0702,5.1337 5.8014,1.844 11.7,8.0043 5.5416,1.0179 7.5402,6.7504 5.3077,1.8396 7.4239,4.2885 7.6031,4.9981 6.3328,1.4233 6.3589,-1.4211 6.2742,2.4756 5.6397,4.6042 9.3102,3.9624 9.4536,5.4141 8.8254,5.1694 5.1793,-0.74279 21.279,17.929 14.908,12.054 18.959,17.054 7.2182,4.8852 8.2951,5.7442 10.236,7.7754 5.4994,1.0173 20.341,20.992 10.136,6.6799 7.3345,4.0259 6.0062,1.2784 7.2259,3.3411 5.0269,-2.6807 6.5479,0.29678 7.5386,3.8845 5.0365,5.7014 10.274,6.7526 5.1077,2.0576 5.7292,0.47953 5.1884,0.20421 6.3557,0.67861 9.7687,7.5435 6.5159,5.3436 8.5172,4.2415 9.1802,6.7981 6.002,0.92695 5.5204,0.152 5.0594,2.8214 5.7077,1.8451 7.6366,4.2959 5.8707,7.2029 5.3054,1.9869 8.2934,0.14454 13.394,9.0551 5.4369,0.61705
Programı Bana Hemen Ver !
calistir.py
# coding=utf-8 """ Main Calistir """ from termcolor import colored from grafik_ciz import dagilim_grafigi, hipotez_grafigi, maliyet_devir_grafigi, maliyet_fonksiyonu_grafikleri from dereceli_azalma import dereceli_azalma import pandas as pd import numpy as np u""" 1- Veri Setinin Yuklenmesi """ print colored('1. Veri Seti Yukleniyor...', 'blue') veri_seti = pd.read_csv('ex1data1.txt', header=None, names=['X', 'Y']) dagilim_grafigi(veri_seti) u""" 2- Kesme Degerinin Eklenmesi""" print colored('2. Kesme Degeri Ekleniyor...', 'blue') veri_seti.insert(0, 'Kesme Degeri', 1) kesme_degeri_kolonu = veri_seti.shape[1] X = veri_seti.iloc[:, 0:kesme_degeri_kolonu - 1] y = veri_seti.iloc[:, kesme_degeri_kolonu - 1:kesme_degeri_kolonu] X = np.matrix(X.values) y = np.matrix(y.values) u""" 3- Ogrenme Orani ve Devir Sayisinin Ayarlanmasi""" print colored('3- Ogrenme Orani ve Devir Sayisi Ayarlaniyor ...', 'blue') alpha = 0.0001 toplam_devir = 1000 teta = np.matrix(np.array([0, 0])) print colored(('Devir Sayisi ', toplam_devir), 'green') print colored(('Alfa ', alpha), 'green') u""" 4- Dereceli Azalmanin Hesaplanmasi""" print colored('4- Dereceli Azalma Hesaplaniyor ...', 'blue') teta, maliyet = dereceli_azalma(X, y, teta, alpha, toplam_devir) u""" 5- Sonuc""" print colored('5- [Sonuc]: Grafikler ...', 'blue') print colored(('Hesaplanan Teta ', teta), 'green') maliyet_devir_grafigi(toplam_devir, maliyet) hipotez_grafigi(veri_seti['X'], veri_seti['Y'], teta) maliyet_fonksiyonu_grafikleri(X, y, teta) print colored('[BILGI] : Program Basari ile Sonlandi.', 'blue')
dereceli_azalma.py
# coding=utf-8 """ Gradient Descent Dereceli Azalma """ import numpy as np from maliyeti_hesapla import maliyet_hesapla def dereceli_azalma(x, y, theta, alpha, devir_sayisi): """ :param x: Ongorucu Degisken :param y: Hedef Degisken :param theta: Parametreler :param alpha: Ogrenme Orani :param devir_sayisi: Iterasyon Sayisi :return: theta: bulunan parametreler ve maliyet """ yeni_theta = np.matrix(np.zeros(theta.shape)) parametreler = int(theta.ravel().shape[1]) maliyet_J = np.zeros(shape=(devir_sayisi, 1)) for i in range(devir_sayisi): hata = (x * theta.T) - y for j in range(parametreler): term = np.multiply(hata, x[:, j]) ara_islem = (np.divide(alpha, len(x)) * np.sum(term)) yeni_theta[0, j] = np.subtract(theta[0, j], ara_islem) theta = yeni_theta maliyet_J[i, 0] = maliyet_hesapla(x, y, theta) return theta, maliyet_J
maliyeti_hesapla.py
# coding=utf-8 """ Compute Cost Function Maliyet Fonksiyonunu Hesapla """ import numpy as np def maliyet_hesapla(x, y, theta): """ :param x: Ongorucu Degisken :param y: Hedef Degisken :param theta: parametre :return: maliyet """ m = len(x) toplamin_acilimi = np.power(((x * theta.T) - y), 2) maliyet = np.sum(toplamin_acilimi) / (2 * m) return maliyet
ozellik_normalizasyonu.py
# coding=utf-8 """ Feature Normalization Ozellik Normalizasyonu """ import numpy as np def normalize_et(x): """ :param x: Normalizasyon Yapilacak Veriler, numpy matrisi olarak :return: x_normalize: X'in normalizasyon Sonucu, ortalama ve standart sapma """ x_normalize = x ortalama = np.mean(x) standart_sapma = np.std(x) x_normalize = (x_normalize - ortalama) / standart_sapma return x_normalize, ortalama, standart_sapma
grafik_ciz.py
# coding=utf-8 """ Plotting Data Veri Setinin Grafiginin Cizilmesi""" import numpy as np import matplotlib.pyplot as plt from matplotlib import cm from matplotlib.colors import LogNorm def dagilim_grafigi(veri_seti): """ :param veri_seti: Dagilim Grafiginin Yapilacagi Veri Seti """ x = np.asarray(veri_seti['X']) y = np.asarray(veri_seti['Y']) plt.figure() plt.scatter(x, y, c="magenta") plt.xlabel('X') plt.ylabel('Y') plt.title('Dagilim Grafigi') plt.show() def hipotez_grafigi(x, y, theta): """ :param x: Ongorucu Degisken :param y: Hedef Degisken :param theta: Parametreler """ agirliklar = np.asarray(theta) hipotez = x * agirliklar[0][1] + agirliklar[0][0] plt.figure() plt.scatter(x, y, c="magenta") plt.plot(x, hipotez, c='blue') plt.title("Hipotez Egrisi") plt.xlabel('X') plt.ylabel('Y') plt.show() def maliyet_devir_grafigi(toplam_devir, maliyet): """ :param toplam_devir: Toplam Devir Sayisi :param maliyet: Maliyet """ plt.xlabel("Devir") plt.ylabel("Maliyet Fonksiyonu") plt.plot(np.arange(toplam_devir), maliyet, 'blue') plt.show() def maliyet_fonksiyonu_grafikleri(x, y, teta): """ :param x:Ongorucu Degisken :param y:Hedef Degisken :param teta: """ theta0_vals = np.linspace(-10, 10, 100) theta1_vals = np.linspace(-1, 4, 100) J_vals = np.zeros([len(theta0_vals), len(theta1_vals)]) for i in range(1, len(theta0_vals)): for j in range(1, len(theta1_vals)): t = [theta0_vals[i], theta1_vals[j]] J_vals[i, j] = np.sum(np.power((np.dot(x, t) - y), 2)) / (2 * len(x)) J_vals = J_vals.T teta = np.asarray(teta) fig = plt.figure(1) from mpl_toolkits.mplot3d import Axes3D ax1 = fig.add_subplot(1, 2, 1, projection='3d') ax1.plot_surface(theta1_vals, theta0_vals, J_vals, cmap=cm.jet) ax1.set_xlabel(r"$\theta_1$") ax1.set_ylabel(r"$\theta_0$") ax2 = fig.add_subplot(2, 2, 4) ax2.plot(teta[0][0], teta[0][1], 'rx', markersize=10) ax2.set_xlabel(r"$\theta_0$") ax2.set_ylabel(r"$\theta_1$") ax2.contour(theta0_vals, theta1_vals, J_vals, norm=LogNorm(), levels=np.logspace(-4, 6, 20)) # -4, 6, 20 plt.tight_layout() fig.savefig("grafik.png") plt.show()
Tekrar etmeden önce programı çalıştırın ve ne yapıldığını anlamaya çalışın. Alpha değerini ve devir sayısını değiştirerek programı tekrar çalıştırarak deneyebilirsiniz.
Dereceli Azalmanın nasıl çalıştığını, nasıl tek değişkenli lineer regresyonda kullanıldığını anlamak istiyorsanız devam edelim. Programı Bana Hemen Ver Diyorsanız, kopyala yapıştır ile işiniz hallolduysa devam etmenize gerek yok.
Evet, şimdi daha derine inmeye devam edelim.