Professional Documents
Culture Documents
Burak Bayramlı
Sayılar ve Kuramlar
https://burakbayramli.github.io/dersblog/sk/
https://github.com/burakbayramli/classnotes
Olasılık, Dağılımlar, Giriş
Dağılımlar
Doğada yapılan çoğu ölçümlerin sıklık / frekans grafiğini alınca sonucun aşağıda
gibi çıkması ilginçtir.
Mesela herhangi bir şehirde, ilçede 2000 yetişkinin kilosunu ölçün. Grafiğini
alın kesinlikle yukarıdaki tepe şekli çıkacak. Ya da, 1000 kişinin boyunu ölçün,
aynı tepe şekli. Keskin nişancının hedefe attığı kurşunların hedefe yakınlığını
ölçüp sıklık grafiğine bakın. Gene aynı tepe şekli! Nasıl oluyor bu iş? Açıklama
için, normal dağılım eğrisinden bahsetmemiz gerekecek. Not: Frekans grafiği,
X sayısının ne kadar çıktığını sayıp, Y ekseni üzerinde bu sayıyı X’e tekabül ed-
erek kolon olarak göstermeye denir. Mesela, 60 kilo değeri 13 kere çıktı ise, X=60,
Y=13 gibi bir kolon çizilecektir.
Normal Dağılım Eğrisi
Normal dağılımın olasılık kavramı ile yakın bağları var. Bu konuda ünlü bir
deney zar atma deneyidir. Elimizde tek bir zar var, ve bu zarı arka arkaya atalım.
Sabrımız yeterse 1000 kere atalım. Sonuçta, frekans grafiği eşit bir dağılımda ola-
caktır.
Bunun sebeplerini anlamak zor değil. Her zar atış olayı birbirinden bağımsız, ve
her sayının üstte gelme ihtimali birbirine eşit olduğu için (1/6), her sayıdan eşit
miktarda gelecek. Tabii bu durumu görmek için deneyin birçok kere tekrarlan-
ması gerekiyor.
Şimdi deneyi biraz değiştirelim, bir yerine 2 zar atalım. Hatta 4 zar atalım, ve bu
sefer sıklık grafik hanesine yazmadan çıkan sayıları önce toplayalım. Bu çıkan
toplamın sıklık grafiğini alalım.
İşte bu sıklık grafiği göreceğiz ki, üstte görülen tepe grafiğine yaklaşıyor. Ne
kadar çok zar atarsak, bu benzerlik o kadar daha fazla olacaktır.
Sebep kabaca tahmin edilebilir, 1 ile 6 arası sayıların tek bir zardan gelme olasılığı
aynı, evet. Fakat toplamlara gelince, mesela iki zarlı örnekte, 10 sayısının olasılığı
2 sayısından daha yüksek. Çünkü, 10 sayısını 5-5, 4-6 ya da 6-4 ile alabiliyoruz. 2
sayısı sadece 1-1 ile geliyor.
Buradan şu sonuç çıkabilir: Eğer doğada ölçtüğümüz bir kavramın oluşmasında
1
birden fazla etken var ise, o ölçümlerin sıklığı her zaman çan (bell shape) şeklinde
olacaktır. Bir kişinin boyunu, kilosunu etkileyen pek çok diğer faktör olduğu
için bu ölçütlerin dağılımlarının normal çıktığı iddia edilebilir. Üstteki örnekteki
toplamların dağılımının çan eğrisine yaklaşması durumu istatistikte Merkezi Limit
Teorisi ile ispatlanmıştır.
Bu durumu hesap yapıp kendimiz de görebiliriz. İlk önce, random.org sitesin-
den rasgele sayı üreteceğiz. Bu site kimsenin kullanmadığı radyo kanallarından
atmosfer gürültüsü dinleyip, bu gürültüleri sayısal değere çevirerek rasgele sayı
üretiyor. Gerçek rasgele sayı üretmek pek kolay bir iş değil. Her ne kadar bil-
gisayarımızda rasgele sayı üreten birçok algoritma olsa bile, bu algoritmalar belli
bir sayı üretiminden sonra kendini tekrar etmeye başlıyorlar, bu sebeple onlara
yarı-rasgele (pseudorandom) sayılar ismi veriliyor. Gerçek rasgele sayılar için
dış bir kaynağa bağlanmak bir seçenek olabilir. Ama şunu da söylemek lazım,
simulasyon tekniklerinin tamamı için yarı-rasgele sayılar yeterlidir.
Neyse bahsedilen siteden rasgele sayıları üretip, bir veri dosyasına koyuyoruz,
kod ile bu sayıları okuyup, ilk önce teker teker sayıların sıklık grafiğini, ondan
sonra sayıları üçer üçer toplayıp, onların grafiğini alıp göstereceğiz.
A = np.loadtxt('rasgele.dat')
plt.hist(A, 50)
plt.savefig('stat_intro_08.png')
A = np.loadtxt('rasgele.dat');
B = []
i = 1;
2
toplam = toplam + s
B.append(toplam/3)
i = i + 3
plt.hist(B, 50);
plt.savefig('stat_intro_09.png')
(x−µ)2
f(x) = N · e− 2σ2
1
ki N normalize edici bir faktör, √2πσ2
, σ, µ dışarıdan bizim tanımladığımız parame-
treler. N kısmı çarpılan bölümün biri bölen entegrali aslında, ki böylece tüm
yoğunluğun entegrali (yani tüm olasılık) 1 olabilsin. Bu şekilde pek çok fonksiyon
olasılık yoğunluğu haline getirebilir.
Farklı yoğunluk fonksiyonları var, hangisinin hangi tür veriye uyacağını bulmak
istatistikçinin önemli işlerinden. Yoğunluk çok boyutlu da olabilir.
Tek boyutlu bir yoğunluk fonksiyonun x-ekseni üzerindeki alanı her zaman 1’e
eşit olmalıdır (yani yoğunluğun −∞, ∞ üzerinden entegrali her zaman 1 sonu-
cunu vermeli). Olasılık teorisinin işlemesi için bu gerekli.
Yoğunluk fonksiyonları doğadan gelen bir tek ölçümü alırlar, boy, kilo gibi, ve
onun ’olasılık yoğunluğunu’ hesaplarlar. Üstteki örnek için mesela 3 ve 1 değerlerinin
yoğunluğunu hesaplayalım,
mu = 0
sigma = 1
def f(x): return (1 / (np.sqrt(2 * np.pi * np.power(sigma, 2)))) * \
(np.power(np.e, -(np.power((x - mu), 2) / (2 * np.power(sigma, 2)))))
print ('3 icin', f(3))
print ('1 icin', f(1))
3
3 icin 0.004431848411938008
1 icin 0.24197072451914337
1 değeri 3’ten daha düşük – çünkü bu 0 merkezli bir yoğunluk fonksiyonu, sıfıra
ne kadar yakınsa yoğunluk o kadar fazla. Bu fonksiyonun tasarlanış şekli böyle.
Eğer tüm olası değerleri x’e verip grafiklesek,
x = np.array(np.linspace(-3,3,num=50))
y = f(x)
plt.plot(x,y)
plt.savefig('stat_intro_03.png')
Dikkat: yoğunluk fonksiyonu olasılık değildir; bazı yoğunluk değerleri bazı sürekli
fonksiyonlarda 1’den fazla çıkabilir! Sürekli ortamda olasılık bir entegraldir, daha
önce söylediğimiz gibi tüm fonksiyon alanı 1. Altta bir normal dağılım yoğunluk
fonksiyonu solda, onun entegrali kümülatif dağılım fonksiyonu (CDF) sağda.
CDF bize mesela üstteki grafikte değerin 0 ila 1.5 arasında olma olasılığını veriyor.
CDF hesabı için istatistik yazılım paketlerinde muhakkak bir çağrı olur, mesela
scipy.stats ile,
4
import scipy.stats
print (scipy.stats.norm.cdf(1.5,0,1))
0.9331927987311419
1’ye yakın oldukca büyük bir sayı, grafiğe uygun. CDF her zaman 0’dan sorulan
değere kadar olan alanı verir, tüm alanın 1 olması bilgisinden hareketle bu öğeler
biraraya koyulup ek sonuçlara varılabilir, mesela değerin 1.5’tan büyük olma
olasılığı için 1-CDF(1.5). Eğer -2 ile 2 arası olma olasılığını istiyorsak CDF(2)-
CDF(-2).
Veriden Fonksiyon
Şimdi mesela elimizde bir grup kişinin 68 kiloya ne kadar yakın / uzak olduğunun
verisi var (68’ten az olanlar eksi değerli olacak tabii). Veriyi grafikleyelim,
import pandas as pd
df = pd.read_csv('boy68.csv')
df.hist()
plt.savefig('stat_intro_04.png')
plt.hold(False)
5
manın yolları var.. Veriden teoriksel yoğunluğa, oradan başka teorilere, oradan
tekrar veriye atlayabilmek istatistiğin özü.
Diyelim ki bir şekilde verinin Normal olduğuna karar verdik (bunun testleri,
metotu var tabii) o zaman veriye uygun µ, σ parametrelerini nasıl bulacağız?
Veriyi kullanıp bir hesap yaparak! Tahmin ediciler burada devreye giriyor,
P mesela
Normal dağılım için µ tahmin edici / kestirme hesaplayıcısı µ̂ = xi /n, yani
verinin ortalaması [5]!
Ayrıksal Dağılımlar
Normal dağılım, üstel dağılım birer sürekli fonksiyondurlar, tek boyutta x bir reel
sayıdır. Fakat ayrıksal olan dağılımlar da var, mesela Poisson,
ki dışarıdan tanımlı parametre λ. Burada geçilen x tam sayı değerler, 1,2,3 gibi..
Ayrıksal olasılık kütle fonksiyonu (süreklideki olasılık yoğunluk yerine) sonuçları
birer olasılık olarak kabul edilebilir, çünkü tam sayılar bir nevi kutucuk, geniş
alan oluştururlar.
x = np.array(range(20))
y = poisson_distribution(x,lam=5)
plt.plot(x,y)
plt.savefig('stat_intro_12.png')
6
Rasgele değişkenler çoğunlukla büyük harfle gösterilirler, mesela X ya da Y gibi
ve bir dağılıma / onun yoğunluk fonksiyonuna göbekten bağlantılıdırlar. On-
ları formül içinde görünce sanki her bakışınızda içlerinin başka bir rasgele sayı
ile doldurulduğunu düşünebiliriz, ama tabii ki bu “rasgelelik” o RD’nin bağlı
olduğu dağılıma göredir. Eğer X üstteki f(x) ile dağılmış dersek, o zaman sıfıra
yakın daha çok, 5’e yakın daha az değerler üretilir.
RD’leri formül içinde bile kullanabilirsiniz, mesela
3X + log X
Ω = {HH, HT , T H, T T }
7
Bunun hesabı için en kolayı, hiç tura gelmeme, yani tamamen yazı gelme olasılığını,
Ac ’yi hesaplamak, ve onu 1’den çıkartmaktır. c sembolü “tamamlayıcı (comple-
ment)” kelimesinden geliyor.
P(A) = 1 − P(Ac )
= 1 − P(hepsi yazı)
10
1
=1− ≈ .999
2
..
.
8
Örnek
Ω = {(x, y); x2 + y2 6 1}, yani küme birim çember ve içindeki reel sayılar (unit
disc). Diyelim ki bu kümeden rasgele seçim yapıyoruz. Tipik bir sonuç ω =
(x, y)’dir. Tipik rasgele değişkenler ise X(ω) = x, Y(ω) = y, Z(ω) = x + y olabilir.
Görüldüğü gibi bir sonuç ile reel sayı arasında eşleme var. X rasgele değişkeni bir
sonucu x’e eşlemiş, yani (x, y) içinden sadece x’i çekip çıkartmış. Benzer şekilde
Y, Z değişkenleri var.
Toplamsal Dağılım Fonksiyonu (Cumulative Distribution Function -CDF-)
Tanım
X rasgele değişkeninin CDF’i FX : R → [0, 1] tanımı
Eğer X ayrıksal ise, yani sayılabilir bir küme {x1 , x2 , ...} içinden değerler alıyorsa
olasılık fonksiyonu (probability function), ya da olasılık kütle fonksiyonu (prob-
ability mass function -PMF-)
fX (x) = P(X = x)
Zb
P(a < X < b) = fX (x) dx
a
Zx
FX = fX (t) dt
∞
Ayrıca FX (x)’in türevi alınabildiği her x noktasında fX (x) = FX0 (x) demektir.
Dikkat! Eğer X sürekli ise o zaman P(X = x) = 0 değerindedir. f(x) fonksiyonunu
P(X = x) olarak görmek hatalıdır. Bu sadece ayrıksal rasgele değişkenler için
işler. Sürekli durumda olasılık hesabı için belli iki nokta arasında entegral hesabı
yapmamız gereklidir. Ek olarak PDF 1’den büyük olabilir, ama PMF olamaz.
PDF’in 1’den büyük olabilmesi entegrali bozmaz mı? Unutmayalım, entegral
hesabı yapıyoruz, noktasal değerlerin 1 olması tüm 1’lerin toplandığı anlamına
gelmez.
9
Olasılık yoğunluk fonksiyonundaki yoğunluk kelimesini tekrar vurgulamak iyi
olur. Özellikle sürekli dağılım bağlamında bu kavramı hakiki yoğunluk gibi
düşünmek iyi olur. Mesela tamamı aynı maddeden olan bir küp düşünelim,
yoğunluğu 2. Bu küpün neresine bakarsak bakalım yoğunluk hep aynı olur, 2.
Yoğunluk bir bakıma belli bir alanı temsil eden bir özet. Sonra bu küpün kütlesini
bulmak için habire bir sürü 2’yi üst üste koyup toplamıyoruz; kütle hesabı için
bir çarpım yapıyoruz / entegral alıyoruz.
Örnek olarak çan eğrisi / normal dağılımdan sayılar üretelim. Bu dağılımda
“ağırlık” ortadadır. Rasgele sayı üretip histograma bakalım,
mu=10;sigma=0.1
data = np.random.normal(mu,sigma,100)
hst = plt.hist(data, normed=True,bins=6)
print hst[0]
Görüldüğü gibi 1’den büyük değerler var, ve “yoğunluk” ortadaki iki kutuda.
Olasılık yoğunluk hesabını formülsel yapsak, mesela 10 noktasının ağırlığı nedir
desek,
print norm.pdf(10,mu,sigma)
3.98942280401
Şimdi olasılık değerleri, P(a < X < b) ifadesi, alan hesabı ve rasgele değişkenler
arasındaki bağlantıyı biraz daha detaylandırmak gerekirse; X bir rasgele değişken,
nokta (kesin) değeri olmasa da denklemde kullanılabiliyor, toplanıp çıkartılabiliyor,
vs. Bu değişkene “değeri sorulduğunda” bu değer o X’in bağlı olduğu dağılımın
zar atması sonucunda gelecektir. Bu zar atışı ise olasılık fonksiyonunun yüksek
değer verdiği x değerlerini daha fazla üretecektir doğal olarak. Bunu kavram-
sal olarak söylüyoruz tabii, istatistiki problemlerde illa bu zar atışını yapmamız
gerekmeyebilir.
Mesela üstteki dağılım için 100 ve çevresindeki değerlerinin olasılığı çok yüksek,
mesela grafiğe bakarsak, kabaca, fX (100) = 0.027, ya da fX (120) = 0.015. Demek
ki bu dağılıma bağlı bir X, o çevreden daha fazla değer üretir.
Rasgele değişkene bağlı olasılık hesabı için ise, mesela P(X < 120) diyelim, bu
ifade ile ne diyoruz? Sorduğumuz şudur, zar atışlarının belli değer altında gelmesi
10
olasılığı... Bu hesap tabii ki bir alan hesabıdır, x eksenindeki belli aralıklar, bölgelerin
toplam olasılığının ne olacağı o bölgenin tam üzerindeki yoğunluğun toplamı
olacaktır, aynen tek değerlerin olasılığının o tek değerin yoğunluk değeri ol-
ması gibi. Yani bu tür olasılık hesapları direk fX (x) üzerinden yapılacaktır. Zar
atıldığında 100’den küçük değerlerin gelme olasılığı nedir? Alana bakarsak 0.5,
yani 1/2, tüm alanın yarısı. Bu normal, çünkü 100’den küçük değerler dağılımın
yarısını temsil ediyor. 200’den küçük değerler gelme olasılığı nedir, yani P(X <
200)? Olasılık 1. fX alanının tamamı. Yani kesin. Çünkü yoğunluk fonksiy-
onunun tamamı zaten 200’den küçük değerler için tanımlı. “Yoğunluk orada”.
Tanım
X rasgele değişkeninin CDF’i F olsun. Ters CDF (inverse cdf), ya da yüzdelik
dilim fonksiyonu (quantile function)
−1
F (q) = inf x : F(x) 6 q
ki q ∈ [0, 1]. Eğer F kesinlikle artan ve sürekli bir fonksiyon ise F−1 (q) tek bir x
sayısı ortaya çıkarır, ki F(x) = q.
Eğer inf kavramını bilmiyorsak şimdilik onu minimum olarak düşünebiliriz.
F−1 (1/4) birinci çeyrek
F−1 (1/2) medyan (median, ya da ikinci çeyrek),
F−1 (3/4) üçüncü çeyrek
olarak bilinir.
d
İki rasgele değişken X ve Y dağılımsal olarak birbirine eşitliği, yani X = Y eğer
FX (x) = FY (x), ∀x. Bu X, Y birbirine eşit, birbirinin aynısı demek değildir. Bu
değişkenler hakkındaki tüm olasılıksal işlemler, sonuçlar aynı olacak demektir.
Uyarı! “X’in dağılımı F’tır” beyanını X ∼ F şeklinde yazmak bir gelenek. Bu biraz
kötü bir gelenek aslında çünkü ∼ sembolü aynı zamanda yaklaşıksallık kavramını
belirtmek için de kullanılıyor.
Tanım
x1 , .., xn verilerini içeren örneklemin (sample) ortalaması
1X
x̄ = xi (1)
n
11
için geçerlidir. Eğer bu temel varsayım geçerli değilse, ortalama kullanarak yapılan
hesaplar bizi yanlış yollara götürür. Ayrıca bir dağılımı simetrik olup olmadığı
da ortalama ya da medyan kullanılıp kullanılmaması kararında önemlidir. Eğer
simetrik, tek tepeli bir dağılım var ise, ortalama ve medyan birbirine yakın ola-
caktır. Fakat veri başka türde bir dağılım ise, o zaman bu iki ölçüt birbirinden çok
farklı olabilir.
Dağılımlar
Bernoulli Dağılımı
X’in bir yazı-tura atışını temsil ettiğini düşünelim. O zaman P(X = 1) = p, ve
P(X = 0) = 1 − p olacaktır, ki p ∈ [0, 1] olmak üzere. O zaman X’in dağılımı
Bernoulli deriz, X ∼ Bernoulli(p) diye gösteririz. Olasılık fonksiyonu, x ∈ {0, 1}.
f(x; p) = px (1 − p)(1−x)
E(X) = p
Var(X) = p(1 − p)
Uyarı!
X bir rasgele değişken; x bu değişkenin alabileceği spesifik bir değer; p değeri ise
bir parametre, yani sabit, önceden belirlenmiş reel sayı. Tabii istatistiki problem-
lerde (olasılık problemlerinin tersi olarak düşünürsek) çoğunlukla o sabit parame-
tre bilinmez, onun veriden hesaplanması, kestirilmesi gerekir. Her halükarda,
çoğu istatistiki modelde rasgele değişkenler vardır, ve onlardan ayrı olarak parame-
treler vardır. Bu iki kavramı birbiriyle karıştırmayalım.
Binom Dağılımı (Binomial Distribution)
Her biri birbirinden bağımsız ve birbiriyle aynı Bernoulli Dağılımına sahip deneyler-
den n tane yapıldığını farzedelim, ki bu deneylerin sadece iki sonucu olacak
(1/0. başarı/başarısızlık, vs). Bu deneylerin p’sı aynı olacak. O zaman n deney
içinden toplam kaç tanesinin başarılı olduğunu gösteren X rasgele değişkeni Bi-
nom Dağılımına sahiptir denir.
Bu dağılımın yoğunluğu
n x
f(x; p, n) = p (1 − p)n−x
x
n!
= px (1 − p)n−x
x!(n − x)!
12
Bu fonksiyonun parametreleri p, n değerleridir. Beklenti ve varyans
µ = E(X) = np
σ2 = Var(X) = np(1 − p)
1
b−a
x ∈ [a, b] icin
f(x) =
0 diger
işe ve a < b olacak şekilde. CDF hesabı olasılık eğrisinin entegralini temel alır,
düz dağılım bir a, b arasında 1/b − a yüksekliğinde bir dikdörtgen şeklinde
olacağı için, bu dikdörtgendeki herhangi bir x noktasında CDF dağılımı, yani
o x’in başlayıp sol tarafın alanının hesabı basit bir dikdörtgensel alan hesabıdır,
yani x − a ile 1/b − a’nin çarpımıdır, o zaman
0 x<a
x−a
F(x) = x ∈ [a, b]
b−a
1 x>b
Beklenti E[X] = 1.
Multinom (Multinomial) Dağılım
13
Çok boyutlu X rasgele değişkeni, ki boyutu k olarak tanımlayalım, X ∼ Mult(m, p)
olarak dağılmıştır deriz, eğer bu dağılım k sınıf, kategori içinden birinin seçildiği
durumda m deney içinden kaç tanesinin hangi kategorilerde olduğunu temsil
ediyorsa, ve p çok boyutludur. Multinom, binom dağılımının çok kategorili ha-
lidir denebilir, ya da binom, multinomun k = 2 halidir. Olasılıklar,
m!
f(x; m, p) = px1 1 · ·px1 k
x1 ! · ·!xk !
Beklenti E(X) = p. Her kategori, hücre i için tabii ki E(Xi ) = p, varyans ise
Var(Xi ) = mpi (1−pi ). Kovaryans Covar(Xi , Xj ) = −mpi pj . Bunun türetilmesini
ilerideki bir bölümde göreceğiz.
Poisson Dağılımı
Sayım verilerini (count data) modellemek için bu dağılım çok kullanılır. Tanımı,
λx
f(x) = P(X = x) = e−λ
x!
14
1 1
= √ exp − (x − µ)σ−2 (x − µ)
σ 2π 2
X
n X
n X
n
2
Xi = N µi , σ
i=1 i=1 i=1
a−µ X−µ b−µ
=P < <
σ σ σ
a−µ b−µ b−µ a−µ
=P <Z< =Φ −Φ
σ σ σ σ
İlk geçişi nasıl elde ettik? Bir olasılık ifadesi P(·) içinde eşitliğin iki tarafına aynı
anda aynı toplama, çıkarma operasyonlarını yapabiliriz.
Son ifadenin anlamı şudur. Eğer standart Normal’ın CDF’ini hesaplayabiliy-
orsak, istediğimiz Normal olasılık hesabını yapabiliriz demektir, çünkü artık X
içeren bir hesabın Z’ye nasıl tercüme edildiğini görüyoruz.
15
Tüm istatistik yazılımları Φ(z) ve Φ(z)−1 hesabı için gerekli rutinlere sahiptir.
Tüm istatistik kitaplarında Φ(z)’nin belli değerlerini taşıyan bir tablo vardır. Ders
notlarımızın sonunda da benzer bir tabloyu bulabilirsiniz.
Örnek
X ∼ N(3, 5) ise P(X > 1) nedir? Cevap:
1−3
P(X > 1) = 1 − P(X < 1) = 1 − P(Z < √ )
5
Soru P(a < X < b) formunda a kullanmadı, sadece b olduğu için yukarıdaki
form ortaya çıktı. Python ile
Soru
Φ(1.13) nedir?
Kümülatif olasılık fonksiyonuna geçilen z değerlerinin bir diğer ismi ise z-skoru.
Bu değerleri anlamanın bir yolu (skora çevirilmiş) orijinal değerlerin “kaç stan-
dart sapma uzakta” olduğunu göstermesidir. Bundan sonra ölçümüz standart
sapma haline geliyor, ve bu değer sola ya da sağa çekildikçe ona tekabül eden
alan (üstte sarı renkle gösterilen kısım), yani olasılık azalıp çoğalıyor. Grafikte
mesela “1.13 standart sapma” yani z-skor nereyi gösteriyor deyince, görülen şekil
/ olasılık ortaya çıkıyor. Tabii temel aldığımız değer baştan z-skorunun ken-
disi ise dağılım standart dağılım ve standart sapma 1 olduğu için “kaç standart
sapma” ile z-skoru birbirine eşit. z-Skorları hakkında ek bir anlatım bu bölümün
sonunda bulunabilir.
Örnek
16
Şimdi öyle bir q bul ki P(X < q) = .2 olsun. Yani Φ−1 (.2)’yi bul. Yine X ∼ N(3, 5).
Cevap
Demek ki tablodan .2 değerine tekabül eden eşik değerini bulup, üstteki formül
üzerinden geriye tercüme etmemiz gerekiyor. Normal tablosunda Φ(−0.8416) =
.2,
q−µ q−µ
.2 = P(X < q) = P(Z < ) = Φ( )
σ σ
O zaman
q−µ q−3
−0.8416 = = √
σ 5
√
q = 3 − 0.8416 5 = 1.1181
Z +∞
2 √
e−x dx = π
−∞
Z +∞
1 2
√ e−x dx = 1
−∞ π
Z +∞
1 x 2
√ e−( 2 ) dx
√
=
−∞ 2π
17
σ = 1’e erişince oradan herhangi bir σ için, σ değişkenine bölelim, yine hem e
üstüne hem sabite bu eki yapalım,
Z +∞
1 √x 2
= √ e−( 2σ ) dx
−∞ σ 2π
Şimdi herhangi bir ortalama µ için bu değişkeni formüle sokalım, bunun için µ’yu
x’den çıkarmak yeterli
Z +∞
1 x−µ 2
√ e−( 2σ ) dx
√
=
−∞ σ 2π
Z +∞
1 (x−µ)2
= √ e− 2σ2 dx
−∞ σ 2π
Böylece integral içindeki kısım tek boyutlu Gaussian formuna erişmiş oluyor.
Gamma Dağılımı
Y rasgele değişkeninin, verilmiş r > 0 ve λ > 0 üzerinden Gamma yoğunluk
fonksiyonuna sahip olduğu söylenir, eğer bu fonksiyon
λr r−1 λy
fγ = y e
Γ (r)
y>0
Peki Γ sembolü nerede geliyor? Bu bir fonksiyondur; Herhangi bir r > 0 için
Gamma fonksiyonu Γ (r) şu şekilde gösterilir,
Z∞
Γ (r) = yr−1 e−y dy
0
18
Bu tanımda A kümesi olarak tanımlanan kavram uygulamalarda bir olaya (event)
tekabül eder. Mesela
Örnek
(X, Y)’in birim kare üzerinde birörnek (uniform) olsun. O zaman
1 eğer 0 6 x 6 1, 0 6 y 6 1 ise
f(x, y) =
0 diğer durumlarda
cx2 y eğer x2 6 y 6 1
f(x, y) =
0 diğer
ZZ Z1 Z1
1= f(x, y) dy dx = c x2 y
−1 x2
Z1 Z1 Z1
2 1 x4
=c x y dy dx = x2 ( − ) dx = 1
−1 x2 −1 2 2
Z1
1 − x4
=c x2 ( ) dx = 1
−1 2
Z1
c
= x2 − x6 dx = 1
2 −1
19
Şimdi, diyelim ki bizden P(X > Y)’yi hesaplamamız isteniyor. Bu hangi A bölgesine
tekabül eder? Elimizdekiler
−1 6 x 6 1, x2 6 y, y 6 1
Şimdi bunlara bir de y 6 x eklememiz lazım. Yani ortadaki eşitsizliğe bir öğe
daha eklenir.
−1 6 x 6 1
x2 6 y 6 x
y61
x2 6 y’yi hayal etmek için x2 = y’yi düşünelim, bu bir parabol olarak çizilebilir,
ve parabolun üstünde kalanlar otomatik olarak x2 6 y olur, bu temel irdelemel-
erden biri.
Z1 Zx Z1 Zx
21 2 21 2
P(X > Y) = x y dy dx = x y dy dx
4 0 x2 4 0 x2
Z1
21 x2 − x4 3
= x2 dx =
4 0 2 20
20
“Hafızasız” Dağılım, Üstel (Exponential) Dağılım
Üstel dağılımın hafızasız olduğu söylenir. Bunun ne anlama geldiğini anlatmaya
uğraşalım. Diyelim ki rasgele değişken X bir aletin ömrünü temsil ediyor, yani
bir p(x) fonksiyonuna bir zaman “sorduğumuz” zaman bize döndürülen olasılık,
o aletin x zamanı kadar daha işlemesinin olasılığı. Eğer p(2) = 0.2 ise, aletin 2 yıl
daha yaşamasının olasılığı 0.2.
Bu hafızasızlığı, olasılık matematiği ile nasıl temsil ederiz?
Yani öyle bir dağılım var ki elimizde, X > t bilgisi veriliyor, ama (kalan) zamanı
hala P(X > s) olasılığı veriyor. Yani t kadar zaman geçtiği bilgisi hiçbir şeyi
değiştirmiyor. Ne kadar zaman geçmiş olursa olsun, direk s ile gidip aynı olasılık
hesabını yapıyoruz.
Şartsal (conditional) formülünü uygularsak üstteki şöyle olur
ya da
21
ıı) Sorunun bu kısmı müşteri 10 dakika geçirdikten sonra 5 dakika daha geçirmesinin
olasılığını soruyor. Fakat üstel dağılım “hafızasız” olduğu için kalan zamanı alıp
yine direk aynı fonksiyona geçiyoruz,
ve
Z
fY (y) = f(x, y) dy
Üstteki integraller gerçek bir dağılım fonksiyonu f(x, y) verilince alt ve üst limit
te tanımlamak zorundadır. Çünkü kısmı yoğunluk için bir veya daha fazla değişkeni
“integralle dışarı atmak (integrate out)” ettiğimiz söylenir, eğer ayrıksal (discrete)
ortamda olsaydık bu atılan değişkenin tüm değerlerini göze alarak toplama ya-
pan bir formül yazardık. Sürekli ortamda integral kullanıyoruz, ama tüm değerlerin
üzerinden yine bir şekilde geçmemiz gerekiyor. İşte alt ve üst limitler bunu
gerçekleştiriyor. Bu alt ve üst limitler, atılan değişkenin “tüm değerlerine” bak-
ması gerektiği için −∞, +∞ olmalıdır. Eğer problem içinde değişkenin belli değerler
arasında olduğu belirtilmiş ise (mesela alttaki örnekte x > 0) o zaman entegral
limitleri alt ve üst sınırını buna göre değiştirebilir.
Örnek
fX,Y (x, y) = e−(x+y) , olsun ki x, y > 0. O zaman fX (x)
Z∞
−x
fX (x) = e e−y dy = e−x · 1 = e−x
0
Örnek
x + y eğer 0 6 x 6 1, 0 6 y 6 1
f(x, y) =
0 diğer
Z1 Z1 Z1
1
fY (y) = (x + y) dx = x dx + y dx = +y (1)
0 0 0 2
Tanım
22
İki rasgele değişken A, B bağımsızdır eğer tüm A, B değerleri için
2x eğer 0 6 x 6 1
f(x) =
0 diğerleri
4xy eğer 0 6 x 6 1, 0 6 y 6 1
f(x, y) = fX (x)fY (y) =
0 diğerleri
Entegralin limitinin üstteki hali sembolik, hesap için bu yeterli değil, eğer x +
y 6 1 ise, y 6 1 − x demektir, ve bölge y = 1 − x çizgisinin altı olarak kabul
edilebilir. x, y zaten sıfırdan büyük olmalı, yani sola doğru yatık çizginin altı ve
y, x eksenlerinin üstü kısmını oluşturan bir üçgen,
Z 1 Z 1−x Z Z 1 Z 1−x
= 4yx dy dx = 4 x y dy dx
0 0 0 0
Z1
(1 − x)2 1
4 x dx =
0 2 6
23
Çok Değişkenli (Multivariate) Dağılımlar ve IID Örneklemler (Samples)
X = (X1 , ..., Xn ) olsun, ki (X1 , ..., Xn )’lerin herbiri bir rasgele değişken, o zaman
X’e rasgele vektör (random vector) ismi verilir. f(x1 , ..., xn )’in PDF’i temsil ettiğini
düşünelim. Bu PDF’i baz alarak aynen iki değişkenli (bivariate) örneklerde olduğu
gibi, benzer tekniklerle kısmi olan, koşullu dağılımları, vs. hesaplamak mümkündür.
Çok Değişkenli Normal
Tek değişkenli Normal dağılımın iki parametresi vardı, µ, σ. Çok değişkenli for-
mda µ bir vektör, σ yerine ise Σ matrisi var. Önce rasgele değişkeni tanımlayalım,
Z1
Z = ...
Zk
Y
1X 2
k k
1
f(z) = f(zi ) = exp − z
i=1
(2π) k/2 2 j=1 j
1 1
= exp − zT z
(2π)k/2 2
Bu durumda Z’nin standart çok değişkenli Normal dağılıma sahip olduğu söylenir,
ve Z ∼ N(0, I) olarak gösterilir. Buradaki 0 değeri içinde k tane sıfır olan bir vektör
olarak, I ise k × k birim (identity) matrisi olarak anlaşılmalıdır.
Daha genel olarak bir vektör X’in çok değişkenli Normal dağılımına sahip olduğunu
söyleriz, ve bunu X ∼ N(µ, Σ) olarak gösteririz, eğer dağılımın yoğunluğu
1 1
f(x; µ, Σ) = exp − (x − µ)T Σ−1 (x − µ)
(2π) det(Σ)1/2
k/2 2
24
n,d = x.shape
S = lin.inv(v)
x = x-m
y = exp(-0.5*np.diag(dot(x,np.dot(S,x.T))))
return y * (2*pi)**(-d/2.0) / ( np.sqrt(lin.det(v)) + 1e-6)
x = np.array( [[1.,1.]] )
v = np.array( [[2.,0],[0,2.]] )
m = np.array([1.,1.])
print gauss(m, v, x)
[ 0.07957743]
Maksimum olurluk ile elde edilen eldeki n veri noktası için µ, Σ’nin tahmin edi-
cileri µ̂, Σ̂,
1X
n
µ̂ = xk
n k=1
1X
n
Σ̂ = (xk − µ̂)(xk − µ̂)T
n k=1
Bu yüzden, P(z1 < Z < z2 ) gibi bir ifadede mesela, Z’nin iki tarafındaki her iki
değer birer z-değeri, olasılık değerleri değil. Olasılık değeri P(·) hesabı sonu-
cunda elde edilecek.
Tabii z-skorları ile ona bağlı olasılık değeri arasında birebir bağlantı var, fakat
z-değerinin “kendisi” olasılık değeri değildir.
Rasgele Değişkenler, Yoğunluklar
25
Şimdi konuların üzerinden bir daha geçelim; rasgele değişken, X, Y gibi büyük
harflerle gösterilen büyüklükler “bir zar atış sonucu içleri doldurulan” değişkenlerdir.
Bu zar atışı her zaman X’in, Y’nin bağlı olduğu dağılıma göre olacaktır. Eğer
X ∼ N(10, 2) ise, bir formülün / hesabın içinde X gördüğümüz zaman çoğunlukla
o noktaya 10’a yakın değerler olacağını biliriz. Tabii ki “kesin” her zaman ne
olacağını bilmeyiz, zaten bir modelde noktasal değer (tipik cebirsel değişkenler)
yerine rasgele değişken kullanmanın sebeplerinden biri budur.
Rasgele değişkenlerin matematiksel formüllerde kullanılması C = X + Y şeklinde
olabilir mesela. O zaman elde edilen yeni değişken de bir rasgele değişken olur.
Bu tür formüller envai şekle girebilir, hatta rasgele değişken içeren formüllerin
türevi bile alınabiliyor, tabii bunun için özel bir Calculus gerekli, İto’nun Calcu-
lus’y bu tür işlerle uğraşıyor.
Elimizde şunlar var; olasılık fonksiyonu bir matematiksel denklem, öne değerler
geçiyoruz, ve bu değerlerin olasılıklarını gayet direk, mekanik bir formülden ce-
vap olarak alıyoruz. Rasgele değişkenler ise bu yoğunluk fonksiyonlarını bir an-
lamda “tersten işletiyor”, o dağılıma “zar attırıyor” (hatta Simulasyon denen bir
derste tam da bu öğretiliyor, yani yoğunluklara yarı-rasgele sayılar üzerinden
zar attırmak!), ve kümülatif olasılık fonksiyonuna geçilen değerler bu sefer dışarı
çıkıyor. Tabii yoğunluğun ne olduğuna göre bazı değerler daha çok, bazıları daha
az çıkıyor. Hesapsal olarak bir rasgele değişkene / dağılıma zar attırmak için özel
kodlamalar, yarı-rasgele sayı üretimi gereklidir, biz kavramsal ve cebirsel olarak
onların neyi temsil ettiğinden bahsediyoruz.
İki kavramdan daha bahsetmek bu noktada faydalı. 1) Nüfus (Population) 2)
Örneklem (Sample). Nüfus, üzerinde istatistiksel analiz yaptığımız kitlenin tamamı.
Eğer insanların boyları hakkında istatistiki analiz yapıyor olsaydık tüm insan-
lar nüfus olurdu. Nüfusun bazen hangi dağılımda olduğu bilinmiyor olabilir,
biliniyor olsa da bazen bu dağılımın parametreleri bilinmiyor olabilir. Örneklem,
nüfus içinden alınan rasgele ölçümlere verilen isimdir, X1 , .., Xn olarak gösterilebiliyor,
bu durumda nüfusun dağılımının “zar attığı” ve her zar atışının rasgele değişkenlerden
birinin içini doldurduğu düşünebilir. Örneklem nüfustan geldiği için dağılımının
aynen nüfus gibi olduğu kabul edilir. Bu bağlantıdan yola çıkılarak birçok istatis-
tiki analiz yapmak mümkündür.
İlginç iki teori daha, hatta bu teoriler İstatistiğin belkemiğini oluşturur, Büyük
Sayılar Kanunu ve Merkezi Limit Teorisi. Diyelim ki X1 , X2 , ..., Xn bir nüfustan
gelen örneklem, ve her veri noktası bağımsız ve dağılımı aynı (nüfus gibi), bu
durumda basit ortalama X̄ = (X1 + X2 + ... + Xn )/n → µ olur, yani basit ortalama
nüfus ortalamasına yaklaşır! Burada ne söylendiğine iyi dikkat, hakkında hiçbir
şey bilmediğimiz nüfusun µ’şu hakkında bir analiz yapabiliyoruz.
Merkezi Limit Teorisi biraz daha √ detay ekler, X̄ = (X1 + X2 + ... + Xn )/n or-
talaması µ standart sapması σ/n olan bir Normal dağılıma yaklaşır. Bu teo-
riler, özellikle ikincisi kullanılarak örneklem (eldeki ufak veri) ve büyük nüfus
arasında bağlantı kurulabilir o tam bilinemeyen gerçek durum hakkında eldeki
örnek verisi ile bir çok analiz yapmak mümkün olur.
26
Kaynaklar
[1] Wikipedia, Confidence interval, http://en.wikipedia.org/wiki/Confidence_
interval
[2] Janert, Data Analysis with Open Source Tools
[3] Bayramli, Çok Değişkenli Calculus Ders 18
[4] Duda, Hart, Pattern Clasification
[5] Bayramli, Büyük Sayılar, Veri, Parametre Tahmin Ediciler (Estimators)
27
Beklenti, Varyans, Kovaryans ve Korelasyon
Beklenti (Expectation)
Bu değer, dağılım f(x)’in tek sayılık bir özetidir. Yani beklenti hesabına bir taraftan
bir dağılım fonksiyonu girer, diğer taraftan tek bir sayı dışarı çıkar.
Tanım
Sürekli dağılım fonksiyonları için E(X)
Z
E(X) = xf(x) dx
X
E(X) = xf(x)
x
Hesabın, her x değerini onun olasılığı ile çarpıp topladığına dikkat. Bu tür bir
hesap doğal olarak tüm x’lerin ortalamasını verecektir, ve dolaylı olarak dağılımın
ortalamasını hesaplayacaktır. Ortalama µx olarak ta gösterilebilir.
E(X)’in bir tanım olduğuna dikkat, yani bu ifade tamamen bizim yarattığımız,
ortaya çıkarttığımız bir şey, matematiğin baz kurallarından gelerek türetilen bir
kavram değil. Notasyonel basitlik için üstteki toplam / entegral yerine
Z
= x dF(x)
R
diyeceğiz, bu notasyonel bir kullanım sadece, unutmayalım, reel analizde x dF(x)’in
özel bir anlamı var (hoca tam diferansiyel dF’den bahsediyor) [2, sf. 69].
Beklentinin tanımının kapsamlı / eksiksiz olması için E(X)’in “mevcudiyeti” için
de bir şart tanımlamak gerekir, bu şart şöyle olsun,
Z
|x|dFX (x) < ∞
x
işe beklenti mevcut demektir. Tersi sözkonusu ise beklenti mevcut değildir.
Örnek
X ∼ Unif(−1, 3)
olsun.
1
Z Z Z3
1
E(X) = x dF(x) = xfX (x) dx = x dx = 1
4 −1
Örnek
Cauchy dağılımının fX (x) = {π(1+x2 )}−1 olduğunu söylemiştik. Şimdi beklentiyi
hesaplayalım. Parçalı entegral tekniği lazım, u = x, dv = 1/1 + x2 deriz, ve o
zaman v = tan−1 (x) olur, bkz [6]. Demek ki
Z Z∞
2 x dx
|x| dF(x) =
π 0 1 + x2
2 nereden çıktı? Çünkü |x| kullanıyoruz, o zaman sınır değerlerinde sadece sıfırın
sağına bakıp sonucu ikiyle çarpmak yeterli. Bir sabit olduğu için π ile beraber
dışarı çıkıyor. Şimdi
Z Z
udv = uv − vdu
üzerinden
Z∞
= [x tan −1
(x)]∞
0 − tan−1 (x)dx = ∞
0
Yani üstteki hesap sonsuzluğa gider. O zaman üstteki tanımımıza göre Cauchy
dağılımının beklentisi yoktur.
Y rasgele değişkeninin varyansı (variance)
Ayrısak olarak diyelim ki her biri pj olasılığa sahip n tane değer yi arasından, ve
beklenti E(Y) = µ ise, varyans bir tür “yayınımın ortalamasıdır”. Yani ortalama
olarak ortalamadan (!) ne kadar sapılır sorusunun cevabını verir,
X
n
Var(Y) = (yi − µ)2 pi
i=1
Kare alma işlemi yapıldı çünkü sapmanın eksi mi artı mı olduğu bizi ilgilendirmiyor,
sadece onun mutlak değeri, büyüklüğü bizi ilgilendiriyor. pi ile çarptık çünkü
mesela bazı sapmaların değeri büyük olabilir, ama eğer o sapmaların ortaya çıkma
olasılığı düşük ise bu sapmalar toplama, yani varyansa, daha az etki edecektir.
Değerlerin pi ile çarpılıp sonuçların toplanması beklenti hesabını çağrıştırabilir,
ve evet, matematiksel olarak varyans bir tür beklenti hesabıdır. O sebeple genel
bir şekilde alttaki gibi belirtilir,
2
İfadede toplama ve bölme gibi işlemler olmadığına dikkat; onun yerine kare
ifadeleri üzerinde beklenti ifadesi var. Yani Y’nin beklentisini rasgele değişkenin
kendisinden çıkartıp kareyi alıyoruz, ve bu işlemin Y’den gelen tüm zar atışları
üzerinden beklentisi bize varyansı veriyor. Bir rasgele değişken görünce onun
yerine “dağılımdan üretilen sayı” düşünmek faydalıdır, ki bu gerçek dünya şartlarından
(ve büyük miktarda olunca) veri noktalarını temsil eder.
Varyans formülünü açarsak, ileride işimize yarayacak başka bir formül elde ede-
biliriz,
Tanım
y1 , .., yn örnekleminin varyansı (literatürde S2 olarak geçebiliyor,
1X
S2 = (yi − ȳ)2 (2)
n
1X 2 1X 2 2X
= y + m − yi ȳ
n i i n i n i
1 X 2 ȳ2 n 2ȳn
= y + − ȳ
n i i n n
1X 2
= y + ȳ2 − 2ȳ2
n i i
1X 2
= y − ȳ2
n i i
3
ya da
X
n
1
X
n 2
= y2i − yi (5)
i=1
n i=1
4
düşünelim. Veri setinin her veri noktası bağımsız özdeşçe dağılmış (i.i.d) du-
rumda. Yani X, Y değişkenlerine “gelen” xi , yi ikilileri her i için diğerlerinden
bağımsız; fakat her ikilinin arasında bir bağlantı var, yani demek ki bu rasgele
değişkenlerin baz aldığı dağılımların bir alakası var, ya da bu iki değişkenin bir
ortak dağılımı (joint distribution) var.
Not: Eğer X, Y bağımsız olsaydı, o zaman
olarak yazılabilirdi, yani iki beklentinin ayrı ayrı çarpılabildiği durum... Ama biz
bu derste bağımsızlığın olmadığı durumla ilgileniyoruz..
Korelasyon kelimesinden bahsedelim hemen, bu kelime günlük konuşmada çok
kullanılıyor, ama bu ders bağlamında korelasyon kelimesinin matematiksel bir
anlamı olacak, onu birazdan, kovaryans üzerinden tanımlayacağız.
Bazı ilginç noktalar:
Özellik 1
varyansı nasıl tanımlamıştık?
Bu denklem aslında
= Var(X)
Yani varyans, bir değişkenin “kendisi ile kovaryansıdır”. İlginç değil mi?
Özellik 2
Cov(X, Y) = Cov(Y, X)
5
Teori
İspat
Bu ispat çok kolay, eşitliğin sol tarafındaki çarpımı parantezler üzerinden açarsak,
ve beklenti lineer bir operatör olduğu için toplamın terimleri üzerinde ayrı ayrı
uygulanabilir,
= E(XY) − E(X)E(Y)
Çarpımı uygularken mesela E(−X · E(Y)) gibi bir durum ortaya çıktı, burada
E(Y)’nin bir sabit olduğunu unutmayalım, çünkü beklenti rasgele değişkene uygu-
lanınca tek bir sayı ortaya çıkartır, ve vu E(Y) üzerinde bir beklenti daha uygu-
lanınca bu “içerideki” beklenti sabitmiş gibi dışarı çıkartılabilir, yani −E(X)E(Y).
Devam edelim, E(XY)−E(X)E(Y) ifadesini gösterdik, çünkü çoğu zaman bu ifade
hesap açısından (1)’den daha uygundur. Ama (1) ifadesi anlatım / sezgisel kavrayış
açısından daha uygun, çünkü bu ifade X’in ve Y’nin kendi ortalamalarına izafi
olarak belirtilmiştir, ve akılda canlandırılması daha rahat olabilir. Fakat matem-
atiksel olarak bu iki ifade de aynıdır.
İki özellik bulduk bile. Bir özellik daha,
Özellik 3
Cov(X, c) = 0
Bu nereden geldi? (1)’e bakalım, Y yerine c koymuş olduk, yani bir sabit. Bu
durumda (1)’in (Y − E(Y)) kısmı c − E(c) = c − c = 0 olur [aslında bayağı absürt
bir durum], ve bu durumda (1) tamamen sıfıra dönüşür, sonuç sıfır.
Özellik 4
Cov(cX, Y) = c · Cov(X, Y)
İspat için alttaki formülde
6
Cov(X, Y + Z) = Cov(X, Y) + Cov(X, Z)
Şimdi 5. özelliği hatırlayalım, orada gösterilen sanki bir nevi basit cebirdeki
dağıtımsal (distributive) kuralın uygulanması gibiydi sanki, yani (a + b)(c + d)’i
açtığımız gibi, 5. özellik te sanki kovaryansı çarpıp topluyormuş gibi “açıyordu”.
En temelde gerçekten olan bu değil ama nihai sonuç benzer gözüktüğü için akılda
tutması kolay bir metot elde etmiş oluyoruz. Her neyse, 6. özellik için aslında 5.
özelliği tekrar tekrar uygulamak yeterli. Bu arada 5. özellik Cov(X, Y + Z) için
ama Cov(Y + Z, X) yine aynı sonucu veriyor.
Bu arada 6. özellik çok çetrefil toplamlar üzerinde de uygulanabilir, mesela
X
m X
n
Cov ai Xi , bi Yi
i=1 j=1
Bu son derece karmaşık gözüküyor, fakat çözümü için aynen 6. özellikte olduğu
gibi 5. özelliği yine tekrar tekrar uygulamak yeterli (4. özellik ile de sabiti dışarı
çıkarırız, vs).
Çoğu zaman üstteki gibi pür kovaryans içeren bir açılımla çalışmak, içinde bek-
lentiler olan formüllerle uğraşmaktan daha kolaydır.
Şimdi toplamlara dönelim; kovaryanslara girmemizin bir sebebi toplamlarla iş
yapabilmemizi sağlaması. Mesela, bir toplamın varyansını nasıl hesaplarız?
Özellik 7
Var(X1 + X2 )
Şimdilik iki değişken, ama onu genelleştirip daha fazla değişkeni kullanabiliriz.
7
Çözelim. 1. özellik der ki varyans değişkenin kendisi ile kovaryansıdır, yani
Var(X) = Cov(X, X). O zaman Var(X1 + X2 ) = Cov(X1 + X2 , X1 + X2 ). Böylece
içinde toplamlar içeren bir kovaryans elde ettik ama bunu çözmeyi biliyoruz
artık. “Dağıtımsal” işlemleri yaparken Cov(X1 , X1 ) gibi ifadeler çıkacak, bunlar
hemen varyansa dönüşecek. Diğer taraftan Cov(X1 , X2 ) iki kere gelecek, yanı
Bu alanda bilinen tekerleme gibi bir başka deyiş, “eğer kovaryans sıfırsa toplamın
varyansı varyansların toplamıdır”. Hakikaten kovaryans sıfır olunca üstteki den-
klemden düşecektir, geriye sadece varyansların toplamı kalacaktır. Kovaryans ne
zaman sıfırdır? Eğer X1 , X2 birbirinden bağımsız ise. Tabii bu bağımsızlık her za-
man ortaya çıkmaz.
İkiden fazla değişken olunca? Yine tüm varyansların ayrı ayrı toplamı, ve ko-
varyanslar da sonda toplanacak,
X
Var(X1 + .. + Xn ) = Var(X1 ) + .. + Var(Xn ) + 2 Cov(Xi , Xj )
i<j
Sondaki toplamın indisinde bir numara yaptık, sadece 1 ile 2, 2 ile 3, vs. eşlemek
için, ve mesela 3 ile 1’i tekrar eşlememek için. Tekrar dedik çünkü Cov(X1 , X3 ) =
Cov(X3 , X1 ). Eğer indisleme numarası kullanmasaydık, 2 ile çarpımı çıkartırdık
(ona artık gerek olmazdı),
X
.. + Cov(Xi , Xj )
i6=j
Z ∼ N(0, 1), X = Z, Y = Z2
8
En sondaki terim sıfırdır, çünkü hem E(Z) ve E(Z3 ) sıfırdır [hoca burada standart
normalin tek sayılı (odd) moment’leri hep sıfırdır dedi]. O zaman şu sonucu
çıkartıyoruz, X, Y arasında korelasyon yok.
Ama bağımlılık var mı? Var. Çünkü hem X hem Y Z’nin birer değişkeni, yani
bu durumda X’i bilmek bize Y’yi tamamen bilmemizi sağlıyor (sadece ek olarak
bir kare alıyoruz). Tabii bağımlılık illa herşeyin bilinmesi demek değildir, bi-
raz bağımlılık ta olabilir, ama biraz bağımlılık bile varsa, bağımsızlık var diye-
meyiz. Aynı şey ters yön için de geçerli, Y bilinince X’in “büyüklüğünü” bilebil-
iriz, karekök işlemi olduğu için -/+ işareti bilemeyiz ama skalar bir büyüklüğü
elde edebiliriz. Yani ters yönde de bağımsızlık yoktur.
Faydalı bir Eşitlik [1, sf 120]
Var(aX + b) = a2 Var(X)
Var(aX) = a2 Var(X)
İspat
µ = E(X) olsun ve E(aX+b) = aµ+b olduğunu hatırlayalım. Varyans tanımından
hareketle,
= E (aX + b − aµ + b)2
= E (aX − aµ)2
= E a2 (X − µ)2
= a2 E (X − µ)
= a2 Var(X)
Korelasyon
Tanım
9
Cov(X, Y)
Corr(X, Y) = (2)
SD(X)SD(Y)
−1 6 Corr(X, Y) 6 1
Yani ölçü biriminden bağımsız olması avantajına ek olarak hep aynı skalada olan
bir değerin rapor edilmesi de faydalıdır. Eğer korelasyon 0.99 bulursam bunun
10
hemen yüksek bir korelasyon olduğunu bilirim.
Bu arada, Çauchy-Schwarz eşitsizliğinden bahsedeyim -ki bu eşitsizlik tanımı
tüm matematikteki en önemli eşitsizliklerden biridir- eğer korelasyon formülünü
lineer cebirsel şekilde ifade etseydim direk Cauchy-Schwarz eşitsizliğini elde ed-
erdim.
İspat
Önce “WLOG çerçevesinde” X, Y’nin önceden standardize edilmiş olduğunu kabul
edelim. [WLOG ne demek? Matematikçiler ispatlar sırasında bunu bazen kul-
lanırlar, genelleme kuvvetinde bir kayıp olmadan (without loss of generality)
takip eden şeyi kullanabiliriz demektir, yani “bir başka şey kullanıyorum, ama
teori bu çerçevede de hala geçerli” demek isterler].
Önceden standardize edildiğini kabul etmek niye fark yaratmıyor? Çünkü bunu
gördük, standart olmayan değişkenleri standardize edince yine aynı sonucu elde
ediyorum, yani bir şey farketmiyor.
Var(X + Y)’i hesaplayalım.
Var(X + Y) = 1 + 1 + 2ρ = 2 + 2ρ
Peki farkların varyansı, Var(X − Y) nedir? Bir numara kullanalım, Var(X − Y)’i
Var(X + (−Y)) olarak görelim,
Aslında bu son ifade ispatı tamamlamış oldu, çünkü varyans negatif olmayam
bir şeydir, yani
0 6 Var(X + Y) = 2 + 2ρ
0 6 Var(X − Y) = 2 − 2ρ
11
−2 6 2ρ
−2 6 −2ρ
ve
−1 6 ρ
ρ61
Dikkat, p bir vektör, tabii ki, çünkü binom durumunda p tek sayı idi, şimdi “pek
çok p”ye ihtiyaç var.
Her i, j için Cov(Xi , Xj )’yi hesapla.
Eger i = j ise Cov(Xi , Xi ) = Var(Xi ) = npi (1 − pi ).
ki son ifade binom dağılımının varyansıdır. Bu basit durum tabii ki, ilginç olan
i 6= j olmadığı zaman.
Tek örnek seçelim, mesela Cov(X1 , X2 ), buradan gelen sonuç gayet kolayca genelleştirilebilir.
Hesaba başlamadan önce kabaca bir akıl yürütelim; Cov(X1 , X2 ) için artı mı eksi
mi bir değer elde ederdik acaba? Multinom dağılımı hatırlayalım, belli sayıda
“şey” yine belli sayıda kategori arasında “kapışılıyor”, yani bu kategoriler arasında
bir yarış var. O zaman herhangi iki kategorinin kovaryansının negatif olmasını
bekleriz.
Çözüm için (4) formülünü kullanacağım, ama seçici bir şekilde,
12
Var(X + Y) = Var(X) + Var(Y) + 2Cov(X, Y)
Eh artık denklemdeki her şeyi biliyoruz, sadece c’yi bilmiyoruz, ona göre herşeyi
düzenleyelim,
Burada biraz haldir huldür işlem lazım [bu kısmı okuyucu isterse yapabilir],
sonuç
Cov(X1 , X2 ) = −np1 p2
Genel olarak
Cov(Xi , Xj ) = −npi pj , ∀i 6= j
Dikkat edelim, bu sonuç her zaman negatiftir (çünkü p değerleri olasılık değerleridirler,
yani pozitif olmak zorundadırlar)
Örnek
Binom değişkenin varyansını hesaplayalım şimdi. Bunu daha önce yapmıştık
ama göstergeç (indicator) rasgele değişkenleri kullanarak yapmıştık bunu, şimdi
elimizde yeni bir araç var, onu kullanalım. Varacağımız sonuç Var(X) = npq
olacak. Tanımlar,
X ∼ Bin(n, p), X = X1 + .. + Xn
13
I2A = IA
I3A = IA
Değil mi? Göstergeç sadece 1/0 olabiliyorsa onun karesi, küpü aynı şekilde olur.
Bunu vurguluyorum, çünkü bazen atlanıyor.
Peki IA IB ? Ki A, B ayrı ayrı olaylar. Gayet basit,
IA IB = IA∩B
Bu normal değil mi? Eşitliğin solundaki çarpım sadece her iki değişken de 1 işe 1
sonucunu verir, bu ise sadece A, B olayları aynı anda olduğu zaman mümkündür,
ki bu aynı anda olmak küme kesişmesinin tanımıdır.
Bernoullli durumuna dönelim, her Bernoulli için
X2j = Xj ’dir, bunu biraz önce gördük, ve Binom değişkenleri göstergeç gibi görüyoruz,
o zaman EX2j = E(Xj ) = p.
Var(Xi ) = p − p2 = p(1 − p) = pq
Var(X) = npq
X ∼ HGeom(w, b, n)
14
Matrisler İle Kovaryans Hesabı
Eğer verinin kolonları arasındaki ilişkiyi görmek istersek, en hızlı yöntem ma-
tristeki her kolonun (değişkenin) ortalamasını kendisinden çıkartmak, yani onu
“sıfırda ortalamak” ve bu matrisin devriğini alarak kendisi ile çarpmaktır. Bu
işlem her kolonu kendisi ve diğer kolonlar ile noktasal çarpımdan geçirecektir
ve çarpım, toplama sonucunu nihai matrise yazacaktır. Çarpımların bildiğimiz
özelliğine göre, artı değer artı değerle çarpılınca artı, eksi ile eksi artı, eksi ile
artı eksi verir, ve bu bilgi bize ilinti bulma hakkında güzel bir ipucu sunar. Poz-
itif sonucun pozitif korelasyon, negatif ise tersi şekilde ilinti olduğu sonucuna
böylece kolayca erişebiliriz.
Tanım
1
S= (X − E(X))T (X − E(X)))
n
print df.cov()
means = df.mean()
n = df.shape[0]
df2 = df.apply(lambda x: x - means, axis=1)
print np.dot(df2.T,df2) / n
Verisel kovaryansın sayısal gösterdiğini grafiklemek istersek, yani iki veya daha
fazla boyutun arasındaki ilişkileri grafiklemek için yöntemlerden birisi verideki
mümkün her ikili ilişkiyi grafiksel olarak göstermektir. Pandas scatter_matrix
bunu yapabilir. Iris veri seti üzerinde görelim, her boyut hem y-ekseni hem x-
ekseninde verilmiş, ilişkiyi görmek için eksende o boyutu bulup kesişme nokta-
larındaki grafiğe bakmak lazım.
import pandas as pd
df = pd.read_csv('iris.csv')
df = df.ix[:,0:4]
pd.scatter_matrix(df)
plt.savefig('stat_summary_01.png')
15
İlişki olduğu zaman o ilişkiye tekabül eden grafikte “düz çizgiye benzer” bir
görüntü olur, demek ki değişkenlerden biri artınca öteki de artıyor (eğer çizgi
soldan sage yukarı doğru gidiyorsa), azalınca öteki de azalıyor demektir (eğer
çizgi aşağı doğru iniyorsa). Eğer ilinti yok ise bol gürültülü, ya da yuvarlak
küreye benzer bir şekil çıkar. Üstteki grafiğe göre yaprak genişliği (petal width)
ile yaprak boyu (petal length) arasında bir ilişki var.
Tanım
X, Y rasgele değişkenlerin arasındaki kovaryans,
Yani hem X hem Y’nin beklentilerinden ne kadar saptıklarını her veri ikilisi için,
çıkartarak tespit ediyoruz, daha sonra bu farkları birbiriyle çarpıyoruz, ve bek-
lentisini alıyoruz (yani tüm olasılık üzerinden ne olacağını hesaplıyoruz).
Ayrı ayrı X, Y değişkenleri yerine çok boyutlu X kullanırsak, ki boyutları m, n ol-
sun yani m veri noktası ve n boyut (özellik, öğe) var, tanımı şöyle ifade edebiliriz,
16
Phi korelasyon katsayısı
ile hesaplanır. Bu ifadeyi türetmek için iki rasgele değişken arasındaki korelasy-
onu hesaplayan formül ile başlıyoruz,
E(XY) − E(X)E(Y)
=p
Var(X) · Var(Y)
XX
E[XY] = xi · yj · P{X = xi , Y = yj }
i j
17
çok daha fazla 1 olan veriler, ya da tam tersi) üzerinde bile hala optimal olarak
çalıştığı [4] bulunmuştur.
Bazı örnekler,
-0.333333333333
Ya da
0.541553390893
print np.mean(data)
213.948899167
print np.median(data)
214.06
print np.std(data)
125.118481954
18
print np.mean(data)+2*np.std(data)
464.185863074
Görüldüğü gibi üç nokta hesabı için ortalamadan iki sapma ötesini kullanırsak,
464.18, fakat 95. yüzdeliği kullanırsak 410.41 elde ediyoruz. Niye? Sebep ortala-
manın kendisi hesaplanırken çok üç değerlerin toplama dahil edilmiş olması ve
bu durum, ortalamanın kendisini daha büyük seviyeye doğru itiyor. Yüzdelik
hesabı ise sadece sayıları sıralayıp belli bazı elemanları otomatik olarak üç nokta
olarak addediyor.
Grupların Ortalamalarını ve Varyanslarını Birleştirmek
Bazen elimizde bir verinin farklı parçaları üzerinde hesaplanmış ortalama, varyans
sonucu olabilir, ve bu hesapları bu parçaların toplamı için birleştirmemiz gereke-
bilir. Belki paralel süreçler var, verinin parçaları üzerinde eşzamanlı çalışıyorlar,
bir ortalama, varyans hesaplıyorlar, ve nihai sonucun bu alt sonuçlar üzerinden
raporlanması lazım [3].
İşlenen veri setinin tamamı, birleşmiş (pooled) veri D = {x1 , x2 , .., xN } olsun, ki
N veri noktası sayısı. Bu verinin ortalaması a = (x1 + x2 + .. + xN )/N, varyansı √
v = ((x1 − a)2 + (x2 − a)2 + ... + (xN − a)2 )/N. Standart sapma tabii ki σN = v.
Veriyi ayrı işledik diyelim, veri şu şekilde ayrıldı D1 = {x1 , x2 , .., xj }, D2 = {xj+1 , xj+2 , .., xj+k },
D3 = {xj+k+1 , xj+k+2 , .., xj+k+m }. Yani her veri grubunun büyüklüğü sırasıyla
j, k, m ve toplam veri noktaları n = j + k + m.
P
DP ’nin ortalaması aP = n1 n i=1 xi . Her grup D1 , D2 , D3 ’un ortalaması a1 , a2 , a3
benzer şekilde bulunabilir. Bu durumda “ortalamaların ortalaması”, yani nihai
ortalama aP şöyle bulunabilir,
X
n
SP = x2i (7)
i=1
1X
n
vP = (xi − aP )2
n i=1
19
Bu ifadeyi acarsak
1X 2
n
= (xi − 2xi ap + a2p )
n i=1
1X 2 1X 1X 2
n n n
= xi − 2xi ap + a
n i=1 n i=1 n i=1 p
1
Pn 1
Pn
n i=1 xi = ap olduğunu hatırlarsak, ve n i=1 ap tabii ki yine ap o zaman
1X 2
n
= Sp /n − 2a2p + a
n i=1 p
1
Pn
n i=1 a2p benzer sekilde tekrar ap ,
= Sp /n − 2a2p + a2p
vP = Sp /n − a2p (8)
vp = (S1 + S2 + S3 )/n
Ya da
nvp = S1 + S2 + S3 − na2p
Açarsak
Şu da söylenebilir,
20
Şimdi (10) formülüne nasıl erisebileceğimizi düşünelim. Alttaki iki kavramdan
hareketle bunu yapabilir miyiz acaba?
Varyansların ortalamasını
ve ortalamaların varyansını
Evet bu hakikaten mümkün, (10) formülüne erişmiş olduk. Demek ki ayrı gru-
plardan elde edilen varyanslar ve ortalamarını alıp, bu varyansların ortalamasını
21
ve ortalamaların varyanslarını hesaplayıp birbirine toplayınca tüm verinin nihai
varyansına erişmiş oluyoruz.
Kod üzerinde görelim, [3]’teki veriyi kullandık,
Not: Birleştirirken n1 ,n2 sayıları ile çarpım var, bu aşırı büyük sayılara sebep ol-
maz mı? Olabilir doğru, ki kısmen bu sebeple artımsal hesap yapıyorduk, fakat
hala büyük sayılardan kaçmak mümkün, mesela genel ortalama hesaplarken n1 ,n2
ile çarpıp n1 + n2 ile bölüyor olabiliriz, fakat bu hesapta tek gerekli olan aslında
n1 ve n2 ’nin birbirine olan izafi büyüklüğüdür. Eğer ni /100 kullansak birleştirme
işlemi yine aynı çıkardı. O zaman bir teknik tüm ni ’leri en büyük olan ile bölmek,
böylece 1’den ufak sayılarla iş yaparız, ve sonuç yine aynı çıkar.
Box Whisker Grafikleri
Tek boyutlu bir verinin dağılımını görmek için Box ve Whisker grafikleri fay-
dalı araçlardır; medyan (median), dağılımın genişliğini ve sıradışı noktaları (out-
liers) açık şekilde gösterirler. İsim nereden geliyor? Box yani kutu, dağılımın
ağırlığının nerede olduğunu gösterir, medyanın sağındada ve solunda olmak
üzere iki çeyreğin arasındaki kısımdır, kutu olarak resmedilir. Whiskers kedi-
lerin bıyıklarına verilen isimdir, zaten grafikte birazcık bıyık gibi duruyorlar. Bu
uzantılar medyan noktasından her iki yana kutunun iki katı kadar uzatılır sonra
verideki ”ondan az olan en büyük” noktaya kadar geri çekilir. Tüm bunların
dışında kalan veri ise teker teker nokta olarak grafikte basılır. Bunlar sıradışı
(outlier) oldukları için daha az olacakları tahmin edilir.
BW grafikleri iki veriyi dağılımsal olarak karşılaştırmak için
içeren Quintus Curtius Snodgrass veri setinin değişik olduğunu ispatlamak için
bir sürü hesap yapmışlardır, bir sürü matematiksel işleme girmişlerdir, fakat basit
bir BW grafiği iki setin farklılığını hemen gösterir.
22
BW grafikleri iki veriyi dağılımsal olarak karşılaştırmak için birebirdir. Mesela
Larsen and Marx adlı araştırmacılar çok az veri içeren Quintus Curtius Snod-
grass veri setinin değişik olduğunu ispatlamak için bir sürü hesap yapmışlardır,
bir sürü matematiksel işleme girmişlerdir, fakat basit bir BW grafiği iki setin
farklılığını hemen gösterir.
Python üzerinde basit bir BW grafiği
data = loadtxt("glass.data",delimiter=",")
head = data[data[:,10]==7]
tableware = data[data[:,10]==6]
containers = data[data[:,10]==5]
print head[:,1]
plt.boxplot(data,0,'rs',0,0.75)
plt.savefig('stat_feat_02.png')
23
Kaynaklar
[1] Ross, Introduction to Probability and Statistics for Engineers, 3rd Edition
[2] Wasserman, All of Statistics
[3] Rudmin, Calculating the Exact Pooled Variance, https://arxiv.org/abs/
1007.1012
[4] Boughorbel, Optimal classifier for imbalanced data using Matthews Correlation
Coefficient metric, http://journals.plos.org/plosone/article/file?
id=10.1371/journal.pone.0177678&type=printable
[5] Cross Validated, Relation between the phi, Matthews and Pearson correlation coeffi-
cients?, https://stats.stackexchange.com/questions/59343/relation-
between-the-phi-matthews-and-pearson-correlation-coefficients
[6] Bayramli, Diferansiyel Denklemler, Ters Trigonometrik Formüller
24
Koşulsal Olasılık ve Koşulsal Beklenti (Conditional Probability, Conditional Ex-
pectation)
Olasılık teorisinin en faydalı tekniklerinden biri koşulsal olasılık ve koşulsal bek-
lentidir. Bunun iki sebebi var. Birincisi pratikte çoğunlukla elimizde bir bilgi
geçtiği durumda olasılık ve beklenti hesabı yaptığımız, yani istediğimiz hesapların
“koşullu” olması. İkincisi olasılık ya da beklenti hesabında bu hesabı ilk önce bir
başka rasgele değişkene koşullamanın çok faydalı olması.
Diyelim ki tavla oynarken iki zar atıyoruz, temel olasılıktan biliyoruz ki her se-
ferinde 36 mümkün sonuçlardan biri ortaya çıkacak, mesela (1,2) ya da (5,5),
vs, o zaman, eğer zar hileli değilse her sonucun olasılığı 1/36. Şimdi diyelim
ki ilk zarın 4 geldiğini gördük, ve birisi diğer zarın üstünü kapattı, ve bu bilgi
ışığında bize iki zarın toplamının 6 olma olasılığının ne olduğunu sordu. İlk
zarın 4 olduğu bilgisi verildiğine göre toplamı gözönüne almadan önce altı tane
mümkün sonucu düşüürüz,, (4,1), (4,2), (4,3), (4,4), (4,5), (4,6). Bu seçeneklerin
herbirinin ortaya çıkma ihtimali birbirine eşit. Biraz önceki sonuçları olaylar
olarak düşünürsek, E’yi iki zarın toplamının 6 olması olayı, F’yi ilk zarın 4 olma
olayı olarak tanımlayabiliriz, bu durumda aradığımız sonuç,
P(E|F)
P(EF)
P(E|F) = (1)
P(F)
P(EF) hem E hem F olaylarının aynı anda olma olasılığı, yani E kümesi ve F
kümesinin kesişimi. Bölendeki P(F) bir anlamda P(E|F) hesabını F bazında yapma
amaçlı; çünkü F olduğunu “biliyoruz” ve artık örneklem uzayımız F haline geliyor,
bu uzay içinde E’nin olma olasılığına bakıyoruz. Not: Hesabın geçerli olması için
P(F) > 0 olmalı tabii ki.
Biraz önceki örnek için aradığımız cevap 1/6 çünkü altı mümkün sonuç içinde
sadece (4,2) olayı bizi ilgilendiriyor.
Bağımsız Olaylar
İki olay E, F’nin birbirinden bağımsız olduğu söylenir, eğer
P(EF) = P(E)P(F)
P(E|F) = P(E)
1
sonucunu verir, bu sonuç akla yatkın olmalı, eğer E, F bağımsız ise, F’in verilmiş
olması bize E hakkında hiçbir şey söylemez.
Bayes Formülü
Yine E ve F olayları var, ki EF hem E, hem de F’nin olma durumu, o zaman E
E = EF ∪ EFc
olarak gösterilebilir çünkü bir öğenin R içinde olması için ya E ve F içinde olması,
ya da E içinde olması ama F içinde olmaması lazımdır. EF ve EFc birbirlerinin
tam tersi, karşılıklı dışarlayan (mütually exclusive) olaylar oldukları için alttaki
doğru olacaktır,
Üstteki son formül P(E)’nin bir ağırlıklı ortalama olduğunu söylüyor; ağırlıklar
F’in olma ve olmama olasılığı, ve bu ağırlıklar F’nin olduğu ve olmadığının ver-
ildiği durumdaki E olasılıklarının ağırlıklı ortalamasını alıyorlar.
Örnek
Bir hastalık için bir labaratuarun test tekniğinin yüzde 95 başarısı var. Fakat bu
test bazen “yanlış pozitif” cevabı da verebiliyor; hasta olmayan kişilerin yüzde
1’i için, yani 0.01 olasılıkla test hasta diyebiliyor. Eğer toplumun yüzde 0.5’inde
bu hastalığın olduğu biliniyorsa, herhangi bir kişinin testi pozitif geldiğinde o
kişinin gerçekten hasta olma olasılığı nedir?
Cevap
D test edilen kişinin hasta olma olayı diyelim, E testin pozitif olması. Aradığımız
P(D|E) olasılığı.
P(DE)
P(D|E) =
P(E)
P(E|D)P(D)
= (2)
P(E|D)P(D) + P(E|Dc )P(Dc )
(0.95)(0.005)
(0.95)(0.005) + (0.01)(0.995)
2
95
= ≈ 0.323
294
Yapılan bazı hareketlere dikkat: 4 üstteki denklemde P(DE)’yi onun bir altında
P(E|D)P(D), yani P(ED)’ye çevirdik, çünkü P(DE) ile P(ED) aynı şey.
Ayrıca çözüme yaklaşma şeklimiz istenen P(D|E) için P(E|D) ve onunla alakalı
olan rakamları kullanmak; problemde bildiğimiz E’nin verildiği durum değil,
onun tersi, D’nin verildiği durum. Yani test tekniği hakkında elimizde bazı bil-
giler var, bu bilgiler ışığında test pozitif verirse bu sonuca ne kadar inanalım diy-
oruz bir anlamda.
(2) formülü, onun ikiden fazla seçenek için ayrıksal, ya da sürekli olarak genelleştirilmiş
hali Bayes Formülü olarak biliniyor.
Rasgele Degiskenler
Hatırlayalım, iki olay E, F için P(F) > 0 ise, F’in verildiği durumda (koşul) E’nin
olasılığı
P(EF)
P(E|F) =
P(F)
P(X = x, Y = y)
=
P(Y = y)
p(x, y)
=
pY (y)
X
pX (a|y)
a6x
3
X
E(X|Y = y) = xP(X = x|Y = y)
x
X
= xpX (x|y)
x
Yani herşey daha önce normal olasılık tanımlarında olduğu gibi, sadece şimdi
tüm ifadeler Y = y olayına koşullu. Bunun söyleyebiliyoruz çünkü eğer X Y’den
bağımsız olsaydı
= P(X = x)
olsun. Y = 1’in verili olduğu durumda X’in olasılık kütle fonksiyonunu hesaplayın.
Çözüm
Y sadece 1 olabileceğine göre, pX|Y (1|1) ve pX|Y (2|1)’i hesaplanırsa iş biter. Bu
değerleri ayrı ayrı bulacağız çünkü dağılım bir formül değil, üstteki gibi sunulan
ayrıksal olasılıklarla her ihtimal ayrı çözülmeli.
P(X = 1, Y = 1)
pX|Y (1|1) = P(X = 1|Y = 1) =
P(Y = 1)
p(1, 1) 5
= =
pY (1) 6
X
pY (1) = p(x, 1) = p(1, 1) + p(2, 1) = 0.6
x
Ayrıca iki üstte 5/6 oldu çünkü 0.5/0.6 = 5/6. Devam edelim,
4
p(2, 1) 1
pX|Y (2|1) = =
pY (1) 6
Sürekli Durum
Sürekli rasgele değişkenler için koşullu olasılık yoğunluk fonksiyonları
fX,Y (x, y)
fX|Y (x|y) =
fY (y)
Eğer koşullu yoğunluk üzerinden olay hesabı yapmak istersek, ve fY (y) > 0
olduğunu farzederek,
Z
P(X ∈ A|Y = y) = fX|Y (x|y) dx
A
Örnek
x + y eğer 0 6 x 6 1, 0 6 y 6 1
f(x, y) =
0 diğer
1
fY (y) = +y
2
fX,Y (x, y)
fX|Y (x|y) =
fY (y)
x+y
= 1
2
+y
Z 1/4 1 1
x+ 3 32
+ 13 14
P(X < 1/4|Y = 1/3) = 1 1
dx = 1
=
0 2
+ 3 2
+ 13 32
5
E(X|Y)’nin kendisi de bir rasgele değişkendir. Koşulsal beklentinin çok önemli
özelliklerinden biri her X, Y rasgele değişkeni için
E(X) = E(E(X|Y))
İspat
Ayrıksal durum için,
X
EY (EX|Y (X|Y)) = EY x · P(X = x|Y)
x
XX
= x · P(X = x|Y = y) P(Y = y)
y x
XX
= x · P(X = x|Y = y)P(Y = y)
y x
X X
= x P(X = x|Y = y)P(Y = y)
x y
X X
= x P(X = x, Y = y)
x y
X
= xP(X = x)
y
= E(X)
Soru
Bir maden işçisi kaza sonrası bir madende tıkalı kalıyor. Dışarı çıkabilmesi için
önünde üç değişik kapı var; birinciyi seçerse 2 saat yürüdükten sonra dışarı
çıkacak. Eğer ikinciyi seçerse 3 saat yürüdükten sonra tekrar madene dönecek.
Üçüncüyü seçerse bu sefer 5 saat yürüdükten sonra madene dönecek. İşçi hangi
kapının onu dışarı çıkartacağını bilmiyor, herhangi bir kapıyı eşit olasılıkla seçecek.
İşçinin dışarı çıkma süresinin beklentisi nedir?
Cevap
6
X değişkeni işçinin dışarı çıkma süresini belirten rasgele değişken olsun, Y ise
işçinin ilk seçtiği kapı.
1
E(X) = E(X|Y = 1) + E(X|Y = 2) + E(X|Y = 3) (3)
3
Buraya kadar basit: Fakat sorudaki puf noktaya dikkat, eger kapi 2 ay da 3 se-
cilirse isci tekrar madene donuyor, yani bastaki haline geri gelmis oluyor. O za-
man
E(X|Y = 1) = 2
E(X|Y = 2) = 3 + E(X)
E(X|Y = 3) = 5 + E(X)
1
E(X) = 2 + 3 + E(X) + 5 + E(X)
3
E(X) = 10
7
Büyük Sayılar, Veri
Büyük Sayılar Kanunu (Law of Large Numbers)
Bu kanun, örneklem (sample) ile rasgele değişkenler, yani matematiksel olasılık
dağılımları arasında bir bağlantı görevi görür. Kanun kabaca bildiğimiz günlük
bir gerçeğin matematiksel ispatıdır. Yazı-tura atarken yazı çıkma ihtimalinin
1/2 olduğunu biliyoruz; herhalde çoğumuz bu yazı-tura işlemin ”bir çok kere”
tekrarlandığı durumda, toplam sonucun aşağı yukarı yarısının yazı olacağını
bilir.
Matematiksel olarak, farzedelim ki her yazı-tura atışı bir deney olsun. Deneylerin
sonucu X1 , X2 ...Xn olarak rasgelen değişkenlerle olsun, bu değişkenlerin dağılımı
aynı (çünkü aynı zar), ve birbirlerinden bağımsızlar (çünkü her deney diğerinden
alakasız). Değişkenlerin sonucu 1 ya da 0 değeri taşıyacak, Yazı=1, Tura=0.
Büyük Sayılar Kanunu tüm bu deney sonuçlarının, yani rasgele değişkenlerin av-
erajı alınırsa, yani X̄ = X1 + .. + Xn ile, elde edilen sonucun Xi ’lerin (aynı olan)
beklentisine yaklaşacağının söyler, yani n büyüdükçe X̄n ’in 1/2’ye yaklaştığını
ispatlar, yani E[Xi ] = 1/2 değerine. Notasyonel olarak E(Xi ) = µ olarak da
gösterilebilir.
Özetlemek gerekirse, bir olasılık dağılımına sahip olan, görmediğimiz bir “yer-
lerde” olan bir dağılımdan bir örneklem alıyoruz, örneklem bir zar atma işlemi
gibi (simülasyon ile bu değişkenleri de doldurabilirdik), sonra bu değişkenlerin
averajını alıyoruz, ve bu averajın o görmediğimiz bilmediğimiz “gerçek” dağılımın
µ değerine yaklaştığını görüyoruz.
Formülsel olarak, herhangi bir > 0 için,
lim P(|X̄ − µ| 6 ) = 1
n→∞
ya da
ya da
P(|X̄n − µ| > ) → 0
Burada ne söylendiğine dikkat edelim, Xi dağılımı ne olursa olsun, yanı ister Bi-
nom, ister Gaussian olsun, örneklem üzerinden hesaplanan sayısal ortalamanın
(empirical mean) formülsel olasılık beklentisine yaklaştığını söylüyoruz! Xi ’ler
en absürt dağılımlar olabilirler, bu dağılımların fonksiyonu son derece çetrefil,
tek tepeli (unimodal) bile olmayabilir, o formüller üzerinden beklenti için gereken
entegralin belki analitik çözümü bile mevcut olmayabilir! Ama yine de ortalama,
1
o dağılımların beklentisine yaklaşacaktır. İstatistik ile olasılık teorisi arasındaki
çok önemli bir bağlantı bu.
Sonuç şaşırtıcı, fakat bir ek daha yapalım, sezgisel (intuitive) olarak bakarsak
aslında sonuç çok şaşırtıcı olmayabilir. Niye? Diyelim ki genel veri N(µ, σ2 )
şeklinde bir Normal dağılımdan geliyor ve örneklem de bu sebeple aynı dağılıma
sahip. Bu durumda örneklemdeki veri noktalarının µ’ya yakın değerler olmasını
beklemek mantıklı olmaz mı? Çünkü bu dağılım “zar atınca” ya da bir genel
nüfustan bir “örnek toplayınca” (ki bunu bir anlamda istatistiksel bir zar atışı
olarak görebiliriz) onu µ, σ2 ’e göre atacak. Örneklemi zar atışı sonuçları olarak
gördüğümüze göre elde edilen verilerin bu şekilde olacağı şaşırtıcı olmamalı. Ve
bu zar atışlarının ortalamasının, son derece basit bir aritmetik bir işlemle hesa-
planıyor olsa bile, µ’ye yaklaşması normal olmalı.
Bu arada, bu argümana tersten bakarsak Monte Carlo entegralinin niye işlediğini
görebiliriz, bkz [3].
Özellikle örneklem ile genel nüfus (population) arasında kurulan bağlantıya dikkat
edelim. İstatiğin önemli bir bölümünün bu bağlantı olduğu söylenebilir. Her
örneklem, bilmediğimiz ama genel nüfusu temsil eden bir dağılımla aynı dağılıma
sahip olan Xi ’dir dedik, ve bu aynılıktan ve bağımsızlıktan yola çıkarak bize
genel nüfus hakkında bir ipucu sağlayan bir kanun geliştirdik (ve birazdan is-
patlayacağız).
Ispata başlayalım.
X1 , X2 , .., Xn bagimsiz degiskenler olsun.
E(Xi ) = µ
Var(Xi ) = σ
1X
n
X̄n = Xi
n i=1
X̄n de bir rasgele değişkendir, çünku X̄n değişkeni her Xi dağılımıyla alakalı.
İspata devam etmek için X̄n dağılımının beklentisini bulmamız gerekiyor.
1X
n
E(X̄n ) = E( Xi )
n i=1
E doğrusal bir işleç (linear operatör) olduğu için dışarıdan içeri doğru nüfuz eder.
2
1X
n
1
= E(Xi ) = nµ = µ
n i=1 n
Y = a + bX
Var(Y) = b2 Var(X)
1X
n
X̄n = Xi
n i=1
1X 1 X
n n
Var(X̄n ) = Var( Xi ) = 2 Var(Xi )
n i=1 n i=1
1 X 2
n
1 σ2
Var(X̄n ) = 2 σ = 2 nσ2 = (3)
n i=1 n n
P(|X̄n − µ| > ) → 0
Çebişev’den
Var(X̄n )
P(|X̄n − µ| > ) 6
2
σ2
P(|X̄n − µ| > ) 6 →0
n2
3
σ2 /n2 ’nin sıfıra gittiğini gösterdik. σ2 /n2 de P(|X̄n −µ| > )’den büyük olduğuna
göre, demek ki o da sıfıra iner.
Çebişev Eşitsizliğinin ispatı ek bölümde bulunabilir.
Büyük Sayılar Kanunu örneklem ortalamasının ve varyansının Xi ’in beklentisi
ve varyansı ile bağlantı kurar. Merkezi Limit Teorisi bir adım daha atar, ve der ki
“X̄’in dağılımı Gaussian dağılım olmalıdır yani normal eğrisi şeklinde çıkmalıdır!”.
Teorinin detayları bu bölümde bulunabilir.
Merkezi Limit Teorisi (Central Limit Theorem -CLT-)
Büyük Sayılar Kanunu örneklem ortalamasının gerçek nüfus beklentisine yaklaşacağını
ispatladı. Örneklem herhangi bir dağılımdan gelebiliyordu. CLT bu teoriyi bir
adım ilerletiyor ve diyor ki kendisi de bir rasgele değişken olan örneklem ortala-
ması X̄ Normal dağılıma sahiptir! Daha detaylandırmal gerekirse,
Diyelim ki X1 , .., Xi örneklemi birbirinden bağımsız, aynı dağılımlı ve ortalaması
µ, standart sapması σ olan (ki o da aynı dağılıma sahip) bir nüfustan geliyorlar.
Örneklem ortalaması X̄,√ki bu rasgele değişkenin beklentisinin µ, ve (3)’e göre
standart sapmasının σ/ n olduğunu biliyoruz. Dikkat: X̄’in kendisinden değil,
beklentisinden bahsediyoruz, BSK’deki aynı durum, yani ortalama dağılımının√or-
talaması. Teori der ki n büyüdükçe X̄ dağılımı (bu sefer kendisi) bir N(µ, σ/ n)
dağılımına yaklaşır.
Bu ifade genelde standart normal olarak gösterilir, herhangi bir normal dağılımı
standart normal’e dönüştürmeyi daha önce görmüştük zaten, beklentiyi çıkartıp
standart sapmaya bölüyoruz, o zaman örneklem dağılımı X̄,
X̄ − µ
Z= √
σ/ n
4
60,90 gibi değerlerin “olurluğu” düşüktür. Gaussin üzerinde örnek,
1 1 2
f(x; µ, σ) = √ exp − 2 (x − µ) , x ∈ R
σ 2π 2σ
Çarpım sonrası
Y
1 1
f(x1 , .., xn ; µ, σ) = √ exp − 2 (xi − µ)2
σ 2π 2σ
P
(2π)−n/2 (xi − µ)2
= exp −
σn 2σ2
Üstel kısım −n/2 nereden geldi? Çünkü bölen olan karekökü üste çıkardık, böylece
−1/2 oldu, n çünkü n tane veri noktası yüzünden formül n kere çarpılıyor. Veri
noktaları xi içinde. Eğer log, yani ln alırsak exp’den kurtuluruz, ve biliyoruz ki
log olurluğu maksimize etmek normal olurluğu maksimize etmek ile aynı şeydir,
çünkü ln transformasyonu monoton bir transformasyondur. Ayrıca olurluk içbukeydir
(concave) yani kesin tek bir maksimumu vardır.
P
1 (xi − µ)2
ln f = − n ln(2π) − n ln σ −
2 2σ2
P
∂(ln f) (xi − µ)2
= =0
∂µ 2σ2
P
xi
µ̂ =
n
Bu sonuç (1)’deki formül, yani örneklem ortalaması ile aynı! Fakat buradan
hemen bir bağlantıya zıplamadan önce şunu hatırlayalım - örneklem ortalaması
formülünü biz tanımladık. “Tanım” diyerek bir ifade yazdık, ve budur dedik.
Şimdi sonradan, verinin dağılımının Gaussian olduğunu farzederek, bu verinin
mümkün kılabileceği en optimal parametre değeri nedir diye hesap ederek aynı
formüle eriştik, fakat bu bir anlamda bir güzel raslantı oldu.. Daha doğrusu
bu aynılık Gaussian / Normal dağılımlarının “normalliği” ile alakalı muhakkak,
fakat örnekleme ortalaması hiçbir dağılım faraziyesi yapmıyor, herhangi bir dağılımdan
geldiği bilinen ya da bilinmeyen bir veri üzerinde kullanılabiliyor. Bunu un-
utmayalım. İstatistikte matematiğin lakaytlaşması (sloppy) kolaydır, o sebeple
neyin tanım, neyin hangi faraziyeye göre optimal, neyin nüfus (population) neyin
örneklem (sample) olduğunu hep hatırlamamız lazım.
Devam edelim, maksimum olurluk ile σ̂ hesaplayalım,
5
P
∂(ln f) n (xi − µ)2
=− + =0
∂σ σ 2σ3
P
2 (xi − µ̂)2
σ̂ =
n
1X
σ̂2 = (Yi − µ̂)2
n
ya da
6
1X
σ̂2 = (Yi − Ȳ)2
n i
ile belirtildi. Tahmin edici σ̂2 , σ2 için yansız midir? Tanımımıza göre eğer tahmin
edici yansız ise E(σ̂2 ) = σ2 olmalıdır.
Not: Faydalı olacak bazı eşitlikler, daha önceden gördüğümüz
1X
2
E(σ̂ ) = E (Yi − Ȳ)2
n i
X X
(Yi − Ȳ)2 = (Yi2 − 2Yi Ȳ + Ȳ 2 )
i i
X X
= Yi2 − 2 Yi Ȳ + nȲ 2
i i
P P
Yi ’nin hemen yanında Ȳ görüyoruz. Fakat Ȳ’nin kendisi zaten 1/n i Yi de-
i
mek değil midir?
P Ya da, toplam içinde her i için değişmeyecek Ȳ’yi toplam dışına
çekersek, Ȳ i Yi olur, bu da Ȳ · nȲ demektir ya da nȲ 2 ,
X
= Yi2 − 2nȲ 2 + nȲ 2
i
X
= Yi2 − nȲ 2
i
Dikkat, artık −nȲ 2 toplama işleminin dışında. Şimdi beklentiye geri dönelim,
X
1 2 2
=E Yi − nȲ
n i
7
Daha önce demiştik ki (genel bağlamda)
Yani
E(Yi2 ) = Var(Yi ) + µ2
E(Ȳ) = µ,
E(Ȳ 2 ) = Var(Ȳ) + µ2
X
1 2 2
= Var(Yi ) + µ − n(Var(Ȳ) + µ )
n i
X
σ2
1 2 2 2
= (σ + µ ) − n( + µ )
n i
n
P
Tekrar hatırlatalım, i sadece ilk iki terim için geçerli, o zaman, ve sabit değerleri
n kadar topladığımıza göre bu aslında bir çarpım işlemi olur,
σ2
1 2 2 2
= nσ + nµ − n( + µ )
n n
σ2
= σ2 + µ2 − − µ2
n
8
σ2
= σ2 −
n
nσ2 σ2
= −
n n
nσ2 − σ2
=
n
σ2 (n − 1)
=
n
n−1
= σ2
n
Görüldüğü gibi eriştiğimiz sonuç σ2 değil, demek ki bu tahmin edici yansız değil.
Kontrol tamamlandı.
Fakat eriştiğimiz son denklem bize başka bir şey gösteriyor, eğer üstteki sonucu
n
n−1
ile çarpsaydık, σ2 elde etmez miydik? O zaman yanlı tahmin ediciyi yansız
n
hale çevirmek için, onu n−1 ile çarparız ve
n 1X
(Yi − Ȳ)2
n−1n i
1 X
= (Yi − Ȳ)2
n−1 i
import pandas as pd
arr = np.array([1,2,3])
print 'numpy', np.std(arr)
print 'pandas', float(pd.DataFrame(arr).std())
numpy 0.816496580928
pandas 1.0
Kaynaklar
[1] Wolfram Mathworld, Maximum Likelihood, http://mathworld.wolfram.
com/MaximumLikelihood.html
[2] Introduction to Probability and Statistics Using R
[3] Bayramli, Istatistik, Monte Carlo, Entegraller, MCMC
9
Örneklem Dağılımları (Sampling Distributions)
Bir (ve en önemli) örneklem dağılımını daha önce gördük, ki bu Normal dağılımdır.
X̄ = (X1 + X2 + ... + Xn )/n ortalaması ortalaması µ ve standard sapması σ/n2 olan
bir Normal dağılıma yaklaşır. Tabii bu dağılım standardize edilebilir, vs. Fakat
rasgele değişkenler üzerinde pek çok işlem mümkündür, ve bu işlemlerin bazıları
artık ünlü olan yeni / başka dağılımlar ortaya çıkartmışlardır. Bu dağılımlar
önemlidir, çünkü mesela bazı uygulamalarda veri noktalarının karesini alırız, ve
bu karesi alınmış normal noktaların bambaşka bir dağılımı vardır! Bu önemlidir
çünkü veri noktalarının normalliği faraziyesinden hareketle kare alma işlemi gerek-
tiren her ne hesap ise onun doğruluğunu bu sonuç dağılıma sorarak kontrol ede-
biliriz!
Devam edelim.
Ȳ−µ Ȳ−µ
√
σ/ n
ve √
S/ n
Karşılaştırması
Diyelim ki normal olarak dağıldığını bildiğimiz bir nüfustan Y1 , .., Yn rasgele örneklemini
topladık, ve amacımız bilinmeyen gerçek µ hakkında bazı sonuçlara varmak.
Eğer varyans σ2 biliniyorsa, bu noktadan sonra ne yapacağımız gayet açık: daha
önce gördüğümüz gibi bir karar kuralı ortaya çıkartmak, ya da güven aralığı
Ȳ−µ
hesaplamak çok kolay, ki bu tekniklerin temelinde Z = σ/ √ dağılımının stan-
n
dart normal fZ (z)’ye yaklaşması yatıyor.
2
Fakat pratikte
Pn σ genellikle bilinmez, o zaman nüfus varyansının tahmin edicisi
2 1 2
S = n−1 i=1 (Yi − Ȳ) kullanılır, ki bu maksimum olurluk tahmin edicisinin
yansız (unbiased) versiyonu. Fakat buradaki önemli soru şu: σ2 yerine S2 koyma
Z oranını nasıl etkiler? Daha önce büyük örneklemler için bir fark olmadığından
bahsettik. Peki küçük örneklemler için?
Küçük n için bu iki oranının birbirinden farklı olduğununun keşfi William Sealy
Gossett adlı araştırmacıya ait. 1899’da Oxford’dan Kimya ve Matematik bölümünden
mezun olduktan sonra Gossey, Guiness adlı şirkette çalışmaya başladı. Ürünlerin
üzerinde yapacağı deneylerden aldığı veriler lojistik bazı sebepler dolaşışıyla çok
azdı, ve “gerçek” σ2 ’nin bilinmesi mümkün değildi. Çoğu zaman n 4 ya da 5’den
Ȳ−µ
bile az oluyordu. Bu gibi durumlarla uğraşa uğraşa Gossey S/ √ ’nin beklendiği
n
gibi çan eğrisi fZ (z) şeklinde değil, daha “etekleri kabarık” başka bir dağılım gibi
gözüktüğünü farketti, yani sıfırdan çok küçük ya da ondan çok büyük oranların
ihtimali çok düşük değildi.
1
Üstteki histogram S kullanarak hesaplanmıştır, n = 4 olmak üzere 500 deney
üzerinden hesap yapılmıştır. İki dağılımın birbirinden uzaklaştığı görülüyor.
Genel olarak düşünmek gerekirse, olasılık dağılımları iki büyük kategori altına
düşer. Aşağı yukarı bir düzine kadarı gerçek dünyadan alınabilecek her ölçümü
olduğu haliyle iyi modelleme kabiliyetine sahiptir; mesela normal, binom, Pois-
son, üstel dağılımlar gibi. Diğer yandan daha az sayıda (ama bir o kadar önemli)
dağılımlar n tane rasgele değişkenin üzerinden hesaplanan fonksiyonların nasıl
davrandığını çok iyi modeller. İşte bu dağılımlara örneklem dağılımları ismi ver-
ilir ve tipik kullanım alanları çıkarsama (inference) yapmaktır.
Normal dağılımı her iki kategoriye de aittir. Hem ayrı ayrı ölçümleri modelle-
Ȳ−µ
mek, hem de σ/ √ ’in olasılıksal davranışını modellemek için kullanılır. İkinci
n
kullanımı normal dağılımın bir örneklem dağılımı olarak kullanılmasına örnektir.
Normal dağılımdan sonra en önemli üç örneklem dağılımı Öğrenci t Dağılımı,
chi kare dağılımı ve F dağılımıdır. Son iki dağılım t oranını temsil eden fT (t)’yi,
Ȳ−µ
yani T = S/ √ ’yi türetmek için gerekli.
n
Türetmek
Şaşırtıcı gelebilir ama t dağılımının yoğunluk fonksiyonunu türetmek pek kolay
bir iş değildir, ilk başta kolay yapılabilirmiş gibi geliyor, çünkü Merkezi Limit
Ȳ−µ
Teorisinin temelini oluşturan σ/ √ ’in yoğunluğunu türetmek nisbeten basit, mo-
n
Ȳ−µ
√ ifadesinden Ȳ−µ
ment üreten fonksiyonlar ile yapılabiliyor. Fakat σ/ n
√ ifadesine
S/ n
geçmek çok daha zor, çünkü bu durumda T iki tane rasgele değişkeninin bir oranı
haline gelmiştir.
t Dağılımının ispatı için şu basamaklar gerekiyor; Önce standart normal ras-
gele değişkenlerin karelerinin toplamının gamma dağılımın özel bir hali olan
chi kare dağılımı olduğunu göstermek. Daha sonra normal dağılmış olan bir
nüfustan alınan n örneklemden elde edilen Ȳ ve S2 ’nin birbirinden bağımsız ras-
gele değişkenler olduğunu göstermek, ve n−1S2
’nin chi kare olarak dağıldığını is-
patlamak. Daha sonra sıra birbirinden bağımsız iki chi kare yoğunluk fonksiy-
onunun arasındaki oranı türetmeye gelecek, ki bu bir F dağılımıdır. En son olarak
Ȳ−µ
T 2 = ( S/ √ )2 ifadesinin birbirinden bağımsız iki chi kare dağılımının oranı olduğunu
n
2
göstermek ki T 2 ifadesi F dağılımının özel bir halidir.
Chi Kare, χ2 Dağılımı
Tanım
P
Z1 , .., Zp bağımsız standart Normal rasgele değişkenler ise, U = pi=1 Z2p ki bu
dagilima p derecede serbestliğe (değrees of freedom) olan chi kare dağılımı (chi
square distribution, yani χ2 ) ismi verilir.
Teori
U, p derece serbestliğe sahip bir χ2 dağılıma sahip ise, ki yoğunluk
1 (p/2)−1 −u/2
fU (u; p) = u e
Γ ( p2 )2p/2
u>0
Z∞
Γ (a) = ta−1 e−t dt
0
E[U] = p
Var[U] = 2p
F Dağılımı
Diyelim ki U ve V birbirinden bağımsız, ve sırasıyla m ve n derece serbestliğe
sahip iki chi kare dağılımı. O zaman V/mU/n
olarak hesaplanan yeni bir rasgele
değişkenin dağılımı, m, n derece serbestliğe sahip bir F dağılımı olarak ifade
edilir.
Teori
Z 2
Rasgele değişken U/n , ki U bir chi kare dağılımıdır, 1,n derece serbestliğe sahip
bir F dağılımına sahiptir.
İspatı burada vermiyoruz.
Teori (1)
Y1 , .., Yn ortalaması µ, varyansı σ2 olan bir normal dağılımdan alınan n örneklem
olsun. O zaman
3
a. S2 ve Ȳ birbirinden bağımsızdır
2 P
b. (n−1)S
σ2
= σ12 n 2
i=1 (Yi − Ȳ) ) hesabı n − 1 derece serbestliğe sahip bir chi kare
dağılımıdır.
İspat için [1, sf. 388].
Ȳ−µ
Nihayet √
S/ n
ifadesinin yoğunluğunu bulmak için tüm altyapıya sahibiz.
Tanım
Z bir standart normal rasgele değişken, U ise n derece serbestlikteki bir chi kare
rasgele değişken olsun. O zaman n derece serbestliği olan Öğrenci t oranı (Stu-
dent’s t ratio)
Z
Tn = q (2)
U
n
olarak belirtilir.
Teori
Y1 , .., Yn , bir µ, σ normal bir dağılımdan alınmış bir rasgele örneklem olsun. O
zaman
Ȳ − µ
Tn−1 = √
S/ n
√ Ȳ−µ
Ȳ − µ σ/ n
√ =q
S/ n (n−1)S2
σ2 (n−1)
Değil mi? Alttaki karekök içindeki bölendeki n−1’ler birbirini iptal eder, karekök
Ȳ−µ
kare ifadelerini iptal eder, ve geriye kalan S/σ, ters çevirilip σ/S olarak σ/ √ ’yi
n
çarpacaktır, onun bölümdeki σ’sini iptal edecektir, ve nihai bölüme S yerleştirilmiş
olur, ve eşitliğin solundaki ifadeye erişiriz. Fakat bu dönüştürücü bölüm ifadesi
sayesinde eşitliğin sağ tarafında yeni bir formüle eriştik; karekök ifadesi içine
2
bakarsak üstteki (b) teorisiyle uyumlu olarak (n−1)S σ2
görüyoruz, ki bu ifade bir
chi kare dağılımı.
Diğer yandan eşitliğin sağındaki bölüm kısmı bir standart normal. Yani (2)’de
tarif edilen duruma erişmiş oluyoruz, üstteki ifade bu tanıma göre bir t Dağılımı.
4
t Dağılımı (Student’s t)
X, n derece bağımsızlıkta t dağılımına sahiptir, ve dağılımı
Γ ( n+1
2
)
fT (t) = (n+1)/2
√
n t2
nπΓ ( 2 ) 1 + n
1
f(x) =
π(1 + x2 )
Çoğunlukla entegre edilen yerde “1 artı ya da eksi bir şeyin karesi” türünde bir
ifade görülürse, yerine geçirme (subsitution) işlemi trigonometrik olarak yapılır.
x = tan θ, θ = arctan x
1 + x2 = 1 + tan2 θ = sec2 θ
dx/dθ = sec2 θ
O zaman
Z∞ Z∞ Z∞
1 dx 1 1 2 1
= = sec θ dθ = 1 dθ =
π −∞ 1 + x2 π −∞ sec2 θ π −∞
1 ∞ 1
= θ|−∞ = [arctan(∞) − arctan(−∞)]
π π
1 π π
= [ − (− )] = 1
π 2 2
Kaynaklar
[1] Larsen, Introduction to Mathematical Statistics and Its Applications
[2] Runger, Applied Statistics and Probability for Engineers
5
Güven Aralıkları
Diyelim ki X1 , .., Xi örneklemi birbirinden bağımsız, aynı dağılımlı ve ortalaması
µ, standart sapması σ ve yine aynı olan bir nüfus dağılımından geliyor. O za-
man biliyoruz ki, Merkezi Limit Teorisi (Central Limit Theorem) teorisine göre, n
arttıkça örneklem ortalaması X̄ = n1 X1 + .. + Xn , ortalaması µ, standart sapması
σ/n2 olan bir normal dağılıma yaklaşıyor.
Peki veriyi (yani örneklemi) ve CLT’yi kullanarak µ hakkında bir tahmin yapa-
bilir miyiz? Yani Büyük Sayılar Kanunua göre µ hakkında noktasal tahmin ya-
pabiliriz fakat, belki ondan bir adım ötesi, bir “güven aralığı” hesaplamaktan
bahsediyoruz. Bu tahmin “gerçek µ, %95 ihtimalde şu iki değer arasındadır”
türünde bir tahmin olacak.
Dikkat: burada verinin yüzde kaçının belli bir aralıkta olup olmadığından bah-
setmiyoruz, tahminsel hesabı yapılan ortalamanın hangi güven seviyesinde bir
aralıkta olup olmadığından bahsediyoruz. Verinin güven aralığı hakkındaki not-
lar bu yazının sonunda.
Bu aralığın hesabı için önce X̄’i standardize edelim, yani N(0, 1) haline çevirelim,
X̄ − µ
Z= √
σ/ n
gibi bir ifade gördük. Eşitliğin sağ tarafı aslında bir alan hesabıdır, sürekli fonksiy-
onlarda olasılık bir entegral, ya da iki kümülatif yoğunluk fonksiyonunun farkı.
Güven aralığı için bize lazım olan da bir olasılık, hatta “kesin” bir olasılık, %95
olasılığı. Demek ki eşitliğin sağ tarafı .95 olacak. .95 hesabı için, normal eğrisini
düşünürsek, sağından ve solundan 0.25 büyüklüğünde iki parçayı “kırpmamız”
lazım. O zaman 0.975 olasılığının z değeri ile, 0.025 olasılığının z değeri arasındaki
olasılıkta olmamız lazım. Bu hesaplarda baz alınan zα/2 değeri ve bu 100 · α/2 üst
yüzdelik kısmına, örneğimizde 0.975 kısmına tekabül ediyor. Normal dağılımın
simetrisi sebebiyle onun eksisi alınmış hali öteki (soldaki) parçayı verir, yani
−zα/2 .
1
Z-skoru hesaplarken tabloya danışmıştık, şimdi tabloya tersinden bakacağız, kesişme
noktasında 0.975 diyen yeri bulup kordinatları alacağız, ki bu değer 1.96.
1.95996398454
Bazı İstatistik kaynaklarında “sihirli değer” şeklinde tarif edilen bir değer bu,
gözlerimiz kamaşmasın, geldiği yer burası işte. Şimdi formülü buna göre değiştirelim,
X̄ − µ
P − zα/2 6 √ 6 zα/2 =1−α
σ/ n
√
P(·) içinde biraz düzenleme, tüm terimleri σ/ n ile çarpalım, X̄ çıkartalım, ve −1
ile çarpalım,
σ σ
P X̄ − zα/2 √ 6 µ 6 X̄ + zα/2 √ =1−α (1)
n n
Güven aralığı ifadesine aslına erişmiş olduk. Eğer %95 kesinlikten bahsediyor
olsaydık, ve nüfusun gerçek varyansı σ2 biliniyor olsaydı, P(·) içine bu değerleri
geçecektik, X̄ zaten verinin aritmetik ortalamasından ibarettir, bu bize µ’nun sol-
unda ve sağında bazı değerler döndürecekti. Bu değerler bizim güven aralığımız
olacaktı. Mesela veri 64.1, 64.7, 64.5, 64.6, 64.5, 64.3, 64.6, 64.8, 64.2, 64.3 şeklinde,
n = 10 çünkü 10 nokta var, σ = 1 olarak verilmiş. Ortalamayı hesaplıyoruz,
64.46. α = 0.05 için
1 1
P 64.46 − 1.96 √ 6 µ 6 64.46 + 1.96 √ = 0.95
10 10
P 63.84 6 µ 6 65.08 = 0.95
2
Yani %95 güven aralığı 63.84 6 µ 6 65.08.
Neler yaptık? CLT bilgisinden hareketle X̄ hakkında bir şeyler biliyorduk. Fakat
X̄’in kesin hangi normal dağılıma yaklaştığını bilmek için nüfus paremetreleri
µ, σ da bilinmelidir. Diğer yandan eğer tek bilinmeyen µ ise, teoriyi bu bil-
inmez etrafında tamamen tekrar şekillendirip / değiştirip CLT’yi bilinmeyen µ
etrafında bir güven aralığı yaratmak için kullandık.
Not: Eğer σ bilinmiyor ise onu da veriden hesaplarız, S2 tahmin edicisi ile, yanlız
bu durumda S2 te bir dağılıma sahip olacaktır, χ2 dağılımı, ve üstte P() içindeki
bölüm bir Normal rasgele değişkeni bolu χ2 bölümü haline gelir, ki bu bölüm
Öğrenci t dağılımı adında başka bir dağılıma sahiptir! O zaman üstteki cebirsel
hareketleri bunu hesaba katarak yapmak gerekir. Bunun detaylarını ilerideki bir
bölümde göreceğiz.
Kac Tane n?
Hatırlarsak güven aralığını üstteki şekilde hesaplayabilmemizin sebebi CLT sayesinde
X̄’in normal dağılıma yaklaşıyor olmasıydı. Ve, teoriyi tekrar düşünürsek yaklaşma
n → ∞ olduğu zaman oluyordu. Buradan X̄’in normalliğinin “büyükçe” n
değerleri için daha geçerli olacağı sonucuna varabiliriz. Peki n ne kadar büyük
olmalı? Literatüre göre CLT’nin genellikle n > 30 durumunda geçerli olduğu
söylenir. Tabii nüfus dağılımının ne olduğu da önemlidir, eğer nüfus normal
ise, ya da genel olarak simetrik tek tepeli dağılım ise örneklem daha ufak kalsa
da bazı sonuçlara varabiliriz. Eğer nüfus dağılımı çok yamuk (skewed), etekleri
geniş dağılım ise o zaman daha büyük örneklem daha iyi olur.
Soru
İÖ 800 yıllarında İtalya’da Etrusyalı (Etruscan) toplumu vardı, bilinmeyen bir se-
beple bu insanlar geldikleri gibi birdenbire ortadan kayboluverdiler. Bilimciler
bu toplumun İtalyalılar ile fizyolojik, genetik ve kültürel olarak bağlantısı olup
olmadığını hep merak etmiştir. Bazıları hafa ölçülerine bakarak sonuçlara var-
maya uğraşmıştır. Arkeolojik kazılarda yapılan ölçümlerde 84 Etrusyalının kafası
ölçülmüştür. Ayrıca bugünkü İtalyanların kafa ölçümlerinin normal dağılımda
µ = 132.4mm, σ = 6.0mm olduğu bilinmektedir. İki toplum arasındaki bağlantı
kurmak için, veriye bakarak kafa ölçümü ortalaması için bir %95 güvenlik aralığı
oluşturabiliriz, ve eğer bugünkü İtalyanların ölçüsü o aralığa düşmüyorsa, Etrusyalılarla
bağlantılarının olmadığını iddia edebiliriz.
import pandas as pd
dfetr = pd.read_csv('../stat_035_tests/etrus.csv')
print (float(dfetr.mean()-1.96*(6.0/np.sqrt(84))))
print (float(dfetr.mean()+1.96*(6.0/np.sqrt(84))))
142.524107721075
145.09035011025028
3
timalle µ = 132.4, σ = 6.0 boyutlarındaki bir normal dağılımdan gelmemiştir.
Buna göre, büyük bir ihtimalle Etrusyalılar İtalyanların atası değildir.
Bilinmeyen σ
Güven Aralıkları bölümünden devam edelim. Bilinmeyen µ durumunu gördük.
Eğer σ bilinmiyorsa, bu durumda σ yerine örneklem varyansı S kullanılabilir,
1X
S2 = (Xi − X̄)2
n
Öğrenci t’nin Z’ye göre farklı bir tarafı belli bir değeri bulmak için iki parame-
treye ihtiyaç olması, bunlardan biri α diğeri ise serbestlik derecesi (degree of
freedom -dof-). Standart normal için tablo paylaştık, fakat t için artık tablolarla
uğraşmayacağız, bilgisayar çağındayız, yazılım ile bu işi halledelim!
Örnek
T bir Öğrenci t dağılımı ise, ve serbestlik derecesi 3 ise, α = 0.01 için için fT (t)’nin
100(1 − α) yüzdeliği nedir? Üstteki grafikteki tα,n notasyonundan hareketle t0.01,3
değerini arıyoruz yani.
4.5407028587
0.00999823806449
Yani
4
P(T3 > 4.541) = 0.01
Ȳ−µ
√
S/ n
ifadesinin n-1 derece serbestliğe sahip Öğrenci t dağılımına sahip olduğunu
bilmek alttaki ifadeyi mümkün kılar,
Ȳ − µ
P − tα/2,n−1 6 √ 6 tα/2,n−1 =1−α
S/ n
Bu ifadeyi daha önce standart normal için yaptığımız gibi tekrar düzenlersek,
S S
P Ȳ − tα/2,n−1 √ 6 µ 6 Ȳ + tα/2,n−1 √ =1−α
n n
Tabii, Yi ’ların normal dağılımdan gelmiş olması lazım. Bunun sonucunda gerçek
veri temel alınarak hesaplanacak S ve Ȳ bize µ için bir %100(1 − α) güven aralığı
verecektir.
Örnek
Yapışkan elementlerin üzerinde yapılan deneyler sonucundaki ölçümler altta verilmiştir.
Acaba µ için %95 güven aralığı nedir?
Öncelikle verinin normal dağılımdan geldiği doğru mudur? Bu faraziyeyi kon-
trol etmemiz gerekir yoksa t dağılımını kullanamayız. Önce bir kutu grafiği (box-
plot) yapalım,
data = np.array([19.8,10.1,14.9,7.5,15.4,15.4,15.4,18.5,7.9,12.7,
11.9,11.4,11.4,14.1,17.6,16.7,15.8,19.5,8.8,13.6,11.9,11.4])
plt.boxplot(data)
plt.savefig('stat_ci_01.png')
Şimdi normal olasılık grafiği (normal probability plot) yapalım, ki bu grafik verinin
normal dağılıma ne kadar uyumlu olduğunu grafik olarak gösterir, eğer uyumlu
ise veri düz çizgiye yakın çıkmalıdır,
5
Bu grafiklere bakınca verinin normal olduğu belli oluyor. Zaten örneklem sayısı
az, bu sebeple t dağılımı kullanmak uygun. Veri sayısal ortalaması ve sayısal
standart sapmasına bakalım, ve güven aralığını hesaplayalım, yani
√ √
x̄ − tα/2,n−1 s/ n 6 µ 6 x̄ + tα/2,n−1 s/ n
ortalama 13.7136363636
sapma 3.47187340764
12.174293931 15.2529787962
Güven aralığı oldukça geniş, çünkü (demek ki) ölçümlerde yüksek değişkenlik
var.
Normal Nüfusun Varyansının Güvenlik Aralığı
Bazen nüfusun varyansı ya da standart sapması üzerinde bir güven aralığı hesapla-
mak gerekebilir. Eğer nüfus normal olarak dağılmış ise, şimdiye kadar gösterdiğimiz
tekniklerin hepsi kullanılabilir. (1) teorisinin b kısmındaki ifadeyi kullanırsak,
nüfusu µ, σ parametreli bir normalden alınan X1 , .., Xn örneklemi üzerinden hesa-
2
planan X2 = (n−1)S
σ2
ifadesinin n − 1 serbestlik derecesindeki bir chi kare dağılımı
olduğunu biliyoruz.
Chi karenin yüzdelik kısımları altta görülebilir,
6
from scipy.stats.distributions import chi2
print chi2.ppf(0.05,5)
print chi2.ppf(0.99,5)
1.14547622606
15.0862724694
Dikkat edilmesi gereken bir konu chi karenin yamuk (skewed) olması sebebiyle
sağdaki ve soldaki alan hesaplarının arasında z skorunda olduğu gibi her se-
ferinde birebir geçiş yapılamayabileceği.
Notasyonel olarak χ2p,n ifadesi, x eksenindeki bir eşik noktasını ifade eder ki bu
değerin sol tarafındaki alan büyüklüğü p, n serbestlik derecesindeki chi kare
dağılımının alanıdır. Mesela üstte χ20.05,5 = 1.145 ve χ20.99,5 = 15.086. Olasılık
ifadesi olarak
Not: Bazı kaynaklar eşik değerinin sağ kısmını referans alıyor her nedense, bu
duruma dikkat.
σ2 İçin Güvenlik Aralığı
Chi kare tanımından hareketle şu ifadeyi yazabiliriz,
(n − 1)S2
2 2
P χα/2,n−1 6 6 χ1−α/2,n−1 = 1 − α
σ2
Belirtildiği üzere, üstteki ifadenin Z’li halinde olduğu gibi, bir z değerini alıp,
eksi ile çarparak (ve çarpmayarak) hem sol hem sağda eşik değeri olarak kul-
lanamadık çünkü chi kare simetrik değil. Eşik değerinin belli noktalarda ayrı
ayrı hesaplanması gerekiyor.
7
Üstteki denklem birkaç cebirsel işlem sonrasında σ2 ’yi ortada tek başına bırakacak
şekilde değiştirilebilir, önce eşitsizlikleri tersine çeviriyoruz, aynı anda ortadaki
bölüme tersine çeviriyoruz, ve yeni böleni hem sol hem sağa çarparak taşıyoruz,
(n − 1)S2 (n − 1)S2
P 2 6 σ2 6 2 =1−α
χ1−α/2,n−1 χα/2,n−1
s s
(n − 1)S2 (n − 1)S2
,
χ21−α/2,n−1 χ2α/2,n−1
Örnek
Bir fabrikada deterjanları doldurmak için bir makina kullanılıyor. Rasgele seçilen
bir örneklemde 20 tane deterjan plastik şişeden alınan ölçümlerde örneklem varyansının
s2 = 0.0153 olduğu hesaplanıyor (birim ons2 ). Bu ölçümlerin standart sapması
σ2 için %95’lik üst güven sınırı nedir?
s
(19)0.0153
σ2 6
χ20.05,19
10.1170130639
r
(19)0.0153
σ2 6 = 0.0287
10.117
Yani
σ 6 0.17
Demek ki nüfusun gerçek standart sapması 0.17 ons kadar büyük olabilir.
Nüfus Ortalama Farkı, µ1 − µ2 Güven Aralığı
İki farklı nüfusun ortalamaları µ1 , µ2 ’nin birbirinden farklı olup olmadığını, ve bu
farkın istatistiki önemli olup olmadığını nasıl anlarız? Bir yaklaşım, iki nüfusun
örneklem ortalaması X̄1 , X̄2 ’i kullanmak ve farklılık µ1 − µ2 ’ için bir güven aralığı
oluşturmak, eğer sıfır değeri bu aralık içine düşüyorsa, farklılık vardır. Birbirinden
aynı olan şeylerin farkı sıfır olduğuna göre eğer sıfır güven aralığı içinde ise bu
iki nüfusun ortalamasının birbirine yakın olduğundan emin olabiliriz.
8
Devam edelim; Merkezi Limit Teorisi’ne göre yeterince büyük örneklemler, yani
n1 > 30, n2 > 30 için, X̄1 , X̄2 Normal olarak dağılmaya mecbur.
Diğer yandan biliyoruz ki iki Normal dağılımın toplamı, ya da çıkartılması yeni
bir Normal dağılım verir. µa , µb ve σa , σb için, toplam N(µa + µb , σa + σb )
elde edilir. Örneklem durumunda ve çıkartma sonrası yeni ortalama ve standart
sapma
σ21 σ2
µ1 − µ2 , + 2
n1 n2
X̄ − µ
Z= √
σ/ n
9
a = [5.20, 4.70, 5.75, 7.50, 6.45, 6.55, 4.70, 4.80, 5.95, \
5.20, 6.35, 6.95, 5.70, 6.20, 5.40, 6.20, 5.85, 6.80, \
5.65, 5.50, 5.65, 5.85, 5.75, 6.35, 14.1, 12.2, 14.0, 14.6, \
5.75, 5.95, 5.90, 7.00, 6.10, 5.80]
ma = np.mean(a); sa = np.std(a,ddof=1)
mb = np.mean(b); sb = np.std(b,ddof=1)
[ 0.53624225 2.09983618]
Yani ortalam etrafında sağda ve solda tek standart sapmayla belirli bölge, bir
Normal dağılımın yüzde 68’ine tekabül eder, ve bir veri Normal şekilde dağılmış
ise, o verinin yüzde 68’inin hangi aralıkta olduğu bu şekilde hesaplanabilir.
[[137.80833099 149.80612685]]
10
Yüzde 95 hesabı için sağda ve solda iki standart sapmaya bakmak gerekir,
[[131.80943306 155.80502478]]
Peki yüzde 68, yüzde 95, gibi değerlerin standart sapma ile bağlantısının nere-
den biliyoruz? Düşünelim, her normal dağılım standart normal dağılıma in-
dirgenebilir, ve standart normal dağılım N(0, 1)’dir, yani ortalaması 0 standart
sapması 1. O zaman bu dağılımın, sıfır etrafında -1 ve +1 sınırları içindeki alan
nedir hesabı basit kumulatif yoğunluk ile yapılabilir,
0.6826894921370859
0.9544997361036416
Her dağılımın tamamının alanı bilindiği gibi 1, bu sebeple üstteki rakamlar bir
yüzde olarak algılanabilir.
Kaynaklar
[1] Larsen, Introduction to Mathematical Statistics and Its Applications
[2] Runger, Applied Statistics and Probability for Engineers
[3] Dekker, Probability and Statistical Inference
11
Binom İçin Normal Yaklaşıksallığı
Merkezi Limit Teorisinden X̄’nin her Xi için aynı olan nüfus beklentisi ve sap-
masını içeren N(µ, σ) olarak dağılacağını biliyoruz. Ve bu durum, nüfus hangi
dağılıma sahip olursa olsun geçerlidir. X1 , .., Xn birbirinden bağımsız ve aynı Bernoulli
olarak dağılmış, ve onların toplamını temsil eden binom dağılımı X olarak tanımlayalım,
o zaman
X = X1 + X2 + .. + Xn
X/n − p X − np
Z= p =p
p(1 − p)/n np(1 − p)
Soru
Amerikalıların yüzde 12’sinin zenci olduğunu biliyoruz. Eğer 1500 kişiyi içeren
bir örneklem alsaydık, bu örneklemde 170’den daha az zenci olmasının olasılığı
nedir?
Cevap
%12 nüfus parametresidir, yani p = 0.12. Örneklem n = 1500. Normal yaklaşıksallaması
ile
180.0 12.585706178
olasilik 0.213437028747
Yani N(180, 12.58) dağılımını elde ettik ve hesapları onun üzerinden yaptık. Sonuç
diyor ki verilen örneklem ve nüfus p değeri ile 170 altında zenci sayısı elde etmek
oldukça düşük bir ihtimalde.
Örnek
Diyelim ki elimizde bir Web sitesinin günlük ziyaret, tıklama sayılarını gösteren
bir veri seti var, CVR ziyaretçilerin sitedeki tıklayan müşteriye dönüşmesi oranı
(conversion).
import pandas as pd
from scipy import stats
1
a = pd.DataFrame({'tiklama': [20.,2.,40.,5.,10.,100.],
'ziyaret': [100.,10.,300.,400.,30.,800.]})
a['cvr'] = a['tiklama'] / a['ziyaret']
print a
Bu veri seti için cvr’in 0.16, yani yüzde 16 olduğunu önceden biliyoruz. Üstteki
başarı oranı binom dağılı ile modellenebilir, ziyaretler ”deneylerdir”, yani örneklem
büyüklüğünü gösterirler. Tıklama ise başarıdır, önceki binom örneğindeki aynı
formülü kullanırsak, normal yaklaşıksallığı üzerinden bir z-skoru hesaplayabili-
riz,
p = 0.16
btest = lambda x: (x['cvr']-p) / np.sqrt( p*(1-p)/x['ziyaret'])
a['guven'] = a.apply(btest, axis=1)
a['guven'] = np.round(stats.zprob(a['guven'])*100,2)
print a
Soru
Amerika’da 2009 yılında halkın ne kadarının arabalarında yakıt tasarrufunu destek-
lediği merak konusuydu. Bir Gallup telefon anketinde bu soru 1012 yetişkine (18
ve üstü yaşta) soruldu. Cevap 810 kişinin tasarrufu desteklediği yönündeydi.
Yani n = 1012, k = 810. O zaman p için %95 güven aralığını bulun.
Cevap
r r
810 (810/1012)(1 − 810/1012) (810/1012)(1 − 810/1012)
− 1.96 , 1.96
1012 1012 1012
= (0.776, 0825)
Python ile
m = 810/1012.
low = m - 1.96*np.sqrt(m*(1-m)/1012.)
2
high = m + 1.96*np.sqrt(m*(1-m)/1012.)
print low, high
0.775768711331 0.825021802503
Soru
Borsa konusunda okuyuculara tiyo veren bir gazete, bir şirket hissesinin belli bir
olay ardından çoğunlukla yükseldiğini söylüyor. Yazara göre hisse 9 olay içinden
6’sında bu çıkmış. Buradan hareketle yazar hissenin tekrar çıkma şansının 6/9=%66.7
olduğunu iddia ediyor. Okuyucu bunu ciddiye alsın mı?
Cevap
Ufak örneklemler için Agresti ve Coull yöntemini kullanmak iyi olur, bu yönteme
göre başarılı olay sayısına iki, tüm olay sayısına 4 ekleriz (yani 2 başarısızlık
eklemiş oluruz) ve p̂ = (x + 2)(n + 4) elde edilir. Bu ekler hem genel teorik olarak
bir değişim yaratmaz, hem de örneklem sayısını arttırarak Normal yaklaşıksallığını
kullanabilmemizi sağlar. Güven aralığı,
x=6.;n=9.;p=(x+2)/(n+4); z = 1.96
print p + np.array([-1,+1])*z*np.sqrt(p*(1-p)/n)
[ 0.29753517 0.93323406]
Demek ki yazar okuyucularına kötü bir tavsiye vermiş, güven aralığının alt kısmı
%30 olduğuna göre hissenin yükselmesi garanti değildir, garanti için güven aralığının
iki ucu da %50 üzerinde olmalıydı. Noktasal tahmin bağlamında %66.7 rakamı
da yanıltıcıdir. Bu yazar okuyucularının para kaybetmesine sebep olabilir.
Örneklem Büyüklüğü
Bir araştırmacı n bağımsız deney baz alınarak elde edilen binom parametresi p’yi
tahmin etmek istiyor, fakat kaç tane n kullanması gerektiğini bilmiyor. Tabii ki
daha büyük n değerleri daha iyi sonuçlar verecektir, ama her deneyin bir masrafı
vardır. Bu iki gereklilik nasıl birbiri ile uzlaştırılır?
Yeterli olacak en az kesinliği, duyarlılığı (precision) bulmak için Z transformasy-
onu kullanılabilir belki. Diyelim ki p için maksimum olurluk tahmini olan X/n’in
en azından 100(1 − α)% olasılıkta p’nin d kadar yakınında olmasını istiyoruz. O
zaman alttaki denklemi tatmin eden en ufak n’i bulduğumuz anda problemimizi
çözdük demektir,
X
P −d6 −p6d =1−α (1)
n
3
dağılmış (ıid) rasgele değişkenlerin aritmetik ortalaması Merkezi Limit Kanunu’na
göre normal’e yaklaştığına göre o zaman, elimizde bir normal dağılım var de-
mektir.
Standardize etmek için X/n’den beklentiyi çıkartıp standart sapmaya bölebiliriz.
Beklenti zaten çıkartılmış durumda (şansa bak!), beklentinin ne olduğunu kontrol
edelim tabii, ezbere yapmayalım bu işi, eğer her Bernoulli’yi Xi olarak temsil
edersek,
X = X1 + .. + Xn
X/n = 1/n(X1 + .. + Xn )
E[X/n] = E[1/n(X1 + .. + Xn )]
= 1/nE[(X1 + .. + Xn )]
= (1/n)np = p
Varyans için
1 1 1
Var(X/n) = 2
Var(X) = 2 np(1 − p) = p(1 − p)
n n n
Binom dağılımlar için Var(X) = np(1 − p) olduğunu biliyoruz. Standart sapma
üstteki ifadenin karekökü, yani
p
Std(X/n) = p(1 − p)/n
X
−d −p d
P p 6p n 6p =1−α
p(1 − p)/n p(1 − p)/n p(1 − p)/n
−d d
P p 6 Zp =1−α
p(1 − p)/n p(1 − p)/n
d
p = zα/2
p(1 − p)/n
4
O zaman
z2α/2 p(1 − p)
=n
d2
Fakat bu bir nihai sonuç olamaz, çünkü n, p’nin bir fonksiyonun haline geldi ve
p bilinmeyen bir değer. Fakat biliyoruz ki 0 6 p 6 1, ve p(1 − p) 6 41 . Yani bir üst
sınır (upper bound) elde ettik.
Bunu kontrol edelim, p(1 − p) hangi p’de maksimize olur? p’ye göre türev alırız,
sıfıra eşitleriz, (p − p2 ) 0 = 1 − 2p = 0, p = 1/2. Ve hesabı yaparsak, 1/2(1 − 1/2) =
1/4. Demek ki p(1 − p) değeri 1/4’ten daha büyük olamaz. Buna göre, üstteki
formüle p(1 − p) yerine onun olabileceği en büyük değeri koyarsak,
z2α/2 1/4
=n
d2
z2α/2
n=
4d2
Not: p(1 − p), 1/4 değerinden daha küçük olabilir mi? Olabilir. Bu durumda
n üstteki formülden elde edebileceğimiz değerden daha küçük te çıkabilecektir.
Fakat p(1 − p)’in olabileceği en büyük değer 1/4’u kullanarak “n’in bundan daha
büyük olmasına gerek yok” diyebilen bir formüle erişmiş olduk, yani, aslında n
için bir üst sınır elde ettik.
Örnek
Büyük bir şehirde çocukların kaçta kaçının aşısını almış olup olmadığını anla-
mak için bir anket gerçekleştirilecek. Anketi düzenleyenler örneklem oranı olan
X/n’in en az 98% oranda gerçek oran p’nin 0.05 yakınında olmasını istiyorlar.
Örneklem ne kadar büyük olmalıdır?
Burada 100(1−α) = 98, o zaman α = 0.02, demek ki zα/2 = z0.02/2 = z0.01 değerine
ihtiyacımız var. Python ile
2.32634787404
(2.33)2
n= = 543
4(0.05)2
5
Hata Payı (Margin of Error)
Basında oranları rapor ederken onunla beraber telafuz edilen bir kavram hata
payıdır. Aslında bu binom dağılımlarda güven aralığı ile çok yakından alakalıdır;
hata payı %95 güven aralığının en maksimum genişliğinin yarısı olarak bilinir.
Yani %95 aralığının bir ucunu diğer ucundan çıkartırsak ve ikiye bölersek, istenen
sonuca erişiriz. Formülsel olarak genişlik w,
r r
k (k/n)(1 − k/n) k (k/n)(1 − k/n)
w = + 1.96 −− − 1.96
n n n n
r
(k/n)(1 − k/n)
= 3.92
n
Şimdi (k/n)(1 − k/n) çarpımını düşünelim. [8] bölümünde gördük, n her zaman
k’den büyük olduğuna göre k/n her zaman 0 ve 1 arasındadır, o zaman (k/n)(1−
k/n) 6 1/4 olmalıdır, yani gösterilen çarpım 1/4’ten büyük olamaz. Bunu alıp
üstteki formül içine koyarsak,
r
1
max w = 3.92
4n
0.98
d= √
n
Örnek
Bir seçim kampanyası sırasında A ve B adayları arasında hangisinin daha önce
olduğunu bulmak için bir anket yapılır. Telefonda 597 kişiye sorulduğunda A
adayının 299 kişinin oyunu alacağı saptanmıştır. Basın durumu “A adayının
avantajı hata payı %4 içinde olduğu için o önde kabul edilebilir” diye rapor
etmiştir. A oylarının hata payı hakikaten %4’müdür?
n = 597.
k = 299
print n/2
print k/n
d = 0.98/np.sqrt(n)
print d*100
298.5
0.500837520938
4.01087299444
6
Dikkat edilirse hata payının anketten gelen sonuçlarla hiçbir alakası yok, A için
tercih %25, %75 olabilirdi ama üstteki hata payı hesabı yine aynı kalırdı. Bunun
sebebi formülün n’ye bağlı olması.
Daha önemli soru hata payı basının üstteki ifadesinin gerçekten seçim sonucu ile
alakalı olup olmadığı!
Hipotez Testleri (Hypothesis Testing)
İstatistik tek ya da aralıklar olarak sayısal tahminler üretmenin ötesinde, “iki
şey arasında birisini seçmek” türünde bir karar bağlamında da kullanılabilir. Bir
psikolog bir davaya uzman görüş vermek için çağrılmıştır ve sanık hakkında ’aklı
olarak dengesiz ya da dengeli’ arasında bir seçim yapacaktır. İlaç regülasyonu ile
uğraşan kurum yeni bir ilaç hakkında ’etkili’ ya da ’etkisiz’ şeklinde bir karara
ulaşacaktır.
Bir deneyin mümkün sonuçlarını belli seçeneklere yönlendirip olasılık teorisini
kullanarak bunlardan birisini seçmeye İstatistik biliminde Hipotez Test Etmek
adı verilir.
Birbiriyle yarış halinde olan iki hipotez vardır, bunlar sıfır hipotezi (H0 olarak
yazılıyor) ve alternatif hipotezdir (H1 olarak yazılıyor). Ho ve H1 arasında nasıl
seçim yapacağımız kavramsal olarak bir davada jürinin yaptığı seçime benzer:
aynen sanığın, tersi ispatlanana kadar, masum kabul edilmesi gibi eğer veri tersi
sonuca varmaya yetmezse H0 da “kabul edilir”, yani suçsuzluğun devam etmesi
gibi H0 görüşü terkedilmemiş olur. Statüko devam eder. Bu kararı verirken
mahkemenin kanıtları incelemesi, hipotez testinde rasgele değişkenlerle verinin
üzerinden hesaplar yapmaya benzer.
Bunu bir örnek üzerinden daha iyi anlayabiliriz. Diyelim ki araba üreten bir
şirket yakıt performansını (gas mileage) arttırmaya uğraşıyor. Benzine katılan
yeni bir madde üzerinde deneyler yapıyorlar, deney için Boston / Los Angeles
arasında 30 tane araba sefer yapıyor. Yeni katkı maddesi olmadığı durumda
(statüko) yakıt performansının ortalama 25.0 mil/galon ve standart sapmanın
2.4 mil/galon olduğu biliniyor. Diyelim ki deney sonrasında arabalar ortalama
olarak ȳ=26.3 mil/galon performansı göstermişler. Katkı maddesi etkili mi, etkili
değil mi?
Araştırmacılar 25.0’dan 26.3’e olan değişikliği daha önce bahsettiğimiz mahkeme
örneğindeki gibi bir çerçevede incelerler. Tipik olarak sıfır hipotezi statükoyu
temsil eder, yani değişmesi için “ezici şekilde aksi yönde veri olması gereken
şey” budur. Öyle değil mi? Eğer etkisiz bir katkı maddesine evet dersek, ve
ileride öyle olmadığı belli olursa bunun şirket için çok negatif etkileri olacaktır,
aynen masum bir kişiyi yanlışlıkla hapse atmış olmak gibi. O yüzden kalmak
istediğimiz güvenli konum H0 ’i temsil etmelidir.
Bu noktada problemi rasgele değişkenlerin terminolojisi üzerinden tekrar tanımlamak
faydalı olur. Diyelim ki test sırasında 30 tane aldığımız ölçüm y1 , .., yn , her yi
normal olarak dağılmış ve bu dağılımların µ’şu aynı, ve µ’u birazdan “eski”
7
ölçümlerin ortalaması olarak alacağız, çünkü çürütmek istediğimiz hipotez bu.
Ayrıca daha önceki tecrübelerimiz gösteriyor ki σ = 2.4. Yani,
1 1 y−µ 2
fY (y; µ) = √ e− 2 ( 2.4 ) , −∞ < y < ∞
2π(2.4)
Üstteki ifade “eğer örneklem eski dağılımdan geliyor olsaydı, 25.25 eşik değerini
geçmesi ne kadar mümkün olabilirdi” diye bir soru soruyor. Ȳ’yi standardize
edelim, o sırada eşitsizliğin sağ tarafı da değişir,
0.57’nin z-skoru (satır 0.5 kolon .07) 0.7157 olarak gösterilmiş, o zaman 1-0.7157
= 0.2843. Kod ile
print 1-norm.cdf(0.57)
0.284338849046
Demek ki
Demek ki yeni deney sonuçlarının, eski dağılıma göre, eşik değerinden fazla
gelmesi hala az da muhtemel, demek ki eski hipotezi tam çürütemedik. Seçtiğimiz
eşik değeri bize kesin bir sonuç sağlamadı, sezgisel olarak bu olasılığın büyük
8
olduğunu görüyoruz. Mahkeme durumunda suçsuz olması çok muhtemeldir
diyemiyoruz. Ya da araba örneğinde (ve pozitif bağlamda) yeni yakıt kesinlikle
farklıdır / fazladır diyemiyoruz. Bize daha kesin noktalar lazım, aklımızda bize
“acaba?” dedittirecek eşik değerler istemiyoruz.
Hayali eşik noktası ȳ∗ ’nin daha büyük yapsak (ki o zaman ona bağlı olan sağdaki
olasılık küçülecek). Bu olur mu? Eğer ȳ∗ = 26.50 olsaydı?
= 0.0003
Bu olasılık ise çok küçük, yani eşik değeri çok büyük! Çıtayı çok fazla kaldırdık,
mahkeme durumunda sanki diyoruz ki suçun 1000 tane tanığı lazım, sanık suçunu
itiraf etmiş olmalı, herşey apaçık olmalı, bir de herşeyi bizzat ben görmüş ol-
malıyım, yoksa kabul etmem. Araba örneğinde katkı maddesi arabaya Formula-1
yarısı kazandırmazsa biz bu yakıtı daha iyi olarak kabul etmeyiz diyoruz.
9
Peki eğer 0.28 çok fazla, 0.0003 çok küçük ise hangi olasılık en iyi eşik değerini
verir? Bu soruya kesin olarak ve matematiksel bir cevap vermek mümkün değil,
fakat hipotez test etme tekniğini kullanan araştırmacıların ulaştığı konsensüs 0.05
olasılık seviyesinin en iyi sonuçlar verdiğidir. Bu durumda sıfır hipotezinin çok
kolayca kenara atılmaması, ya da ona gereğinden fazla bağlı kalınmaması mümkün
oluyor.
O zaman 0.05 olasılığını verdirtecek eşik değeri hesaplayalım,
ȳ∗ − 25.0
P(Z > √ ) = 0.05
2.4/ 30
ya da
ȳ∗ − 25.0
P(Z 6 √ ) = 0.95
2.4/ 30
z-Skor tablosuna bakıyoruz, “hangi z değeri 0.95 değeri sonucunu verir”, kordi-
natlardan 1.64 z-skorunu buluyoruz. Ya da
print norm.ppf(0.95)
1.64485362695
ȳ∗ − 25.0
√ = 1.64
2.4/ 30
ve buradan ȳ∗ = 25.178 sonucu çıkıyor. 26.3 değeri bu değerden yüksektir de-
mek ki sıfır hipotezi çürütülmüştür. Yeni yakıt katkısının performansı arttırıyor
olması büyük bir olasılıktır.
Not: Bu testi aslında daha basit şekilde ȳ∗ = 26.3 değerini vererek elde edilen
değeri 0.05’ten küçük olup olmadığına bakarak ta yapabilirdik. Fakat metotu
inşa ediyorduk o sebeple daha fazla örnekli anlatmak gerekti.
Örnek
SAT-I testinde ülke averajına oldukça yakın sonuçlar alan bir lisede yeni bir müfredat
denenmesine karar veriliyor. Deneme için 86 öğrenci rasgele şekilde seçiliyor ve
yeni bir tür cebir ve geometri dersine sokuluyor. Sonraki SAT-1 testinde sonuçlarına
10
göre bu çocuklar ortalama 502 sonuç almışlar, ülke çapındaki ortalama 494, stan-
dart sapma 124. α = 0.05 önemliliği (significance) seviyesinde yeni müfredatın
başarılı olduğu iddia edilebilir mi?
İlk önce µ parametresinin yeni müfredatın gerçek ortalaması olduğunu farzediy-
oruz. O zaman statüko nedir? Bu ortalamanın ülke ortalaması seviyesinde kalmasıdır,
yani µ0 = 494 olmasıdır. Fakat bu sefer alternatif hipotez iki yönlü (two-sided)
olmalı çünkü yeni müfredat, hiç istenmese de, test sonuçlarında negatif sonuca
da yol açabilir! O zaman H0 ’i reddetmeliyiz eğer z istatistiği 6 −z0.025 ise (yani
-1.96’dan küçük ise), ya da > z0.025 (yani 1.96’dan büyük ise).
502 − 494
z= √ = 0.60
124 86
Sonuç 1.96’dan büyük değil. O zaman H0 ’i, yani statükoyu değiştiremedik. Elde
edilen sonuçlar bir ilerlemedir fakat bu ilerlemenin şans eseri olması da muhtemel.
11
2. kategoriye ait olmasını temsil ediyoruz. O zaman k = k1 + k2 + .. + k747 bir-
inci kategorideki toplam ölümü temsil ediyor. Üstteki her k doğal olarak Binom
dağılımı, ve p parametresini kullanıyor ki
k − np0
z= p 6 −z0.05 = −1.64
np0 (1 − p0 )
60 − 747(0.25)
= = −10.7 6 −1.64
747(0.25)(0.75)
Test istatistiği kritik değerin aşırı derecede sol tarafına düştü. Demek ki ezici
miktarda kanıt, veri, sonuç elde ettik, %25’ten %8’e düşüşün pür şans dışında
başka bir sebebi var. Tabii bu sebep Erteleme Teorisi haricinde bir şey de olabilir,
fakat yine de ortaya çıkan kalıp bize ölüm vaktimizin kontrolümüzde olduğunu
destekleyen yönde bir sonuç veriyor.
Not: Üstteki test “büyük örneklem” olduğu durumlarda geçerlidir. Küçük örneklem
durumunda Binom dağılımının kendisi test için kullanılabilir.
Tek Örneklem t Testi (The One-Sample t test)
Bu test verinin bir N(µ, σ) Normal dağılımından geldiğini farzeder, test etmek
istediğimiz hipotez / karşılaştırma µ = µ0 . Ayrıca σ bilinmiyor, ki Öğrenci t
dağılımından bahsetmemizin ana sebebi buydu zaten, o zaman hipotez testine
Tek Örneklem t Testi adı verilir.
Örnek
Alttaki veride bir grup hanımın ne kadar kalori tükettiği kayıtlanmış. Acaba bu
hanımların aldığı enerji tavsiye edilen 7725’ten ne kadar sapmıştır?
daily_intake = np.array([5260.,5470.,5640.,6180.,6390.,6515.,6805.,\
7515.,7515.,8230.,8770.])
ȳ−µ
Örneklem küçük. O sebeple t dağılımı kullanmak mantıklı. t değerini s/ √ o olarak
n
hesaplayacağız, ki µ0 = 7725 olacak.
12
from scipy.stats.distributions import t
import pandas as pd, math
data = pd.DataFrame(daily_intake)
n = len(data)
df = n-1 # serbestlik derecesi
mu0 = 7725.
ybar = float(data.mean())
s = float(data.std())
print 'ortalama',ybar,'std',s
tval = (ybar-mu0)/(s/np.sqrt(n))
print 'df',df,'tval',tval
print 'sol',t.ppf(0.025,df)
print 'sag',t.ppf(0.975,df)
ortalama 6753.63636364 std 1142.12322214
df 10 tval -2.82075406083
sol -2.22813885196
sag 2.22813885196
Sol ve sağ eşik değerlerini hesapladık ve t değeri bu aralığın içine düşmüyor. Yani
hipotezi reddediyoruz. Bazıları bu problemde p değeri görmek isteyebilir,
Sonuç p değeri 0.05’ten küçük çıktı yani yüzde 5 önemliliğini (significance) baz
aldık bu durumda veri hipotezden önemli derecede (significantly) uzakta. De-
mek ki ortalamanın 7725 olduğu hipotezini reddetmemiz gerekiyor.
İki Örneklemli Test
Gruplar 0/1 değerleri ile işaretlendi, ve test etmek istediğimiz iki grubun ortala-
masının (mean) aynı olduğu hipotezini test etmek. t-test bu arada varyansın aynı
olduğunu farzeder.
energ = np.array([
[9.21, 0],[7.53, 1],
13
[7.48, 1],[8.08, 1],
[8.09, 1],[10.15, 1],
[8.40, 1],[10.88, 1],
[6.13, 1],[7.90, 1],
[11.51, 0],[12.79, 0],
[7.05, 1],[11.85, 0],
[9.97, 0],[7.48, 1],
[8.79, 0],[9.69, 0],
[9.68, 0],[7.58, 1],
[9.19, 0],[8.11, 1]])
group1 = energ[energ[:, 1] == 0][:, 0]
group2 = energ[energ[:, 1] == 1][:, 0]
t_statistic, p_value = ttest_ind(group1, group2)
print "two-sample t-test", p_value
p değeri < 0.05 yani iki grubun ortalaması aynı değildir. Aynı olduğu hipotezi
reddedildi.
Eşlemeli t-Test (Paired t-test)
Eşlemeli testler aynı deneysel birimin ölçümü alındığı zaman kullanılabilir, yani
ölçüm alınan aynı grupta, deney sonrası deneyin etki edip etmediği test edilebilir.
Bunun için aynı ölçüm deney sonrası bir daha alınır ve ”farkların ortalamasının
sıfır olduğu” hipotezi test edilebilir. Altta bir grup hastanın deney öncesi ve son-
rası ne kadar yiyecek tükettiği listelenmiş.
intake = np.array([
[5260, 3910],[5470, 4220],
[5640, 3885],[6180, 5160],
[6390, 5645],[6515, 4680],
[6805, 5265],[7515, 5975],
[7515, 6790],[8230, 6900],
[8770, 7335],
])
pre = intake[:, 0]
post = intake[:, 1]
t_statistic, p_value = ttest_1samp(post - pre, 0)
print "paired t-test", p_value
14
işlemi sonucunun işaretine bakmak, ve eksi işareti taşıyan sıra değerlerini topla-
mak, aynı işlemi artı işareti için yapmak, ve eksi toplamı artı toplamından çıkartmak.
Sonuçta elimize bir istatistik W gelecek. Bu test istatistiği aslında 1..n tane sayı
içinden herhangi birini 1/2 olasılığıyla seçmek, ve sonuçları toplamaya tekabül
etmektedir. Ve bu sonuç yine 0.05 ile karşılaştırılır.
Hipotezi reddettik.
Eşlemeli t-testi şimdi Wilcoxon testi ile yapalım,
Normallik Testi
Paket scipy.stats altında normallik testleri için bazı çağrılar var, bu tekniklerden
ikisini altta gösteriyoruz,
import scipy.stats as st
arr = np.array([3,4,3,10,10,444,444,3,98])
arr2 = np.array([np.random.normal() for i in range(100)])
Shapiro-Wilk
(0.6167718172073364, 0.00015052134403958917)
(0.9891485571861267, 0.5962899923324585)
15
xi − µ
yi = Φ
σ
Burada Φ standart Gaussian’ı temsil ediyor (detaylar için [7] ve CDF fonksiy-
onuna tekabül ediyor. CDF fonksiyonunun aynı zamanda yüzdelik dilimi (quan-
tile) hesapladığı söylenir, aslında CDF son derece detaylı bir olasılık değeri verir
fakat evet, dolaylı yoldan noktanın hangi çeyrek içine düştüğü de görülecektir.
Şimdi bir numara yapalım, iki tarafa ters Gaussian formülünü uygulayalım, yani
Φ−1 .
−1 xi − µ
−1
Φ (yi ) = Φ Φ
σ
xi − µ
Φ−1 (yi ) =
σ
xi = Φ−1 (yi )σ + µ
import statsmodels.api as sm
fig = sm.qqplot(arr)
plt.savefig('stat_tests_01.png')
16
Gerçekten Gaussian olan bir veri şöyle gözükür,
fig = sm.qqplot(arr2)
plt.savefig('stat_tests_02.png')
Kaynaklar
[1] Dalgaard, Introductory Statistics with R
[2] Kerns, Introduction to Probability and Statistics Using R
[3] Blondel, t-test and wilcoxon-test examples in Python, urlhttps://gist.github.com/mblondel/17617
[4] Runger, Applied Statistics and Probability for Engineers
[5] Stack Exchange, Sample variance converge almost surely, http://math.stackexchange.
com/questions/243348/sample-variance-converge-almost-surely
[6] Haslwanter, Introduction to Statistics using Python
[7] Bayramli, İstatistik, Giris)
[8] Bayramli, Istatistik, Örneklem Büyüklüğü
17
Testlere Devam
İstatistiki test yaratmak için takip edilen teknik basit; bir istatistiki ölçüt hesaplıyoruz,
ya da hesabımızın başka noktasından çıkanı alıyoruz, ki bu ölçüt mesela bir or-
talama olabilir bu durumda bilinen bir dağılımı vardır, ya da lineer regresyon-
dan bize verilen bir katsayıdır, onun t değeri vardır, bu durumda da dağılımın
ne olduğunu biliyoruz. Yani hangi ölçüte bakarsak bakalım, ya da biz yeni bir
tanesini uyduralım, önce elde ettiğimiz rasgele değişkeninin ideal koşullarda
dağılımının ne olduğuna bakarız, ki test ettiğimiz bir anlamda bu ideal koşullar
olacaktır. Ardından bir kriter ortaya koyarak testi ortaya çıkartırız.
Ama ondan önce biraz regresyon.
Örnek veri olarak Big Andy’s Burger Barn adında hamburger satan bir restoran
zincirinin verisini kullanalım [1, sf. 168]. Veride her nokta ayrı bir şehirdeki belli
bir aydaki dükkan için kaydedilmiş reklam gideri ADVERT , burger fiyatı PRICE,
ve satış getirisi SALES (SALES ve ADVERT bin dolarlık birimde kaydedilmiş).
Şirket yönetimi diyelim ki reklam harcamalarının satışları nasıl etkilediğini merak
ediyor. Ayrıca yönetim bir fiyatlama stratejisi belirlemek istiyor, fiyatın geliri
nasıl etkilmektedir? Fiyatta düşüş çok az satış artışı yaratıyorsa bu durum kazancı
düşürür, demek ki talep fiyatsal-elastik değildir (price inelastic). Tam tersi de ola-
bilir, fiyat değişimi satışı arttırır, o zaman talep fiyatsal-elastiktir.
import pandas as pd
df = pd.read_csv('andy.dat',sep='\s*',names=['sales','price','advert'])
print df.head(3)
1
==============================================================================
coef std err t P>|t| [95.0% Conf. Int.]
------------------------------------------------------------------------------
Intercept 118.9136 6.352 18.722 0.000 106.252 131.575
price -7.9079 1.096 -7.215 0.000 -10.093 -5.723
advert 1.8626 0.683 2.726 0.008 0.501 3.225
==============================================================================
Omnibus: 0.535 Durbin-Watson: 2.183
Prob(Omnibus): 0.765 Jarque-Bera (JB): 0.159
Skew: -0.072 Prob(JB): 0.924
Kurtosis: 3.174 Cond. No. 69.5
==============================================================================
Fiyatsal elastikliği kontrol etmek için β2 ’nin t değerine bakabiliriz çünkü bu değer
β2 = 0 hipotezini reddedip reddedemeyeceğimiz hakkında bize bir şeyler söylüyor.
Eğer t değer ve P>|t| değeri 0.05’ten küçük ise hipotezi reddedebiliriz. Çıktıya
bakıyoruz, 0 değerini görüyoruz. Demek ki fiyatsal elastiklik vardır.
Gayrı Lineerlik: Fakat acaba reklam harcaması ile satış arasında tam lineer bir
ilişki mi var? Belli bir noktadan sonra ne kadar harcarsak harcayalım daha fa-
zla kazanamayacağımız bir durum da olamaz mı? Bunu test edelim, ADVERT 2
değişkenini ekleyip yeni bir regresyon yaratalım. ADVERT ’in karesini aldık çünkü
karesi alınmış ADVERT normal olana göre daha hızlı büyür, yani büyük değerlerde
karesinin sonucu çok daha büyüktür, ve eğer bu uç noktalarda bir kalıp var ise,
onu “yakalamak” bu karesi alınmış yeni değişken sayesinde mümkün olur.
2
==============================================================================
Yeni regresyon için R2 = 0.50! Bu yeni model verideki varyansın yüzde 50’sini
açıklıyor! Eskisinden daha iyi bir model ve AIC’i de daha düşük zaten, ve ADVERT 2
için hesaplanan katsayı -2.768 eksi değeri taşıyor. Demek ki reklam harcamalarının
belli bir noktadan sonra etkisinin aynı olmayacağı varsayımımız doğru.
Birleşik Hipotez Testleri
Ne yazık ki t testi ile ortak (joint) hipotez testleri yapamıyoruz. Mesela sadece bir
değil, birkaç değişkenin model için ne kadar önemli olduğunu bilmek istiyoruz.
Tabii bu değişkenleri regresyondan atabiliriz, sonra çıplak gözle AIC’e bakarız,
vs. Fakat bu testi daha İstatistiksel bir hipotez testi olarak yapmak daha iyi olmaz
mıydı? Alttaki test bu durumlar için kullanılır,
F Testi
Diyelim ki reklam harcamasının satışı etkileyip etkilemediğini merak ediyoruz.
Fakat artık bir değil iki tane reklam ile alakalı değişkenimiz var! Biri ADVERT
diğeri onun karesi ADVERT 2 . Sıfır hipotezimiz şu olacak, “reklam harcaması
satışları belirlemede etkili değildir”. Yani
H0 : β3 = 0, β4 = 0
3
hesabı bir Fj,n−k dağılımıdır. F dağılımının tanımını hatırlayalım, iki chi kare
dağılımının birbiriyle bölünmüş hali idi,
χ2 /j
Fj,n−k = 2
χ /n − k
SSE hesapları karelerin toplamı olduğu için ve hataların normal dağıldığı varsayımından
hareketle bölüm ve bölendeki rasgele değişkenler Chi kare dağılımına sahiptir.
Peki neden üstteki F dağılımının j, n − k derece serbestliği vardır? İki chi kare
dağılımını toplayınca onların dereceleri toplanır. Aynı şekilde çıkartma derece
eksiltir. Şimdi, SSEr ’nin derecesi n − k’dir, k tane katsayı dereceyi / serbestliği
azaltmıştır. Eğer SSEr elde etmek için j tane katsayıyı çıkartırsak, bu durum
dereceyi fazlalaştırır, yani SSEr için n − k + j elde ederiz. O zaman bölümdeki
çıkartmanın derecesi
(n − r + j) − (n − r) = j
olacaktır. Şimdi nihai hesabı yapalım, regresyonu reklamla alakalı iki değişkeni
çıkartılmış şekilde bir daha işletiriz, sonra SSE hesabı için her iki regresyondan
gelen artıklar resid’leri kullanırız, onların karelerinin toplamı bize gerekli SSE
hesabını verecektir,
import scipy.stats as st
f = st.f(J,N-K)
print 1-f.cdf(F)
0.000514159058424
Üstteki değer 0.05 kritik değerinden daha ufak olduğu için hipotez reddedilmiştir.
Direk p değeri hesabı yerine yüzde 95 güven için bir eşik değeri de hesaplaya-
bilirdik,
4
print f.ppf(0.95)
3.12576423681
S2x
F=
S2y
import pandas as pd
m1 = np.array(method_1); m2 = np.array(method_2)
df = pd.DataFrame([m1,m2]).T
ss = df.std()
F = ss.ix[0]**2/ss.ix[1]**2
print F
0.243934673841
import scipy.stats as st
f = st.f(len(m1)-1,len(m2)-1)
print 1-f.cdf(F)
0.981334830069
5
Örneklem Korelasyonu
Korelasyon ρ’yu daha önce gördük, tahmin edicisi r’dir,
Sxy
ρ̂ = r = p (1)
Sxx Syy
X
n
Sxx = (xi − x̄)2
i=1
X
n
Sxy = (xi − x̄)(yi − ȳ)
i=1
X
n
Syy = (yi − ȳ)2
i=1
olsun; bu hesapların teorik varyans ile olan bağlantısı görülebilir. Eğer X, Y iki
değişkenli (bivariate) bir normal dağılımından geliyorsa, o zaman ortada bir re-
gresyon varmış gibi gösterebiliriz
E(Y|X = x) = β0 + β1 x +
ki β1 = σY /σX · ρ olur. Detaylar için [4]. Soru şu, r için bir istatistiksel önemlilik
(significance) hesabı nasıl yapardık? Yani, eğer −1 6 r 6 1 işe, ve r = 0 hiç
korelasyon olmama durumu ise, acaba bu “sıfır olmama” durumunu test ede-
bilir miydim? Evet. Yukarıdaki normallik faraziyesi doğru ise β1 = 0 olmama
durumunu test etmek ρ = 0 olmama testi ile aynı, bu durumda
β̂1
t0 = q
Var(β̂1 )
gibi bir test istatistiği yaratırız, ki bu istatistik Öğrenci t dağılımına sahip olurdu
çünkü sıfır hipotezi β̂1 = 0, ve üstteki istatistik sıfır hipotezi altında ile Öğrenci
t dağılımına sahip olmak zorundadır, çünkü bölünen normal dağılmış, bölen chi
karenin karekökü olarak dağılmış. Eğer to hesabı veriye uygulandıktan sonra
hipotezin öngördüğü dağılıma uymaz ise, sıfır hipotezini reddederiz.
Bu noktada lineer regresyon ile alakalı bilgiler devreye sokulabilir, [4]’den biliy-
oruz ki
6
σ2
Var(β̂1 ) =
Sxx
β̂1
t0 = p
S/Sxx
SSE
S= , SSE = Syy − β̂1 Sxy
n−2
√ √
Sxx β̂1 n − 2
t0 = √
SSE
√ √
Sxx β̂1 n − 2
= q
Syy − β̂1 Sxy
p
Bölümün iki kısmını Sy ile bölelim,
p √
Sxx /Syy β̂1 n − 2
= q
1 − β̂1 Sxy /Syy
√
r n−2
=q
1 − β̂1 Sxy /Syy
Bölen kısmındaki β̂1 yerine β̂1 = Sxy /Sxx koyarsak yine (1)’deki r tanımına geli-
riz, ve alttaki basitleştirilmiş ifade ortaya çıkar,
s
(n − 2)r2
to =
(1 − r2 )
7
Possum adı verilen bir tür hayvanın dişilerinin tüm uzunluğu ve kafa ölçümü
totlngth,hdlngth değişkenleri arasında korelasyon olup olmadığı merak edilmek-
tedir.
import pandas as pd
import scipy.stats
df = pd.read_csv('fossum.csv')
c,tval, pval = p_corr(df.totlngth,df.hdlngth)
print c, pval
0.779239322172 3.75045772216e-10
8
X
k
(Nj − npj )2
2
χ =
j=1
npj
ile belirtilir, üstteki toplamın yaklaşıksal olarak χ2k−1 dağılımına yaklaştığı ispatlanmıştır.
Detaylar için [5, sf 318, 6]. Nihai ispat oldukça çetrefil, biz burada alternatif bazı
yaklaşıksal ispatlardan bahsetmek istiyoruz (okkalı ispat için yukarıdaki refer-
anslar geçerli tabii).
Eğer her Nj binom dağılımını Gaussian ile yaklaşıkladığımızı düşünürsek, ki bu
yeterince büyük n, ve npi > 5 için mümkün, bu dağılım µ = npj ve varyans
npj (1 − pj )’ye sahip olur, o zaman Gaussian’ı standardize etmek için
N − npj
p j ≈ N(0, 1)
npj (1 − pj )
Z = N(0, 1) diyelim,
(Nj − npj )
q
√ ≈ (1 − pj )Z
npj
X (Nj − npj )2 X
≈ (1 − pj )Z2
j
npj j
Üstteki eşitliğin sol tarafı Pearson istatistiğiyle aynı. Sağ tarafı neye eşit?
X
(1 − pj )Z2 = (1 − p1 )Z2 + (1 − p2 )Z2 + ... + (1 − pk )Z2
j
= Z2 [(1 − p1 ) + (1 − p2 ) + ... + (1 − pk )]
X
= Z2 [k − (p1 + p2 + .. + pk ))] = (k − 1)Z2 = Z2
k−1
Şimdi, bu eriştiğimiz toplamın χ2k−1 dağılımı, yani k−1 derece serbestliği olan bir
chi kare dağılımı olduğunu iddia edebilir miyiz? Eğer Zj ’ler birbirinden bağımsız
ise kesinlikle evet, çünkü standart normal rasgele değişkenlerin toplamı chi kare
dağılımını verir. Üstteki kolay ispatın önündeki tek engel budur, bizim burada
yapacağımız yaklaşıksal argüman i, j ikilisi için Z’lerin bağlantısının, kovaryansının
küçük olduğudur, ki bu küçüklük sebebiyle Zj ’ler çoğu durumda bağımsız kabul
edilebilir.
9
Diyelim ki X1 , X2 , .. değişkenleri ba
ğımsız ve Mult(1,
P p), yani multinom dağılımdan
geliyorlar [7, sf. 180], ve p = p1 p2 . . . , ve j pj = 1. Yani her Xi zar
attığında 1 × k boyutlu bir vektör ortaya çıkıyor, bu vektörün sadece bir hücresi 1
diğerleri 0. Multinom dağılımların tanımından biliyoruz ki Cov(Xi , Xj ) = −npi pj =
−pi pj (çünkü n = 1).
Bu demektir ki 1’den küçük iki değer çarpılıyor bu daha da küçük bir değer
verecektir. Eğer k yeterince büyük ise, bu, mesela sürekli yoğunlukları ayrıksal
olarak gösterdiğimiz durumda ve yeterince çok kutucuk var ise bu kutucuklara
“düşen” olasılıkların ufalması demektir, ve ufak değerlerin çarpımı iyice ufalır,
ki bu kovaryansı sıfıra yaklaştırır. Yani yeterince büyük k için i, j bağlantısını
sezgisel bağlamda etkisiz olduğunu görebiliriz. Tabii, toplamın kesinlikle chi kare
olduğunun ispatı için dediğimiz gibi verdiğimiz referanslara bakılabilir.
İstatistiki testlerin mantığını hatırlarsak, tarif edilen Pearson istatistiği sıfır hipotezi.
Bize reddetmeye uğraşacağımız bir dağılım / hesap ikilisi üretiyor. Eğer hesap
beklenen, normal (sıfır hipotez durumu) uymuyorsa, hipotezi reddediyoruz. Ret
durumu özellikle seçiliyor çünkü kabul edilmezlik daha kesin bir cevap.
Örnek
Bir paralı otoyolunda geçiş noktasında durulmuş ve her dakika gelen araç sayılmış,
ve dakika başına bu araç sayısı yazılmış. Bu deney 106 dakika süresince yapılmış
(elde 106 satırlı bir veri var yani). Bu veri için Poisson dağılımının uygun olup
olmadığını yüzde 5 önemlilik seviyesinde ispatlamamız isteniyor.
import pandas as pd
vehicle = [2, 3, 3, 3, 4, 4, 4, 4, 4, 5, 5, 5, 5, 5, 5, 5, 6,\
6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 7, 7, 7, 7, 7, 7, 7,\
7, 7, 7, 7, 7, 8, 8, 8, 8, 8, 8, 8, 8, 9, 9, 9, 9, 9, 9, 9,
9, 9, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, \
11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 12, 12, 12, 12, \
12, 13, 13, 13, 13, 13, 13, 14, 14, 14, 14, 15, 15, 15, 15,\
15, 16, 16, 16, 16, 18]
df = pd.DataFrame(vehicle)
f = plt.figure(); df.hist(bins=13)
plt.savefig('stat_tests2_01.png')
10
Poisson dağılımı muhtemel gözüküyor. Ama şimdi bunu uyum derece testi ile
daha kararlı şekilde göstermeye uğraşacağız. Verideki sayımları o sayım rakamı
bazında gruplayalıp gösterelim,
kt = plt.hist(np.array(df),bins=range(20))
kt = pd.DataFrame([kt[1],kt[0]]).T
kt = kt[:-1] # sonuncu satiri at
kt.columns = ['kac araba','kac kere']
print (kt)
kac araba kac kere
0 0.0 0.0
1 1.0 0.0
2 2.0 1.0
3 3.0 3.0
4 4.0 5.0
5 5.0 7.0
6 6.0 13.0
7 7.0 12.0
8 8.0 8.0
9 9.0 9.0
10 10.0 13.0
11 11.0 10.0
12 12.0 5.0
13 13.0 6.0
14 14.0 4.0
15 15.0 5.0
16 16.0 4.0
17 17.0 0.0
18 18.0 1.0
Yani bir dakikada 6 araba sayımı 13 kere yapılmış (13 değişik dakikada). Not:
Üstte bir kütüphane çağrısı hist kullandık (grafikleme kısmını kullanmadan),
ama Poisson frekans hesabı elle çok kolay yapılabilir.
Eğer üstteki verinin bir Poisson dağılımdan geldiğini kabul ediyorsak, Poisson’un
parametresi λ’yi veriden hesaplamak için ortalama almak yeterlidir,
11
lambda 5.58
1X
n
λ̂ = xj
n j=1
Bu λ̂’yi kullanarak Poisson hesaplarını yapabiliriz artık. Bir kutucuğa düşen Pois-
son olasılığının hesabı P(a 6 X < b), ki bu basit bir F(b) − F(a), yani a, b nokta-
larındaki kümülatif yoğunluk fonksiyonun farkı üzerinden hesaplanabilir, altta
kullanılan çağrı poisson.cdf.
12
lam = df.mean() # tahmin edici
def f(x):
high = poisson.cdf(x.int_high-1,lam)
low = poisson.cdf(x.int_low-1,lam)
return pd.Series(high-low)
kt2['p_i'] = kt2.apply(f,axis=1)
kt2['np_i'] = len(df) * kt2['p_i']
kt2['chi'] = (kt2['n_i']-kt2['np_i'])**2 / kt2['np_i']
kt2 = kt2[:-1]
print kt2
print '\nchi kare istatistigi', kt2.chi.sum()
Şimdi üstteki değerin istatistiki önem taşıyıp taşımadığını anlamaya geldi sıra.
Eşik değerimiz χ29,0.05 olacak. Peki niye serbestlik derecesi 9 alındı? Elde kaç tane
kutucuk var?
11 kutucuk
11-1=0 niye olmadı, -1 ile serbestlik derecesi hesaplamıyor muyduk? Evet. Fakat
bir kavis daha var, tahmin edici ile λ’yi hesaplayınca 1 serbestlik derecesi daha
kaybettik! χ2 ile çalışırken hatırlanması gereken bilgilerden biri bu. Pearson
bu testi keşfettiğinde aslında bu eksiltmeye gerek görmüyordu, daha sonraları
Fisher adlı istatistikçi bunun gerekli olduğunu ispatladı.
serbestlik derecesi 9
chi kare 16.9189776046
Hesaplanan değer üstteki değerden küçük olduğu için Poisson hipotezi kabul
edilmiştir (ya da olmadığı reddedilememiştir, eğer p-değeri hesaplasaydık, 0.05’den
az sonuca bakacaktık, aynı şey).
Örnek
13
Gördüğümüz gibi bir dağılım varlığlığını test için o dağılımın analitik yoğunluk
fonksiyonunu veriden gelen tahmin ediciler üzerinden tanımlayıp, veriyi bu fonksiyon
ile üretmeyi deneyebiliriz, ve bu sonuç ile veri arasında uyumluluğa bakabiliriz.
Mesela olayların coğrafi olarak dağılımına bakalım.. Bu tür olayları nasıl model-
leriz? Olaylar depremler, yangınlar, ya da bir savaşta bir alana atılan bombalar
olabilir, ve bu tür sayılar Poisson dağılımı ile modellenir. Bu dağılım ilk bölümde
gördüğümüz gibi,
λx
f(x) = P(X = x) = e−λ
x!
olay sayısı x = 1, x = 2, vs.. olacak şekilde, ki önceden tanımlı belli bir za-
man aralığında x tane olayın olma olasılığını bu yoğunluk veriyor. Coğrafi olay
sayılarını ölçmek için biraz farklı düşünmek gerekiyor, mesela 2’inci Dünya Savaşı
sırasında Almanların Londra’ya attıkları bombaları düşünelim, analizi [13]’te var;
Merak edilen şuydu, acaba bombalar belli bir yerde kümeleniyor muydu (cluster-
ing)? Cevap önemli olabilirdi, belki özel bir yer vurulmak isteniyordu? Analizde
olayların doğal oluş sayısını modelleyen Poisson varlığı ispatlanırsa, kümelenme
hipotezi reddedilmiş olacaktı. İstatistikçi Clarke Londra’yı 536 tane ızgaraya
böldü, ve her öğe içine düşen bombaları saydı. Bu bittikten sonra 1 tane bomba,
2 tane bomba, vs.. şeklinde olan hücrelerin sayısını aldı, ki yoğunluğa x ile
geçilecek olan bu sayıydı.
Sonra Clarke yoğunluğu λ tahmin edici hücre sayısı bölü bomba sayısı üzerinden
tanımladı, ve bu yoğunluktan tüm sayılar için bir tahmini bomba sayısı ürettirdi,
sonuçları gerçek bomba sayıları ile karşılaştırdı.
N = 576.
lam = 537/N
d = N*np.exp(-lam)
probs = [d*1, d*lam, d*lam**2/2, d*(lam**3)/(3*2), d*(lam**4)/(4*3*2)]
list(map(lambda x: np.round(x,2), probs))
Gerçek sayılar 229, 211, 93, 35, 7, .. idi, görüldüğü gibi oldukca yakın sayılar. Bir
adım daha atılıp bunun üzerinde bir istatistik testi uygulanınca Poisson varlığı,
ve dolaylı olarak kümelemenin olmadığı ispatlanmış oldu.
Kaynaklar
[1] Hill, Principles of Econometrics
[2] Uriel, Introduction to Econometrics, Lecture
[3] Haslwanter, Introduction to Statistics Using Python
[4] Wackerly, Mathematical Statistics, 7th Edition
[5] Soong, Fundamentals of Probability and Statistics for Engineers
14
[6] OCW MIT, Statistics for Applications, 18.443
[7] Hunter, Asymptotics for Statisticians
[8] Steiger, Correlation and Regresion, Lecture Notes
[9] Sheppard, Introduction to Python for Econometrics
[10] Greene, Econometric Analysis
[11] Uriel, Introduction to Econometrics
[12] Bayramlı, İstatistik, Gayri Lineer Regresyon, Petrol Tepe Noktası
[13] Clarke, An application of the Poisson distribution, https://www.actuaries.
org.uk/system/files/documents/pdf/0481.pdf
15
Çok Değişkenli Gaussian Dağılımlar
Çok değişkenli normal dağılımlarla iş yaparken, mesela Gaussian karışımları
kullanırken, bazı numaraları bilmek faydalı olabiliyor. Bunlardan birincisi (x −
µ)T Σ−1 (x − µ) hesabını yapmaktır, diğer log-toplam-exp numarası (logsumexp
trick) diye bilinen hesaptır.
Birinciden başlayalım, daha kısalaştırmak için y = x − µ diyelim, yani yT Σ−1 y ol-
sun. Şimdi bu formülde bir ters alma (inversion) işleminin olduğunu görüyoruz.
Fakat bu işlem oldukça pahalı bir işlem olarak bilinir, hele hele boyutların yükseldiği
durumlardan (binler, onbinler), kovaryansı temsil eden Σ, n × n olacaktır. Acaba
tersini almayı başka bir şekilde gerçekleştiremez miyiz?
Σ matrisi bir kovaryans matrisi olduğu için simetrik, pozitif yarı kesin bir matri-
stir. Bu tür matrislerin Cholesky ayrıştırmasının olduğunu biliyoruz ve bu işlem
çok hızlı yapılabiliyor. O zaman
Σ = LLT
= L−T L−1
Parantezden bir şeyin devriği gibi temsil edersek, parantez içindekilerin sırası
değişir ve tek tek devriği alınır,
= |L−1 y|2
1
(overdetermined) değil, yani en az kareler değil direk lineer sistem çözümü yapıyoruz.
Bu durumda her standart lineer cebir kütüphanesinde mevcut bir çağrı kullanacağız,
mesela solve_triangular (ve lower -alt- doğru seçeneğini kullanacağız), ki bu
çağrı özellikle alt üçgensel matris üzerinden çözüm yapmaktadır, çünkü L alt-
üçgensel olduğu için çözüm geriye değer koymak (back substitution) ile anında
bulunabilir. Geriye değer koymayı hatırlarsak, mesela
2 0 x1 6
=
3 4 x2 8
En üst satırda her zaman tek bir bilinmeyen olacak, çünkü matris alt üçgensel, en
üst satır her zaman en boş satırdır. Bu tek bir eşitlik demektir, yani 2x1 = 6, ki
x1 = 3. Bunu alıp bir sonraki satıra gideriz, artık x1 ’i biliyoruz, sonraki satırda
sadece x2 bilinmeyen kalıyor, 3 · x1 + 4 · x2 = 8, yani x2 = −1/4. Sonuca ulaştık.
Daha fazla boyut olsaydı durum değişmezdi, aynı işlem daha fazla tekrarlanırdı.
Bu arada bu türden bir çözümün ne kadar hızlı olacağını belirtmemize gerek yok
herhalde.
Demek ki yT Σ−1 y hesabı için önce Σ üzerinde Cholesky alıyoruz, sonra L−1 y
çözdürüyoruz. Elde edilen değerin noktasal çarpımını alınca Σ’nin tersini elde
etmiş olacağız.
Örnek (önce uzun yoldan),
Σ11 Σ12
Σ=
Σ21 Σ22
2
Şimdi birleşik Gaussian’ı
T −1
1 1 x1 − µ1 Σ11 Σ12 x1 − µ1
f(x; µ, Σ) = exp −
(2π)(p+q)/2 det(Σ)1/2 2 x2 − µ2 Σ21 Σ22 x2 − µ2
−1
E F E−1 F−1
6=
G H G−1 H−1
Tersini alma işlemi için bazı numaralar lazım. Ana numara bölüntülenmiş matrisi
köşegen bir matris haline getirmek, çünkü köşegen matrislerin tersi, köşegendeki
elemanların tersidir, yani ters alma operasyonu bu tür matrislerin “içine işler”,
o yüzden bir şekilde bir köşegen matris elde etmeye uğraşacağız. Bunun için
bölüntülenmiş matrisimizi sağdan ve soldan bazı matrislerle çarpacağız. Ayrıca
şunu da bilelim,
XYZ = W
Y = X−1 WZ−1
Y −1 = ZW −1 X
3
Tamam, başlayalım.
E F
M=
G H
matrisini köşegen yapacağız. Eğer sadece alt sol köşeyi sıfırlayasaydık, bunu
yapacak özel bir matrisle soldan çarpardık,
I −FH−1 E F E F
=
0 I G H 0 H
E F I 0 E 0
=
G H −H−1 G I G H
I −FH−1 E F I 0 E − FH−1 G 0
−1 = (2)
0 I G H −H G I 0 H
XYZ = W
Y −1 = ZW −1 X
ile olur.
I −FH−1 E F I 0 E − FH−1 G 0
=
0 I G H −H−1 G I 0 H
| {z } | {z } | {z } | {z }
X Y Z W
O zaman
−1 −1
E F I 0 E − FH−1 G 0 I −FH−1
= −1
G H −H G I 0 H 0 I
4
Daha kısa olması eşitliğin sağ tarafında, ortadaki matris için E − FH−1 G yerine
M/H kullanalım (bu arada M/H lineer cebirde “M’in H’e göre Schur tamam-
layıcısı (complement)” olarak bilinir),
−1
E F I 0 (M/H)−1 0 I −FH−1
= −1 −1 (3)
G H −H G I 0 H 0 I
(M/H)−1 −(M/H)−1 FH−1
=
−H−1 G(M/H)−1 H−1 + H−1 G(M/H)−1 FH−1
Bu final ifade bölüntülenmiş bir matrisin tersini o matrisin içindeki parçalar üzerinden
temsil eden bir ifadedir.
İçinde bir köşesi sıfır olan bölüntülenmiş matrislerde determinantlar şöyle işler,
E 0 E F
det = det = det(E) det(H)
G H 0 H
Ayrıca
T
A B A T CT
=
C D BT DT
Şimdi çok değişkenli Normal için bileşen ve koşullu yoğunluk hesaplarına gele-
lim. Gaussian formülünün exp kısmını alırsak,
T −1
1 x1 − µ1 Σ11 Σ12 x1 − µ1
exp −
2 x2 − µ2 Σ21 Σ22 x2 − µ2
5
(3)’teki açılımı kullanırsak, ve E = Σ11 , F = Σ12 , .. olacak şekilde,
T
I −Σ12 Σ−1
1 x1 − µ1 I 0 (Σ/Σ22 ) 0 22 x1 − µ1
exp −
2 x2 − µ2 −Σ−1
22 Σ21 I 0 Σ−1
22 0 I x2 − µ2
1
= exp − 2
(x1
− µ1 − Σ12 Σ−1
22 (x2
T −1
− µ2 )) (Σ/Σ22 ) (x1 − µ1 − Σ12 Σ−1
22 (x2 − µ2 )) ·
exp 1 12 (x2 − µ2 )T Σ−1
22 (x2 − µ2 )
Not: ΣT12 = Σ21 . Üstte birinci exp içinde sol bölümde devriğin içindeki ifadeler-
den, mesela xT1 , µT1 ’den ve Σ21 ’li ifadeden devrik işlemini çekip, büyük paranteze
alınınca bu değişim oldu.
Şimdi mesela 1. exp’ye dikkat edersek, ortada (Σ/Σ22 )−1 var, ve bu ifadenin sol-
unda ve sağında birbirinin devriği olan aynı terimler duruyor. İfadenin tamamı
bir Normal dağılım. Aynı şey 2. exp için geçerli.
İşin exp tarafını halletik. Şimdi exp öncesindeki kesiri (4) kullanarak parçalayalım,
1 1
= 1/2
(2π)(p+q)/2 det(Σ)1/2
(2π)(p+q)/2 det(Σ/Σ22 ) det(Σ22 )
1 1
=
(2π) det(Σ/Σ22 )1/2
p/2 (2π) det(Σ22 )1/2
q/2
Bu parçaların her birini ayrı bir exp önünde kullanabiliriz, ve ikinci exp ifadesinin
1 1
exp (x2 − µ2 )T Σ−1
22 (x2 − µ2 )
(2π) det(Σ22 )1/2
q/2 2
1
·
(2π)p/2 det(Σ/Σ22 )1/2
1
exp − (x1 − µ1 − Σ12 Σ−1 T −1 −1
22 (x2 − µ2 )) (Σ/Σ22 ) (x1 − µ1 − Σ12 Σ22 (x2 − µ2 ))
2
6
1) X2 ’nin bileşen yoğunluğu X2 ∼ N(µ2 , Σ22 )
2) X2 = x2 olmak üzere X1 ’in koşullu dağılımı
X1 |X2 = x2 ∼ N µ1 + Σ12 Σ22 (x2 − µ2 ) , Σ/Σ22
−1
Yani
X1 |X2 = x2 ∼ N µ1 + Σ12 Σ22 (x2 − µ2 ) , Σ11 − Σ12 Σ22 Σ21
−1 −1
r = p1 · p2 . . . pn
Olasılıklar 1’den küçük olduğu için 1’den küçük değerlerin çarpımı aşırı küçülebilir,
ve küçüklüğün taşması (underflow) ortaya çıkabilir. Eğer çarpım yerine log alırsak,
çarpımlar toplama dönüşür, sonra sonucu exp ile tersine çeviririz, ve log’u alınan
değerler çok küçülmez, çarpma yernie toplama işlemi kullanıldığı için de nihai
değer de küçüklüğe doğru taşmaz.
Bir diğer durum içinde exp ifadesi taşıyan bir olasılık değerinin çok küçük değerler
taşıyabilmesidir. Mesela çok değişkenli Gaussian karışımları için alttaki gibi bir
hesap sürekli yapılır,
X
1 1
= wi exp − (x − µ)T Σ−1 (x − µ)
i
(2π) det(Σ)1/2
k/2 2
7
log(e−1000 + e−1001 )
-inf
Bu durumdan kurtulmak için bir numara şudur; exp ifadeleri arasında en büyük
olanını dışarı çekeriz, ve log’lar çarpımı toplam yapar,
Bunu hesaplarsak,
-999.686738312
8
Kullback-Leibler (KL) Mesafesi
İki olasılık dağılımının arasındaki uyumsuzluğu (discrepancy) hesaplayan bir
ölçüt KL mesafesidir. Gerçi bu ölçüt tam tanımıyla mesafe değil, f ile g arasındaki
mesafe g ile f arasındaki mesafeden farklı olabiliyor, KL mesafesi üçgen eşitsizlik
(triangle inequality) kavramını takip etmiyor. Tam tanımlamak gerekirse KL bir
yönsel (directed) mesafedir [2].
Kullback-Leibler aslında 1951’de bir enformasyon ölçütü bulmuş oldular, bu ölçüt
ilginç bir şekilde fizikçi Boltzmann’ın bir sistemdeki düzensizliği ölçen entropi
kavramının negatif değerli halidir. Ayrıca KL mesafesi Enformasyon Teorisi’ni
keşfeden Shannon’un enformasyon tanımının da bir uzantısıdır, bu sebeple bazen
KL mesafesine “izafi entropi” ismi de veriliyor.
Tüm bu kavramların tabii ki İstatistik’teki model seçme uygulamalarıyla yakın
alakaları var. Diyelim ki elimizde iki dağılım var, f yaklaşmaya çalıştığımız bir
model, g ise onu yaklaşık olarak temsil etmeye uğraşan başka bir model, θ parame-
treleri üzerinden tanımlı, yani g(x|θ). θ çoğunlukla veriden kestirilmeye çalışılır,
θ̂ elde edilir, o zaman g(x|θ̂) olur. Bu iki dağılım / model arasındaki KL mesafesi
Z
f(x)
I(f, g) = f(x) log dx
g(x; θ)
X
k
pi
I(f, g) = pi log
i=1
πi
1
cebirsel olarak bölümün log’u olarak tek bir log altında gruplanabilir, ve mümkün
tüm sayılar üzerinden bu farkların beklentisini alırsak üstteki entegral (ya da
toplam) formülünü elde etmiş oluruz.
KL mesafesi her zaman pozitiftir, tek bir durum haricinde, eğer f, g eşitse - o
zaman I(f, g) = 0.
Bir örnek üzerinde görmek gerekirse, diyelim ki f 2 parametreli bir Gamma dağılımı,
α = 4, β = 4. Şimdi bu modeli yaklaşık olarak temsil etmeye uğraşan 4 tane
seçeneği görelim, Weibull, lognormal, ters Gaussian, ve F dağılımı.
Yaklaşık Model I(f, gi )
2
Bir başka örnek için Testlere Devam yazısındaki araba sayım verisine bakalım.
Şimdi ham veriye en uygun olan dağılımı bulmaya çalışacağız.
import pandas as pd
df = pd.read_csv('../stat_tests2/vehicles.csv',header=None)
df.hist(bins=13)
plt.savefig('stat_kl_02.png')
3
Veride Poisson görünümü var. Eşit aralıklarda yapılan sayımların Poisson dağılımını
takip etmeye meyilli olduğunu biliyoruz. Bu tezi kontrol edelim. Eğer, diye-
lim, Possion ve Gaussian arasında seçim yapacak olsak, bu seçimi KL mesafesi
üzerinden yapabilirdik. Her iki durumda da dağılım parametrelerini veriden
tahmin ediyor olurduk,
9.09433962264 3.54166574177
import scipy.stats
s = 4000
b = 15
r1 = scipy.stats.poisson.rvs(mu=8, size=s)
plt.hist(r1, bins=b,color='b')
plt.title('Poisson $\lambda = 8$')
plt.xlim(0,20)
plt.savefig('stat_kl_04.png')
plt.figure()
r2 = scipy.stats.norm.rvs(2, 1, size=s)
plt.hist(r2, bins=b,color='b')
plt.title('Gaussian $\mu = 2,\sigma=1$')
plt.xlim(0,20)
plt.savefig('stat_kl_06.png')
plt.figure()
r3 = scipy.stats.poisson.rvs(mu=9.0943, size=s)
plt.hist(r3, bins=b,color='b')
4
plt.title('Poisson $\lambda = 9.1$')
plt.xlim(0,20)
plt.savefig('stat_kl_07.png')
plt.figure()
r4 = scipy.stats.norm.rvs(9.1, 3.54, size=s)
plt.hist(r4, bins=b,color='b')
plt.title('Gaussian $\mu = 9.1,\sigma=3.54$')
plt.xlim(0,20)
plt.savefig('stat_kl_08.png')
b = range(0,30)
eps = 1e-5
dh = np.histogram(df, bins=b, density=True)[0]+eps
h1 = np.histogram(r1, bins=b, density=True)[0]+eps
h2 = np.histogram(r2, bins=b, density=True)[0]+eps
h3 = np.histogram(r3, bins=b, density=True)[0]+eps
h4 = np.histogram(r4, bins=b, density=True)[0]+eps
print 'Poisson lambda = 8', kl(h1, dh)
print 'Gaussian mu = 2,sigma=1', kl(h2, dh)
print 'Poisson lambda = 9.1', kl(h3, dh)
print 'Gaussian mu = 9.1,sigma=3.54', kl(h4, dh)
5
En yakın olan Poisson λ = 9.1 olarak gözüküyor.
Çok Boyutlu Dağılımlar
Eğer bir dijital görüntü üzerinde çalışıyorsak, o resimdeki piksel değerlerinin de
bir “dağılımı” olduğunu düşünebiliriz. Yani resmi, ya da resmin bir bölgesini bir
teorik dağılımdan “üretilmiş” bir örneklem olarak görmek mümkün. Bu dağılımı
çok boyutlu histogram alarak yaklaşık olarak hesaplayabiliriz. Eğer iki farklı
resim bölgesini bu şekilde belirtirsek, bu iki dağılımı KL mesafesiyle karşılaştırabililiriz,
ve böylece görüntüsel olarak iki bölgeyi karşılaştırabiliriz.
def draw_boxes_color(bs,imfile):
im = Image.open(imfile).convert('HSV')
arr = np.asarray(im)
draw = ImageDraw.Draw(im)
colors = ['magenta','green','white','red','yellow']
for i,b in enumerate(bs):
fr = b[0]; to = b[1]
bnew = [(fr[0],arr.shape[0]-fr[1]),(to[0],arr.shape[0]-to[1])]
draw.rectangle(bnew,outline=colors[i])
plt.imshow(im)
box1 = [(35,144),(87,292)]
box2 = [(106,183),(158,287)]
box3 = [(117,86),(132,160)]
f = '../../vision/vision_50colreg/castle.png'
draw_boxes_color([box1,box2],f)
plt.savefig('stat_kl_03.png')
draw_boxes_color([box2,box3],f)
plt.savefig('stat_kl_05.png')
6
Renklerin HSV kodlamasını kullanalım, o zaman her piksel kordinatında 3 değer
olur. Bu durumda histogram almak demek çok boyutlu histogram demektir, üç
boyut için sırasıyla 8,8,4 tane kutu tanımlarsak, 256 tane kutu elde ederiz. Bu
kutuları numpy.histogramdd ile hesaplarız, KL karşılaştırması için kutuları düz
vektör haline getirebiliriz -KL hesabında her iki tarafın birbirine tekabül eden
kutuları kullanıldığı sürece problem yok- ve böylece nihai hesap yapılır.
def box_kl_dist(b1,b2,im):
im = Image.open(f).convert('HSV')
arr1 = get_pixels(b1, im)
r = [(0,255),(0,255),(0,255)]
7.55231179178e-06
7.30926985663e-07
7
Lineer Regresyon
Bir hedef değişkeninin bir veya daha fazla kaynak değişkenine olan bağlantısını
bulmak için en basit yöntemlerden biri bu ilişkinin lineer olduğunu kabul et-
mektir, yani eldeki değişkenlerin belli ağırlıklar ile çarpımının toplamı olarak.
İlk başta bilinmeyen bu ağırlıkları, ya da katsayıları bulmak için En Az Kareler
(Least Squares) en iyi bilinen yöntemlerden biri; En Az Kareler daha önce pek
çok değişik ders notlarında, yazıda türetildi. Mesela [7], [8], ya da [9].
Lineer Regresyonun sadece iki değişken temelli işlemek gerekirse,
Y = β0 + β1 x +
olabilir. Eğer iki değişkenden fazlası var ise bu bir düzlem uydurulacak demek-
tir. Değişken , N(0, σ2 ) dağılımından gelen hatadır ve σ bilinmez. Eğer veriyi
(x1 , y1 ), ...(xn , yn ) ikili olarak grafiklesek
gibi gözükebilirdi, lineer regresyon ile yapmaya çalıştığımız tüm noktalara ola-
bilecek en yakın düz çizgiyi (üstte görüldüğü gibi) bulmaktır.
Bu düz çizgiyi (ki boyutlu ortamda bu çizgi bir hiper düzlem olurdu, β2 , β3 , ..
gibi daha fazla katsayı gerekirdi), En Az Kareler ile bulduktan sonra elimize
geçenler katsayı değerlerinin tahminidir, ki bunlar bazı kaynaklarda β̂0 , β̂1 olarak
tanımlanır, bu notasyon istatistikteki “tahmin edici (estimator)” notasyon ile uyumlu.
Bu tahmin ediciler ile elde edilen y’nin kendisi de bir tahmin edici haline gelir ve
bir düz çizgiyi tanımlar,
ŷ = β̂0 + β̂1 x
1
import pandas as pd
df = pd.read_csv('galton.csv',sep=',')
print df.head(4)
child parent
0 61.7 70.5
1 61.7 68.5
2 61.7 65.5
3 61.7 64.5
Şimdi regresyonu işletelim, sadece bağımsız tek değişken olacak, ebeveyn boyu
parent, hedef değişken ise çocuk child içinde.
Warnings:
[1] Standard Errors assume that the covariance matrix of the errors is correctly speci
[2] The condition number is large, 2.61e+03. This might indicate that there are
strong multicollinearity or other numerical problems.
print pd.Series(results.resid).describe()
count 9.280000e+02
mean 4.484995e-13
std 2.237339e+00
min -7.805016e+00
25% -1.366144e+00
50% 4.869321e-02
75% 1.633856e+00
max 5.926437e+00
dtype: float64
2
Bu çıktıda gösterilenler ne anlama gelir?
1) coef altında görülen değerler sırasıyla βo , β1 tahminleridir, yani β̂o , β̂1 . Bun-
lar bulmak istediğimiz katsayılar. İki boyutta olduğumuz için düz bir çizgiden
bahsediyoruz, bu çizginin y eksenini kestiği yer kesi (intercept) β̂0 ’da ve ebeyne
(parent) tekabül eden katsayı β̂1 .
Teorik olarak eğer bir katsayı sıfır ise bu işe yaramaz bir katsayıdır, çünkü modele
hiçbir şey “eklemez”. Fakat Basit En Az Kareler (ordinary least squares -OLS-)’in
hesapladığı bir tahmindir nihayetinde ve hiçbir zaman sıfır olmayacaktır. O za-
man soruyu biraz daha değiştirmek gerekir: istatistiki olarak düşünürsek gerçek
katsayının sıfır olma olasılığı nedir? Katsayı yanında görülen t ve P > |t| (diğer
ismiyle p-değeri) bunun için kullanılır.
t değeri bir katsayı için onun tahminini ve standart hatasına bölerek elde edilir.
Üstteki çıktıda mesela 23.9415/2.811=8.517. Bu değer katsayı tahmininin veri-
den veriye ne kadar değişik sonuçlar verebileceğini (variability) gösterir, ve bir
bakıma bu katsayı tahmininin kesinliği (precision) hakkında bir rapordur. Eğer
bir katsayı tahmini, standart hatasına göre büyük ise (ki bölüm bunu gösterir) bu
katsayının sıfır olmadığına dair güçlü bir işaret olarak alınabilir.
Peki ne kadar büyük bir sayı büyük sayılmalıdır? Bunun için p-değerine başvuruyoruz.
P-değerini hesaplamak için t değeri ve standart hatasının dağılımından bahset-
mek lazım.
t değeri bir rasgele değişken olduğu için bir dağılımı vardır, ve bu dağılım Öğrenci
t (Student t) dağılımıdır. Sebep şu, t değerinin kendisi de iki rasgele değişkeninin
bölümüdür, bu değişkenlerden biri katsayının kendisidir, ki bu değer nüfustaki
“gerçek” katsayı etrafında normal olarak dağılmış bir rasgele değişken olarak
kabul edilir. Diğeri ise, yani bölen, tahmin edici S’tır ki bir chi kare rasgele
değişkenin kareköküdür. Bu bölümün Öğrenci t dağılımına sahip olduğu daha
önce gösterildi.
Standart hata ise, artık / kalıntı değerlerle (residuals) alakalıdır (results.resid
içinde), ve bu değerler model uydurulduktan sonra o modeli kullanarak gerçek
veriye ne kadar uzak düştüğümüzü gösterir. Formül olarak her veri noktası i için
ri = yi − β1 xi − βo . Her katsayı için de ayrı ayrı kalıntı hesaplanabilir.
İdeal durumda, yani modelin doğru, veriye uyduğu durumda artıkların mükemmel
bir Normal dağılıma sahip olması gerekir, çünkü veri içindeki tüm örüntü, kalıp
model tarafından “bulunmuştur” ve geri kalanlar gürültüdür (gürültü tabii ki
Normal dağılımda). İdeal ortamda OLS algoritmasının, matematiksel olarak, or-
talaması (mean) sıfır olan artıklar üretmesi garantidir. Bir diğer varsayım uy-
duralan değişkenlerin katsayılarının onların “gerçek” değerleri etrafında merke-
zlenen bir Normal dağılıma sahip olduğudur (ispat için [10] yazısının sonuna
bakılabilir). Bu normallik önemli çünkü katsayı tahmini ile standart hatayı bölünce
başka bir Öğrenci t dağılımı ortaya çıkacak.
Kalıntıların normalliği QQ grafiği ile kontrol edilebilir, bkz [11],
3
import statsmodels.api as sm
sm.qqplot(results.resid)
plt.savefig('stat_linreg_01.png')
Z
t= p = tm
V/m
Ayrıca bu olasılık sonucu sıfır ile karşılaştırmak kolay olsun diye 1’den çıkartılır
4
ve 2 ile çarpılır, istatistiğin böylece iki taraflı (two-sided) olduğu belirtilir. m,
veri nokta sayısı, eksi katsayı sayısı, artı bir olarak hesaplanıyor. Eğer sonuç
0.05’ten küçük ise bu iyiye işarettir, 0.05’ten büyük olan değerler iyi değildir. Gal-
ton örneğinde β̂0 için,
0.0
Üstteki sonuç 0.0 değeri çok iyi. Demek ki bu katsayı önemli (significant).
2) Artıklarda sıfırdan sapma, herhangi bir yöne doğru yamukluk (skew) OLS
uyumsuzluğunun işareti olabilir, üstte artıklar üzerinde describe çağrısı ile me-
dyanı (%50 noktası) hesaplattık, bu değerin 0.04 ile sıfırdan çok az sağa doğru
saptığını görüyoruz. %25, %75 bölgelerinin işaretlerine bakmadan tam (absolute)
değerlerine bakalım, 1.36 ve 1.63, çok az farklılar. İdealde hiç fark olmamasını is-
teriz çünkü normal dağılım simetriktir, her iki tarafında da bu bölgelerin yakın
değerde olmasını bekleriz. Fakat bu değerler alarm yaratacak nitelikte değil.
Artıkların minimum, maksimum (min,max) değerleri verideki ekstrem, aykırı değerlere
(outlier) dair bir işaret olabilir.
3) R2 , ya da R-squared, modelin kalitesiyle alakalıdır, ne kadar büyükse o kadar
iyidir. Matematiksel olarak bu değer y’nin değişiminin / varyansının oran olarak
ne kadarının regresyon modeli tarafından “açıklanabildiğini” belirtir. Üstteki
örnekte R2 = 0.21 ise model varyansın yüzde 21’ini açıklıyor. Ya da “bir çocuğun
boyunun yüzde 21’i ebeveyn boyu ile açıklanabilir” sözü de söylenebilir. Geri
kalan 0.75’lik yani yüzde 75’lik “açıklanamayan” kısmın değişik sebepleri ola-
bilir; belki hesaba katmadığımız değişkenler vardır, ya da örnekleme prosedüründe
hatalar yapılmıştır, ya da lineerlik bu probleme uygun değildir, vs.
Tavsiyemiz düz R2 yerine OLS çıktısında görülen “düzeltilmiş R2 ” yani Adj. R-squared
bilgisinin kullanılmasıdır, çünkü bu bilgi modeldeki değişken sayısını da hesaba
katar ve daha iyi bir ölçüttür.
4) F istatistiği: Bu istatistik tüm modelin önemli mi önemsiz mi olduğunu ird-
eler. Eğer modelde sıfır olmayan en az bir katsayı var ise model önemlidir (her-
hangi bir i için βi 6= 0). Eğer tüm katsayılar sıfır ise model önemsizdir (β0 =
β1 , . . . , βn = 0). Örnekte
Prob (F-statistic) bir p-değeri, ve bu değer 0.05’ten küçük ise model büyük
bir ihtimalle önemlidir, eğer 0.05’ten büyük ise büyük ihtimalle önemli değildir.
Üstteki p-değeri 1.73e-49 gösteriyor, çok ufak bir değer, yani bu iyi.
Not: Çoğu kişi OLS çıktısında ilk önce R2 ’ye bakar, fakat bilgili istatistikçi F’e
bakar, çünkü bir model önemli değilse, geri kalan hiçbir ölçütün önemi yoktur.
5
Nihai analiz olarak bu veride parent katsayısının pozitif olan değerine bakarak
çocuk ve ebeveyn boyu arasında bir bağlantı olduğunu söyleyebiliriz.
Basamaklı Regresyon (Stepwise Regression)
Eğer elimizde çok fazla değişken var ise, bu değişkenlerden hangilerinin en iyi
olduğunu seçmek oldukça zor olabilir. Önemlilik sayıları burada biraz yardımcı
olabilir, fakat değişkenlerin eklenip, çıkartılması regresyonun tamamını etkilediği
için deneme / yanılma ile ekleme / çıkartma işleminin yapılması gerekebilir, ki
bu işlemi elle yapmak külfetli olur. Acaba bu yöntemi otomize edemez miyiz?
R dilindeki lm’in step adlı özelliği burada yardımcı olabilir. Önce yapay bir veri
üretelim,
import pandas as pd
n = 100
df = pd.DataFrame()
np.random.seed(10)
df['x1'] = np.random.normal(size=n)
df['x2'] = np.random.normal(size=n)
df['x3'] = np.random.normal(size=n)
df['x4'] = np.random.normal(size=n)
df['y'] = 10 + -100*df['x1'] + 75*df['x3'] + np.random.normal(size=n)
%load_ext rpy2.ipython
%R -i df
%R fullmodel <- lm(y˜x1+x2+x3+x4,data=df)
%R -o res res = summary(fullmodel)
print res
Call:
lm(formula = y ˜ x1 + x2 + x3 + x4, data = df)
Residuals:
Min 1Q Median 3Q Max
-3.15789 -0.63251 -0.01537 0.58051 2.30127
Coefficients:
Estimate Std. Error t value Pr(>|t|)
(Intercept) 9.94953 0.09378 106.098 <2e-16 ***
x1 -99.95333 0.09686 -1031.975 <2e-16 ***
x2 -0.04103 0.09500 -0.432 0.667
x3 75.14720 0.10240 733.851 <2e-16 ***
x4 0.04863 0.10015 0.486 0.628
---
6
Residual standard error: 0.9292 on 95 degrees of freedom
Multiple R-squared: 0.9999,Adjusted R-squared: 0.9999
F-statistic: 4.23e+05 on 4 and 95 DF, p-value: < 2.2e-16
Görüldüğü gibi daha baştan x2,x4 önemsiz bulundu. Ama daha karmaşık bir
modelde bu o kadar rahat bulunmayabilirdi. Şimdi step ile tam modelden bu
değişkenler çekip çıkartılabiliyor mu ona bakacağız.
R dilinde basamaklı regresyon iki şekilde işler. Ya tam modelden geriye gider-
siniz yani tam modelden ise yaramayan değişkenleri atarsınız, ya da en baz (boş)
modelden başlayıp ileri gidersiniz yani ekleye ekleye en iyi değişkenlere erişmeye
uğraşırsınız. İlk önce eliminasyonu görelim,
Call:
lm(formula = y ˜ x1 + x3, data = df)
Residuals:
Min 1Q Median 3Q Max
-3.1667 -0.6078 -0.0256 0.5732 2.3592
Coefficients:
Estimate Std. Error t value Pr(>|t|)
(Intercept) 9.95039 0.09251 107.6 <2e-16 ***
x1 -99.95181 0.09540 -1047.7 <2e-16 ***
x3 75.14514 0.10101 744.0 <2e-16 ***
---
Doğru sonuçlar bulundu. Bu yöntem fena değildir, ama bazen o kadar çok değişken
vardır ki tam modelle başlamak iyi bir fikir olmayabilir, o zaman boş başlayıp
ileri gitmek daha mantıklı olabilir. Boş modelde sadece y ˜ 1 olacak, biraz garip
gelebilir, çünkü hiç değişken yok (ki bu durumda uydurulan tüm değişkenler
sadece y’nin ortalamasıdır). Neyse, ileri giden modelde step’e hangi değişkenlerin
aday / potansiyel değişken olduğunu belirtmek gerekir, bunu scope ile yaparız,
Call:
lm(formula = y ˜ x1 + x3, data = df)
7
Residuals:
Min 1Q Median 3Q Max
-3.1667 -0.6078 -0.0256 0.5732 2.3592
Coefficients:
Estimate Std. Error t value Pr(>|t|)
(Intercept) 9.95039 0.09251 107.6 <2e-16 ***
x1 -99.95181 0.09540 -1047.7 <2e-16 ***
x3 75.14514 0.10101 744.0 <2e-16 ***
---
Yine aynı sonuca geldik. Tabii bu çok basit bir yapay veri, o yüzden aynı yere
gelmiş olmamız şaşırtıcı değil. Gerçek problemlerde geriye ve ileri giden mod-
ellerin ikisini de deneyip sonuçları karşılaştırmak iyi oluyor. Sonuçlar şaşırtıcı
olabilir.
Bir diğer tavsiye basamaklı regresyonu her derda deva bir yöntem olarak görmemek,
çünkü üstteki çıktılara göre sihirli bir şekilde en kullanışlı alt kümeyi buluveriyor,
vs, fakat bu metot, değişkenleri iyi tanıyan birisi tarafından dikkatli bir şekilde
alt kümenin elenip, seçilerek bulunması yerine geçemez. Bunu özellikle belirtiy-
oruz, çünkü bazılarının aklına şöyle bir şey gelebilir,
ri = yi − β0 + β1 xi
8
Veriyi ikiye katlayınca,
rP r P r
2 2
i (2ri ) 4 r
i i 4C
= =
2n 2n 2n
p
Eski veri seti için aynı hesap C/n. İki tarafta da karekök var, sadece karekök
içine bakalım,
C 4C
?
n 2n
Aradaki ilişki nedir? Eğer veriyi ikiye katlarsak C 4 katına çıkıyor, ama herhangi
bir n > 2 için, 2n bu büyümeyi geçer, ve sağdaki büyüklük soldakina nazaran
küçülür.
C 4C
> , n > 2 için
n 2n
Demek ki yeni veri setinde standard hata küçülür. Eğer bu değer küçülürse, kat-
sayılara ait olan standart hatalar da, ki onlar biraraya gelerek standart hatayı
oluşturacaklar, küçülecektir. Standart hatanın küçülmesi aslında şaşırtıcı olma-
malı, aynı yönde daha fazla veri alınca elimizdeki katsayılarından daha “emin”
hale geldik. Bu iyi bir şey olarak görülebilirdi belki, ama bu durumun mod-
elin geri kalanı üzerindeki etkilerini şimdi düşünelim. Eğer katsayı aynı kalır,
hata küçülürse katsayı / hata olarak hesaplanan t değeri buyur. Daha büyüyen
t değeri daha küçülen p-değeri demektir! Yani veriyi ikiye katlayınca birden
bire önemsiz olan (> 0.05) bir değişken, önemli hale gelebilir. Altta örneğini
görüyoruz,
9
==============================================================================
coef std err t P>|t| [95.0% Conf. Int.]
------------------------------------------------------------------------------
Intercept 9.9495 0.094 106.098 0.000 9.763 10.136
x1 -99.9533 0.097 -1031.975 0.000 -100.146 -99.761
x2 -0.0410 0.095 -0.432 0.667 -0.230 0.148
x3 75.1472 0.102 733.851 0.000 74.944 75.350
x4 0.0486 0.100 0.486 0.628 -0.150 0.247
==============================================================================
Omnibus: 3.126 Durbin-Watson: 2.267
Prob(Omnibus): 0.210 Jarque-Bera (JB): 2.795
Skew: -0.191 Prob(JB): 0.247
Kurtosis: 3.724 Cond. No. 1.26
==============================================================================
df2 = pd.concat((df,df))
results = smf.ols('y˜x1+x2+x3+x4', data=df2).fit()
print results.summary()
10
[5]’te bulunabilir), ya da daha öz, basit bir metot [3] mevcuttur. En basit ve etk-
ili yöntem Değişim Zamanı (Time for Change) modeli, bu modele göre başkanlık
yarışının olduğu Haziran ayı itibariyle ekonomik büyüme yüzdesi (gdp_growth),
mevcut başkanın net destek oranı (net_approval, ki bu rakam destek yüzdesinden
desteklemeyen yüzdesi çıkartılarak hesaplanır) ve o anki başkanının partisinin, 2
dönem ya da daha fazladır Beyaz Ev’de olup olmadığı bilgisi 1/0 değeri ile kod-
lanarak (two_terms) lineer regresyona verilir ve hedef değişken olarak, yönetimi
elinde tutan partinin ülke genelinde tüm oyların (popular vote) yüzde kaç alacağı
tahmin edilmeye uğraşılır.
Örnek olarak Clinton ve Bush I arasındaki 1992 yarısında Cumhuriyetçi adayın
(çünkü o zamanki başkan Cumhuriyetçi) yüzde kaç oy alacağı tahmin edilecek,
two_terms=1 çünkü iki dönem Cumhuriyetçi Reagan ardından bir dönem Cumhuriyetçi
Bush gelmiş, Cumhuriyetçiler uzun süredir baştalar.
Gore / Bush arasındaki 2000 yılı yarısında Demokratların yüzdesini tahmin et-
meye uğraşıyoruz, çünkü başta Demokrat Clinton var, ve iki dönemdir orada.
Net popülarite ve büyüme hep o anki başkan ve onun partisinin performansı ile
alakalı. Bu regresyonu işlettiğimizde, sonuçlar şöyle,
11
==============================================================================
Omnibus: 0.333 Durbin-Watson: 1.545
Prob(Omnibus): 0.847 Jarque-Bera (JB): 0.484
Skew: -0.169 Prob(JB): 0.785
Kurtosis: 2.246 Cond. No. 71.4
==============================================================================
İnanılmaz bir başarı, Prob (F-statistic) değeri neredeyse sıfır, Adj. R-squared
değeri yüzde 80’den daha fazla, tüm değişkenler istatistiki olarak önemli (P>|t|
değerleri 0.05’ten küçük).
Acaba bu modeli kullanarak geçmişteki yarışları “tahmin etsek” sonuç ne olurdu
diye merak ediyoruz, bunun için tahmin edeceğimiz senenin veri noktasını dışarıda
bırakarak (out-of-sample) regresyon işletip o seneyi bilmiyormuş gibi yapıp tah-
min ediyoruz,
def out_of_sample_pred(year):
df2 = df[df['year'] != year]
results2 = smf.ols(regr, data=df2).fit()
conf = results2.conf_int()
pred = np.array(df[df['year'] == year])[0][:-1]; pred[0] = 1.
return np.dot(pred, conf)
# o senenin verisinin disarida birakarak gecmisi tahmin et
print 'bush/clinton'; print out_of_sample_pred(1992)
print 'gore/bush'; print out_of_sample_pred(2000)
print 'bush/kerry'; print out_of_sample_pred(2004)
print 'mccain/obama'; print out_of_sample_pred(2008)
print 'obama/romney'; print out_of_sample_pred(2012)
bush/clinton
[ 43.68758927 52.47911415]
gore/bush
[ 48.31291287 60.68132985]
bush/kerry
[ 50.66667848 55.79188333]
mccain/obama
[ 41.05409775 46.15966954]
obama/romney
[ 49.81182614 54.45584122]
12
genelinde oyu tahmin etmeye uğraşıyor, ki ülke genelinde bakılınca Gore daha
fazla oy almıştı. Amerikan sistemine göre başkanlık seçimleri de eyalet bazında
hesaplanır, bir eyalette kazanan tüm oyları alır, bu sebeple ülke geneli ile eyalet
bazı arasında uyumsuzluk ortaya çıkabiliyor.
Gore / Bush olayına bir diğer bakış açısı şöyle: oy yüzdesi tahminini yüzdenin
kendisi için değil, kazanma / kazanmama için bir sinyal olarak kabul etmek,
yani popüler oyun kime gittiğine bakmamak, o zaman modelimizin Göre / Bush
seçimini başarısız tahmin ettiğini kabul etmek lazım. Bu şaşırtıcı değil aslında
çünkü 2000’de Bush kazandığına kendisi bile şaşırmıştı.
2016 senesindeki yarışta kim kazanacak? Demokratların şansı şöyle (dikkat belli
bir adaydan bahsetmiyoruz bile); Haziran 2016 itibariyle büyüme 2%, Obama’nın
net popülaritesi sıfır olduğu durumda (bu değişkenlerin ne olduğuna o tarihte
tekrar bakılmalı),
conf = results.conf_int()
pred = [1., 2.0, 0.0, 1]
print np.dot(pred, conf), np.dot(pred, results.params)
Yani Demokrat adayın kaybetme şansı daha fazla, her ne kadar kesin bir şey
söylenemezse de, güven aralığının iki ucu da yüzde 50 altında (ya da üstünde)
değil, Hillary Clinton’un işi zor olacaktı, ki kaybetti. Trump ülke genelinde oy
çoğunluğunu kaybetti, ama eyalet bazında kazandı. Demek ki model tahminini
kazanma sinyali olarak almak daha uygun.
Analiz
Model oldukça basit, 3 değişken ile tahmin yapılıyor, fakat bu basitlik aldatıcı ola-
bilir. Modele neyin dahil edildiği yanında neyin dahil edilmediği de önemlidir,
mesela.. ham petrol fiyatı, işsizlik, seçim yılındaki suç oranı, iklim vs kullanılmamış,
sadece bu 3 değişken kullanılmış. Ya da model, Cumhuriyetçiler için ayrı, Demokrat-
lar için ayrı bir tahmin üretmiyor, o an başta hangi parti varsa onun başarısını tah-
min etmeye uğraşıyor. Yani bir bakıma iddiası şu, insanlar aslında başta olan par-
tiye göre oy verirler, bir süre sonra (2 dönem ardından) onu değiştirmeye meyilli
olurlar, ve o anda başta olan başkanın popülaritesi ve genel bir ekonomik perfor-
mansını kullanarak onun partisi hakkında bir tamam / devam kararını verirler.
Bu tür modelcilik yetenek ister. Basitlik zor iş!
Tahmin edilirliğin yüksekliği ve değişkenlerin azlığı hakkında bir diğer yorum;
bu durum aslında o kadar da şaşırtıcı olmamalı belki de, çünkü başkanlık seçimi
son derece kaba hatlı bir karar, tek bir kişi / parti hakkında karar veriliyor, ve
doğal olarak seçim için kullanılan parametreler de oldukça genel. Bir bakıma,
bu tahmin edilirlik iyi olarak ta görülebilir, stabilite, sakin ortamın işareti olarak
algılanabilir. “Vay o taraf ne dedi, bu taraf ne dedi” gibi faktörlerle oylar haldır
huldur inip çıkmıyor, belli genel parametreler ışığında sonuç ta dört ay önceden
oldukça belli (baz veri Haziran sonu itibariyle alınır, seçim Kasım ayında).
13
Model Karşılaştırmak
Bu alanda, mesela gazetelerde, yorumlara rastlanıyor. Bunlardan biri “mevcut
başkanın (incumbent) ikinci dönem için yarışa girerse avantajlı olduğu” söylemidir,
ki üstteki modelin ilk halini keşfeden Abromitz de bunu söylemektedir. Bizim
referans aldığımız model [6] o söylemi biraz değiştirmiş, avantajlı olan yerindeki
başkan değil, dezavantajlı olan 2 dönemden fazla başta kalan parti. İnsanlar 2 veya
daha dönemden fazla başta olan partiyi görevden almaya meyilli oluyor. Tabii
eğer parti yeni başa gelmişse, o zaman dezavantaj olmadığı için bazı durumlarda
“ilk dönem başkan avantajlıymış gibi” durmuş olabilir. Şimdi bu faraziyeyi test
edelim, hangi model daha doğru? Yeni bir veri setinde bu değişikliği test edebil-
iriz,
14
[10] Bayramlı, Istatistik, Tahmin Aralıkları
[11] Bayramlı, Istatistik, Güven Aralıkları, Hipotez Testleri
[12] Bayramlı, Istatistik, Tahmin Aralıkları (Prediction Interval)
15
F(X) = U
Başlıktaki matematiğin alt dallarından Simulasyon’un en temel formüllerinden
biri. Basitliği derin bir sonucu gizliyor aslında; ve simulasyon dahil olmak üzere
en az iki istatistiksel yöntemi mümkün kılıyor. Formülü ve mümkün kıldığı iki
yöntemi bu yazıda göreceğiz.
Başlıkta söylemi tam notasyonla vermek gerekirse;
FX (X) ∼ U(0, 1)
Yani, dağılımı her ne olursa olsun, bu dağılımdan gelen bir rasgele değişkenin
değerlerini o dağılımın kümülatif dağılım fonksiyonuna (cdf) geçersek, elde edilen
değerler yeni bir rasgele değişken U(0, 1) olarak, yani birörnek (uniform) olarak
dağılacaktır! Müthiş bir sonuç. Bu metot simülasyonda Ters Transform Metotu
(Inverse Transform Method) olarak geçiyor.
Teori
Diyelim ki X cdf FX ’e sahip surekli rasgele degisken. O zaman FX (X) ∼ U(0, 1).
İspat
Y = FX (X) olsun, ve Y’nin cdf’i G(y). O zaman
Olasılık operatörü içinde iki tarafa FX ’in tersini uygulayalım, sol tarafta tersi ile
kendisi sonucu fonksiyon kaybolur, geri kalanlar,
= P(X 6 F−1
X (y))
Üstteki ifadeye geldik. Bu ifade de aslında bir cdf hesabı değil midir? Evet. X’in
cdf hesabıdır,
= FX (F−1
X (y)) = y
G(y) = y
Yani y’nin cdf değeri y’nin kendisidir, bu da sadece Y birörnek olarak dağılmışsa
mümkündür [1].
Herhangi Bir Dağılım İçin Rasgele Sayı Üretmek
Bu teorinin rasgele sayı üretmek için nasıl kullanıldığını görmek zor değil. Çünkü
eğer
1
FX (X) = U
ise
X = F−1
X (U)
Zi = (aZi−1 + c) mod m
Zi = (5Zi−1 + 3) mod 8
2
Görüldüğü gibi 8. adımda başa dönmüş olduk, çünkü Z8 = 0. Bu üreteç tam-
periyot üretecidir, yani mod 8 dedik ve tekrar edene kadar 8 tane sayı ürettik.
Genel olarak tam periyot iyi bir şeydir. Eğer
Zi = (5Zi−1 + 1) mod 7
Bu çok hızlı işleyen, tekrar edene kadar 2 milyar (dikkat: milyar) sayıdan daha
fazla sayı üretebilen bir üreteçtir. Kodu altta bulunabilir, 231 − 1 = 2147483647
olduğunu biliyoruz,
def do_unif(ix):
u = (16807*ix) % 2147483647
return u
u = do_unif(1e7)
print u
u = do_unif(u)
print u
u = do_unif(u)
print u
566275534.0
1892860081.0
476634709.0
def do_unif(ix):
k1 = int(ix/127773)
ix = 16807*(ix - k1*127773) - k1*2836
if ix < 0: ix = ix + 2147483647
u = ix*4.656612875e-10 # 1'den kucuk olmasi icin
return ix, u
ix, u = do_unif(1e7)
print u
3
ix, u = do_unif(ix)
print u
ix, u = do_unif(ix)
print u
0.263692594242
0.881431662376
0.22195033226
Eğer tek bir çağrı ile istediğimiz kadar birörnek sayı üretmek istiyorsak,
def unif(size,seed=1e7):
tmp = seed; res = []
for i in range(size):
tmp,u=do_unif(tmp)
res.append(u)
return np.array(res)
print unif(size=10)
x = unif(size=1000)
lam = 4.
y = -np.log(1-x) / lam # cdf tersi
f=plt.figure();
plt.hist(y)
plt.savefig('stat_fxu_02.png')
Üstel dağılıma benziyor! İşin iyi tarafı bu üretimi yapmak için tüm öğeleri evde
kendimiz pişirdik. Birörnek rasgele sayıları bile kendimiz üretiyoruz.
Uyum Derecesi ve Düzgünlük Testi (Goodness-of-Fit, Smooth Test)
4
FX (X) = U başka bir açıdan bir “numara” olarak ta kullanılabilir, çünkü teoriye
göre sadece ve sadece FX fonksiyonu hakikaten X’in cdf’i ise ispat geçerli. Bu
gerçeği bir istatistiki test için başlangıç noktası olarak kullanabiliriz; Diyelim ki
elimizde bir X var ve dağılımının ne olduğunu bilmiyoruz. Ama eğer doğru
dağılımı seçmişsek, mesela F0 , F0 (X) bize birörnek sonuç verir, değilse vermez.
O zaman bir tahmini cdf’i birörneklik testiyle birleştirirsek, verinin / rasgele
değişkenin dağılımın ne olduğunu test eden bir istatistiki test bulmuş oluruz [3,
sf. 325].
Birörneklik testi dedik, bunun için zaten bilinen chi kare, K-S uyum derece testi
gibi testleri mi kullansak acaba? Neyman adlı istatistikçi mevcut olanları kullan-
mak yerine özellikle birörnek dağılımına odaklı bir test yaratmaya karar verdi.
Neyman’ın düzgünlük testi (Neyman’s smooth test) birkaç baz fonksiyonunun
toplamından oluşan bir alternatifi (0,1) aralığına gömüyor (embed), ki sıfır hipotezinde
bu gömülü fonksiyon bize birörnek sonuçla aynı sonucu verir, ama birörneklikten
sapma varsa, baz fonksiyonları öyle oluşturulmuştur ki bu sapmanın etkisi düzgün,
sürekli bir şekilde birörneklikten ayrılır (ki testin ismi buradan geliyor). Ayrıca
baz fonksiyonları öyle seçilmiştir ki sıfır hipotezi altında test için bir chi kare
dağılımı elde ederiz, birörnek olmama durumunu bu chi kare dağılımda aykırı
bölgeye düşmek olarak irdeleyebiliriz, ve testimiz bunun üzerinden hesaplanır.
Bu özel fonksiyonlar nelerdir? Onları hj (y) olarak gösterelim, ki j = 1, .., d olsun,
yani d tane baz fonksiyonu var. Neyman’a göre d = 4 yeterlidir (baz fonksiy-
onuna göre değişir tabii, biz alttaki örnekte 5 kullandık). Bu fonksiyonlara bazı
şartlar getiriliyor, öncelikle hj ’ler sabit fonksiyona (yani 1’e) ve birbirlerine dik-
gen (orthogonal) olmalılar. Yani
Z1
hj (y) dy = 0
0
Z1
hk (y)hj (y) dy = 0
0
Z1
hj (y)2 dy = 1 (1)
0
Bu şartları tatmin eden hangi fonksiyonlar vardır? Aklımıza gelen her fonksiyon
tipi üstteki şartlara uymayabilir. Neyman Legendre polinomları denen polinom-
ları kullandı, fakat aslında üstteki şartları yerine getiren
hj (y) = cj cos(2πjy)
5
bir dağılım haline getirmez, “büyüklük hesabı için” onu normalize eder. Sebebini
birazdan göreceğiz.
Not: Üstteki fonksiyon eğer Fourier serilerini hatırlattıysa bu doğru bir gözlemdir,
böyle bir bağlantı var.. Birbirine dikgen fonksiyonlar özel fonksiyonlar tabii,
Fourier serilerinde bu sebeple kullanılıyorlar, ve dikgenlik lineer cebirde de çok
ortaya çıkar. Kontrol edilmek istenirse 1, cos(2πy), cos(4πy), cos(6πy), .. fonksiy-
onlarının birbirine dikgen olduğu entegral hesabını yapılarak görülebilir.
Devam edelim, (1)’i tatmin etmek için gereken cj ’i hesaplayalım,
Z1
c2j cos(2πy)2 dy = 1
0
Z1
cos(2πy)2 dy = 1/c2j
0
1 + cos 2θ
cos(θ)2 =
2
O zaman,
1 1
cos(2πy)2 = + cos(4πy)
2 2
Z1
1 1
+ cos(4πy) dy
0 2 2
1
y 1 1
= + sin(4πy) ⇒ = 1/c2j
2 8π 0 2
√
cj = 2
1X
n
hj = hj (yi )
n i=1
6
√
Sıfır hipotezi altında ve Büyük Sayılar Kanununa göre hj → 0. n·hj ise Merkezi
Limit Teorisi’ne göre Gaussian’dır, ve bu Gaussian’ın varyansı 1 olacaktır. Demek
ki
X
d
2
2
Ψ =n hj
j=1
hesabı sıfır hipotezi altında χ2d dağılımına sahiptir. hj ’lerin birbirine dikgen seçilmesinin
sebebi şimdi biraz daha açıklık kazanıyor herhalde, dikgen fonksiyonlar ile arasında
hiç korelasyon olmayan standart normaller üretiyoruz, ve bu normallerin toplamının
bize chi kare vermesini bekliyoruz (chi kare için korelasyonsuz standard normal-
lerin toplamı gerekir).
hj → 0 ispatı için sıfır hipotezinde yi ’lerin, ya da ui diyelim, birörnek dağılım
U(0, 1)’dan geldiğini hatırlayalım, yani o zaman hj (U) bir rasgele değişkendir, ve
hj ’nin nüfus beklentisine yaklaşır. Peki hj ’in nüfus beklentisi nedir? Bunun için
Z∞
E(hj ) = fU (u)hj (u) du
−∞
Z1 Z1 1
sin 2jπu
= hj (u) du = cos 2πju du = =0
0 0 2jπu 0
üstte E(hj ) = 0 olduğunu bulduk, bu terim üstteki formülde iptal oldu. Ve (1)’ın
de yardımıyla,
Z1
= h2j (u) du = 1
0
7
3) En son Ψ2 , sonucu χ2d üzerinde kontrol et.
Örnek
Bir standart normal, bir 4 derece serbestliğe sahip bir Öğrenci t dağılımı, bir de
üstel (exponential) dağılımdan üretilmiş veriyi standart normal olup olmadığına
bakmak için test ettik.
test(xstudent)
test(xnorm)
test(xexp)
Görüldüğü gibi Öğrenci t reddedildi, normal kabul edildi, üstel çok ciddi şekilde
reddedildi. Öğrenci t dağılımı normal dağılıma çok benzer bu arada, buna rağmen
arada büyük fark dikkate değer.
Kaynaklar
[1] Goldsman, D., ISyE 6644 - Simulation Lecture, http://www2.isye.gatech.
edu/˜sman/courses/6644/
[2] Ross, Introduction to Probability Models, 10th Edition
[3] Shalizi, Advanced Data Analysis from an Elementary Point of View
[4] Thomas, Thomas’ Calculus, 11th Ed
[5] Schrage, A Guide to Simulation
8
Üstel Kanunlar (Power Laws)
Bir web sitesini bir ayda ziyaret etmiş olan özgün kullanıcı sayısı üzerinden bir
alarm programı yazmak gerekti diyelim. Eğer çok fazla kullanıcı var ise bir ad-
min’e bir email gönderilecek.. Akla gelen çözümlerden aylık kullanıcı sayılarının
ortalamasını alıp 2 ya da 3 standart sapma kadar olan cevapları aykırı değer (out-
lier) olarak kabul etmek ve bu durumlarda alarm çalmak [1, sf. 255]. Çünkü, eh,
veri noktalarının yüzde 99.7’si 3 standart sapma içine düşer değil mi?
Burada gözardı edilen nokta şudur: verinin yüzde 99.7’si 3 standart sapma içine
düşer eğer veri Gaussian olarak dağılmış ise. Ayrıca ortalama hesabı da problemli,
burada ilk akla gelebilecek Merkezi Limit Teorisi üzerinden örneklem ortala-
ması gerçek ortalamaya yaklaşacağı, ki bu çoğu dağılım için doğrudur, fakat bazı
dağılımlar üzerinde Merkezi Limit Teorisi işlemez! Güç Kanunları ile istatistik
biliminin sınırlarına geliyoruz - gerçek dünyadan önümüze atılan veriler artık
sıkça bir şekilde normal dışı verileri içerebiliyor, ve bu durumlara hazır olmamız
lazım.
Üstte bahsettiğimiz senaryo için aslında elimizde veri var (pek çok ay için). Verinin
histogramına bakalım,
import pandas as pd
dfvis=pd.read_csv('visits.csv',header=None,sep='\t',index_col=0)
visits = np.array(dfvis[1])
dfvis.hist(bins=80)
plt.ylim([0,50])
plt.savefig('stat_powerlaw_05.png')
Görüldüğü gibi bazı değerlerden aşırı çok var, bazılarından neredeyse yok. Aşırı
değerler her iki uçta da gözüküyor, büyük olanlardan daha az var, evet, ama
oradaki yoğunluk dikkate alınmaz seviyede de değil. Bu arada eğer y eksenini
ufaltmasaydık aşırı değerler haricinde kalan değerler üstteki kadar bile gözükmeyecekti.
Olasılık yoğunluk fonksiyonu (probability density function),
1
p(x) = Cx−α
∞
C −α+2
= x
2−α xmin
ln p(x) = −α ln x + c (1)
Üstteki yaklaşımla grafiği nasıl oluşturuz? Bunun için hist çağrısından histogram
grafiğini değil, histogramdaki kutucukların üç noktalarını düz veri olarak al-
mamız lazım, ki bu değerler x değerlerimizi oluşturacak, sonra onların normalize
edilmiş değerlerini almamız gerekiyor [4], bu değerler de ln p(x) olacak. Grafik-
lemeden önce elle log almamıza gerek yok, grafik rutinine skalayı log bazında
ayarlamasını söylememiz yeterli, xscale,yscale çağrıları ile bunu yapabiliriz.
def plot_power(data):
hst = plt.hist(data, normed=True,bins=1000)
f=plt.figure() # histogram halinden cik
x = hst[1][:-1]; y = hst[0]
plt.plot(x, y,'o')
plt.xscale('log')
plt.yscale('log')
plot_power(visits)
plt.title('Ziyaretler')
plt.ylim(1e-5,1e-3)
plt.savefig('stat_powerlaw_04.png')
2
Düz çizgiye benzer bir şekil ortaya çıktı, negatif eğimli, demek ki bir üstel kanun
mümkün.
Üstel kanunu yoğunluk formülüne nasıl erişiriz? Başlangıç önceden gösterdiğimiz
formül olmak üzere,
ln p(x) = −α ln x + c
ln p(x) = −α ln x + ln C
= ln Cx−α
p(x) = Cx−α
∞
C −α+1
x =1
(−α + 1) xmin
3
∞
C −α+1
x =1
(1 − α) xmin
C
x−α+1 =1
(−α + 1) min
C = (α − 1)xα−1
min
C ile beraber ve bazı düzeltmeler ardından p(x) bazen şöyle gösteriliyor [5],
−α
α−1 x
p(x) =
xmin xmin
alpha 0.540551473071
kesi 0.00241514844497
Bu basit yöntemin, ne yazık ki, çok ciddi problemleri var. Bu metotun niye kul-
lanılmaması gerektiği [3, sf. 31]’de bulunabilir.
Alternatif yöntem şöyle; önce α için hızlı çalışan bir tahmin edici mevcut, bunu
görelim; Maksimum olurluk üzerinden,
Yn
α−1
xi
−α
p(x; α) =
i=1
xmin xmin
4
Yn
α−1
xi
−α
ln p(x; α) = ln
i=1
xmin xmin
X
n
α−1
xi
−α
= ln
i=1
xmin xmin
X
n
xi
= ln(α − 1) + ln xmin − α ln
i=1
xmin
X
n
xi
= n ln(α − 1) + n ln xmin − α ln
i=1
xmin
Maksimum değer için α’ya göre türevi alıp sıfıra eşitleriz ve çözeriz, ln(α − 1)’in
türevini hatırlayalım bu arada,
import sympy
alpha = sympy.symbols('alpha')
print sympy.diff(sympy.log(alpha-1))
1/(alpha - 1)
n X n
xi
= − ln =0
(α − 1) i=1 xmin
n X n
xi
= ln
(α − 1) i=1
xmin
X
n −1
(α − 1) xi
= ln
n i=1
xmin
Xn −1
xi
α̂ = 1 + n ln
i=1
xmin
Fakat tahmin edicinin hesabı için xmin ’i bilmek gerekiyor. Bir tavuk-yumurta
problemi var, α̂ için xmin gerekli, ama xmin ’in kendisi de bilinmiyor.
O zaman üstteki tahmin ediciyi şöyle kullanırız; verideki her noktayı potan-
siyel bir xmin ’mis gibi alırız (ve bu nokta altındaki hiçbir noktayı dikkate al-
mayız, bu alt sınırı bunun için seçtik), ve bu nokta için yukarıdaki formül ile
α̂’yi hesaplarız, sonra elde ettiğimiz xmin , α̂ ikilisini kullanarak (artık özgün bir
üstel kanun dağılımımız var), bu dağılım ile veri arasındaki uyum derecesini
Kolmogorov-Şmirnov testi ile hesaplarız. Elimizdeki n veri noktası için n tane
hesap elde ederiz, ve raporlanan mesafeler arasından en ufak olanını seçeriz, ve
5
bu mesafeye tekabül eden xmin , α̂ ikilisini optimal parametreler olarak seçeriz.
Altta örneği gösterilen powerlaw adlı paket [6] tam da bunu yapıyor. Ziyaret verisi
üzerinde işletelim,
import powerlaw
fitvis = powerlaw.Fit(visits, discrete=False)
print 'xmin', fitvis.xmin, 'alpha', fitvis.alpha
print fitvis.exponential.KS()
print fitvis.power_law.KS()
0.487151691713
0.0312634791749
Üstel kanun görüldüğü gibi daha olası (p-değer 0.05 altında). Bir olasılık hesabını
da elle yapalım,
x0 = 1e2
p = x0**-fitvis.alpha
C = (fitvis.alpha-1) * fitvis.xmin**(fitvis.alpha-1)
print p*C
0.00308315744794
Bazı farklı veriler üzerinde aynı hesapları görelim. Mesela 2003 senesindeki en
zengin 300 Amerikalının net varlıklarının dağılımı.
import powerlaw
dfwl=pd.read_csv('wealth.dat',header=None)
wealth=np.array(dfwl)[:,0]
fitwl = powerlaw.Fit(wealth, discrete=True)
print 'xmin', fitwl.xmin, 'alpha', fitwl.alpha
print 'K-S testi', fitwl.power_law.KS()
plot_power(wealth)
plt.savefig('stat_powerlaw_03.png')
plt.hold(False)
6
Dikkat, çoğunlukla bu konularda araştırma yapanlar zengin, fakir herkesi kap-
sayan bir ölçüm üzerinden (bu konulara ilk bakan Pareto öyle yapmıştı) tüm
kazancın üstel kanunu takip ettiğini söylerler, ki bu doğrudur. Üstteki sonuç,
bunun üstüne, en zengin 400 kişinin kendi arasında bile üstel kanunun işlediğini
söylemektedir. Yani zenginlik öyle dengesiz dağılan bir şeydir ki, en zengin 400
içinde çoğunluk en tepedekilere göre daha fakirdir!
Devam edelim: Herman Melville adlı yazarın ünlü Moby Dick romanındaki özgün
kelimelerin kullanılma frekansının dağılımı,
import powerlaw
dfwords=pd.read_csv('words.txt',header=None)
words=np.array(dfwords)[:,0]
fitw = powerlaw.Fit(words, discrete=True)
plot_power(words)
plt.ylim(1e-6,1e-3)
plt.savefig('stat_powerlaw_02.png')
7
f = plt.figure()
fitw.power_law.plot_pdf(linestyle='--', color='g')
plt.hold(True)
fitw.exponential.plot_pdf(linestyle='--', color='r')
plt.hold(True)
fitw.plot_pdf(color='b', linewidth=2)
plt.xlim(1e2,1e4)
plt.ylim(1e-8,1e-4)
plt.savefig('stat_powerlaw_01.png')
plt.hold(False)
Kaynaklar
[1] Janert, Data Analysis with Open Source Tools
[2] Shalizi, Advanced Data Analysis from an Elementary Point of View
[3] Causet, Power-Law Distributions in Empirical Data
[4] Bayramlı, Histogram Numaralari, https://burakbayramli.github.io/
dersblog/sk/2015/10/histogram-numaralari.html
[5] Newman, Power laws, Pareto distributions and Zipf’s law
[6] Alstott, powerlaw: A Python Package for Analysis of Heavy-Tailed Distributions
8
Tahmin Aralıkları (Prediction Interval)
Lineer Regresyon yazısında regresyon katsayıları β’yi veriden hesaplamayı öğrendik.
Bu bir anlamda alttaki denklemde verili y, A ile geri kalanları tahmin etmektir.
y = Aβ +
ki
∼ Normal(0, σ2 I)
Yani katsayıların A ile çarpımları artı gürültü (σ ile parametrize edilmiş bir Gaus-
sian üzerinden) bu sonucu verecektir. Tahmin edici,
β̂ = (AT A)−1 AT y
olarak bilinir. Bu formülü pek çok yazıda gördük, mesela [3]. O zaman
Fakat E() = 0 olduğu için üstteki hemen E(β̂) = β haline geliyor. Vektör rasgele
değişkenler üzerinde varyans, ya da kovaryans hesabını daha önce görmüştük,
bu hesabı β̂ üzerinde uygularsak,
β̂ − β = β + (AT A)−1 AT − β
1
= (AT A)−1 AT
ŷa = aT β̂
X
Var(X1 + .. + Xn ) = Var(X1 ) + .. + Var(Xn ) + 2 Cov(Xi , Xj )
i<j
2
Bizim elimizde ai β̂i ’lar var tabii, o zaman
X
Var(aT β̂) = Var(a1 β̂1 ) + .. + Var(an β̂n ) + 2 Cov(ai β̂i , aj β̂j )
i<j
X
= a21 Var(β̂1 ) + .. + a2n Var(β̂n ) + 2 Cov(ai β̂i , aj β̂j )
i<j
X
= a21 c11 σ2 + .. + a2n cnn σ2 + 2 Cov(ai β̂i , aj β̂j )
i<j
X
= a21 c11 σ2 + .. + a2n cnn σ2 + 2 ai aj cij σ2
i<j
X
= a21 c11 + .. + a2n cnn + 2 ai aj cij σ2
i<j
Üstteki ifadeyi rahat bir şekilde aT (AT A)−1 a σ2 olarak yazabiliriz.
Şimdi güven aralığı yaratmanın zamanı geldi. Hatırlayalım ki β̂1 , β̂2 , , . tahmin
edicilerinin kendileri birer rasgele değişkendir, ve bu değişkenler Normal dağılıma
sahiptirler. O zaman aT β̂ da normal olarak dağılmıştır ve bu dağılımın beklen-
tisinin E(aT β̂) = aT β olduğunu biliyoruz (dikkat eşitliğin sağında şapkasız β
var). O zaman “gerçek” β için bir güvenlik aralığı oluşturmak için aT β̂ − aT β’nin
da Normal olarak dağılmasının zorunlu olduğundan hareketle,
aT β̂ − aT β aT β̂ − aT β
Z= q = p
Var(aT β̂) σ aT (AT A)−1 a
Böylece bir standart normal yarattık, ve bu formülü daha önce güvenlik aralığı
için yaptığımız gibi düzenlersek,
3
p
aT β̂ ± zα/2 σ aT (AT A)−1 a
aT β̂ − aT β
T= p
S aT (AT A)−1 a
ki bu güven aralığı
p
aT β̂ ± tα/2 S aT (AT A)−1 a
import pandas as pd
import numpy as np
df = pd.read_csv('11.1.csv',sep=' ')
print df.head()
import statsmodels.formula.api as smf
results = smf.ols('y ˜ x', data=df).fit()
mse = np.sum(results.resid**2) / (len(df)-2)
s = np.sqrt(mse)
print 'mse', mse, 's', s
print results.summary()
x y
0 -2 0
1 -1 0
2 0 1
3 1 1
4 2 3
mse 0.366666666667 s 0.605530070819
OLS Regression Results
==============================================================================
Dep. Variable: y R-squared: 0.817
Model: OLS Adj. R-squared: 0.756
Method: Least Squares F-statistic: 13.36
Date: Mon, 11 May 2015 Prob (F-statistic): 0.0354
Time: 17:26:07 Log-Likelihood: -3.3094
No. Observations: 5 AIC: 10.62
Df Residuals: 3 BIC: 9.838
Df Model: 1
Covariance Type: nonrobust
==============================================================================
coef std err t P>|t| [95.0% Conf. Int.]
------------------------------------------------------------------------------
4
Intercept 1.0000 0.271 3.693 0.034 0.138 1.862
x 0.7000 0.191 3.656 0.035 0.091 1.309
==============================================================================
Omnibus: nan Durbin-Watson: 2.509
Prob(Omnibus): nan Jarque-Bera (JB): 0.396
Skew: -0.174 Prob(JB): 0.821
Kurtosis: 1.667 Cond. No. 1.41
==============================================================================
[[ 0.2 0. ]
[ 0. 0.1]]
pm = np.dot(np.dot(a.T, ATA_inv),a)[0][0]
pred = np.dot(a.T,beta_hat)[0]
print pm, pred
0.3 1.7
tval 2.3533634348
0.427509698202
Yuzde 90 guven araligi [ 0.91947765 2.48052235]
5
import numpy.linalg as lin
from scipy.stats.distributions import t
t975_val1 = t.ppf(0.975,len(df1)-2)
beta_hat1 = np.array(results1.params)
ATA_inv1 = lin.inv(np.dot(A1.T,A1))
a1 = np.array([[1., 2.0, 0., 1]]).T
pm1 = np.dot(np.dot(a1.T, ATA_inv1),a1)[0][0]
pred1 = np.dot(a1.T,beta_hat1)[0]
mse1 = np.sum(results1.resid**2) / (len(df1)-2)
s1 = np.sqrt(mse1)
print 'Yuzde 95 Guven Araligi', \
(pred1 - np.array([1,-1])*t975_val1*s1*np.sqrt(pm1))
Yuzde 95 Guven Araligi [ 46.95198025 49.64353527]
Yani Demokratların kazanma şansı neredeyse hiç yok gibi. Önceki başkanlık
yarışı tahmini katsayıların güven aralıklarını kullanmıştı; şimdi nihai tahminin
güven aralığına baktık. Aradaki fark şudur - katsayıların güven aralıklarını kul-
landığımızda onları en kötüleri birarada ve en iyileri birada olacak şekilde yanyana
kullanmış olduk; bu tür bir kullanım bu katsayıların arasındaki korelasyonu dikkate
almaz, çünkü, belki bir katsayı X’in en kötümser olduğu noktada katsayı Y daha
iyimser bir tahminde bulunacaktır, çünkü aradaki bağlantı böyledir...? Bu du-
rumlar ilk kullanımda yakalanamazdı. Bu sebeple ilk yöntemle hesaplanan güven
aralığı ikincisine nazaran daha geniş olacaktı, ki bunun olduğunu gördük.
σ, σ̂, S İlişkileri
Öncelikle mümkün bazı notasyonel karışıklığı düzeltmeye uğraşalım; kitaplarda
σ, σ̂ kullanımı tek boyutlu verinin nüfus standart hatası ve onun tahmin edicisi
(estimatör) için de kullanılıyor. Bu yazıda bu farklı, bu yazıdaki σ bir lineer mod-
elin hatasını temsil eden σ.
Bu tür bir σ’nin tahmin edicisi σ̂ şu şekilde tanımlı,
1X
n
2
σ̂ = (Yi − Ŷi )2
n i=1
6
boyutlu değişkenler / matris / vektör ve ∼ N(0, σI) yani cok boyutlu bir Gaus-
sian. Soru su: Acaba β’nın tahmin edicisi β̂’nin dağılımı nedir?
Tahmin edici hesabi
β̂ = (XT X)−1 XT Y
T
=
(XX)−1XT Xβ + (XT X)−1 XT
= β + (XT X)−1 XT
Bir yan not, biliyoruz ki çok boyutlu Gaussian mesela G ∼ N(φ, ρ)’a BG + A
şekilde ilgin (affine) transform uygulayınca sonuç N(φ+A, BρBT ) oluyor. Burada
bir çok boyutlu Gaussian. O zaman üstteki transformu hesaplayabiliriz. β
toplamı basit, esas iki taraftan (XT X)−1 XT ve onun devriği ile çarpılan standart
sapmaya ne olacak ona bakalım,
= σ(XT X)−1
Sonra β toplamını hatırlarız, yani β̂ ∼ N(β, σ(XT X)−1 ) olarak dağılmıştır, demek
ki katsayılarımızın regresyon tahmini “gerçek” katsayılar etrafında merkezlenen
bir Gaussian’dır.
Kaynaklar
[1] Wackerly, Mathematical Statistics, 7th Edition
[2] Larsen, Introduction to Mathematical Statistics and Its Applications, 5th Edition
[3] Bayramli, Lineer Cebir, Ders 15,16
[4] Bayramli, Istatistik, Beklenti, Kovaryans ve Korelasyon
[5] Bayramli, Istatistik, Lineer Regresyon
7
Lojistik Regresyon (Logistic Regression)
Lojistik regresyon normal regresyonun θT x olarak kullandığı ağırlıklar (katsayılar)
ile verinin çarpımını alır ve ek bir filtre fonksiyonundan geçirerek onları 0/1
değerleri bağlamında bir olasılığa eşler. Yani elimizdeki veri çok boyutta veri
noktaları ve o noktaların 0 ya da 1 olarak bir ”etiketi” olacaktır. Mesela
x y labels
0 -0.017612 14.053064 0
1 -1.395634 4.662541 1
2 -0.752157 6.538620 0
3 -1.322371 7.152853 0
4 0.423363 11.054677 0
5 0.406704 7.067335 1
6 0.667394 12.741452 0
7 -2.460150 6.866805 1
8 0.569411 9.548755 0
9 -0.026632 10.427743 0
Görüldüğü gibi veride x, y boyutları için etiketler (labels) verilmiş. Lojistik re-
gresyon bu veriyi kullanarak eğitim sonrası θ’ları elde eder, bunlar katsayılarımızdır,
artık bu katsayıları hiç görmediğimiz yeni bir veri üzerinde 0/1 etiketlerinin tah-
minini yapmak için kullanabiliriz.
Filtre fonksiyonu için kullanılan bir fonksiyon sigmoid fonksiyonudur, g(x) is-
mini verelim,
ex
g(x) =
1 + ex
Bu nasıl bir fonksiyondur, kabaca davranışını nasıl tarif ederiz? Cebirsel olarak
bakarsak, fonksiyon öyle bir durumda ki ne zaman bir x değeri geçersek, bu
değer ne kadar büyük olursa olsun, bölendeki değer her zaman bölünenden 1
daha fazla olacaktır bu da fonksiyonun sonucunun 1’den her zaman küçük ol-
masını garantiler. Çok küçük x değerleri için bölüm sonucu biraz daha büyük
olacaktır tabii, vs.
Daha temiz bir ifade için bölen ve bölüneni e−x ile çarpalım,
ex e−x
g(x) =
e−x + ex e−x
1
g(x) =
1 + e−x
1
Sigmoid fonksiyonun ”-sonsuzluk ile +sonsuzluk arasındaki değerleri 0 ve 1 arasına
eşlediği / indirgediği (map)” ifadesi de litaratürde mevcuttur.
def sigmoid(arr):
return 1.0/(1+exp(-arr))
import sympy
x = sympy.Symbol('x')
print sympy.integrate('1/(1+exp(-x))')
x + log(1 + exp(-x))
x + ln(1 + e−x )
x ifadesi aynı zamanda suna eşittir x = ln(ex ). Bu ifade bize kolaylık sağlayacak
böylece,
ln ex + ln(1 + e−x )
2
diyebiliriz. Doğal log’un (ln) çarpımları toplamlara dönüştürdüğünü biliyoruz,
bunu tersinden uygulayalım,
ln(ex · 1 + ex e−x )
ln(ex + 1) = ln(1 + ex )
0.0
inf
Demek ki fonksiyon bir olasılık dağılımı olamaz, çünkü eğri altındaki alan son-
suz büyüklüğünde. Aslında bu fonksiyonun kümülatif dağılım fonksiyonu (cu-
mulative distribution function -CDF-) özellikleri vardır, yani kendisi değil ama
türevi bir olasılık fonksiyonu olarak kullanılabilir (bu konumuz dışında). Her
neyse, sigmoid’in bir CDF gibi hareket ettiğini g’nin 0 ile 1 arasında olmasından
da anlıyoruz, sonuçta CDF alan demektir (yoğunluğun entegrali) ve en üst değeri
1 demektir, ki bu CDF tanımına uygundur.
Şimdi elimizde olabilecek k tane değişken ve bu değişkenlerin bilinmeyen kat-
sayıları için 0 ve 1’e eşlenecek bir regresyon oluşturalım. Diyelim ki katsayılar
θ0 , .., θk . Bu katsayıları değişkenler ile çarpıp toplayarak h(x)’e verelim, (0/1)
çıkıp çıkmayacağı katsayılara bağlı olacak, verideki etiketler ile h(x) sonucu arasında
bir bağlantı kurabilirsek, bu bize katsayıları verebilir. Bu modele göre eğer θ’yi
ne kadar iyi seçersek, eldeki veri etiketlerine o kadar yaklaşmış olacağız. Şimdi
sigmoid’i katsayılarla beraber yazalım,
1
hθ (x) = g(θT x) =
1 + e−θT x
”Veriye olabildiğince yaklaşmak için en iyi α’yi bulmak” sözü bize maksimum
olurluk (maximum likelihood) hesabını hatırlatmalı. Bu hesaba göre içinde bilin-
meyen α’yi barındıran formülün üzerinden tüm verinin sonuçlarının teker teker
birbiri ile çarpımı olabildiğince büyük olmalıdır. Bu ifadeyi maksimize edecek α
veriye en uygun α olacaktır.
Şimdi her iki etiket için ve sigmoid’i kullanarak olasılık hesaplarını yapalım,
3
Not: Olasılık değerleri (büyük P(·) ile) ve CDF fonksiyonları olurluk hesabında
kullanılabilir. P(·) ile CDF bağlantısı var, P(X < x) gibi kümülatif alansal hesapların
CDF üzerinden gerçekleştirilebildiğini hatırlayalım.
Devam edelim, hepsi bir arada olacak şekilde yanyana koyarsak ve sonuca, y’yi
doğru tahmin edip etmediğimizin ölçümünü de eklersek,
Olurluk için tüm veri noktalarını teker teker bu fonksiyona geçip sonuçlarını
çarpacağız (ve verilerin birinden bağımsız olarak üretildiğini farzediyoruz), eğer
m tane veri noktası var ise
Y
m
i i
L(θ) = (hθ (xi ))y (1 − hθ (xi ))1−y
i=1
X
m
= yi log((hθ (xi ))) + (1 − yi ) log((1 − hθ (xi )))
i=1
1 − g(z) = g(−z)
İspat
1 1 + e−z − 1
1− =
1 + e−z 1 + e−z
e−z 1
−z
=
1+e 1 + ez
Hakikaten son eşitliğin sağ tarafına bakarsak, g(−z)’yi elde ettiğimizi görüyoruz.
Şimdi türeve gelelim,
d 1
g 0 (z) =
dz 1 + e−z
4
Ispat
1
= −z 2
(e−z )
(1 + e )
e−z türevinden bir eksi işareti geleceğini beklemiş olabiliriz, fakat hatırlanacağı
üzere
d 1 −1
=
dx 1 + x (1 + x)2
Yani eksiler birbirini yoketti. Şimdi iki üstteki denklemin sağ tarafını açalım
1 e−z
=
1 + e−z 1 + e−z
1 1
=
1 + e 1 + ez
−z
Çarpımda iki bölüm var, bölümler g(z) ve g(−z) olarak temsil edilebilir, ya da
g(z) ve 1 − g(z),
= g(z)(1 − g(z))
Bu bağlamda ilginç bir diğer denklem log şansı (log odds) denklemidir. Eğer ilk
baştaki denklemi düşünürsek,
ez
p = P(y = 1|x; θ) = g(z) =
1 + ez
Bu denklem 1 olma olasılığını hesaplıyor. Temiz bir denklem log şansı olabilir ki
bu denklem olma olasılığını olmama olasılığına böler ve log alır.
p
log
1−p
ez
log (1 + ez ) = log(ez ) = z = θT x
1 + ez
5
noktadaki θ’yi bulmak istiyorsak (dikkat sadece olurluğun en maksimal nok-
tasını aramıyoruz, o noktadaki θ’yi arıyoruz), o zaman bir θ ile başlarız, ve adım
adım θ’yi maksimal olana doğru yaklaştırırız. Formül
Üstteki formül niye işler? Çünkü gradyan ∇θ l(θ), yani l(θ)’nin gradyanı her
zaman fonksiyon artışının en fazla olduğu yönü gösterir. Demek ki o yöne adım
atmak, yani l(θ)’a verilen θ’yi o yönde değiştirmek (değişim tabii ki θ bazında,
θ’nin değişimi), bizi fonksiyonun bir sonraki noktasına yaklaştıracaktır. Sabit
α bir tek sayı sadece, atılan adımın (hangi yönde olursa olsun) ölçeğini azaltıp
/ arttırabilmek için dışarıdan eklenir. Adım yönü vektör, bu sabit bir tek sayı.
Çarpımları vektörü azaltır ya da çoğaltır.
Not: Bu şekilde azar azar sonuca yaklaşmaya uğraşmak tabii ki her fonksiyon için
geçerli değildir, çünkü eğer fonksiyonda ”yerel maksimumlar” var ise, gradyan
çıkışı bu noktalarda takılıp kalabilir (o yerel tepelerde de birinci türev sıfırlanır,
gradyanın kafası karışır). Gradyan metotunun kullanmadan önce fonksiyonu-
muzun tek (global) bir maksimumu olup olmadığını düşünmemiz gerekir. Fakat
şanlıyız ki olurluk fonksiyonu tam da böyle bir fonksiyondur (şans değil tabii, bu
özelliği sebebiyle seçildi). Fonksiyon içbükeydir (concave), yani tek bir tepe nok-
tası vardır. Bir soru daha: olurluğun içbükey olduğunu nasıl anladık? Fonksiy-
ona bakarak pat diye bunu söylemek mümkün, değişkenlerde polinom bağlamında
küpsel ve daha üstü seviyesinde üstellik yok, ayrıca log, exp içbükeyliği boz-
muyor.
Simdi ∇θ l(θ) turetmemiz gerekiyor.
∂ ∂
∂l(θ) ∂θj
g(θT x) ∂θj
g(θT x)
=y − (1 − y)
∂θj g(θT x) 1 − g(θT x)
1 1 ∂
= y − (1 − y) g(θT x)
g(θT x) 1 − g(θT x) ∂θj
∂ ∂ T
g(θT x) = g 0 (θT x) θ x = g 0 (θT x)xj
∂θj ∂θj
∂
∂θj
θT x nasıl xj haline geldi? Çünkü tüm θ vektörünün kısmi türevini alıyoruz
fakat o kısmi türev sadece tek bir θj için, o zaman vektördeki diğer tüm öğeler
sıfır olacaktır, sadece θj 1 olacak, ona tekabül eden x öğesi, yani xj ayakta kala-
bilecek, diğer x öğelerinin hepsi sıfırla çarpılmış olacak.
6
Türevin kendisinden de kurtulabiliriz şimdi, daha önce gösterdiğimiz eşitliği de-
vreye sokalım,
y(1 − g) − (1 − y)g xj = (y − yg − g + yg)xj = (y − g)xj
yani
= (y − g(θT x))xj
= (y − hθ (x))xj
Kodu işletelim,
theta = np.array(grad_ascent(array(data),array(labels).T ))
print theta.T
7
def plot_theta(theta):
x = np.array(arange(-3.0, 3.0, 0.1))
y = np.array((-theta[0]-theta[1]*x)/theta[2])
plt.plot(x, y)
plt.hold(True)
class0 = data[labels==0]
class1 = data[labels==1]
plt.plot(class0['x'],class0['y'],'b.')
plt.hold(True)
plt.plot(class1['x'],class1['y'],'r.')
plt.hold(True)
plot_theta(theta)
plt.savefig('stat_logit_03.png')
Üstteki kod bir döngü içinde belli bir x noktasından başlayarak gradyan inişi
yaptı ve optimal θ değerlerini, yani regresyon ağırlıklarını (weights) hesapladı.
Sonra bu ağırlıkları bir ayraç olarak üstte grafikledi. Ayracın oldukça iyi değerler
bulduğu belli oluyor.
Rasgele Gradyan Çıkışı (Stochastic Gradient Ascent)
Acaba θ’yi güncellerken daha az veri kullanmak mümkün mü? Yani yön hesabı
için sürekli tüm veriyi kullanmasak olmaz mı?
Olabilir. Güncellemeyi sadece tek bir veri noktası kullanarak yapabiliriz. Yine
gradyanı değiştirmiş oluruz, sadece azar azar değişim olur, fakat belki de bu
şekilde sonuca daha çabuk ulaşmak mümkün olacaktır.
Kodlama açısından, θ güncellemesi için bulduğumuz formülü tek nokta bazında
da vermiştik. O zaman o tek noktayı sırayla alıp güncellersek, otomatik olarak
yeni bir şekilde gradyan çıkışı yapmış oluruz.
8
for i in range(m):
h = sigmoid(sum(dot(data_mat[i],theta)))
error = label_mat[i] - h
theta = theta + alpha * data_mat[i].reshape((n,1)) * error
theta = theta.reshape((n,1))
return theta
theta = np.array(stoc_grad_ascent0(array(data),array(labels).T ))
print theta.T
plot_theta(theta)
plt.savefig('stat_logit_04.png')
Neredeyse işimiz tamamlandı. Üstteki grafik pek iyi bir ayraç göstermedi. Niye?
Problem çok fazla salınım (oscillation) var, yani değerler çok fazla uç noktalar
arasında gidip geliyor. Ayrıca veri noktalarını sırayla işliyoruz, veri tabii ki ras-
gele bir şekilde sıralanmış olabilir, ama sıralanmamışsa, o zaman algoritmaya
raslantısal noktaları vermek için kod içinde zar atmamız lazım. Metotun ismi
”rasgele (stochastic)” gradyan çıkışı, bu rasgelelik önemli. 2. problemi düzeltmek
için yapılacak belli, 1. problem için α değeri her döngüde belli oranda küçültülerek
(yani α artık sabit değil) sonuca yaklaşırken oradan buraya savrulmasını engellemiş
olacağız. Yeni kod altta,
9
theta = theta + alpha * data_mat[rand_index].reshape((n,1)) * error
theta = theta.reshape((n,1))
return theta
theta = np.array(stoc_grad_ascent1(array(data),array(labels).T ))
print theta.T
[[ 14.67440542 1.30317067 -2.08702677]]
plot_theta(theta)
plt.savefig('stat_logit_05.png')
Sonuç çok iyi, ayrıca daha az işlemle bu noktaya eriştik, yani daha az işlem ve
daha hızlı bir şekilde sonuca ulaşmış olduk.
Tahmin (Prediction)
Elde edilen ağırlıkları tahmin için nasıl kullanırız? Bu ağırlıkları alıp, yeni veri
noktası ile çarpıp sonuçları sigmoid’den geçirdiğimiz zaman bu noktanın ”1 etiketi
olma olasılığını” hesaplamış olacağız. Örnek (diyelim ki mevcut veri noktası
içinden bir veriyi, -mesela 15. nokta- sanki yeniymiş gibi seçtik)
pt = df.ix[15,['intercept','x','y']]
print sigmoid(dot(array(pt), theta)),
print 'label =',labels[15]
[ 0.99999653] label = 1
Oldukça yüksek bir olasılık çıktı, ve hakikaten de o noktanın gerçek değeri 1 imiş.
Logit
İstatistik kaynaklarında genellikle “logit” adlı bir regresyon türünden bahsedildiğini
görebilirsiniz, burada aslında lojistik regresyondan bahsediliyor, ki bu konuyu
[10] yazısında bulabiliriz. Ama istatistik literatüründe (yapay öğrenim literatüründen
farklı olarak), terminoloji biraz kafa karıştırıcı olabiliyor. Lojistik regresyon yazısında
odağımız sigmoid fonksiyonuydu, peki logit nereden geliyor? Logit,
10
fonksiyonudur, ve bu fonksiyon (0,1) arasındaki bir sayıyı −∞, ∞ arasına eşler
(map). Fonksiyona verilen x bir olasılık, ve bu olasılık, bir olayın (event) olma
/ olmama oranlarının log’una dönüşüyor. Ki bu fonksiyona “log ihtimali (log
odds)” ismi de veriliyor. Hatırlamanın kolay bir yolu belki de logit, “bir şeyi
logla” çağrışımı yapıyor, sonra “neyi logluyoruz?” diye düşünürüz, cevap bir
olasılığı, daha detaylı olarak olma / olmama oranını.
-2.19722457734
0.0
0.847297860387
11.5129154649
Sigmoid bunun tam tersidir, −∞, ∞ arasındaki bir değeri (0,1) arasına eşler, ki lo-
jistik regresyon katsayılarından bir olasılık üretmek istiyorsak, sigmoid lazım. Bu
ters gidişi ispatlamak kolay, ki bu “ters yönde” harekete logit−1 ismi de veriliyor,
ters yöne doğru gidelim,
p
logit(p) = log( )=x (1)
1−p
p 1 1
⇒ = exp(x) ⇒ x = − 1
1−p e p
1 1 1 + ex 1 ex
⇒ + 1 = ⇒ = ⇒ p =
ex p ex p 1 + ex
ki her Xi bir vektördür, veri noktalarımız Xi , yi olarak eşli olarak gelir. Diye-
lim ki elimizde 1992’de ABD seçimlerinde oy vermiş insanların gelir seviyesi
(income) ve kime oy (vote) verdikleri var. Bush’a verilmiş oyu 1 verilmemişi 0
olarak işaretlersek, bu problemi lojistik regresyon problemine çevirebiliriz,
import pandas as pd
df = pd.read_csv('nes.dat',sep=r'\s+')
df = df[['presvote','year','female','income','black']]
df = df[df['presvote'] < 3] # sadece 2 partinin oylarini al
df = df.dropna()
# 1,2 oylari 1,0 yap, Cumhuriyetciye verildi mi evet/hayir
# haline getir
11
df['presvote2'] = df['presvote'].map(lambda x: x-1)
df = df.drop('presvote',axis=1)
df2 = df[df['year'] == 1992]
print df2[:4]
import statsmodels.api as sm
import statsmodels.formula.api as smf
mdlm = smf.logit("presvote2 ˜ income", df2)
mdlmf = mdlm.fit()
print(mdlmf.summary())
Katsayıları irdelemenin iyi bir yolu şudur. Logit tersinden kurtulmak istiyorsak,
(1)’e deki formülü (2)’ye uygularız, iki tarafın logit’ini alırız, sağ taraftaki ters
logit kaybolur,
Pr(y = 1)
log = α + βx
Pr(y = 0)
12
Bu formülün sağ tarafına göre, x’e 1 eklemek demek, β(1+x) = βx+β·1 = βx+β,
formüle bir bakıma β eklemek demektir. Bunu bir tarafa koyalım, şimdi üstteki
formülün iki tarafının exp’sini alalım,
Pr(y = 1)
= exp(α + βx)
Pr(y = 0)
Şimdi exp içindeki x’e 1 eklersek, exp(α+βx+β) olur, bu da exp(α) exp(βx) exp(β)
demektir, o zaman iki tarafı da dengelemek için her iki tarafı da exp(β) ile çarpmak
lazım,
Pr(y = 1)
exp(β) = exp(α + βx + β) = exp(α) exp(βx) exp(β)
Pr(y = 0)
O zaman, x’deki bir birimlik değişimin, olma / olmama oranı olan ihtimal (odds)
üzerindeki etkisini hesaplamak istiyorsak, incelediğimiz değişkenin katsayısını
alıp mesela β = 0.3, onun exp’sini hesaplarız, exp(0.32) = 1.37, ve bu değerin
üstteki eşitliğin sol tarafını da çarpacağı bilgisinden hareketle, ihtimalin o kadar
artacak olduğunu rapor edebiliriz. Yani β = 0.3 için bu artış 1.37 katıdır. Yani
gelirde 1 birimlik bir artış (ki gelir veride 1,2,3,4 gibi sayısal aralıklar olarak gösterilmiş)
Bush’a oy verme şansının 1.37 kat arttırıyor. Bu aslında mantıklı, ABD’de Cumhuriyetçiler
“zenginlerin partisi” olarak biliniyor.
İhtimal oranları (odds ratio) ile düşünmek için bazı örnekler, ihtimal oranı 1,
olasılıkların 0.5 olması demektir, yani her iki ihtimal de eşit ağırlıktadır. İhtimal
oranı 0.5, ya da 2.0 (1/3,2/3) olasılıklarına tekabül eder, formülü hatırlayalım,
p/(1 − p).
Katsayıları İrdelemek
Eğer bir katsayı değerinin sıfırdan uzaklığı Std. Hatanın (Error) iki katından fa-
zla ise katsayı istatistiki olarak anlamlı / değerli (significant) demektir ve kul-
lanılabilir. Tabii burada biraz daha ek irdeleme gerekebilir; mesela kişilerin ara-
balarının beygir gücünü kazandıkları maaşa bağlayan bir regresyon, beygir gücü
katsayısı için beygir başına 10 Eur ve std. hata 2 Eur vermişse bu istatistiki olarak
önemli, ama pratikte önemsizdir. Benzer şekilde eğer beygir katsayısı için 10,000
Eur ve std. hata 10,000 Eur bulmuşsak, bu istatistiki olarak önemsiz, ama pratikte
önemlidir.
İlginç Durum
Siyahi oyların bazı yıllara göre analizini yapalım,
print 'coefs','error'
13
df2 = df[df['year'] == 1964]
mdlm = smf.logit("presvote2 ˜ female + black + income", df2)
mdlmf = mdlm.fit()
print np.vstack((mdlmf.params.index, mdlmf.params,mdlmf.bse)).T
1964 yılında siyahi (black) seçmenlerin oylarına ne oldu? Üstteki analizde kat-
sayı müthiş alçak (büyük negatif değer), ve standard hata çok büyük. Eğer o
sene için veriye bakarsak neler olduğunu anlıyoruz; elimizdeki anket verisin-
deki kişilerden siyahi olan kimse 1964 yılında Cumhuriyetçilere oy vermemiş.
Bu durumda katsayı tabii ki büyük negatif değer (çünkü regresyon hedefimiz
Cumhuriyetçilere oy verilip verilmeyeceği), siyahi olmak ile Cumhuriyetçilere
oy vermek arasında negatif bir korelasyon ortaya çıkmış oluyor. Büyük stan-
dart hata iyi durmuyor tabii, ama bunun sebebi özyineli (iteratif) model uyduran
(fitting) algoritmanın bir nüansıdır. Daha ufak bir değer elde etmek için [3]’de
görülen numaralar yapılabilir, fakat pratikte bu büyük değeri görünce analizi ya-
pan kişi veriye bakacak, ve neler olduğunu anlayacaktır.
Bangladeş’te su kuyusu değişiminin lojistik modeli
Verimizde 3,000 haneye gidilerek anketle toplanmış veri var. Veride hanelerin
yakınlarındaki kuyudaki arsenik seviyesi toplanmış, ve paylaşılan verideki tüm
hanelerin kuyular sağlıksız seviyede arsenik içeriyor. Verideki diğer bilgiler en
yakındaki ”sağlıklı” bir kuyuya yakınlık, ve o hanenin bu sağlıklı su kuyusuna
(bir sene sonra yapılan kontrole göre) geçip geçmediği. Ayrıca hanede fikri soru-
lan kişinin eğitim seviyesi ve bu hanedeki kişilerin herhangi bir sosyal topluluğa
14
(community assocation) ait olup olmadıkları.
Amacımız su kuyusunun değişimini modellemek. Bu eylem olup / olmama
bağlamında evet / hayır şeklinde bir değişken olduğu için ikili (binary) olarak
temsil edilebilir ve ikili cevaplar / sonuçlar lojistik regresyon ile modellenebilir-
ler.
Veriye bakalım.
Uzaklık (dist) için elde edilen katsayı -0.0062, fakat bu sayı kafa karıştırıcı olabilir
çünkü uzaklık metre olarak ölçülür, o zaman bu katsayı mesela 90 metre ile 91
metre uzaklığın değişime olan etkisini ölçmektedir, kısacası pek faydalı değildir.
Yani uzaklık metre ile ölçüldüğü için 1 metrenin modeldeki etkisi ufak, o yüzden
bu ölçütü ölçeklersek (scale) belki regresyon katsayılarımız daha net çıkar.
Bunu nasıl yapacağız? Ölçeklenmiş yeni bir değişken yaratmak yerine, onu formülün
içinde tanımlayabiliriz. Burada bir ara not: eğer formül içinde +,- gibi operasy-
15
onları aritmetik işlem olarak kullanmak istiyorsak, o zaman ’I()’ çağrısını yap-
mak lazım, çünkü + operasyonu mesela statsmodels formüllerinde başka amaçlar
için kullanılıyor. ’I’ harfi birim (identity) kelimesinden geliyor, yani hiçbir şeyin
değişmediğini anlatmaya uğraşıyoruz, ”içinde ne varsa onu ver” diyoruz .
16
Mavi noktalar gerçek veri, yeşil çizgi ise uzaklık geçilerek modelin oluşturduğu
”tahmin”. Modelin gerçek veriye ne kadar uyduğunu görüyoruz böylece, yeşil
çizginin yüksek olasılık verdiği bölgelerde üst kısmın daha mavi olmasını bek-
leriz mesela. Üstteki resimde aşağı yukarı bunu gösteriyor.
Bir problemin grafiklemesine başka bir yönden yaklaşalım, kuyu değiştirenlerin
değişim uzaklığının yoğunluğu, bir de kuyu değiştirmeyenlerin değişim uzaklığının
yoğunluğu. Değişimi yapanların dağılımına bakınca, kısa mesafelerde daha fa-
zla yoğunluk görmeyi bekliyoruz, değiştirmeyenlerin ise uzun mesafelerde daha
fazla yoğunluğu olur herhalde.
Yoğunluğu göstermek için çekirdek yoğunluk hesabı (kernel density estimation)
tekniğini kullanıyoruz. Bu teknik her veri noktasına Gaussian, kutu (box), ya da
diğer türden bir ”çekirdek” fonksiyonunu koyar (ve veriyi o fonksiyona geçer,
sonucu kaydeder), ve bu iş bitince tüm çekirdekler üst üste toplanarak genel
dağılım ortaya çıkartılır. Teknik histogram tekniğiyle aynı işi yapmaya uğraşır,
bir anlamda verinin dağılımını daha pürüzsüz (smooth) hale getirir.
Bu teknik istatistikte oldukça yeni bir teknik sayılır, kullanılması için bilgisayar
hesabı gerekiyor (kıyasla histogram elle de yapılabilir), yeni hesapsal tekniklerde
olan ilerlemelerin veri analizine getirdiği bir yenilik yani!
[KDE bölümü atlandı]
Model 2: Güvenli kuyuya olan uzaklık ve kendi kuyusunun arsenik seviyesi
Şimdi arsenik seviyesini modelimize ekleyelim. Bekleriz ki kuyusunda yüksek
arsenik miktarı olan kimselerin kuyu değiştirmesi daha çok beklenen bir şeydir.
17
Date: Wed, 20 May 2015
Pseudo R-squ.: 0.04551
Time: 21:25:48
Log-Likelihood: -1965.3
converged: True
LL-Null: -2059.0
LLR p-value: 1.995e-41
==================================================================================
coef std err z P>|z| [95.0% Conf. Int.]
----------------------------------------------------------------------------------
Intercept 0.0027 0.079 0.035 0.972 -0.153 0.158
I(dist / 100.) -0.8966 0.104 -8.593 0.000 -1.101 -0.692
arsenic 0.4608 0.041 11.134 0.000 0.380 0.542
==================================================================================
Bu sonuca göre, ankette soru sorulan ortalama kişi için en yakın kuyuya olan
uzaklıkta 100 metrelik bir değişim olasılığında %22 düşüş anlamına gelmektedir.
Fakat kendi kuyusundaki arsenikte 1 seviyesinde bir artış değişim olasılığını %11
oranında arttırmaktadır.
Sınıfların ayırılabilirliği
Bu modelin kuyu değiştirenler ile değiştirmeyenleri ne kadar iyi sınıflayabildiğini
anlamak için her sınıftaki kişiyi uzaklık-arsenik uzayında grafikleyebiliriz.
Biz pek bir iyi bir ayırım göremedik, o sebeple modelin oldukça yüksek bir hata
oranının olmasını bekliyoruz. Fakat başka bir şey farkediyoruz, grafiğin ”kısa
mesafe-yüksek arsenik” bölgesinde çoğunlukla değişimciler var, ve ”uzun mesafe-
düşük arsenik” bölgesinde çoğunlukla değiştirmeyenler var.
logit_pars = model2.params
intercept = -logit_pars[0] / logit_pars[2]
slope = -logit_pars[1] / logit_pars[2]
18
dist_sw = df['dist'][df['switch'] == 1]
dist_nosw = df['dist'][df['switch'] == 0]
arsenic_sw = df['arsenic'][df['switch'] == 1]
arsenic_nosw = df['arsenic'][df['switch'] == 0]
plt.figure(figsize = (12, 8))
plt.plot(dist_sw, arsenic_sw, '.', mec = 'purple', mfc = 'None',
label = 'Switch')
plt.plot(dist_nosw, arsenic_nosw, '.', mec = 'orange', mfc = 'None',
label = 'No switch')
plt.plot(np.arange(0, 350, 1), intercept + slope * np.arange(0, 350, 1) / 100.,
'-k', label = 'Separating line')
plt.ylim(0, 10)
plt.xlabel('Distance to safe well (meters)')
plt.ylabel('Arsenic level')
plt.legend(loc = 'best')
plt.savefig('stat_logit_07.png')
19
Model: Logit
Df Residuals: 3016
Method: MLE
Df Model: 3
Date: Wed, 20 May 2015
Pseudo R-squ.: 0.04625
Time: 21:26:26
Log-Likelihood: -1963.8
converged: True
LL-Null: -2059.0
LLR p-value: 4.830e-41
======================================================================================
coef std err z P>|z| [95.0% Conf. I
--------------------------------------------------------------------------------------
Intercept -0.1479 0.118 -1.258 0.208 -0.378 0
I(dist / 100.) -0.5772 0.209 -2.759 0.006 -0.987 -0
arsenic 0.5560 0.069 8.021 0.000 0.420 0
I(dist / 100.):arsenic -0.1789 0.102 -1.748 0.080 -0.379 0
======================================================================================
20
converged: True
LL-Null: -2059.0
LLR p-value: 4.588e-46
======================================================================================
coef std err z P>|z
--------------------------------------------------------------------------------------
Intercept 0.3563 0.040 8.844 0.00
center(I(dist / 100.)) -0.9029 0.107 -8.414 0.00
center(arsenic) 0.4950 0.043 11.497 0.00
center(I(educ / 4.)) 0.1850 0.039 4.720 0.00
center(I(dist / 100.)):center(arsenic) -0.1177 0.104 -1.137 0.25
center(I(dist / 100.)):center(I(educ / 4.)) 0.3227 0.107 3.026 0.00
center(arsenic):center(I(educ / 4.)) 0.0722 0.044 1.647 0.10
======================================================================================
21
def plot_binned_residuals(bin_df):
'''
Plotted binned residual averages and confidence intervals.
'''
plt.plot(bin_df['var'], bin_df['resid'], '.')
plt.plot(bin_df['var'], bin_df['lower_ci'], '-r')
plt.plot(bin_df['var'], bin_df['upper_ci'], '-r')
plt.axhline(0, color = 'gray', lw = .5)
22
'center(I(dist / 100.)) : center(I(educ / 4.)) + ' +
'center(np.log(arsenic)) : center(I(educ / 4.))'
)
23
Model hata oranları
pred_table() çağrısı bize bu modelin ”kafa karışıklığı matrisini (confusion ma-
trix)” veriyor. Bu matrisi kullanarak modelimizin hata oranını hesaplayabiliriz.
Not: Kafa karışıklığı matrisi sınıflandırma hatalarını verir, ve her türlü hata kom-
binasyonunu içerir, mesela iki sınıf için, gerçekte 0 ama 1 tahmin hataları, gerçekte
1 ama 0 hataları vs. Bu matrisin satırlar gerçek veri, kolonları tahminleri içerir.
Tabii ki köşegendeki sayılar doğru tahmin oranlarıdır.
Sonra bu sonucu, en fazla verilen cevabı herkesin cevabıymış gibi farzeden daha
basit bir ”sıfır (null) modelinin” hata oranı ile karşılaştırmalıyız. Mesela bu-
rada kişilerin %58’i kuyu değiştirmiş, bu durumda sıfır modeli ”herkes kuyu
değiştiriyor” diye modeller, ve bu basit modelin hata payı 42% olur. Bizim model
bu modelden daha iyi bir sonuç verecek midir? Sonuç altta.
print model5.pred_table()
print 'Model Error rate: {0: 3.0%}'.format(
1 - np.diag(model5.pred_table()).sum() / model5.pred_table().sum())
print 'Null Error Rate: {0: 3.0%}'.format(
1 - df['switch'].mean())
[[ 568. 715.]
[ 387. 1350.]]
Model Error rate: 36%
Null Error Rate: 42%
Ek: qcut
Yukarıdaki qcut kullanımını özetlemek gerekirse; arsenik değişkeni için mesela
dağılım bölgeleri (n-tile) üzerinden bir atama yapacağız, önce DataFrame yaratalım,
resid var
1 3013 2.36
2 3013 0.71
24
3 3013 2.07
4 3013 1.15
5 3013 1.10
6 3013 3.90
7 3013 2.97
8 3013 3.24
9 3013 3.28
10 3013 2.52
model4.
Şimdi 40 tane dağılım bölgesi yaratalım
1 (2.327, 2.47]
2 (0.68, 0.71]
3 (1.953, 2.07]
4 (1.1, 1.15]
5 (1.0513, 1.1]
6 (3.791, 4.475]
7 (2.81, 2.98]
8 (3.21, 3.42]
9 (3.21, 3.42]
10 (2.47, 2.61]
11 (2.98, 3.21]
12 (2.98, 3.21]
13 (2.81, 2.98]
14 (2.98, 3.21]
15 (1.66, 1.76]
...
3006 (0.64, 0.68]
3007 (2.327, 2.47]
3008 (0.71, 0.75]
3009 (1.25, 1.3]
3010 (0.71, 0.75]
3011 (0.56, 0.59]
3012 (0.95, 1.0065]
3013 (0.86, 0.9]
3014 [0.51, 0.53]
3015 (0.95, 1.0065]
3016 [0.51, 0.53]
3017 (1.0513, 1.1]
3018 [0.51, 0.53]
3019 (0.62, 0.64]
3020 (0.64, 0.68]
Name: arsenic, Length: 3020, dtype: category
Categories (40, object): [[0.51, 0.53] < (0.53, 0.56] < (0.56, 0.59] <
(0.59, 0.62] ... (3.21, 3.42]
< (3.42, 3.791] < (3.791, 4.475] < (4.475, 9.65]]
Görüldüğü gibi bölgeler bir obje aslında ve içinde levels diye bir değişkeni var.
Ayrıca labels diye bir değişken de var,
25
[31 6 28 ..., 0 4 5]
ki bu değişken içinde hangi noktanın hangi olasılık bölgesine ait olduğunun ata-
ması var. Mesela 2. nokta 6. bölgeye aitmiş, bu bölge hangisi?
(0.68, 0.71]
Şimdi şöyle bir atama yaparsak, yani qcut sonucunu direk olduğu gibi resid_df
içine atarsak, qcut içindeki levels, resid_df üzerindeki index (sıra) ile uyum-
landırılacaktır, ve her var için doğru olan qcut sonucu atanmış olacaktır!
Üstte hakikaten bakıyoruz ki 2. nokta var=0.71 doğru aralık olan (0.68, 0.71]
ile eşleşmiş.
Kredi Kart Analizi ve Lojistik Regresyon
Kredi Kart başvurularının kabul edilip edilmediğinin kayıtları üzerinde başvurunun
kabul edilip edilmeyeceğini tahmin etmek için bir model kullanabiliriz. Örnek [1,
sf. 390]’dan alındı. Veri
card = Başvuru kabul edilmiş mi?
reports = Kişi hakkında kötü bir olay rapor edilmiş mi?
income = Yıllık gelir, birim $10000
age = Yaş
owner = Kişi kendi evinin sahibi mi?
dependents = Bakılan / bağımlı kaç kişi var (çocuk, yaşlı kişi, vs)
months = Mevcut adreste kaç aydır yaşanıyor
share = Aylık kredi kart harcamalarının yıllık kazanca olan oranı
selfemp = Kişi kendi işinin sahibi mi?
majorcards = Büyük kredi kart şirketlerinden kaç tane kartı var
26
active = Kaç tane aktif kredi kart hesabı var
expenditure = Aylık kredi kartı harcaması
Tahmin edeceğimiz ilk değişken card olacak, ki bu değişken evet/hayır bazında;
ona bağlı olarak modellenecek değişkenler geri kalanları, bu değişkenlerin kredi
kart kabulünde ne kadar etkili olacağını analiz edeceğiz.
Biraz veri önişlemesi yapalım; 1’den küçük bazı yaş verileri var, onları silelim ve
değişkenlerin histogramını basalım.
import pandas as pd
df = pd.read_csv('CreditCard.csv',index_col=0)
col='reports';ax=axes[0,0];ax.set_title(col)
df[col].hist(ax=ax)
col='income';ax=axes[0,1];ax.set_title(col)
df[col].hist(ax=ax)
col='share';ax=axes[0,2];ax.set_title(col)
df[col].hist(ax=ax)
col='age';ax=axes[1,0];ax.set_title(col)
df[col].hist(ax=ax)
col='owner';ax=axes[1,1];ax.set_title(col)
df[col].hist(ax=ax)
col='dependents';ax=axes[1,2];ax.set_title(col)
df[col].hist(ax=ax)
col='months';ax=axes[2,0];ax.set_title(col)
df[col].hist(ax=ax)
col='log(share)';ax=axes[2,1];ax.set_title(col)
df[col].hist(ax=ax)
col='log(reports+1)';ax=axes[2,2];ax.set_title(col)
df[col].hist(ax=ax)
plt.savefig('stat_logit_01.png')
27
Görüldüğü gibi share sola doğru çok yamuk (highly skewed) duruyor, bu değişkenin
bu sebeple log’unu aldık. Değişken reports aynı durumda, ayrıca bu değişkenin
çoğu değeri 0 ya da 1, ama maksimum değeri 14. Bu sebeple log(reports+1)
kullandık ki 0’in logunu almak zorunda olmayalım, ki zaten bu tanımsızdır. Bu
transformasyonu yapıyoruz çünkü belli noktalarda aşırı yoğun olan değişkenler
(ki yamukluklarının sebebi bu) çok yüksek katsayı değerlerinin çıkmasını tetikleye-
biliyor, bu yüzden transformasyon ile onları biraz daha yaymaya uğraşıyoruz.
Alttaki regresyon transformasyon yapılmış hali, onun altında yapılmamış hali de
var.
28
Link Function: logit Scale: 1.0
Method: IRLS Log-Likelihood: -69.895
Date: Thu, 21 May 2015 Deviance: 139.79
Time: 10:14:51 Pearson chi2: 247.
No. Iterations: 13
================================================================================
coef std err z P>|z| [95.0% Conf. Int.]
--------------------------------------------------------------------------------
Intercept 21.4739 3.674 5.844 0.000 14.272 28.675
log_reports1 -2.9086 1.098 -2.650 0.008 -5.060 -0.757
income 0.9033 0.190 4.760 0.000 0.531 1.275
log_share 3.4230 0.530 6.452 0.000 2.383 4.463
age 0.0227 0.022 1.036 0.300 -0.020 0.066
owner 0.7052 0.533 1.323 0.186 -0.340 1.750
dependents -0.6649 0.267 -2.487 0.013 -1.189 -0.141
months -0.0057 0.004 -1.435 0.151 -0.014 0.002
================================================================================
BIC -9222.02662057
AIC 155.790971664
29
Görüldüğü gibi share katsayısı oldukça büyük, ve bu modelde modelin veriye
uyum kalitesini ölçen BIC değeri aşağı yukarı 3 civarında büyüdü (daha küçük
BIC daha iyi).
Bir önceki regresyona bakarsak (ki doğru olarak onu kabul ediyoruz artık) değişkenlerin
p-değerine göre log_reports1, share, income, ve dependents değişkenlerinin önemli
(significant) olduğunu görüyoruz. Demek ki bu değişkenlerin kredi kartı başvurusunun
kabulü bağlamında en önemli değişkenler. Sayısal olarak income ve share arttıkça
kabul şansı artıyor, reports ve dependents arttıkça şans azalıyor.
Not: Üstte AIC değeri niye nan oldu? Tabii ondan önce AIC ve BIC nedir tanımlayalım.
AIC = −2 log{L(θ̂ML )} + 2p
AIC ve BIC bir modelin veriye ne kadar iyi uyduğunu gösteren ölçütlerdir. Log
olurluk, yani verinin bir modele göre kadar ne kadar olası olduğu AIC’in önemli
bir parçası. Fakat ek olarak modelin parametre sayısı p e 2p olarak AIC’e dahil
edilmiş, yani olurluğu aynı olan iki modelden daha basit olanı tercih edilecektir
[8].
Ayrıca AIC ölçütünün, standart varsayımlar altında, verinin bir parçasını dışarıda
bırakarak yapılan çapraz sağlamaya (cross-validation) eşdeğer olduğu da ispatlanmıştır
[9, sf. 90]. Bu çok ciddi bir avantajdır! Düşünürsek, yeni veri üzerinde elde
edilecek başarının ölçümü çoğunlukla ana “eğitim” verisinin bir kısmı dışarıda
bırakılarak, yani hakikaten “yeni veri” yaratarak hesaplanmaya uğraşılır - AIC
bu işi verinin kendisine bakarak doğal olarak yapıyor.
Bozukluğa dönelim: sebep nedir? Burada tahmin yürütmek gerekirse, AIC hesabındaki
log olurluk (likelihood) hesabı bozukluğa yol açmış olabilir, çünkü problem log
transform edilmemiş veride ortaya çıktı. Hatırlarsak transformasyonda sıfırlara
1 eklenmişti çünkü sıfırın log’u tanımsızdır. Bu tanımsızlık AIC hesabındaki
log olurluk hesabını da bozmuş olabilir. BIC için de aynı şey geçerli olabilirdi,
fakat bu modül değişik bir şekilde bu hesabı yapıyor herhalde (ayrı kişiler ayrı
tekniklerle yazılmış olabilirler).
Kaynaklar
[1] Ruppert, Statistics and Data Analysis for Financial Engineering
[2] Vogel, Logistic models of well switching in Bangladesh, http://nbviewer.ipython.
org/urls/raw.github.com/carljv/Will_it_Python/master/ARM/ch5/
arsenic_wells_switching.ipynb
[3] A Weakly Informative Default Prior Distribution for Logistic and Other Regression
models, http://www.stat.columbia.edu/˜gelman/research/published/
priors11.pdf
30
[5] Harrington, P. Machine Learning in Action
[7] Gelman, Hill, Data Analysis Using Regression and Multilevel/Hierarchical Models
[8] Burnham, Model Selection and Inference
[9] Shalizi, Advanced Data Analysis from an Elementary Point of View
[10] Bayramli, Istatistik, Lojistik Regresyon
31
Sayım, Poisson ve Negatif Binom Bazlı Genel Lineer Modelleri (GLM)
Sayım (count) verisini modellemek için genellikle Poisson dağılımına başvurulur.
Ayrıca ortada bir regresyon problemi var ise, yani belli katsayılar üzerinden çarpılan
değişkenlerin sonucu ile bir sayım arasında ilişki kurulmak istenirse -ki bu Logit
örneğinde görülmüştü, link fonksiyonu sigmoid yerine Poisson olur- o zaman
Poisson GLM kullanılır.
Poisson dağılımını hatırlarsak,
λx
f(x; λ) = e−λ
x!
Eğer bir yi rasgele değişkenini dağılımı λ = θi olan Poisson rasgele değişkeni
diye tanımlamak istersek, ki bu dağılım alttaki tanıma göre her i için değişik olur,
yi ∼ Poisson(θi )
Yoğunluk
f(yi ; θi ) = Poisson(yi ; θi )
olarak ta gösterilebilir. Şimdi GLM, yani regresyon yapmak için θi ’yi biraz daha
detaylandıralım / içini dolduralım,
θi = exp(Xi β)
print np.exp(-2)
print np.exp(1./6)
0.135335283237
1.18136041287
Y
n
f(y; β, X) = Poisson(yi ; eXi β )
i=1
1
Veri
Devam etmeden önce veriye bakıp Poisson varsayımını kontrol etmek iyi olur.
Mesela örnek verimiz bir bölgede oturan insanların medyan kazanç (median in-
come) ile bu kazanca sahip olan şahısların evlerine ne kadar hırsız girdiği arasındaki
ilişki. Medyan kazanç için kaç eve hırsız girdiği bir sayım verisi, ilk akla gelen
Poisson ile modellenmesi, bakalım,
import pandas as pd
burg = pd.read_csv('burglary.txt',sep=' ')
burg.plot(y='burglaries',x='median_income',kind='scatter')
plt.savefig('stat_count_01.png')
2
Aradaki fark bu sefer daha da büyük. Eğer bu veriye Poisson bazlı bir GLM
uydurmaya kalksaydık, ortaya aşırı saçılmış (överdispersed) bir durum ortaya
çıkardı. Ya da terminoloji olarak ve Poisson bazlı düşünürsek bu verinin aşırı
saçılmış olduğu söylenecekti. Her iki yöntemi de deneyebiliriz, önce Poisson
bazlı sonra Negatif Binomial bazlı bir GLM. İkincisinin daha iyi sonuç verdiğini
daha düşük kalıntı sapma (residual deviance) değerinden anlayabiliriz.
import pandas as pd
import statsmodels.formula.api as smf
import statsmodels.api as sm
model=smf.glm("burglaries ˜ median_income", data=burg,
family=sm.families.Poisson()).fit()
print(model.summary())
model=smf.glm("burglaries ˜ median_income", data=burg,
family=sm.families.NegativeBinomial()).fit()
print(model.summary())
Titanik Verisi
Daha ilginç bir veri batan Titanik gemisinin kayıtları. Bu kayıtlarda yolcuların
sağ kurtulup kurtulmadığı onlar hakkında baz bilgi ile beraber kişi seviyesinde
3
kaydedilmiş. Hangi sınıfta (whichclass) seyahat etmiş, yetişkin mi (adult) çocuk
mu, cinsiyeti erkek mi kadın mı (man / woman), hayatta kaldı mı (survived) gibi
bilgiler bu kayıtlarda. Bu veriye bakıp istatistiki olarak mesela yolcunun seyahat
ettiği sınıfın hayatta kalmaya etki edip etmediği görülebilir. Ham verinin birkaç
satırına bakalım,
import pandas as pd
tmp = pd.read_csv("titanic.csv",sep=',',index_col=0)
print tmp.head(5)
class age sex survived
1 1st class adults man yes
2 1st class adults man yes
3 1st class adults man yes
4 1st class adults man yes
5 1st class adults man yes
Tahmin bağlamında verinin 1/0 etiketlerine sahip olmasından hareketle ilk akla
gelen ona bir lojistik regresyon ya da Logit modeli uydurmak olabilir. Fakat bu
verinin her satırı üzerinden Logit yapmak yerine grup toplamları üzerinden Pois-
son ya da Negatif Binom yapmak daha uygun olur. Toplamlara bakalım (ayrı bir
dosyada),
import pandas as pd
df = pd.read_csv("titanicgrp.csv",sep=',',index_col=0)
print df
survive cases age sex whichclass
1 1 1 0 0 1
2 13 13 0 0 2
3 14 31 0 0 3
4 5 5 0 1 1
5 11 11 0 1 2
6 13 48 0 1 3
7 140 144 1 0 1
8 80 93 1 0 2
9 76 165 1 0 3
10 57 175 1 1 1
11 14 168 1 1 2
12 75 462 1 1 3
Poisson ile ilerlemeden önce, bir soru soralım: niye 1. sınıfta kurtulan çocuk
sayısı 2. ve 3. sınıftakinden daha az?
Bu bizi şaşırtıyor, çünkü o sınıftan daha fazla kişinin kurtulmasını bekleriz. Fakat
sebep başka, sebep 1. sınıfta seyahat eden toplam çocuk sayısının zaten az olması.
Toplamlara bakarsak,
4
print '1. sinif cocuk sayisi,',
df[(df['age']==0) & (df['whichclass']==1) ].sum()['cases']
print '2. sinif cocuk sayisi,',
df[(df['age']==0) & (df['whichclass']==2) ].sum()['cases']
print '3. sinif cocuk sayisi,',
df[(df['age']==0) & (df['whichclass']==3) ].sum()['cases']
θi
= exp(Xi β)
ui
log θi − log ui = Xi β
log θi = log ui + Xi β
Böylece ui değişkeni bir kaydırma operasyonu ile olduğu haliyle modele eklenmiş
oldu! Modelde bu değişkenin bir katsayısı olacak, maksimum olurluk onu öğrenmeye
çalışacak, vs. Tek bir ek işlem lazım, regresyona veriyi vermeden önce kaydırılan
değişkenin (toplam sayımın) log’u alınır (Poisson modelleri kendi içinde hedef
değişkenini zaten log’lar, ona dokunmaya gerek yok).
Şimdi Titanik verisini modelleyelim.
import pandas as pd
import statsmodels.formula.api as smf
import statsmodels.api as sm
5
df = pd.read_csv("titanicgrp.csv",sep=',',index_col=0)
df['lncases'] = df['cases'].map(lambda x:np.log(x))
yi ∼ NegativeBinomial(θi )
kullanımı olacaktır, ve tabii ki farklı bir kütüphane çağrısı yapılır, ama geri kalan
her şey aynı.
6
coef std err z P>|z| [95.0% Conf. Int.]
--------------------------------------------------------------------------------------
Intercept 0.5197 0.340 1.527 0.127 -0.147 1.187
C(whichclass)[T.2] -0.2573 0.354 -0.728 0.467 -0.950 0.436
C(whichclass)[T.3] -0.9164 0.352 -2.605 0.009 -1.606 -0.227
age -0.6795 0.286 -2.380 0.017 -1.239 -0.120
sex -0.8033 0.284 -2.825 0.005 -1.361 -0.246
======================================================================================
Görüldüğü gibi kalıntı sapmada (residual deviance) seviyesinde büyük bir düşüş
oldu, yani hata azaldı. Bu regresyon çıktısında bazı katsayılar Poisson GLM’dekiyle
aynı olsa da bazıları değişti. Daha doğru olan değerler bunlar.
Katsayıları Yorumlamak
Elde edilen sonuçları pek çok şekilde yorumlamak mümkün, fakat en faydalı
olanı kategorik değişkenler için hesaplanabilen bir Oluş Oran Hızıdır (İncidence
Rate Ratio -IRR-). İsim biraz garip, evet, İngilizcesi de öyle. Bu gayet basit
bir operasyon, sadece katsayının exp’sini almak yeterli. İRR ne sağlar? Aynı
büyüklükteki bir oluş sayısının içinden iki grubu (ve onu gösteren değişken üzerinden)
karşılaştırmayı. Mesela her ikisi de t büyüklüğünde (yani aynı büyüklükte) olan
yetişkin ve çocuk gruplarının birbirinle oranla hayatta kalma şansı nedir? Mod-
ele dönersek, yetişkinler için oran,
exp(β1 (1))
= = e β1
exp(β1 (0))
kalır. Yani İRR’i hesaplamak bir katsayının exp’sini almaktan ibarettir. Biz altta
tüm katsayıların exp’sini aldık,
7
exp katsayilar
Intercept 1.681497
C(whichclass)[T.2] 0.773108
C(whichclass)[T.3] 0.399941
age 0.506850
sex 0.447870
dtype: float64
Bizim aradığımız sonuç eβ1 = e−0.678 = 0.50, üstte görülen soldan 2. değer.
İRR’de bölen çocuk ve değer 1’den küçük olduğuna göre, demek ki yetişkenlerin
çocuklara göre hayatta kalma oranı yarı yarıya! Çocuklar daha şanslı.
Not: Bir sürü işlem yaptık, insanın aklına gelebilir, acaba bu cevabı ana veri
üzerinde sadece basit bölme operasyonları ile yapamaz mıydık?
adults = np.array(df[(df['age']==1)].sum()[['survive','cases']])
ratea = adults[0] / float(adults[1])
children = np.array(df[(df['age']==0)].sum()[['survive','cases']])
ratec = children[0] / float(children[1])
print ratea, ratec, 'nihai sonuc', ratea/ratec
0.70 sonucu üstteki 0.50’den oldukça farklı. Daha doğru olan GLM değeri.
Tahmin Üretmek
Katsayıları kullanarak tahmin nasıl üretiriz? Yeni veri noktasına tekabül eden
katsayıları alıp çarpıp, toplarız, ve sonuç üzerine exp uygularız. Bu bize θi /ui
oranını verecektir.
Örnek, acaba 3. sınıftaki erkek çocukların hayatta kalma oranı nedir?
p = model.params
arr = np.array(df[ (df['whichclass']==3) & (df['sex']==1) & (df['age']==0) ])
print 'veri', arr[0][0] / arr[0][1]
print 'tahmin', np.exp(p[0] + p[2] + p[4])
veri 0.270833333333
tahmin 0.234504990187
p = model.params
arr = np.array(df[ (df['whichclass']==2) & (df['sex']==1) & (df['age']==1) ])
print 'veri', arr[0][0] / arr[0][1]
print 'tahmin', np.exp(p[0] + p[1] + p[4] + p[4])
veri 0.0833333333333
tahmin 0.108052057562
Eğer üretilen tahminler için bir güven aralığı tanımlamak istiyorsak, conf_ınt()
ile tüm katsayılar için %95 güven aralığını alabiliriz,
print model.conf_int()
8
0 1
Intercept 0.171628 0.797290
C(whichclass)[T.2] -0.608738 -0.147836
C(whichclass)[T.3] -0.978885 -0.559276
age -0.768391 -0.197547
sex -1.351899 -0.979415
9
Çok Seviyeli Modeller (Multilevel Models)
Lineer, lojistik regresyon tek seviyeli modellerdir; modellenen verinin regresy-
ona bildirilen tüm katsayılarının hepsi, aynı anda kullanılır. Fakat bazı durum-
larda, mesela coğrafi bir parametrenin modelin parçası olduğu durumlarda daha
değişik bir yaklaşım gerekli olabilir. Eğer regresyonumuzun katsayılarının belli
bir grup için (şehir, okul, zaman, bölge, vs), her grup için farklı şekillerde veriye
uydurulmasını (fit) istiyorsak, o zaman çok seviyeli modelleri kullanmak gereke-
bilir.
Altta gösterilen iki parametreli klasik regresyon
yi = α + βxi + i
çok seviyeli modellerde mesela α’yi, yani kesisi (intercept) her grupta farklı ola-
cak şekilde uydurabilir,
yi = αj[i] + βxi + i
Bu durumda her grup j’nin kendi kesi değeri olacaktır. Ya da her grubun kendi
eğimi (slope) olacak şekilde β’nin gruptan gruba değişmesine izin verilebilir,
yi = α + βj[i] xi + i
yi = αj[i] + βj[i] xi + i
Terminoloji
Literatürde bazen çok seviyeli modeller hakkında sabit etkiler (fixed effects), ras-
gele etkiler (random effects) gibi kelimeler kullanıldığını görürsünüz. Bu termi-
nolojiye göre grup seviyesinde değişmesine izin verilen αj , βj gibi parametrelere
“sabit etki” adı veriliyor, çünkü o parametreler grup içinde değişmemektedir,
modelin geri kalanı ise rasgele etki olacaktır. Bu iki kavramın karışımı da (ki
neredeyse her zaman öyle olur) “karışık etki (mixed effects)” modeli olarak anılıyor.
Bu terminoloji biraz kafa karıştırıcı olabilir, bilinmesi iyidir böylece literatürü
takip edebiliriz, ama biz [1]’deki tavsiyeyi kullanıp “çok seviyeli modeller” ke-
limelerini kullanacağız.
Örnek
Yeni bir ilacın etkili olup olmadığını anlamak için hastalar (subject) üzerinde
deneyler yapılır [2]. Bu veride ilginç olan hastanın durumunun tekrar tekrar belli
aralıklarla ölçülmesi, ve durumun (status) yeni bir veri satırı olarak kaydedilmesi.
Ayrıca rasgele seçilen hastalara ya ilaç, ya da etkisiz ilaç (placebo) veriliyor. Veride
1
cinsiyet (gender), yaş (age), tedavi merkezi numarası (centre) kolonları var. İlk
aydaki durum “başlangıç noktası (baseline)” olarak ayrı bir kolona ayrılıyor, ve
ilk ay satırları regresyon öncesi siliniyor. Soru şudur: ilaç etkili midir?
Soru bir evet/hayır sorusu olduğu için lojistik regresyon kullanacağız.
2
Görülen katsayılara göre tedavinin (treatment) katsayısı 1.3, exp(1.3) = 3.66.
Yani tedavi katsayısındaki 1 birimlik değişiklik (ki bu 0/1 bazlı bir değişken
olduğu için tedavi uygulamak ya da uygulamamak anlamına gelir), hastanın
iyileşmesinde 3.66 kat etki yaratıyor.
Fakat bu regresyon sonuçlarındaki standart hatalarının bazılarından pek mem-
nun değiliz, mesela gruplararası değişkenlerin (between-subject covariates), yaş
gibi, standart hataları aşırı ufak. Bunun sebebi regresyon işleminin tüm veri
satırlarını bağımsız (independent) kabul etmesidir, yani her satırdaki verinin çoğu
aynı kişiye ait olsa bile farklı kişilere aitmiş gibi işlenmektedir. Regresyon sonuçlarını
irdelerken sürekli tetikte olmak gerekir, görüldüğü gibi ufak hata bile bazen iyi
bir şey olmayabiliyor!
Peki çözüm nedir? Çok seviyeli modeller burada devreye girebilir. Eğer kişiyi
ve ona tekabül eden tüm verileri bir grup olarak alırsak, o kişi için alınan tüm
ölçümlerin tekrar eden kısımlarının genele daha az etkide bulunmasını sağlayabiliriz.
Altta glmer adlı komut üzerinden çok seviyeli regresyon örneğini görüyoruz,
ayrıca R diliyle bağlantı kurmak ta burada gösteriliyor; Python statsmodels’a
bu fonksiyon daha taşınmadı. Daha fazla detay için [3]’e bakılabilir.
%load_ext rpy2.ipython
%R library(lme4)
%R -i df
%R p1 = "status ˜ baseline + month + treatment + gender "
%R p2 = "+ age + centre + (1 | subject) "
%R params = paste(p1,p2)
%R resp_lmer <- glmer(as.formula(params), family = binomial(), data = df)
%R -o res res = summary(resp_lmer)
%R -o exp_res exp_res = exp(fixef(resp_lmer))
print res
print exp_res
Scaled residuals:
Min 1Q Median 3Q Max
-2.8574 -0.3590 0.1427 0.3693 2.2393
Random effects:
Groups Name Variance Std.Dev.
subject (Intercept) 3.89 1.972
Number of obs: 444, groups: subject, 111
3
Fixed effects:
Estimate Std. Error z value Pr(>|z|)
(Intercept) 1.68254 0.84436 1.993 0.046296 *
baselinepoor -3.07838 0.60272 -5.107 3.26e-07 ***
month -0.10133 0.12518 -0.809 0.418257
treatmenttreatment 2.16325 0.55644 3.888 0.000101 ***
gendermale 0.20249 0.67270 0.301 0.763402
age -0.02546 0.02014 -1.264 0.206125
centre2 1.04667 0.54784 1.911 0.056064 .
---
(1+subject) kullanımı gruplamayı kişi bazında yapıyor ve her grup için kesinin
değişmesine izin veriliyor. Regresyonun sonucu 2.16, exp(2.16) = 8.67, yani bu
ilaç aslında hastanın iyileşmesinde 8.67 kat etkili! Bu çok daha büyük bir rakam
ve gerçek sonuç aslında bu. Yaş değişkeninin standart hatasına bakarsak, daha
büyük olduğunu görüyoruz, yani bu katsayı daha uygun bir seviyeye gelmiş
bulunuyor.
Kaynaklar
[1] Gelman, Hill, Data Analysis Using Regression and Multilevel/Hierarchical Models
[2] Everitt, A Handbook of Statistical Analysis Using R
[3] Bayramlı, iPython, rpy2, rmagic, https://burakbayramli.github.io/
dersblog/sk/2015/02/ipython-rpy2-rmagic.html
4
Algılayıcı Birleştirimi, Füzyonu (Sensor Fusion)
Tek boyutlu ortamda bir büyüklüğü mesela bir lokasyon bilgisi x’i, iki kere ölçüyoruz,
ve bu ölçümü iki değişik algılayıcıya yaptırıyoruz, ve yine diyelim ki iki değişik
alet bir cismin olduğu uzaklığını / yerini bize geri döndürüyor. Devam ede-
lim, bu bilgilerde belli ölçüde gürültü var; bu aletlerin hatalı ölçümü yüzünden
olabilir, çevre şartları sebebiyle olabilir, örnek olarak iki z1 , z2 ölçümü için iki
değişik belirsizlik (uncertainty) olduğunu farzedelim, bunlar σ1 , σ2 . Soru şu: bu
iki ölçümü kullanarak daha iyi bir x tahmini yapabilir miyiz?
Bunun için iki ölçümü bir şekilde birleştirmemiz gerekiyor. Her ölçümü Gaus-
sian / Normal dağılım olarak modelleyebiliriz, o zaman iki Gaussian dağılımı
bir şekilde birleştirmemiz (fusion) lazım.
Ölçümleri temsil etmek için Gaussian biçilmiş kaftan. Ölçümdeki belirsizliği
standart sapma (standart deviation) üzerinden rahatlıkla temsil edebiliriz. Peki
birleştirimi nasıl yapalım?
Bu tür problemlerde maksimum olurluk (maximum likelihood) kullanılması gerektiğini
aşağı yukarı tahmin edebiliriz, çünkü maksimum olurluk verinin olurluğunu
(olasılığını yani) maksimize ederek bilinmeyen parametreleri tahmin etmeye uğraşır.
Çoğunlukla bu tekniği hep tek bir dağılım bağlamında görürüz, bazı bilinmeyen
parametreleri olan tek bir dağılıma değişik veri noktaları verilerek olasılık sonuçları
çarpılır, ve elde edilen formül maksimize edilmeye uğraşılırken aynı anda bilin-
meyen parametrelerin optimal değerleri saptanmaya uğraşılır. Bizim bu prob-
lemimizde iki değişik dağılım olacak, maksimum olurluk illa tek bir dağılımla
kullanılabilir diye bir kural yok.
Problemimizde iki ölçümü, iki Gaussian ile temsil edebiliriz, ve bu iki Gaussian’a
verilen iki ölçüm noktasını olurluğunu bu Gaussian’ların sonuçlarını çarparak
hesaplayabiliriz. Peki bilinmeyen parametre nedir? Onu da her iki Gaussian için de
aynı olduğunu farzettiğimiz orta nokta (mean) olarak alabiliriz, ve x olarak belirtiriz.
Yani
1 (z − x)2
p(z; x, σ) = √ exp −
σ 2π 2σ2
Ders notları [1]’de iki üstteki formülün nasıl maksimize edilerek bir xMLE formülüne
erişildiğini görebiliriz.
1
Formül başındaki sabit kısmının L(x)’de kullanılmadığını görüyoruz, çünkü mak-
simizasyon açısından düşünürsek o kısım tekrar tekrar çarpılacak ve hesapla-
maya çalıştığımız değişkenler açısından bu sürekli tekrar bir fark yaratmaz.
Bu metot işler. Fakat biz alternatif olarak daha temiz olacak değişik bir yoldan
gideceğiz. Elimizdeki her iki ölçümü iki farklı tek boyutlu Gaussian yerine 2
boyutlu tek bir Gaussian içine koyacağız, iki ölçümü tek bir 2 boyutlu vektör
içinde belirteceğiz yani, ve tek bir olasılık hesabını p(z; x, Σ)’i baz alacağız. Be-
lirsizlikler ne olacak? Ölçüm belirsizliklerini bu 2D Gaussian’ın kovaryansında
çapraza (diagonal) koyabiliriz, çapraz dişindaki matris öğeleri sıfır yapılırsa iki
ölçümün birbirinden bağımsızlığını temsil etmiş oluruz. Maksimizasyon? Tek bir
ölçümün olurluğunu maksimize edeceğiz, bu tek bir ölçümün olasılığını hesapla-
maktan ibarettir, ve bu hesap sırasında bilinmeyen değişkenleri içeren yeni bir
formül ortaya çıkacaktır. Maksimize etmeye uğraşacağımız bu formül olur.
Çok boyutlu Gaussian’ı hatırlayalım (artık z, x birer vektör),
1 1
p(z; x, Σ) = exp − (z − x)T Σ−1 (z − x)
(2π) det(Σ)1/2
k/2 2
Kısaca,
1 1
= exp − (z − x)T Σ−1 (z − x)
C 2
Bir numara, exp ve parantez içi negatif ibareden kurtulmak için − ln p alalım,
1
L = − ln p(z) = (z − x)T Σ−1 (z − x)
2
T −1
σ21 0
1 z1 − x z1 − x
=
2 z2 − x 0 σ22 z2 − x
Çapraz matrisin tersini almak için çaprazdaki öğelerin tersini almak yeterlidir,
T
σ−2
1 z1 − x 1 0 z1 − x
=
2 z2 − x 0 σ−2
2 z2 − x
1 −2 z1 − x
σ1 (z1 − x) σ−2
= 2 (z2 − x) z2 − x
2
1 2 1 −2 2
= σ−2
1 (z1 − x) + σ2 (z2 − x)
2 2
2
Maksimize etmek için, formül karesel olduğuna göre, bilinmeyen x değişkenine
göre türev alıp sıfıra eşitleyebiliriz,
dL
= σ−2 −2 −2 −2
1 z1 − σ1 x + σ2 z2 − σ2 x = 0
dx
x üzerinden gruplarsak,
−x(σ−2 −2 −2 −2
1 + σ2 ) + σ1 z1 + σ2 z2 = 0
σ−2 −2 −2 −2
1 z1 + σ2 z2 = x(σ1 + σ2 )
σ−2 −2
1 z1 + σ2 z2
= xMLE
σ−2
1 + σ−2
2
130/102 + 170/202
xMLE = = 138.0
1/102 + 1/202
Sonuç belirsizliği daha az olan ölçüme daha yakın çıktı, bu akla yatkın bir sonuç.
Çok Boyutlu Gaussian Füzyon
Peki ya elimizdeki ölçümlerin kendisi çok boyutlu ise? Yani z1 , z2 birer vektör
ise?
Yine maksimum olurluk üzerinden bir formül türetebiliriz. Bu durumda tek
olasılık hesabı yetmez, iki ayrı dağılım olmalı,
1 1
p(z1 ; x, Σ1 ) = exp − (z1 − x)T Σ−1
1 (z1 − x)
C1 2
1 1
p(z2 ; x, Σ2 ) = exp − (z2 − x)T Σ−1
2 (z2 − x)
C2 2
Orta nokta x her iki formülde aynı çünkü değişmeyen olan o; aynı orta nokta için
tahmin üretmeye uğraşıyoruz. Bu durum bildik maksimum olurluk hesaplarına
3
benziyor, fakat ilk başta belirttiğimiz gibi farklı türden olasılık fonksiyonlarının
(bu sefer çok boyutlu) farklı veri noktaları üzerinden çarpılması.
Devam edelim. Daha önce ln alarak exp’yi yoketmiştik. Bunun bir diğer faydası
ln alınınca çarpımların toplama dönüşmesidir,
L = p(z1 ; x, Σ1 )p(z2 ; x, Σ2 )
− ln L = − ln p(z1 ; x, Σ1 ) − ln p(z2 ; x, Σ2 )
1 1
L = − ln L = (z1 − x)T Σ−1 T −1
1 (z1 − x) + (z2 − x) Σ2 (z2 − x)
2 2
Şimdi eşitliğin sağ tarafının x’e göre türevini alalım, vektör ve matris bağlamında
türev nasıl alınır? Herhangi bir M’in simetrik olduğu durumlarda (ki kovaryans
matrisleri her zaman simetriktir, çünkü mesela iki değişkenli durumda x1 , x2 ko-
varyansı -ilişkisi- x2 , x1 kovaryansından farklı olamaz),
∂ T
[x Mx] = 2Mx
∂x
dL
= (z1 − x)T Σ−1 T −1
1 + (z2 − x) Σ2
dx
(z1 − x)Σ−1 −1
1 + (z2 − x)Σ2 = 0
z1 Σ−1 −1 −1 −1
1 − xΣ1 + z2 Σ2 − xΣ2 = 0
−x(Σ−1 −1 −1 −1
1 + Σ2 ) + z1 Σ1 + z2 Σ2 = 0
z1 Σ−1 −1 −1 −1
1 + z2 Σ2 = x(Σ1 + Σ2 )
Σ−1 −1 −1
x = Σ1 + Σ2
4
Not: Aslında Σx te diyebilirdik, fakat tersi alınmış matrislerin toplamı olduğunu
temsil etmesi için “tersi alınmış bir sembol” kullandık. Tabii diğer yandan tersin
tersini alınca ele geçecek Σx ’in de bir anlamı olduğu iddia edilebilir, bu Σx en
olası x tahmininin yeni belirsizliğidir de bir bakıma.
Simdi ana formule donelim,
z1 Σ−1 −1 −1
1 + z2 Σ2 = xΣx
Σx (z1 Σ−1 −1
1 + z2 Σ2 ) = xMLE
Örnek
Elimizde iki tane iki boyutlu ölçüm var,
1 2
z1 = , z2 =
1 −1
1 0 4 0
Σ1 = , Σ2 =
0 4 0 1
X, Y = np.meshgrid(x, y)
Z1 = mlab.bivariate_normal(X, Y, sigmax=1.0, sigmay=4.0,mux=1., \
muy=1.,sigmaxy=0.0)
Z2 = mlab.bivariate_normal(X, Y, sigmax=4.0, sigmay=1.0,mux=2., \
muy=-1.,sigmaxy=0.0)
# iki yuzeyi ayni grafikte birlestirmek icin herhangi iki nokta arasinda
# daha fazla (maksimum) olani al, cunku nihai yuzey olarak onu gormek
# istiyoruz zaten
Z = np.maximum(Z1,Z2)
fig = plt.figure()
ax = Axes3D(fig)
ax.view_init(elev=50., azim=80)
5
ax.plot_surface(X,Y,Z,cmap=cm.jet)
plt.savefig('fusion_1.png')
CS = plt.contour(X, Y, Z1,rotation=70)
CS = plt.contour(X, Y, Z2,rotation=70)
plt.savefig('fusion_3.png')
Resimde önce ilk ölçüm, sonra onunla yanyana olacak ikinci ölçüm koyulmuş.
1 0 0.25 0 1.25 0
Σ−1
x = Σ−1
1 + Σ−1
2 = + =
0 0.25 0 1 0 1.25
Tersini alalım
6
0.8 0
Σx =
0 0.8
0.8 0 1 0 1 0.25 0 2 1.2
xMLE = + =
0 0.8 0 0.25 1 0 1 −1 −0.6
fig = plt.figure()
ax = Axes3D(fig)
ax.view_init(elev=40.,azim=80)
ax.plot_surface(X,Y,Z3,cmap=cm.jet)
plt.savefig('fusion_2.png')
Yeni tahminimiz böyle çıktı. Çok daha emin olduğumuz bir noktada en olası
ölçümü ortaya çıkardık. Kontur olarak grafiklersek,
CS = plt.contour(X, Y, Z3)
plt.savefig('fusion_4.png')
7
[1] Zisserman, Lectures 3 & 4: Estimators, www.robots.ox.ac.uk/˜az/lectures/
est/lect34.pdf
[2] Hart, Duda, Pattern Classification
8
Markov Zincirleri (Markov Chains)
Markov Zincirlerinde (MZ) i konumundan j konumuna geçiş olasılığını, Pij gösterir.
Farklı şekile P(Xn+1 = j|Xn = i) olarak açılabilir. Açılımdan görüleceği üzere
bir MZ sonraki adıma geçiş olasılığı için sadece bir önceki adıma bakar. Bu tür
önce/sonra yapısındaki iki boyutlu hal, çok rahat bir şekilde matrise çevirilebilir.
Önceki konum satırlar, sonraki konum kolonlar olarak temsil edilir mesela.
Örnek
Bir sonraki günde yağmur yağmayacağını bir MZ olarak tasarlayalım [1, sf 196].
Bir sonraki günde yağmur yağmayacağını sadece bugün etkiliyor olsun. Eğer
bugün yağmur yağıyorsa yarın yağmur yağması 0.7, eğer bugün yağmıyor ise
yarın yağması 0.4. MZ şöyle
0.7 0.3
P=
0.4 0.6
n
Pij = P(Xn+k = j|Xk = i), n > 0, i, j > 0
1
Tabii ki Pij = Pij . Chapman-Kolmogorov denklemleri bu n-adım geçişlerini
hesaplamak için bize bir yöntem sağlıyoar. Bu denklemler,
X
∞
n+m n m
Pij = Pik Pkj , ∀n, m > 0, ∀i, j (1)
k=0
n+m
Pij formülü şunu söylüyor, i’de başlayan süreç n + m geçiş sonrası j’e varacak,
ve geçtiği yol onu n anında k’den geçirecek. O zaman tüm bu geçiş noktaları k’ler
üzerinden bir toplam alırsak sürecin n + m adım sonrası j’de olma olasılığını elde
etmiş oluyoruz.
Formel olarak
n+m
Pij = P(Xn+m = j|X0 = i)
1
söylenmiş oluyor. Üstteki olasılık hesabına / birleşik olasılığa k’den geçme ak-
siyonunu ekleyip aynı anda tüm k’ler üzerinden toplam alırsak (entegre edip
çıkartma tekniği -integrate out-) hiçbir şey değiştirmemiş oluruz,
X
∞
= P(Xn+m = j, Xn = k|X0 = i)
k=0
X
∞
= P(Xn+m = j, Xn = k, X0 = i)P(Xn = k|X0 = i)
k=0
X
∞
n+m m n
Pij = Pkj Pik
k=0
Pn+m = Pn · Pm
işlemini ima ediyor. Nokta işareti çarpım işlemi, çünkü hatırlarsak matris çarpımının
tanımı şöyleydi; elimizde N x M boyutunda A matrisi var, B ise M x K boyutunda
olsun, her ikisinin i satırı j kolonundaki öğesi aij , bij ise, A · B çarpımı bir N x K
P
matrisidir, bu matrisin i, j öğesi Mk=1 aik bkj ile verilir. Toplamın üst sınırı sonsuz
değil M fakat sonsuzluk üst sınırı genel bir formül için tanımlanmış zaten.
İlk örneğe dönersek, eğer bugün yağmur yağıyorsa 4 gün sonra yağmur yağma
olasılığı nedir?
Aradığımız geçiş için kordinat 0,0’a bakıyoruz ve sonuç 0.5749. Numpy matrix_power
bir matrisi istediğimiz kadar kendisiyle çarpmamızı sağlıyor.
Durağan Dağılım (Stationary Distribution)
Eğer yağmur örneğindeki matrisi çarpmaya devam edersek, mesela 8 kere ken-
disiyle çarpsak sonuç ne olurdu?
2
[[ 0.57145669 0.42854331]
[ 0.57139108 0.42860892]]
Dikkat edilirse, her satır bir değere yaklaşmaya başladı. Bu değer MZ’nin durağan
dağılımıdır, belli koşullara uyan her MZ’nin böyle bir durağan dağılımı vardır.
Bu koşullar MZ’nin periyodik olmayan (aperiodic) ve tekrar eden (recurrent) ol-
masıdır. Bu şartlar çok “özel” şartlar değildir aslında, daha çok “normal” bir
MZ’yi tarif ediyor diyebiliriz. Tüm konumları tekrar eden yapmak kolaydır, MZ
tek bağlı (singly connected) hale getirilir, yani her konumdan her diğer konuma
bir geçiş olur, ve periyodik olmaması için ise MZ’de olmadığı zamanlarda bir
konumdan kendisine geçiş sağlanır (az bir gürültü üzerinden).
Neyse, matematiksel olarak durağanlık şu denklemi ortaya çıkartır,
π = πP
Burada durağan dağılım π’dir. Bu denklem tanıdık geliyor mu? Devriğini alarak
şöyle gösterelim, belki daha iyi tanınır,
PT πT = πT
P T πT = 1 · πT
Ax = λx
3
Örnekteki durumda 1’den başlayınca hangi olasılıkla hangi diğer düğüme at-
landığı görülebiliyor. Bu geçiş olasılıklarına göre zar atılıp geçiş yapılabilir. Markov
matrisleri bu bağlamda kendi içindeki geçişleri gösteriyor, sürekli 1,2,3,.. düğümleri
arasında gidip geliyoruz. 1’den 3’e geçiş için 1’inci satır 3’üncü kolona bakıyoruz,
bir sonraki geçiş için P2 ’nin 3’üncü satırına bakıyoruz.
Bu kavramı daha da genişletebiliriz. Bir çizitin katman katman, farklı blokları
arasındaki geçişleri de ayrı matris çarpımları olarak gösterebiliriz.
4
Monte Carlo, Entegraller, MCMC
Fizik, biyoloji ve özellikle makina öğrenimi problemlerinde bazen çok boyutlu
bir fonksiyon üzerinden entegral almak gerekebiliyor. En basit örnek, mesela bir
dağılımın başka bir fonksiyon ile çarpımının beklentisini (expectation) hesapla-
mak gerektiğinde, ki bu
Z
E(f) = p(x)h(x) dx
1 X
N
EN = h(x(i) )
N 1=1
üstteki entegralin yaklaşıksal temsilidir, x(i) p(x) olasılığına göre üretilen sayıları
temsil ediyor. Üstteki bağlantının teorik olarak ispatı da var, bu ispatı burada
vermeyeceğiz.
İşte Monte Carlo entegral hesabının artasında yatan numara budur.
Demek ki Monte Carlo entegralının işlemesi için p(x)’den örnekleme yapmak
gerekiyor. Şimdi ikinci numaraya gelelim. Bazen ne yazık ki p(x)’den örnekleme
yapmak kolay olmuyor. Mesela alttaki bölümdeki entegralın hesabı zorlaşıyor,
R
h(x)p(x) dx
I= R
p(x) dx
ki bölünende yine h(x)’e göre beklenti almış oluyoruz. Bu durumda q(x) adında
kolay örneklenebilen başka bir yoğunluk fonksiyonu buluyoruz. Ve formülü şu
hale getirerek bir şey değiştirmiş olmayız [3],
R p(x)
h(x) q(x) q(x) dx
I= R p(x)
q(x)
dx
1
Bu formül bir nevi q(x)’e göre alınmış beklentilerin oranı. Aynı numarayı kul-
lanıp entegralı toplam haline getirebiliriz, xi değerleri i = 1, .., N i.i.d olarak
q(x)’ten örneklenir, o zaman I’yi yaklaşık olarak Î olarak hesaplarız,
1
PN p(x)
N =1h(x) q(x) dx
Î = 1
P p(x)
N q(x)
dx
X
N
Î = wi h(xi )
i=1
Bu metota Önemsel Örnekleme metotu adı veriliyor çünkü üstteki ağırlıklar bir
nevi “önemi” temsil ediyorlar. Bir örnek [1]’den görelim; q(x) için birörnek bir
dağılım seçilmiş, belli değerler arasında hep aynı değeri donduruyor.
def importance(nsamples):
samples = np.zeros(nsamples,dtype=float)
w = np.zeros(nsamples,dtype=float)
for i in range(nsamples):
samples[i] = qsample()
w[i] = p(samples[i])/q(samples[i])
return samples, w
x = np.arange(0,4,0.01)
x2 = np.arange(-0.5,4.5,0.1)
realdata = 0.3*np.exp(-(x-0.3)**2) + 0.7* np.exp(-(x-2.)**2/0.3)
box = np.ones(len(x2))*0.8
box[:5] = 0; box[-5:] = 0
plt.plot(x,realdata,'k',lw=6)
plt.plot(x2,box,'k--',lw=6)
samples,w = importance(5000)
plt.hist(samples,normed=1,fc='k')
plt.savefig('stat_mcmc_02.png')
2
Altta Örnekleme ve Öneme Göre Tekrar Örnekleme (Sampling İmportance Re-
sampling) metotu için örnek kod,
def sir(n):
sample1 = np.zeros(n)
w = np.zeros(n)
sample2 = np.zeros(n)
sample1 = np.random.rand(n)*4
w = p(sample1)/q(sample1)
w /= sum(w)
cumw = zeros(len(w))
cumw[0] = w[0]
for i in range(1,len(w)): cumw[i] = cumw[i-1]+w[i]
u = np.random.rand(n)
index = 0
for i in range(n):
indices = where(u<cumw[i])
sample2[index:index+size(indices)] = sample1[i]
index += size(indices)
u[indices]=2
return sample2
x = np.arange(0,4,0.01)
x2 = np.arange(-0.5,4.5,0.1)
realdata = 0.3*np.exp(-(x-0.3)**2) + 0.7* np.exp(-(x-2.)**2/0.3)
box = np.ones(len(x2))*0.8
box[:5] = 0
box[-5:] = 0
plt.plot(x,realdata,'k',lw=6)
plt.plot(x2,box,'k--',lw=6)
plt.savefig('stat_mcmc_03.png')
3
MCMC
Yine p(x)’den örnekleme yapılamadığı durum, bu sefer p(x) yerine onu yaklaşıksal
olarak temsil eden bir π(x)’i elde etmekle uğraşılıyor. Bu π(x) işe bir Markov
Zincirinin (Markov Chain -yine MC harfleri!-) durağan dağılımı olarak hayal
ediliyor.
Markov Zinciri teorisinde bir geçiş matrisi, yan Markov Zincirinin kendisi ver-
ilir, ve durağan dağılımın hesaplanması istenir. MCMC problemlerinde ise, yani
Monte Carlo entegralı için Markov Zinciri kullanıldığı durumlarda elimizde bir
π(x) dağılımı vardır ve bir Markov Zinciri oluşturmamız gerekir. Nihai dağılımı
biliriz, ve bu dağılıma “giden” geçişleri üretiriz. Bu geçişleri öyle ayarlayabiliriz
ki üretilen rasgele sayılar hedef dağılımından geliyormuş gibi olur.
Geçişleri üretmek için literatürde bir çok teknik vardır. Önemsel Örnekleme (Im-
portance Sampling), Örnekleme ve Öneme Göre Tekrar Örnekleme (Sampling
İmportance Resampling), Metropolis-Hastings, Gibbs Örneklemesi gibi teknikleri
vardır, ve detayları değişik olsa da hepsi de MCMC kategorisine girer, ve yap-
maya çalıştıkları π(x)’e giderken bir şekilde bir geçişleri, zinciri ortaya çıkartmak
ve bu geçişleri entegral hesabında kullanmaktır.
Üstteki tekniklerden en yaygın kullanılanı Metropolis-Hastings algoritmasıdır.
Şunu vurgulamak önemli, geçişleri üretmek, “bir tür sanal Markov Matrisi” yarat-
maktır aslında. Ve her MCMC algoritması bunu farklı şekillerde yapabilir; mesela
MH daha basit başka bir dağılım ile ana dağılım arasında sürekli karşılaştırmalar
yapar, belli aralıklarda geçiş yapar, diğerlerinde yapmaz, ve bunun bir yan etkisi
olarak ortaya bir Markov Zinciri çıkartmış / onu kullanmış olur. O geçişlerin bir
Markov Zinciri’ne eşdeğer olduğunun matematiksel olarak ispatı da vardır.
Not: Bu alandaki makalelerde bir dağılımın “belli bir çarpımsal sabite kadar”
bilindiği (known up to a multiplicative constant) söylenir. Bu söz aslında şu an-
lama gelir. Mesela ayrıksal bir dağılımımız var, ama bu dağılımın kendisini, şu
halini biliyoruz
[ 4.3 2. 8.4 8.7 1.8]
4
Bu bir dağılım değil, çünkü öğelerin toplamı 1 değil. Onu bir dağılım haline
çevirmek için, tüm öğeleri toplamak ve bu vektördeki tüm sayıları bu toplam ile
bölmek gerekir. Toplam 25.2, bölersek
[ 0.17063492 0.07936508 0.33333333 0.3452381 0.07142857]
İlk vektör “belli bir çarpımsal sabite kadar” bilinen dağılım, çarpımsal sabit 25.2.
Esas dağılım ikinci vektör.
Peki niye bu sözü söyleyenler toplamı hesaplayıp gerçek dağılımı hesaplamıyorlar?
Sebep performans. Bazen ayrıksal dağılım o kadar yüksek boyutlu, fazla öğe
içeren bir halde oluyor ki, performans açısından bu basit toplam hesabını yap-
mak bile çok pahalı oluyor. İşte MCMC metotlarının bir güzel tarafı daha burada,
dağılımın kendisi olmasa bile belli bir çarpımsal sabite kadar bilinen versiyonları
ile gayet rahat bir şekilde işliyorlar.
Metropolis-Hastings
def p(x):
mu1 = 3; mu2 = 10
v1 = 10; v2 = 3
return 0.3*np.exp(-(x-mu1)**2/v1) + 0.7* np.exp(-(x-mu2)**2/v2)
def q(x):
mu = 5; sigma = 10
return np.exp(-(x-mu)**2/(sigma**2))
stepsize = 0.5
x = np.arange(-10,20,stepsize)
px = np.zeros(x.shape)
for i in range(len(x)): px[i] = p(x[i])
N = 5000
# independence chain
u = np.random.rand(N)
mu = 5
sigma = 10
y = np.zeros(N)
y[0] = np.random.normal(mu,sigma)
for i in range(N-1):
ynew = np.random.normal(mu,sigma)
alpha = min(1,p(ynew)*q(y[i])/(p(y[i])*q(ynew)))
if u[i] < alpha:
y[i+1] = ynew
else:
y[i+1] = y[i]
5
alpha = min(1,p(y2new)/p(y2[i]))
if u2[i] < alpha:
y2[i+1] = y2new
else:
y2[i+1] = y2[i]
plt.figure(1)
nbins = 30
plt.hist(y, bins = x)
plt.plot(x, px*N/np.sum(px), color='r', linewidth=2)
plt.savefig('stat_mcmc_01.png')
Gibbs Örneklemesi
Bu örnekleme metodu Metropolis yönteminin bir versiyonu olarak kabul edilir,
Metropolis yöntemlerinde bir teklif (proposal) dağılımı Q vardır, ve bu dağılımın
örneklenmek istenen P ile ilişkisine göre zar atılıp elde edilen yeni nokta kabul
edilir, ya da kenara atılır. Gibbs ile de bir Q vardır, ama bir cinlik yapılmıştır,
Q için P’nin kendisi, daha doğrusu onun koşullu dağılım hali kullanılır. Bu
koşullu dağılım her i için P(xi |{xj }j6=i , burada xi çok boyutlu x’in bir öğesidir,
{xj }j6=i işe i olmayan diğer tüm öğelerdir. Yani i olmayan her değişken koşulunda
i örneklenir. Bu kullanımın Metropolis yöntemi ile aynı olduğu ispatlanmıştır.
Koşullu dağılımın kullanılmasının ana sebebi ise çok boyutlu P zor bir dağılım
olsa bile çoğunlukla onun koşullu ve tek boyutlu dağılımının rahatça örneklenebilir
halde olmasıdır.
Algoritma şöyle; Rasgele bir başlangıç noktasından başlanır, ve biri harici tüm
değişkenler sabit tutulup sabit olmayan değişken örneklenir. Bu işlem sürekli
uygulanır, bu yapılınca sanki örneklenen dağılımın en olası yerleri gezilmiş olur.
Mesela 2 boyutta, bir x(t) noktasından başladığımızı farzedelim, P(x1 |x2 ) dağılımından
bir x1 örneklenir, (b) şeklinde koşullu dağılımın tek boyutlu bir Gaussian olduğunu
görüyoruz (çünkü ana dağılım iki boyutlu Gaussian), bu tek boyutlu dağılımdan
bir örneklem alınıyor, doğal olarak o tek boyutlu dağılımın tepe noktasının altına
yakın bir yerden.
6
Sonra bu nokta sabitleniyor (yani yeni bir koşullu dağılım yaratılıyor, ve örneklenen
x1 şimdi sağ tarafta), yani P(x2 |x1 ) dağılımından. Bu bizi x(t+1) konumuna (state)
götürüyor, bu böyle devam ediyor. K değişken (boyutundaki) içeren bir sistemde,
genel formüller şöyle,
(t+1)
x1 ∼ P(x1 |xt2 , xt3 , .., xtK )
(t+1)
x2 ∼ P(x2 |xt1 , xt3 , .., xtK )
(t+1)
x3 ∼ P(x3 |xt1 , xt2 , .., xtK )
vs..
Monte Carlo ile pi Hesabı
Yaklaşık olarak π’yi nasıl hesaplarız? İçinde π olan hangi formülü biliyoruz?
Çember alanı formülü. Bunu nasıl kullanabiliriz. Yarıçapı r olan bir çember
düşünelim, ve bu çember bir kare içinde olsun, yani karenin kenarları 2r,
7
Bu durumda kırmızıyla işaretli bölgenin alanı r2 . Mavi çemberin alanı ise πr2 ,
çemberin kırmızı bölge içine düşen kısmi πr2 /4. O zaman ufak karenin oradaki
2
çember kısminin alanına olan oranı p = πr4 olur. O zaman, eğer iki boyutlu
birörnek bir dağılımdan (yani üstteki karenin içine düşecek sayılar) örneklem
alırsak, bu her sayı için çember içine mi düşüyor, dışına mı düşüyor hesabı kolay,
x, y sayısı için x2 +y2 < r2 ise çember içinde, değilse dışında. İçeri düşen sayıların
oranını p kabul ederiz, bu sayıyı 4 ile çarpınca yaklaşık π elde edilir.
import random
NB_POINTS = 10**4
LENGTH = 10**5
CENTER = [LENGTH/2,LENGTH/2]
def in_circle(point):
x,y = point
center_x, center_y = CENTER
radius = LENGTH/2
return (x - center_x)**2. + (y - center_y)**2. < radius**2.
def compute_pi(nb_it):
inside_count = sum(1.0 for _ in range(nb_it) if \
in_circle( (random.randint(1,LENGTH),random.randint(1,LENGTH)) ) )
return (inside_count / nb_it) * 4.
if __name__ == "__main__":
print u'yaklaşık', compute_pi(NB_POINTS), u'gerçek', np.pi
Kaynaklar
[1] Marsland, Algorithmic Machine Learning
[2] MacKay, Information Theory, Inference and Learning Algorithms
[3] Turner, An Introduction to Particle Filtering, http://www.lancaster.ac.
uk/pg/turnerl/PartileFiltering.pdf
8
Değişim Noktası Analizi (Changepoint Analysis)
İngiltere’de 1851 ve 1962 yılları arasında kömür madenlerinde olan kazaların
sayısı yıllık olarak kayıtlıdır. Acaba bu kazaların dağılımına bakarak, değişimin
olduğu seneyi bulabilir miyiz? Böyle bir değişim anı neyi gösterir? Belki maden-
lerle alakalı regülasyonlarda, denetimlerde bir değişiklik olmuştur, ve kaza oranı
azalmıştır [1, 2], [3, sf. 141]. Veriye bakalım.
import pandas as pd
coal = pd.read_csv('coal.txt',header=None)
coal.hist(bins=7)
plt.savefig('stat_coal_02.png')
Eğer veride bir değişim noktası var ise, bu durum veride iki fark bölge olduğunu
gösterir, ki bu bölgelerin iki farklı dağılımla temsil edileceğini tahmin edebiliriz.
Aynı zaman diliminde vuku bulan olay toplamlarının (event counts) Poisson
dağılımına sahip olduğunu biliyoruz. O zaman, belki de ilk yapmamız gereken
bu veriye iki tane Poisson uydurmak, yani veriyi iki Poisson dağılımının karışımı
olarak temsil etmek. Karışımlar konusu [5] yazısında görülebilir, buradaki tek
fark Bernoulli yerine Poisson kullanılacak olması. İdeal olarak uydurma operasy-
onu için Beklenti-Maksimizasyon (Expectation-Maximization -EM-) kullanılır. Fakat
denklemleri türetmek zaman alabilir, biz şuradaki tavsiyeyi [4, sf. 11] takip ed-
erek bu örnek için uydurmayı bir gayrı lineer optimizasyon paketi lmfit ile ya-
pacağız (tavsiyenin R kodu coal.r içinde).
def f(pars,x):
m1 = pars['m1'].value
lam1 = pars['lam1'].value
lam2 = pars['lam2'].value
model = m1*poisson(lam1).pmf(x) + (1-m1)*poisson(lam2).pmf(x)
1
return model
def residual(pars,y,x):
return -np.log(f(pars,x).T[0])
fit_params = Parameters()
fit_params.add('m1', value=0.5, min=0,max=1.)
fit_params.add('lam1', value=1.0, min=1.,max=7.)
fit_params.add('lam2', value=2.0, min=2.,max=7.)
[[Variables]]
m1: 0.51428096 +/- 0.406949 (79.13%) (init= 0.5)
lam1: 1.00000004 +/- 0.557045 (55.70%) (init= 1)
lam2: 3.35150806 +/- 1.791094 (53.44%) (init= 2)
[[Correlations]] (unreported correlations are < 0.100)
C(m1, lam1) = 0.905
C(m1, lam2) = 0.878
C(lam1, lam2) = 0.772
Peki bu bulguyu şimdi değişim noktası keşfine nasıl çevireceğiz? Dikkat, üstteki
iki dağılımın ayrıldığı λ anı değil aradığımız, verideki senesel akış içinde hangi
sene sonrası bir dağılımın diğerinin yerine geçtiği.
2
Şöyle bir yaklaşım olabilir mi acaba: bir döngü içinde potansiyel ayraç noktası
olabilecek tüm seneler için veriyi iki parçaya ayırırız. Sıfır hipotezi nedir? Bu
veri parçaları üstteki bulduğumuz Poisson dağılımlarından geliyor. O zaman
şöyle devam ederiz: Üstteki optimizasyondan elimizde her iki dağılımın beklen-
tisi, yani λ değerleri var, ve Poisson dağılımlarının bir avantajı beklentisinin ve
varyansının aynı olması! Şimdi, eğer her iki parçanın sayısal ortalamasını ve sıfır
hipoteze göre bilinen µ, σ2 (her ikisi de λ) üzerinden standardize edersek, yani
N(0, 1) haline getirirsek, elimize iki tane N(0, 1) geçer, diyelim ki Z1 , Z2 . Bunların
karelerinin toplamının chi kare olacağını biliyoruz. Sıfır hipotezine göre böyle
olmalı. O zaman bundan “sapma” sıfır hipotezinden ne kadar uzaklaşıldığını
gösterir, bu bağlamda en yüksek p-değerini veren ayraç noktası bize değişim
anını verir.
Daha detaylı matematiği vermek gerekirse; Merkezi Limit Teori’sine göre bir-
birinden bağımsız, aynı dağılımlı X1 , .., Xn ’in, ki her birinin beklentisi E(Xi ) = µ
ve varyansı Var(Xi ) = σ2 , o zaman sayısal ortalama X̄ üzerinden, ve n → ∞
X̄ − µ
Z= √
σ n
yani standard normal Z ∼ N(0, 1). Daha önce belirttiğimiz gibi Poisson için µ =
σ2 .
Gerekli olan diğer teori: χ2n ∼ Z21 + ... + Z2n , yani n tane standart normalın toplamı
yaklaşık olarak serbestlik derecesi n olan chi kare dağılımı. Bu iki bilgiyi yan
yana koyarsak, ve üstte bahsettiğimiz döngüyü yazarsak,
1885
3
için ayrı ayrı AIC’leri hesaplayarak hangisinin daha düşük olduğuna göre bu
kararı verebiliriz.
Bayes ve MCMC
Bir değişik yöntem Bayes yaklaşımını kullanarak ve hesapsal olarak Markov Chain
Monte Carlo (MCMC) tekniği. Kazaların sayısının tümünü iki Poisson dağılımının
ortak dağılımı (joint distribution) üzerinden modelleyeceğiz, ve bu dağılımların
birinci Poisson’dan ikincisine geçtiği anı hesaplamaya uğraşacağız.
Poisson dağılımı
e−θ θy
p(y|θ) =
y!
Eldeki n tane veri noktası y = y0 , y1 , ..., yn ’nin hep birlikte θ ile tanımlı bir Poisson
dağılımından gelip gelmediğinin ne kadar mümkün olduğu (likelihood) hesabı
şöyledir:
P
e−nθ θ yi
p(y|θ) = Q
yi !
βα α−1 −βθ
p(θ) = θ e
Γ (α)
p(y|θ)p(θ)
p(θ|y) =
p(y)
p(θ|y) ∝ p(y|θ)p(θ)
İkinci formüle dikkat, eşitlik yerine orantılı olma (proportional to) işaretini kul-
lanıyor. Sebep: bölen kısmındaki p(y)’yi kaldırdık, sonuç olarak soldaki p(θ|y)
değeri artık bir dağılım değil – bu bir bakımdan önemli ama örnekleme amacı için
bir fark yaratmıyor, basitleştirme amacıyla bunu yaptık, böylece p(y)’yi hesapla-
mamız gerekmeyecek, ama örnekleme üzerinden diğer tüm hesapları hala yapa-
biliriz. Tamam.
4
Şimdi Bayes Teorisini Gamma önsel (apriori) ve Poisson olurluğu (likelihood)
üzerinden kullanırsak,
P
βα α−1 −βθ e−nθ θ y
p(θ|y) = θ e × Q
Γ (α) y!
βα P
p(θ|y) = Q θα−1 θ y e−βθ e−nθ
Γ (α) y!
Şimdi sol taraftaki bölümü atalım; yine üsttekine benzer numara, bu kısım gid-
ince geri galan dağılım olamayacak, ama ona ”oranlı” başka bir formül olacak.
P
p(θ|y) ∝ θα−1 θ y −βθ −nθ
e e
P
∝ θα−1+ y −(β+n)θ
e
Yi = Poisson(θ) i = 1, .., k
Yi = Poisson(λ) i = k + 1, .., n
5
Burada Yi sene i sırasında olan kazaların sayısını belirtiyor. Bayes kuralını hatırlarsak
θ ve λ parametrelerine önsel dağılım atayacağız. Bu dağılım Gamma olacak. Yani
θ ∼ Gamma(a1 , b1 ) ve λ ∼ Gamma(a2 , b2 ).
Ayrıca k değerini de bilmiyoruz, k değeri yani ”değişim noktası” Poisson dağılımların
birinden ötekine geçtiği andır. Bu seneyi bulmaya çalışıyoruz. Şimdi tüm verinin,
tüm seneleri kapsayacak şekilde modelini kurmaya başlayalım. k parametresinin
aynen öteki parametreler gibi bir önsel dağılımı olacak (ki sonradan elimize k için
de bir sonsal dağılımı geçecek), ama bu parametre elimizdeki 112 senenin her-
hangi birinde ”eşit olasılıkta” olabileceği için onun önsel dağılımı Gamma değil
k ∼ Unif(1, 112) olacak. Yani ilk başta her senenin olasılığı birbiriyle eşit, her sene
1
112
olasılık değeri taşıyor.
Bu modelin tamamının olurluğu nedir?
1 Y
k
e−θ θyi Yn
e−λ λyi
L(θ, λ, k|y) = × ×
112 i=1 yi ! i=k+1
yi !
Sonsal geçişini yapınca yukarıda olduğu gibi Gamma dağılımlarını elde ederiz:
Pk P
yi −(b1 +k)θ a2 −1+ n
L(θ, λ, k|y) ∝ θa1 −1+ i=1 e λ i=k+1 yi −(b2 +n−k)λ
e
1
112
’yibir sabit olduğu için formülden attık, bu durum orantılı hali etkilemiyor.
Üstteki formül içindeki Gamma dağılımlarını görebiliyoruz, hemen yerlerine koyalım:
X
k X
n
L(θ, λ, k|y) ∝ Gamma(a1 + yi , b1 + k) Gamma(a2 + yi , b2 + n − k)
i=1 i=k+1
X
k
θ|Y1 , .., Yn , k ∼ Gamma(a1 + yi , b1 + k)
i=1
X
n
λ|Y1 , .., Yn , k ∼ Gamma(a2 + yi , b2 + n − k)
i=k+1
6
Pk Pn
yi −kθ yi kλ
p(k|Y1 , .., Yn ) ∝ θ i=1 e λ i=k+1 e
En son formülde içinde k olan terimleri tuttuk, gerisini attık. Formül e terimleri
birleştirilerek biraz daha basitleştirilebilir:
Pk Pn
yi yi (λ−θ)k
p(k|Y1 , .., Yn ) ∝ θ i=1 λ i=k+1 e
X
k
K= yi
i=1
Pn Pn P
yi yi − ki=1 yi
λ i=k+1 =λ i=1
Üstel işlemlerde eksi işareti, üstel değişken ayrılınca bölüm işlemine dönüşür:
Pn
yi
λ i=1
= Pk
λ i=1 yi
Pn
yi
λ i=1
=
λK
Pn
yi
Kλ
i=1
p(k|Y1 , .., Yn ) ∝ θ e(λ−θ)k
λK
K P
θ n
= λ i=1 yi e(λ−θ)k
λ
Pn
yi
λ i=1 terimi k’ye değil n’ye bağlı olduğu için o da final formülden atılabilir
K
θ
p(k|Y1 , .., Yn ) ∝ e(λ−θ)k
λ
p(k) için ortaya çıkan bu formüle bakarsak, elimizde verilen her k değeri için
bir olasılık döndürecek bir formül var. Daha önceki Gamma örneğinde formüle
bakarak elimizde hemen bir Gamma dağılımı olduğunu söyleyebilmiştik. Bu
kodlama sırasında işimize yarayacak bir şeydi, hesaplama için bir dağılıma ”zar
attırmamız” gerekiyor, ve Gamma örneğinde hemen Python Numpy kütüphanesindeki
random.gamma çağrısına Gamma’dan gelen rasgele sayılar ürettirebiliriz. Üstteki
formüle bakarsak, hangi dağılıma zar attıracağız?
Cevap şöyle: p(k|..) pdf fonsiyonundaki k değişkeni 1, .., 119 arasındaki tam sayı
değerleri alabilir, o zaman ortada bir ayrıksal (discrete) dağılım var demektir. Ve
7
her k noktası için olabilecek olasılık değerini üstteki p(k|..) formülüne hesaplattırabiliyorsak,
ayrıksal bir dağılımı her nokta için üstteki çağrı, ve bu sonuçları normalize ed-
erek (vektörün her elemanını vektörün toplamına bölerek) bir dağılım şekline
dönüştürebiliriz. Daha sonra bu ”vektörsel dağılım” üzerinden zar attırırız. Python
kodundaki w_choice ya da R dilindeki sample çağrısı bu işi yapar.
import math
import random
np.random.seed(0); random.seed(0)
#
# hyperparameters: a1, a2, b1, b2
#
def coal(n,x,init,a1,a2,b1,b2):
nn=len(x)
theta=init[0]
lam=init[1]
k = init[2]
z=np.zeros((nn,))
for i in range(n):
ca = a1 + sum(x[0:k])
theta = np.random.gamma(ca, 1/float(k + b1), 1)
ca = a2 + sum(x[(k+1):nn])
lam = np.random.gamma(ca, 1/float(nn-k + b2), 1)
for j in range(nn):
z[j]=math.exp((lam-theta)*(j+1)) * (theta/lam)**sum(x[0:j])
# sample
zz = z / sum(z)
k = w_choice(zz)
print float(theta), float(lam), float(k)
data = np.loadtxt("coal.txt")
coal(1100, data, init=[1,1,30], a1=1,a2=1,b1=1,b2=1)
Kodları işletince elimize k = 42 değeri geçecek, yani değişim anı 1851+42 = 1893
senesidir. Kaynaklar:
[1] Ioana A. Cosma, Ludger Evers, Markov Chain Monte Carlo Methods (Lecture)
[2] Koop, Bayesian Econometric Methods
[3] Anderson, A. (1911). Labour legislation. In H. Chisholm (Ed.), Encyclopedia
8
britannica (11th ed., Vol. 16, sf. 7-28)
[4] Zuccini, Hidden Markov Models for Time Series An Introduction Using R
[5] Bayramli, Istatistik, Çok Değişkenli Bernoulli Karışımı
[6] Bayesian estimation of changepoints, https://ruivieira.dev/bayesian-
estimation-of-changepoints.html
[7] Coal-Mine Accidents: Their Causes and Prevention, https://pubs.usgs.gov/
bul/0333/report.pdf
9
Çok Değişkenli Bernoulli Karışımı (Mixture of Multivariate Bernoulli)
Eğer verimizi, her biri verinin değişik bir bölümünü, yönünü temsil eden bir
“dağılım grubu” yani karışım ile modellemek istiyorsak, karışım modellemesi
kullanılabilir. Mesela boy ve ağırlık verisinde bayanlar ve erkekler ayrı dağılımlara
sahip olabilir, bu durumu modele dahil etmek modelin tahmin gücünü arttırır.
Karışım modellerinin güzel bir tarafı kümeleme teknikleri ile başta “bilinmeyen”
kümelerinin neye benzediğini bulmaları, ayrıca her veri noktasının bu kümelere
olasılıksal olarak aidiyetini, “yakınlığını” hesaplamamızı mümkün kılmaları.
Formel olarak bir karışım dağılımı f her biri ayrı bir dağılım olan f1 , f2 , ..., fK ile K
öğeden oluşan, bir yeni dağılımdır diyoruz, eğer
X
K
f(x) = λk fk (x)
k=1
P
ise, ve λk karışım oranları, λk > 0, k λk = 1 olacak şekilde.
Üstteki model üzerinden zar atılabilecek bir model aynı zamanda (tüm olasılıksal
dağılımlar simule edilebilir tabii, ama üstteki için simulasyon oldukça direk), λ
içindeki olasılıklara göre zar atıp bir karışım öğesi seçilir, daha sonra bu öğenin
dağılımına gidilip ona zar attırılır. Bunun olabileceğini ispatlamak için, Z rasgele
değişkeninin λk ile dağıldığını (ayrıksal dağılım) düşünelim, yani
Z ∼ Mult(λ1 , .., λk )
fk (x) bir diğer açıdan f(x|Z = k)’dir, notasyonel olarak böyle. O zaman,
X
K
= f(x|Z = k)λk
k=1
X
K
= f(x|Z = k)P(Z = k)
k=1
X
K
= f(x, k)
k=1
= f(x)
1
Karışımın içindeki dağılımlar parametrik dağılımlar olduğu zaman onları nasıl
hesapsal olarak kestiririz? Bir dağılımın parametrelerini kestirebilmek için en iyi
yöntemlerden biri maksimum olurluk (maximum likelihood) yöntemi. Olurluk
eldeki verinin belli dağılım parametreleri üzerinden olasılığı, yani “verinin olasılığı”.
Örneklemlerin bağımsız olduğundan hareketle x1 , x2 , ..., xN verisi için olurluk,
Y
N
f(xi ; θ)
i=1
Her zaman olduğu gibi çarpımı toplam haline döndürmek için log alırız,
X
N
`(θ) = log f(xi ; θ)
i=1
X
N X
K
= log λk f(xi ; θk ) (2)
i=1 k=1
Şimdi log olurluğun mesela θj ’ye göre türevini almayı deneyelim, yani j’inci
öğenin parametresine göre bir kısmi türev.
∂` X N
1 ∂f(xi ; θj )
= PK λj
∂θj i=1 k=1 λk f(xi ; θk )
∂θj
X
N
λj f(xi ; θj ) 1 ∂f(xi ; θj )
= PK
i=1 k=1 λk f(xi ; θk )
f(xi ; θj ) ∂θj
X
N
λj f(xi ; θj ) ∂ log f(xi ; θj )
= PK
i=1 k=1 λk f(xi ; θk )
∂θj
Eğer elimizdeki, karışım olmayan, basit bir parametrik model olsaydı, log olurluk
şuna benzeyecekti,
∂ log f(xi ; θj )
∂θj
2
olurluk haline getirdi. Karışımın log olurluğunu maksimize etmek istiyorsak, bu
ağırlığı alınmış olurluğu maksimize etmemiz gerekli. Bu ağırlığın alındığı kısmı
iki üstteki formülden çekip çıkartırsak,
λj f(xi ; θj )
wij = PK
k=1 λk f(xi ; θk )
λj f(xi ; θj )
wij = PK = P(Z = j|X = xi ; θ) (1)
k=1 λk f(xi ; θk )
O zaman
∂` X N
∂ log f(xi ; θj )
= wij
∂θj i=1
∂θj
wij ile, veriye göre, Z’nin sonsal (posterior) hesaplamış oluyoruz. Yani karışımsal
modeli hesaplarken bir ağırlıksal olurluk hesabı yapıyoruz, ki bu ağırlıklar son-
sal dağılımlardan gelen değerlere ihtiyaç duyuyor. Ama bu sonsal dağılımlar da
aslında hesaplamaya çalıştığımız parametrelere ihtiyaç duyuyor, yani bir kördüğüm!
Ama şöyle bir deyiş vardır; kimisine kördüğüm gibi gözüken, bir başkasına ardışıl
yaklaşıksal prosedür gibi gözükür (succcessive approximation procedure) [hoca
şakadan uydurdu bu deyişi, ama teknik doğru]. Demek istiyorum ki eğer kördüğümde
takılı kaldıysak, bir taraf için tahmin yapıp diğer tarafı hesaplarız, sonra bu hesa-
planan değerleri kullanarak ilk tarafı hesaplarız. Bunu sürekli devam ettiririz.
Ünlü Beklenti-Maksimizasyon (Expectation-Maximization -EM-) prosedürü tam
da bunu yapıyor. Detaylar için [3, sf. 450]. EM özyinesel çalışan bir rutindir,
birkaç adımda sonuca erişir, ve her adımda olurluğu iyileştirmesi ve yerel mak-
simuma erişmesi garantidir; Tabii başlangıç noktasına göre bu yerel maksimum
tamamın (global) maksimumu olmayabilir, o zaman EM yerel maksimumda takılıp
kalmış olur (stuck at local maxima), bu sebeple EM’i birkaç değişik rasgele başlangıç
noktasından başlatıp en iyi yerel maksimimumu, yani en iyi olurluğu veren parame-
treleri bulmak iyi bir yaklaşımdır.
3
wij ’ye Değişik bir Yönden Erişmek
θj hesabı için formülasyonu biraz değiştirmek lazım. Tüm ortak dağılımı yazalım,
ayrıca zik değişkenini katalım, Z değişkeni multinom idi, onu 0/1 değerleri içeren
vektörel olarak tasarlayalım, yani z veri noktası i ve bileşen k için, Zi ise i’inci
nokta için
Y
K
zik
P(Xi = xi , Zi = k) = f(xi ; θk )P(Zi = k)
k=1
X
K
= zij ln f(xi ; θk )P(Zi = k)
k=1
X
N X
K
`(θ) = zij ln f(xi ; θk )P(Zi = k)
i=1 k=1
X
N X
K
= zik ln f(xi ; θj ) + ln(λj )
i=1 k=1
X
N X
K
E[l(θ)] = E[zik ] ln f(xi ; θj ) + ln(λj )
i=1 k=1
4
Hesaplanacak tek şey burada E[zik ]. Peki bu beklenti nedir?
= P(zik = 1|xi )
E[zik ] = wik
Yani
X
N X
K
E[l(θ)] = wik ln f(xi ; θj ) + ln(λj ) (4)
i=1 k=1
EM Hesap Adımları
wij hesabına EM’in “beklenti adımı (expectation step)” ismi veriliyor, çünkü görüldüğü
gibi beklenti alıyoruz. Bu adım için θ’nin bilindiği farz edilir, bilinmiyorsa, ki
hesap döngüsünün ilk adımında durum böyledir, o zaman rasgele θ kullanılır.
Döngünün diğer adımlarında döngünün bir önceki adımındaki değerler kullanılır.
Maksimizasyon adımı için bilinen wij için θ’nin hesaplanması gerekir; bu adıma
maksimizasyon adı verilmesi de mantıklı, çünkü altta da görüleceği üzere, kısmi
türevler alıp sıfıra eşitleyerek maksimal değerler hesaplayacağız.
Bu hesap şöyle: Eğer (4) çok değişkenli Bernoulli modeli içinse, ki xid i’inci veri
noktasının D boyutlu Bernoulli için d’inci hücresinin değeri, θjd ise j’inci karışım
öğesinin D boyut içinden d’inci olasılık değeri olsun, f içinde yerine koyunca ve
f üzerinde log etki yapınca çarpım yine toplam olur,
X
N X
K X
D
θxkd 1−xid
= wik ln(λk ) + ln id
(1 − θkd )
i=1 k=1 d=1
X
N X
K X
D
E[l(θ)] = wik ln(λk ) + xid ln θkd + (1 − xid ) ln(1 − θkd )
i=1 k=1 d=1
Şimdi θkd hesabı için ona göre türevi alıp sıfıra eşitleriz,
∂ X N
∂ ∂
E[l(θ)] = wik xid (ln θkd ) + (1 − xid ) ln(1 − θkd ) = 0
∂θkd i=1
∂θkd ∂θkd
5
X
N
xid 1 − xid
wik ( − )=0
i=1
θkd 1 − θkd
X
N
wik xid X
N
wik − wik xid
=
i=1
θkd i=1
1 − θkd
1 X X
N N
1
wik xid = wik − wik xid
θkd i=1 1 − θkd i=1
1 − θkd X X
N N
wik xid = wik − wik xid
θkd i=1 i=1
P P
1 − θkd wik − i wik xid
= i P
θkd i wik xid
P
1 wik
−1= P i −1
θkd i wik xid
P
i wik xid
θ̂kd = P
i wik
Ya da
P
wik xi
θ̂k = Pi
i wik
λj Hesabı
Şimdi λj ’ye
Pgöre bir türev almamız, sıfıra eşitlememiz ve çözmemiz lazım. Tek
bir pürüz k λk = 1 olması şartı, yani tüm ağırlıkların toplamı 1’e eşit olmalı ve
bu şartı bir şekilde denklemlere dahil etmemiz lazım. Lagrange çarpan tekniği
burada kullanılır [1, sf. 395].
∂ X
`(θ) + α( λk − 1)
∂λj k
Ondan önce olurluğun λj ’ye göre kısmi türevi lazım, (1) formülüne dönersek, ve
kısmi türevi alırsak,
∂` X N
f(xi ; θj ) X f(xi ; θj )
N
= PK =
∂λj i=1 k=1 λk f(xi ; θk ) i=1
f(xi )
6
O zaman iki üstteki türev su hale gelir, sıfıra da eşitlersek,
X
N
f(xi ; θj )
+α=0
i=1
f(xi )
X
N
f(xi ; θj )λj
= −αλj
i=1
f(xi )
Eşitliğin sol tarafında toplam içinde yine (1)’de görülen wij ’ye eriştik! Yerine
koyalım,
X
N
wij = −αλj (3)
i=1
P
Şimdi tüm öğeler / kümeler üzerinden bir toplam alalım (yani k ’yi her iki
tarafa da uygulayalım),
X
K X
N X
K
wij = −α λj
k=1 i=1 k=1
P P
k λj = 1, j wij = 1 olduğu için,
N = −α
PN
i=1 wij
λj =
N
import numpy as np
def loginnerprodexp(t,a):
eps=1e-15
t[t>0.] = 1
tmp = np.dot(t,np.exp(a)) + eps
b=np.log(tmp)
return b
def logsumexp(a):
return np.log(np.sum(np.exp(a), axis=0))
def do_EMmixtureBernoulli(Y,K,iter,tol):
7
N,D=Y.shape
OMY=1+(-1*Y) # "One minus Y", (1-Y)
tmp=np.random.rand(N,K)
tmp2=np.sum(tmp,axis=1).reshape((N,1))
tmp3=np.tile(tmp2,(1,K))
lR=np.log(np.divide(tmp, tmp3))
L = []
for i in range(iter):
# lPi log Mixture params Kx1
lPi=np.tile(-1 * np.log(N),(K,1))+logsumexp(lR).T.reshape((K,1))
const=np.tile(logsumexp(lR).T.reshape((K,1)),(1,D))
# lP log Bernoulli params KxD
lP=loginnerprodexp(Y.T,lR).T - const
# lOMP log(1-P), also KxD
lOMP=loginnerprodexp(OMY.T,lR).T-const
# *** E-step
lR=np.tile(lPi.T,(N,1))+np.dot(Y,lP.T) + np.dot(OMY,lOMP.T) # + const
Z=logsumexp(lR.T)
lR=lR-np.tile(Z.T.reshape((N,1)),(1,K))
L.append(np.sum(Z))
if (i>1):
if np.abs(L[i]-L[i-1]) < tol: break
iters = i
return lR,lPi,lP,L,iters
def EMmixtureBernoulli(Y,K,iter,tol,attempts):
Lbest = -np.inf
eps=1e-15
# EM'i farkli noktalardan birkac kere (attempts kadar) baslat
# En iyi sonucun sonuclarini elde tut
for attempt in range(attempts):
lRtmp,lPitmp,lPtmp,L,iters = do_EMmixtureBernoulli(Y,K,iter,eps)
if L[iters]>Lbest:
lR=lRtmp
lPi=lPitmp
lP=lPtmp
Lbest=L[iters]
itersbest=iters
aic = -2*Lbest + 2*lP.shape[0]*lP.shape[1]
return lR, lPi, lP, Lbest, aic
Y = np.loadtxt('binarydigits.txt')
plt.imshow(Y[4,:].reshape((8,8),order='C'), cmap=plt.cm.gray)
8
plt.savefig('mixbern_04.png')
plt.imshow(Y[7,:].reshape((8,8),order='C'), cmap=plt.cm.gray)
plt.savefig('mixbern_05.png')
import numpy as np
import mixbern
[0 0 0 2 2 1 2 0 2 2 1 1 2 1 0 0 0 1 0 1 1 0 0 1 0 2 0 2 1 1 1 2 0 0 0 0 0
0 1 2 0 0 0 0 0 1 2 0 0 2 2 2 1 2 1 2 2 0 0 1 2 1 2 1 0 1 0 0 2 2 2 1 0 2
2 2 0 1 1 2 2 0 1 0 2 0 0 2 2 0 0 2 0 2 1 2 0 1 0 2]
log olurluk -3049.95050527 aic 6483.90101054
dim = (8,8)
templates = np.exp(lP)
digit0 = np.reshape(templates[0,:], dim,order='C')
plt.imshow(digit0, cmap=plt.cm.gray)
plt.savefig('mixbern_01.png')
digit1 = np.reshape(templates[1,:], dim,order='C')
9
plt.imshow(digit1, cmap=plt.cm.gray)
plt.savefig('mixbern_02.png')
digit2 = np.reshape(templates[2,:], dim, order='C')
plt.imshow(digit2, cmap=plt.cm.gray)
plt.savefig('mixbern_03.png')
10
Gaussian Karışım Modeli (GMM) ile Kümelemek
Gaussian (normal) dağılımı tek tepesi olan (unimodal) bir dağılımdır. Bu de-
mektir ki eğer birden fazla tepe noktası olan bir veriyi modellemek istiyorsak,
değişik yaklaşımlar kullanmamız gerekir. Birden fazla Gaussian’ı ”karıştırmak
(mixing)” bu tür bir yaklaşım. Karıştırmak, karışım içindeki her Gaussian’dan ge-
len sonuçları toplamaktır, yani kelimenin tam anlamıyla her veri noktasını teker
teker karışımdaki tüm dağılımlara geçip sonuçları ve bir ağırlık üzerinden topla-
maktır. Çok boyutlu Gaussian’lar için mesela,
X
f(x) = πk N(x|µk , Σk )
z
data = np.loadtxt('biometric_data_simple.txt',delimiter=',')
women = data[data[:,0] == 1]
men = data[data[:,0] == 2]
plt.xlim(55,80)
plt.ylim(80,280)
plt.plot (women[:,1],women[:,2], 'b.')
plt.hold(True)
plt.plot (men[:,1],men[:,2], 'r.')
plt.xlabel('boy (inch)')
plt.ylabel('agirlik (pound)')
plt.savefig('mixnorm_1.png')
1
Bu grafik kadınlar ve erkeklerin boy (height) ve kilolarını (weight) içeren bir veri
setinden geliyor, veri setinde erkekler ve kadınlara ait olan ölçümler önceden
işaretlenmiş / etiketlenmiş (labeled), biz de bu işaretleri kullanarak kadınları
kırmızı erkekleri mavi ile grafikledik. Ama bu işaretler / etiketler verilmiş olsun
ya da olmasın, kavramsal olarak düşünürsek eğer bu veriye bir dağılım uydur-
mak (fit) istersek bir karışım kullanılması gerekli, çünkü iki tepe noktasiyle daha
rahat temsil edileceğini düşündüğümüz bir durum var ortada.
data = np.loadtxt('biometric_data_simple.txt',delimiter=',')
women = data[data[:,0] == 1]
men = data[data[:,0] == 2]
plt.xlim(55,80)
plt.ylim(80,280)
plt.plot (women[:,1],women[:,2], 'b.')
plt.hold(True)
plt.plot (men[:,1],men[:,2], 'r.')
plt.xlabel('boy (inch)')
plt.ylabel('agirlik (pound)')
plt.hold(True)
x = np.arange(55., 80., 1)
y = np.arange(80., 280., 1)
X, Y = np.meshgrid(x, y)
Z = np.zeros(X.shape)
nx, ny = X.shape
mu1 = np.array([ 72.89350086, 193.21741426])
sigma1 = np.matrix([[ 7.84711283, 25.03111826],
[ 25.03111826, 1339.70289046]])
for i in xrange(nx):
for j in xrange(ny):
Z[i,j] = em.norm_pdf(np.array([X[i,j], Y[i,j]]),mu1,sigma1)
2
levels = np.linspace(Z.min(), Z.max(), 4)
Z = np.zeros(X.shape)
nx, ny = X.shape
mu2 = np.array([ 66.15903841, 135.308125 ])
sigma2 = np.matrix([[ 14.28189396, 51.48931033],
[ 51.48931033, 403.09566456]])
for i in xrange(nx):
for j in xrange(ny):
Z[i,j] = em.norm_pdf(np.array([X[i,j], Y[i,j]]),mu2,sigma2)
import scipy.stats
data = np.loadtxt('biometric_data_simple.txt',delimiter=',')
3
women = data[data[:,0] == 1]
men = data[data[:,0] == 2]
plt.xlim(55,80)
plt.ylim(80,280)
plt.plot (data[:,1],data[:,2], 'k.')
plt.xlabel('boy (inch)')
plt.ylabel('agirlik (pound)')
plt.savefig('mixnorm_3.png')
Fakat yine de şekil olarak iki kümeyi görebiliyoruz. Acaba öyle bir yapay öğrenim
algoritması olsa da, biz bir karışım olduğunu tahmin edip, sonra o karışımı veriye
uydururken, etiket değerlerini de kendiliğinden tahmin etse?
Alttaki kod Beklenti-Maksimizasyon üzerinden kümeleme yapar. Konunun teorik
kısmı altta ve [6] yazısında bulunabilir.
Türetmek
Karışımda birden fazla çok boyutlu Gaussian olacak, bu Gaussian’lardan i’inci
Gaussian
1 (x − µ)T Σ−1
i (x − µi )
fi (x) = f(x; µi , Σi ) = exp − (1)
(2π)d/2 |Σi |1/2 2
X
k X
k
f(x) = fi (x)P(Ci ) = f(x; µi , Σi )P(Ci )
i=1 i=1
P
P(Ci )’a karışım oranları deniyor, ki i P(Ci ) = 1. Bazı metinlerde bu πi olarak
ta gösterilebiliyor. Tüm veri için maksimum olurluk
4
X
n X
n X
k
L= ln f(xj ) = ln f(xj ; µi , Σi )P(Ci )
j=1 j=1 i=1
X
n
∂L ∂
= ln f(xj )
∂θi ∂θi j=1
X
n
1 ∂f(xj )
= ·
j=1
f(xj ) ∂θi
Xn
1 X ∂
k
f(xj ; σa , Σa )P(Ca )
j=1
f(xj)
a=1
∂θi
Xn
1 ∂
· f(xj ; σi , Σi )P(Ci )
j=1
f(x j ) ∂θi
ki
1
g(µi , Σi ) = − (xj − µi )T Σ−1
i (xj − µi )
2
∂L X n
1 ∂
|Σi | exp g(µi , Σi ) P(Ci )
−d/2 −1 1/2
= (2π) (3)
∂θi j=1
f(xj ) ∂θi
∂ ∂
exp g(µi , Σi ) = exp g(µi , Σi ) · g(µi , Σi ) (2)
∂θi ∂θi
5
ve
∂
g(µi , Σi ) = Σ−1
i (xj − µi )
∂µi
∂L X n
1
(2π)−d/2 |Σ−1 |1/2
P(Ci )Σ−1 (xj − µi )
= i exp g(µ i , Σ i )
∂µi j=1
f(xj )
X
n
f(xj ; µi , Σi )P(Ci )
= · Σ−1
i (xj − µi )
j=1
f(xj )
X
n
= wij Σ−1
i (xj − µi )
j=1
ki bunun anlamı
f(xj ; µi , Σi )P(Ci )
wij = P(Ci |xj ) =
f(xj )
Üstteki kısmi türevi sıfıra eşitleyip çözer ve her iki tarafı Σi ile çarparsak,
X
n
wij (xj − µi ) = 0
j=1
X
n X
wij xj = µi wij
j=1 j=1
o zaman
Pn
j=1 wij xj
µi = Pn
j=1 wij
6
Σi hesabı için (3) kısmi türevinin |Σ−1
i |
1/2
exp(g(µi , Σi )) üzerindeki çarpım kuralı
−1
(product rule) kullanılarak Σi ’ye göre alınması gerekiyor.
i |
∂|Σ−1 1/2
1 1 −1 1/2
−1
= · |Σ−1
i |
−1/2
· |Σ−1
i | · Σi = |Σi | · Σi
∂Σi 2 2
∂
Şimdi A ∈ Rd×d ve vektörler a, b ∈ Rd için ∂A
aT Ab = abT olmasından hareketle
(3)’teki exp[g(µi , Σi )]’in Σ−1
i gore türevi,
∂ 1
exp g(µi , Σi ) = − exp g(µi , Σi )(xj − µi )(xj − µi )T
∂Σ −1 2
∂
i |
|Σ−1 1/2
−1
exp g(µi , Σi ) =
∂Σi
1 1 −1 1/2
= |Σ−1 |1/2
|Σ | (xj − µi )(xj − µi )T
Σ i exp g(µ i , Σ i ) − exp g(µ i , Σ i )
2 i 2 i
1
· |Σ−1
i |
1/2
· exp g(µi , Σi ) Σi − (xj − µi )(xj − µi )T
=
2
1 X (2π)−d/2 |Σ−1
n
i |
1/2
∂L exp g(µi , Σi )P(Ci ) T
= Σ i − (xj − µ i )(xj − µ i )
∂Σ−1
i
2 j=1 f(xj )
1 X f(xj ; µi , Σi )P(Ci )
n
· Σi − (xj − µi )(xj − µi )T
=
2 j=1 f(xj )
1X
n
wij Σi − (xj − µi )(xj − µi )T
=
2 j=1
X
n
wij Σi − (xj − µi )(xj − µi )T = 0
j=1
7
olur, ve devam edersek alttaki sonucu elde ederiz,
Pn
wij (xj − µi )(xj − µi )T
Σi =
j=1
Pn
j=1 wij
∂
X
k
ln L + α P(Ca ) − 1
∂P(Ci ) a=1
∂L X f(xj ; µi , Σi )
n
=
∂P(Ci ) j=1
f(xj )
X
n
f(xj ; µi , Σi )
+α
j=1
f(xj )
X
n
f(xj ; µi , Σi )P(Ci )
= −αP(Ci )
j=1
f(xj )
X
n
wij = −αP(Ci ) (4)
j=1
X
k X
n X
k
wij = −α P(Ci )
i=1 j=1 i=1
ya da n = −α.
P
Son adım ki=1 wij = 1 sayesinde mümkün oldu. n = −α’yi (4) içine sokunca
P(Ci )’in maksimum olurluk hesabını elde ediyoruz,
8
Pn
j=1 wij
P(Ci ) =
n
from scipy.stats import multivariate_normal as mvn
import pandas as pd
import numpy as np
import matplotlib.pyplot as plt
import numpy.linalg as linalg
import math, random, copy, sys
import scipy.stats
def norm_pdf(b,mean,cov):
k = b.shape[0]
part1 = np.exp(-0.5*k*np.log(2*np.pi))
part2 = np.power(np.linalg.det(cov),-0.5)
dev = b-mean
part3 = np.exp(-0.5*np.dot(np.dot(dev.transpose(),np.linalg.inv(cov)),dev))
dmvnorm = part1*part2*part3
return dmvnorm
9
maxP_k = np.c_[np.max(log_p_nk, axis=1)] == log_p_nk
maxP_k = maxP_k * (np.array(range(K))+1)
return np.sum(maxP_k, axis=1) - 1
10
print cc
else:
raise "Unknown initialization of EM of MoG centers."
if clusters_found:
return center_list, cov_list, p_k, logL
else:
raise Cov_problem()
11
delta_stop = 1e-6,\
diag_add = 1e-3,\
delta_stop_count_end=10):
"""
"""
delta_stop_count = 0
samples, dim = np.shape(X)
K = len(center_list) # We should do some input checking
if diag_add!=0:
feature_var = np.var(X, axis=0)
diag_add_vec = diag_add * feature_var
old_logL = np.NaN
logL = np.NaN
for i in xrange(max_iter):
try:
center_list, cov_list, p_k, logL = __em_gm_step(X, center_list,\
cov_list, p_k, K, diag_add_vec)
except np.linalg.linalg.LinAlgError: # Singular cov matrix
raise Cov_problem()
if iter_call is not None:
iter_call(center_list, cov_list, p_k, i)
# Check if we have problems with cluster sizes
for i2 in range(len(center_list)):
if np.any(np.isnan(cov_list[i2])):
print "problem"
raise Cov_problem()
if old_logL != np.NaN:
if verbose:
print "iteration=", i, " delta log likelihood=", \
old_logL - logL
if np.abs(logL - old_logL) < delta_stop: #* samples:
delta_stop_count += 1
if verbose: print "gmm_em_continue: delta_stop_count =", delta_stop_co
else:
delta_stop_count = 0
if delta_stop_count>=delta_stop_count_end:
break # Sufficient precision reached
old_logL = logL
try:
gm_log_likelihood(X, center_list, cov_list, p_k)
except np.linalg.linalg.LinAlgError: # Singular cov matrix
raise Cov_problem()
return center_list, cov_list, p_k, logL
12
log_p_nk = np.zeros((samples, K))
for k in range(K):
log_p_nk[:,k] = log_p_Xn_mat[:,k] - log_p_Xn
p_Xn = np.e**log_p_Xn
p_nk = np.e**log_p_nk
# M-step:
for k in range(K):
ck = np.sum(p_nk[:,k] * X.T, axis = 1) / np.sum(p_nk[:,k])
center_list[k] = ck
cov_list[k] = np.dot(p_nk[:,k] * ((X - ck).T), (X - ck)) / sum(p_nk[:,k])
p_k[k] = np.sum(p_nk[:,k]) / samples
data = np.loadtxt('biometric_data_simple.txt',delimiter=',')
data = data[:,1:3]
import em
mc = [0.4, 0.4, 0.2]
centroids = [ np.array([0,0]), np.array([3,3]), np.array([0,4]) ]
ccov = [ np.array([[1,0.4],[0.4,1]]), np.diag((1,2)), np.diag((0.4,0.1)) ]
cen_lst, cov_lst, p_k, logL = em.em_gm(data, K = 2, max_iter = 400)
for cen in cen_lst: print cen
for cov in cov_lst: print cov
[ 66.22733783 135.69250285]
[ 72.92994695 194.55997484]
[[ 14.62653617 53.38371315]
[ 53.38371315 414.95573112]]
[[ 7.77047547 24.7439079 ]
[ 24.7439079 1369.68034031]]
import pandas as pd
ff = '../../app_math/kmeans/synthetic.txt'
df = pd.read_csv(ff,comment='#',names=['a','b'],sep=" ")
10 clusters 124325.897319
13
11 clusters 124132.382945
12 clusters 123931.508911
13 clusters 123865.913489
14 clusters 123563.524338
15 clusters 123867.79925
16 clusters 123176.509776
17 clusters 123239.708813
18 clusters 123019.873822
19 clusters 122728.247239
20 clusters 122256.554363
21 clusters 122259.954752
22 clusters 122271.805211
23 clusters 122265.886637
24 clusters 122265.344662
25 clusters 122277.924153
26 clusters 122184.54412
27 clusters 122356.971927
28 clusters 122195.916167
29 clusters 122203.347265
Görüldüğü gibi AIC azalıyor, azalıyor, ve K=20’de azıcık artıyor, sonra 25’e kadar
artmaya devam ediyor, sonra tekrar düşmeye başlıyor ama bizi ilgilendiren uzun
süreli düşüşten sonraki bu ilk çıkış. O nokta optimal K değerini verecektir, ki bu
sayı 20.
plt.scatter(df.a,df.b)
plt.hold(True)
plt.plot(g.means_[:,0], g.means_[:,1],'ro')
plt.savefig('stat_gmm_03.png')
14
Üniversitesi’nde yapay öğrenim dersi veren Tony Jebara derste paylaşmıştı bir
kere (bu tür gayrı resmi, lakırdı seviyesinde tiyolar bazen çok faydalı olur), deri
rengi bulmak için bir projesinde tüm deri renklerini R,G,B olarak grafiğe basmışlar,
ve beyaz olsun, zenci olsun, ve sonuç grafikte deri renklerinin çok ince bir bölgede
yanyana durduğunu görmüşler. İlginç değil mi?
Buradan şu sonuç çıkıyor ki diğer renklerin arasında deri renklerine odaklanan,
onları “tanıyan” bir yapay öğrenim algoritmasının oldukça şansı vardır. Ama
ondan önce veriye bakıp grafiksel olarak ne olduğunu görelim.
s v
0 0.750000 0.125490
1 0.073394 0.427451
2 0.597403 0.301961
Burada önemli olan R,G,B ve H,S,V kolonları. Bu iki grup değişik renk kodlama
yöntemini temsil ediyorlar. Grafikleyelim,
nd = d[d['skin'] == False]
sd = d[d['skin'] == True]
plt.plot(nd['r'],nd['g'],'.')
plt.hold(True)
plt.plot(sd['r'],sd['g'],'rx')
plt.savefig('stat_gmm_01.png')
Ya da H,S üzerinden
nd = d[d['skin'] == False]
sd = d[d['skin'] == True]
15
plt.plot(nd['h'],nd['s'],'.')
plt.hold(True)
plt.plot(sd['h'],sd['s'],'rx')
plt.savefig('stat_gmm_02.png')
Demek ki Jebara haklıymış. Veriye bakınca bir kabaca / sezgisel (intuitive) bazı
çıkarımlar yapmak mümkün. Mesela her iki grafikte de deri renklerini belirten
bölgenin grafiği sanki 3 boyutlu bir Gaussian’ın üstten görünen / kontur (con-
tour) hali. Bunu bilmek bir avantaj, bu avantajı kullanmak lazım. Modelimiz
gerçek dünya verisine ne kadar yakınsa, yapay öğrenim şansı o kadar fazlalaşacaktır.
Eğer o bölgeye bir Gaussian uydurursak (fit) tanıma şansımız artacaktır.
O zaman deri rengi tanıma şu şekilde yapılabilir. Scikit Learn kütüphanesinin
Gaussian Karışımları (GMM) paketini kullanabiliriz. Tek problem bu karışımlar
olasılık fonksiyonunu öğreniyorlar, sınıflama (classification) yapmıyorlar. Önemli
değil, şöyle bir ek kod ile bunu halledebiliriz; iki tane GMM yaratırız, bir tanesi
deri renk bölgeleri için, diğeri diğer bölgeler için. Eğitim sırasında her iki GMM’i
kendi bölgeleri üzerinde eğitiriz. Sonra, test zamanında, her yeni (bilinmeyen)
veri noktasını her iki GMM’e veririz, hangisinden daha yüksek olasılık değeri
geliyorsa, etiket değeri olarak o GMM’in değerini alırız.
GMM’leri, ve onların içindeki Gaussian’ların kovaryanslarını kullanmak faydalı,
kovaryans bildiğimiz gibi bir Gaussian’ın hangi yönde daha fazla ağırlığının olacağını
belirler, eğer kovaryans hesabı yapılmazsa, yani kovaryans matrisinin sadece
çaprazında değerler varsa, mesela üç boyutta Gaussian’ın konturu bir çember
olarak gözükür [1, sf 90]. Tabii her yönde aynı ağırlıkta olan bir Gaussian her
türlü veriyi temsil edemez, en esneği (ki grafiğe bakınca bu gerekliliği görüyoruz)
tam kovaryans kullanmaktır. Scikit Learn ile bu seçim GMM için full ile yapılır,
sadece çaprazı kullan anlamına gelen diag da olabilirdi.
import zipfile
from sklearn.cross_validation import train_test_split
from sklearn.metrics import roc_curve, auc
from sklearn.metrics import roc_auc_score
from sklearn.mixture import GMM
import pandas as pd
16
class GMMClassifier():
def __init__(self,k,var):
self.clfs = [GMM(n_components=k,
covariance_type=var,thresh=0.1,
min_covar=0.0001,n_iter=100) for i in range(2)]
def fit(self,X,y):
self.clfs[0].fit(X[y==0])
self.clfs[1].fit(X[y==1])
def predict(self,X):
res0 = self.clfs[0].score(X)
res1 = self.clfs[1].score(X)
res = (res1 > res0)
return res.astype(float)
if __name__ == "__main__":
res = []
for i in range(5):
clf = GMMClassifier(k=10,var='full')
x_train, x_test, y_train, y_test = train_test_split(X, y, test_size=2000)
clf.fit(x_train,y_train)
preds = clf.predict(x_test)
print 'deneyler'
print res
print 'nihai ortalama', np.array(res).mean()
deneyler
[0.99075081610446136, 0.98417442945172173, 0.98641291695170819,
0.98779826464208242, 0.99239130434782608]
nihai ortalama 0.9883055463
Başarı oranı yüzde 98.8! Bu problem üzerinde pek çok diğer yöntem denedik,
mesela KNN sınıflayıcı, Lojistik Regresyon, vs. gibi, bu yöntem tüm diğerlerini
geçti.
İlginç bir yan bir soru, “hangi kolonların kullanılacağı”. Bu bağlamda projede
arkadaşlardan “ama HSV değerleri RGB değerlerinden türetilebiliyor, ya birini
ya ötekini kullanmak yeterli olmaz mı?” yorumu yapanlar oldu. Evet, bu verinin
diğerinden “türetilmiş” olduğu doğru, ve beklenir ki ideal bir dünyada mükemmel
bir yapay öğrenim algoritmasının bu tür bir yardıma ihtiyacı olmaz, algoritma o
kadar iyidir ki ona sanki aynı veriyi tekrar vermiş gibi oluruz, en iyi ihtimalle ek
külfet yaratırız. Fakat pratikte bu ek veri algoritmaya ek bazı sinyaller verebilir.
17
Mesela eğer müşterilerin kilosu üzerinden bir öğrenim yapıyor olsaydık, 80 kilo-
dan daha az ya da daha fazla olmayı (problem alanına göre) ayrı bir kolon olarak
kodlamak avantaj getirebilirdi. Tabii ki kilo verisi sayısal değer olarak azıyla fa-
zlasıyla oradadır, fakat önem verdiğimiz noktaları türetilmiş veri olarak öğrenim
algoritmasına vermenin zararı yoktur. Üstteki örnekte GB değerlerinin HSV ile
beraber kullanılmasının başarı şansını biraz daha arttırdığını görebiliriz.
Kaynaklar
[1] Alpaydin, E., Introduction to Machine Learning
[2] Jebara, T., Columbia Machine Learning Course
[3] Aaron A. D’Souza, Using EM To Estimate A Probability Density With A Mixture
Of Gaussians, http://www-clmc.usc.edu/˜adsouza/notes/mix_gauss.
pdf
[4] Expectation-Maximization (Python Recipe), http://code.activestate.com/
recipes/577735-expectation-maximization
[5] Zaki, Data Mining and Analysis: Fundamental Concepts and Algorithms
[6] Bayramli, Istatistik, Çok Değişkenli Bernoulli Karışımı
18
Birden Fazla Düz Çizgi Regresyonu, Çizgi Karışım Modeli (Line Mixture Model
-LMM-)
Aynen veriye bir veya birden fazla boyutlu Gaussian karışımlarını uydurabildiğimiz
gibi birden fazla çizgilerin karışımını da veriye uydurabiliriz. Alttaki veriye bakalım,
#lines = [[1,4,10,50],[-1,30,5,50],[4,10,20,40],[0.4,0,80,100]]
lines = [[1,4,10,50],[-1,30,5,50],[4,10,20,40]]
xs = []; ys = []
for a,b,x1,x2 in lines:
x = np.linspace(x1,x2,100)
y = a*x + b
y += np.random.randn(100)*4
xs.append(x); ys.append(y)
xs = np.array(xs).T.flatten()
ys = np.array(ys).T.flatten()
plt.scatter(xs,ys)
plt.hold(True)
plt.savefig('stat_lmm_01.png')
Model olarak düz çizgi kullanmaya karar verdikten sonra önemli soru şu: çizgileri
nasıl modelleriz? Bize bir olasılıksal temsil yöntemi lazım ki böylece bir maksi-
mum olurluk denklemi türetebilelim ve bu denklemi Beklenti-Maksimizasyon
(Expectation-Maximization -EM-) ile çözelim.
Bir fikir: her nokta üzerinde sanki bir tek boyutlu Gaussian varmış gibi düşünebiliriz,
ve o noktada hatayı (negatif olurluk) ölçeriz, ki hata o noktada olduğu düşünülen
bir çizginin gerçek veri noktasına olan y eksenindeki uzaklığı olabilir. Böylece li-
neer regresyon tekniğini aslında çok çizgili olacak şekilde genişletmiş oluyoruz.
Bu karışım modelin formu şöyle,
Y
N X
K
L= πk N(yi ; fk (xi ), σ2k )
i=1 k=1
1
X
N X
K
1
log L = log πk p exp(−(yi − fk (xi ))2 /2σ2k )
i=1 k=1
2πσ2k
fk (xi ) = ak xi + bk
Q fonksiyonu,
X
N X
K
1 (yi − (ak xi + bk ))2
2
Q∝ log πk − log(σk ) − ηik
i=1 k=1
2 2σ2k
∂Q X N
∝ (yi − ak xi − bk )xi ηik = 0
∂ak i=1
∂Q X N
∝ (yi − ak xi − bk )ηik = 0
∂bk i=1
PK
∂ Q+λ k=1 πk − 1 X
N X
K
ηik
∝ +λ=0 πk = 1
∂πk i=1
πk k=1
PN
i=1 xi (yi − bk )ηik
âk = PN 2
i=1 xi ηik
PN
i=1 (yi − ak xi )ηik
b̂k = PN
i=1 ηik
PN
i=1 (yi − (ak xi + bk ))2 ηik
σ̂2k = PN
i=1 ηik
1 X
N
π̂k = ηik
N i=1
2
def em_line(x,y,n_components):
eta = np.random.rand(len(x),n_components)
a = np.random.rand(n_components) * 10
b = np.random.rand(n_components) * 10
sigma2 = np.random.rand(n_components) * 10
pi = np.random.rand(n_components)
for i in range(1000):
for k in range(n_components):
# hats
ahat = np.sum(x*(y-b[k])*eta[:,k]) / np.sum(x**2*eta[:,k])
etasum = np.sum(eta[:,k])
bhat = np.sum((y-a[k]*x)*eta[:,k]) / etasum
sigma2hat = np.sum( (y - (a[k]*x+b[k]))**2 * eta[:,k] ) / etasum
pihat = (1./len(x)) * etasum
#print ahat, bhat, sigma2hat, pihat
a[k] = ahat
b[k] = bhat
sigma2[k] = sigma2hat
pi[k] = pihat
for k in range(n_components):
tmp1 = 1. / np.sqrt(2*np.pi*sigma2[k])
tmp2 = (y-(a[k]*x+b[k]))**2
eta[:,k] = tmp1 * np.exp(-( tmp2 / (2*sigma2[k]) ) )
return a,b,eta
a,b,eta = em_line(xs,ys,n_components=3)
print a
print b
plt.scatter(xs,ys)
plt.hold(True)
for k in range(3):
tmp = np.linspace(0,60,100)
plt.plot(tmp,tmp*a[k]+b[k])
plt.hold(True)
plt.savefig('stat_lmm_02.png')
3
labels = np.argmax(eta, axis=1)
colors = ['r','b','g','c']
for k in range(3):
plt.plot(xs[labels==k],ys[labels==k],'.'+colors[k])
plt.hold(True)
plt.savefig('stat_lmm_03.png')
4
Regresyon, Ridge, Lasso, Çapraz Sağlama, Regülarize Etmek
Konumuz regresyon çeşitleri, ve örnek veri olarak diyabet hastalığı olan kişilerden
alınmış bazı temel verilerle hastalığın bir sene sonraki ilerleme miktarı kullanılacak.
Regresyon sayesinde temel veriler ile hastalığın ilerlemesi arasında bir bağlantı
bulunabilir, bu sayede hem veri açıklanır / daha iyi anlaşılır (hangi değişken
önemlidir, hangisi değildir), hem de başka bir hastanın temel verilerini kulla-
narak o hastanın diyabetinin bir sene sonra ne olacağını tahmin etmek mümkün
olur. Kullanılan temel veriler kişinin yaşı, cinsiyeti, vücut kütle endeksi (body
mass index) ortalama tansiyonu ve altı kere alınmış kan serum ölçümleridir.
İlk önce basit regresyonu hatırlayalım. Bu tekniği daha önce pek çok yönden
gördük. Lineer Cebir, Çok Değişkenli Calculus ders notlarında bu tekniğin türetilmesi
mevcut. Formül
ŵ = (XT X)−1 XT y
Sayısal olarak hemen bu hesabı yapabiliriz. Bir hatırlatma: veri setine y ekseninin
nerede kesildiğinin bulunabilmesi için suni bir ekstra kesi, “intercept” adlı kolon
ekleyeceğiz, bu kolon iki boyutta y = ax + c formülündeki c’nin bulunabilmesi
içindir. Pandas ile bu ekstra kolonu eklemek çok basit, ismen mevcut olmayan
kolon erişildiği anda o kolon hemen yoktan yaratılır.
import numpy.linalg as la
x_tmp = diabetes_x_train.copy()
x_tmp['intercept'] = 1
xTx = np.dot(x_tmp.T,x_tmp )
ws = np.dot(la.inv(xTx),np.dot(x_tmp.T,diabetes_y_train))
print ws
1
lin.fit(diabetes_x_train, diabetes_y_train)
print lin.coef_
print "score", lin.score(diabetes_x_test, diabetes_y_test),
2
ki λ Lagrange çarpanıdır. Aslında şimdiye kadar üstteki çevrimin tersini gördük
çoğunlukla (yani sınırlı problemden sınırsıza gitmeyi), bu gidiş tarzını görmek te
iyi oldu.
Neyse baştaki sınırsız problemi çözmek için ifadenin gradyanını alalım,
∇(yT y − yT Xw − wT XT y + wT XT Xw + λwT w)
O zaman
(XT X + λI)w = XT y
ŵ = (XT X + λI)−1 XT y
Bu son ifade en az kareler (least squares) yani normal regresyon çözüm formülüne
çok benziyor, sadece ek olarak bir λI toplama işlemi var. Demek ki sırt regresy-
onunu kullanmak için zaten yaptığımız hesaba, zaten bizim kendimizin karar
verdiği bir λ üzerinden λI eklersek, geri kalan tüm işlemler aynı olacak.
Kontrol edelim
3
lam = 0.2
wridge = np.dot(la.inv(xTx+lam*np.eye(xTx.shape[0])),\
np.dot(x_tmp.T,diabetes_y_train))
print wridge
ridge = linear_model.Ridge(alpha=0.2)
ridge.fit(diabetes_x_train, diabetes_y_train)
print ridge.score(diabetes_x_test, diabetes_y_test), ridge.coef_
Bir yöntem daha var, bu yönteme Lasso ismi veriliyor. Lasso’ya göre cezalandırma
X
n
w2k 6 λ
k=1
lasso = linear_model.Lasso(alpha=0.3)
lasso.fit(diabetes_x_train, diabetes_y_train)
print lasso.coef_
4
k-Katlamalı Çapraz Sağlama bu iki parçalı eğitim / test kavramını bir adım öteye
taşır. Ufak bir k seçeriz, ki bu genellikle 5 ila 10 arasında bir sayı olur, ve tüm ver-
imizi rasgele bir şekilde ama k tane ve eşit büyüklükte olacak şekilde parçalara
ayırırız. Bu parçalara ”katlar (folds)” ismi verilir bazen (ki isim buradan geliyor).
Sonra teker teker her parçayı test verisi yaparız ve geri kalan tüm parçaları eğitim
verisi olarak kullanırız. Bu işlemi tüm parçalar için tekrarlarız.
Bu yaklaşım niye faydalıdır? Çünkü veriyi rasgele şekillerde bölüp, pek çok
yönden eğitim / test için kullanınca verinin herhangi bir şekilde bizi yönlendirmesi
/ aldatması daha az mümkün hale gelir.
Ve işte bu özelliği, ek olarak, çapraz sağlamayı ”model seçmek” için vazgeçilmez
bir araç haline getirir.
Model seçmek nedir? Model seçimi üstteki bağlamda optimal bir λ bulmaktır
mesela, yani her modeli temsil eden bir λ var ise, en iyi λ’yi bulmak, en iyi modeli
bulmak anlamına geliyor, çapraz sağlama bunu sağlıyor. Çapraz sağlama için
scikit-learn’un sağladığı fonksiyonlar vardır, önce katları tanımlarız, sonra bu
değiştirilmiş regresyon fonksiyonlarına katlama usulünü geçeriz.
Katları üstteki gibi tanımladık. 420 tane veri noktasını 7 kata bol dedik. Şimdi bu
katları kullanalım,
ridge_cv = linear_model.RidgeCV(cv=k_fold)
ridge_cv.fit(np.array(diabetes_x), np.array(diabetes_y))
print ridge_cv.alpha_
0.1
Üstteki sonuç λ = 0.1’i gösteriyor. Bu λ daha optimalmış demek ki. Lasso için
benzer şekilde
lasso_cv = linear_model.LassoCV(cv=k_fold)
print lasso_cv.fit(diabetes_x, diabetes_y)
LassoCV(alphas=None, copy_X=True,
cv=sklearn.cross_validation.KFold(n=420, n_folds=7), eps=0.001,
fit_intercept=True, max_iter=1000, n_alphas=100, normalize=False,
precompute=auto, tol=0.0001, verbose=False)
print lasso_cv.alpha_
0.00283958719118
0.597090337358
Şimdi veri setinin bir kısmı üzerinde teker teker hangi algoritmanın daha başarılı
olduğunu görelim.
5
def predict(row):
j = row; i = row-1
new_data = diabetes_x[i:j]
print diabetes_y[i:j], "lasso",lasso_cv.predict(new_data), \
"ridge",ridge_cv.predict(new_data), \
"linear",lin.predict(new_data)
439 132
Name: response, dtype: int64 lasso [ 122.2361344] ridge [ 127.1821212] linear [ 123.56
438 104
Name: response, dtype: int64 lasso [ 101.85154189] ridge [ 108.89678818] linear [ 102.
437 178
Name: response, dtype: int64 lasso [ 192.95670241] ridge [ 189.58095011] linear [ 194.
436 48
Name: response, dtype: int64 lasso [ 52.8903924] ridge [ 57.66611598] linear [ 52.5445
433 72
Name: response, dtype: int64 lasso [ 60.42852107] ridge [ 66.3661042] linear [ 61.1983
Üstteki sonuçlara göre gerçek değeri 132 olan 439. satırda lasso 122.2, sırt (ridge)
127.1, basit regresyon ise 123.5 bulmuş. O veri noktası için sırt yöntemi daha
başarılı çıktı.
Sonuçlara bakınca bazen sırt, bazen normal regresyon başarılı çıkıyor. Hangi
yöntem kazanmış o zaman? Bir o, bir bu öndeyse, hangi yöntemi kullanacağımızı
nasıl bileceğiz?
Aslında her seferinde tek bir metotu kullanmak gerekmiyor. Bu metotları bir
takım (ensemble) halinde işletebiliriz. Her test noktasını, her seferinde tüm metot-
lara sorarız, gelen sonuçların mesela.. ortalamasını alırız. Bu şekilde tek başına
işleyen tüm metotlardan tutarlı olarak her seferinde daha iyi sonuca ulaşacak
bir sonuç elde edebiliriz. Zaten Kaggle gibi yarışmalarda çoğunlukla birinciliği
kazanan metotlar bu türden takım yöntemlerini kullanan metotlar, mesela Netflix
yarışmasını kNN ve SVD metotlarını takım halinde işleten bir grup kazandı.
Kaynaklar
[1] Figueiredo, Lecture Notes on Linear Regression, www.lx.it.pt/˜mtf/Figueiredo_
Linear_Regression.pdf
[3] Harrington, P., Machine Learning in Action
[4] Shalizi, Data Analysis from an Elementary Point of View
6
Özellik İşlemek (Feature Engineering)
Veri madenciliğinde ”veriden veri yaratma” tekniği çok kullanılıyor; mesela bir
sipariş veri satırında o siparişin hangi zamanda (timestamp) olduğunu belirten
bir kolon varsa (ki çoğu zaman vardır), bu kolonu ”parçalayarak” ek, daha genel,
özetsel bilgi kolonları yaratılabilir. Ya da kategoriksel verileri pek çok farklı şekilde
sayısal hale çevirebiliriz, mesela 1-hot kodlama ile N kategori N kolon haline
gelir, eldeki kategoriye tekabül eden öğe 1 diğerleri sıfır yapılır.
Özellik işlemenin önemi yapay öğrenme açısından önemi var, mesela bir SVM
sınıflayıcısını en basit haliyle siyah/beyaz görüntüden sayı tanıma probleminde
kullandık, ve diyelim yüzde 70 başarı elde ettik. Şimdi çok basit bir yeni özellik
yaratalım, görüntüyü dikey ikiye bölelim, ve üstteki ve alttaki siyah noktaları
toplayarak iki yeni kolon olarak görüntü matrisine ekleyelim. Bu yeni özellikleri
kullanınca basit sınıflayıcının yüzde 20 kadar tanıma başarısında ilerleme kay-
dettiğini göreceğiz!
Not: Derin yapay sınır ağları teknikleri ile özellik işlemeye artık gerek olmadığı
söylenir, bu büyük ölçüde doğru. Bir DYSA farklı seviyelerdeki pek çok farklı
nöronları üzerinden aslında üstte tarif edilen türden yeni özellikleri otomatik
olarak yaratır, ögrenir. Fakat yine de yeni özellikleri elle yaratma tekniklerini
bilmek iyi.
Şimdi farklı yöntemlere bakalım.
Zaman Kolonlarını Zenginleştirmek
Zaman kolonları çoğu zaman saniyeye kadar kaydedilir, bu bilgiyi alıp mesela
ay, mevsim, haftanın günü, saat, iş saati mi (9-5 arası), akşam mı, sabah mı, öğlen
mi, vs. gibi ek bilgiler çıkartılabilir. Tüm kolonlar veri madenciliği algoritmasına
verilir, ve algoritma belki öğlen saati ile sipariş verilmiş olması arasında genel bir
bağlantı bulacaktır.
Python + Pandas ile bir zaman kolonu şöyle parçalanabilir, örnek veri üzerinde
görelim, sadece iki kolon var, müşteri no, ve sipariş zamanı,
import pandas as pd
from StringIO import StringIO
s = """customer_id;order_date
299;2012-07-20 19:44:55.661000+01:00
421;2012-02-17 21:54:15.013000+01:00
437;2012-02-20 22:18:12.021000+01:00
463;2012-02-20 23:46:21.587000+01:00
482;2012-05-21 09:50:02.739000+01:00
607;2012-02-21 11:57:12.462000+01:00
641;2012-02-21 13:40:28.088000+01:00
674;2012-08-21 14:53:15.851000+01:00
780;2012-02-23 10:31:05.571000+01:00
"""
df = pd.read_csv(StringIO(s),sep=';', parse_dates=True)
def f(x):
1
tmp = pd.to_datetime(x['order_date'])
tpl = tmp.timetuple(); yymm = int(tmp.strftime('%m%d'))
spring = int(yymm >= 321 and yymm < 621)
summer = int(yymm >= 621 and yymm < 921)
fall = int(yymm >= 921 and yymm < 1221)
winter = int( spring==0 and summer==0 and fall==0 )
warm_season = float(tpl.tm_mon >= 4 and tpl.tm_mon <= 9)
work_hours = float(tpl.tm_hour > 9 and tpl.tm_hour < 17)
morning = float(tpl.tm_hour >= 7 and tpl.tm_hour <= 11)
noon = float(tpl.tm_hour >= 12 and tpl.tm_hour <= 14)
afternoon = float(tpl.tm_hour >= 15 and tpl.tm_hour <= 19)
night = int (morning==0 and noon==0 and afternoon==0)
cols = ['ts_hour','ts_mon','ts_wday','ts_warm_season',\
'ts_work_hours','ts_morning','ts_noon','ts_afternoon',\
'ts_night', 'ts_spring', 'ts_summer', 'ts_fall', 'ts_winter']
Sıcak mevsim (warm season) Mart-Eylül aylarını kapsar, bu ikisel bir değişken
hale getirildi. Belki siparişin, ya da diğer başka bir verinin bununla bir alakası
vardır. Genel 4 sezon tek başına yeterli değil midir? Olabilir, fakat bazı kalıplar /
örüntüler (patterns) belki sıcak / soğuk mevsim bilgisiyle daha çok bağlantılıdır.
Aynı şekilde saat 1-24 arasında bir sayı olarak var, fakat ”iş saatini” ayrı bir ikisel
değişken olarak kodlamak yine bir ”kalıp yakalama” şansımızı arttırabilir. Bu
kolonun ayrı bir şekilde kodlanmış olması veri tasarımı açısından ona önem ver-
2
ildiğini gösterir, ve madencilik algoritmaları bu kolonu, eğer ona bağlı bir kalıp
var ise, yakalayabilirler.
Not: Burada ufak bir pürüz sabah, öğlen, akşamüstü gibi zamanları kodlarken
çıktı. Gece 19’dan sonra ve 7’den önce bir sayı olacaktı, fakat bu durumda x > 19
ve x < 7 hiçbir sonuç getirmeyecekti. Burada saatlerin 24 sonrası başa dönmesi
durumu problem çıkartıyordu, tabii ki karşılaştırma ifadelerini çetrefilleştirerek
bu iş çözülebilir, ama o zaman kod temiz olmaz (mesela (x > 19 ve x < 24)
ya da (x > 0 ve x < 7) yapabilirdik). Temiz kod için gece haricinde diğer tüm
seçenekleri kontrol ediyoruz, ve gece ”sabah, öğlen, akşamüstü olmayan şey”
haline geliyor. Aynı durum mevsimler için de geçerli. Onun için
kullanıldı.
Kategorileri İkileştirme
Yapay öğrenim algoritmalarının çoğu zaman hem kategorik hem sayısal değerleri
aynı anda bulunduran verilerle iş yapması gerekebiliyor. Ayrıca literatüre bakılınca
görülür ki çoğunlukla bir algoritma ya biri, ya diğeri ile çalışır, ikisi ile aynı anda
çalışmaz (çalışanlar var tabii, mesela karar ağaçları -decision tree-). Bu gibi du-
rumlarda iki seçenek var, ya numerik veri kategoriselleştirilir (ayrıksallaştırılır),
ya da kategorik veri numerik hale getirilir.
Bu durumda, kategorik bir kolon eyalet için, eyaletin Ohio olup olmaması başlı
başına ayrı bir kolon olarak gösteriliyor. Aynı şekilde Nevada. Bu kodlamaya lit-
eratürde 1-hot kodlaması adı veriliyor. KMeans, lojistik regresyon gibi metotlara
girdi vermek için bu transformasyon kullanılabilir.
import numpy as np
import pandas as pd, os
import scipy.sparse as sps
from sklearn.feature_extraction import DictVectorizer
df = pd.DataFrame(data)
3
df2, _, _ = one_hot_dataframe(df, ['state'], replace=True)
print df2
Unutmayalım, kategorik değerler bazen binleri bulabilir (hatta sayfa tıklama tah-
mini durumunda mesela milyonlar, hatta milyarlar), bu da binlerce yeni kolon
demektir. Yani 1/0 kodlaması, yani 1-hot işleminden ele geçen yeni blok içinde
aslında oldukca çok sayıda sıfır değeri olacak (sonuçta her satırda binlerce ’şey’
içinde sadece bir tanesi 1 oluyor), yani bu bloğun bir seyrek matris olması iyi
olurdu. O zaman matrisin tamamını sps.csr_matrix ya da sps.lil_matrix ile
gerçekten seyrek formata çevirebiliriz, ve mesela scikit-learn paketi, numpy, scipy
işlemleri seyrek matrisler ile hesap yapabilme yeteneğine sahip. Seyrekselleştirince
ne elde ediyoruz? Sıfırları depolamadığımız için sadece sıfır olmayan değerler ile
işlem yapıyoruz, o ölçüde kod hızlanıyor, daha az yer tutuyor.
Dikkat etmek gerekir ki yeni kolonları üretince değerlerin yerleri sabitlenmiş
olur. Her satır bazında bazen state=Ohio, state=Nevada, bazen sadece state=Ohio
üretiyor olamayız. Üstteki örnekte her zaman 4 tane kolon elde edilmelidir.
Not: 1-hot yerine bir diğer seçenek kategoriyi bir indise çevirmek (tüm katego-
rileri sıralayıp kaçıncı olduğuna bakarak mesela) sonra bu sayıyı ikisel sistemde
belirtmek, eğer ’a’ sayısı 30 indisine tekabül ediyorsa, 30 ikisel sistemde 11110,
bu değer kullanılır (aslında bu son tarif edilen sistemin 1-hot sistemden daha iyi
işlediği rapor ediliyor).
Anahtarlama Numarası (1-Hot Encoding, Hashing Trick)
Fakat bir problem var, dokümanı temsil eden ve içinde 1 ya da 0 hücreli özellik
vektörünü (feature vector) oluşturmak için tüm kelimelerin ne olduğunu bilmeliyiz.
Yani veriyi bir kere baştan sonra tarayarak bir sözlük oluşturmalıyız (ki öyle yap-
maya mecbur kaldık) ve ancak ondan sonra her doküman için hangi kelimenin
olup olmadığını saptamaya ve onu kodlamaya başlayabiliriz. Halbuki belgelere
bakar bakmaz, teker teker giderken bile hemen bir özellik vektörü oluşturabilseydik
daha iyi olmaz mıydı?
Bunu başarmak için anahtarlama numarasını kullanmamız lazım. Bilindiği gibi
temel yazılım bilime göre bir kelimeyi temsil eden bir anahtar (hash) üretebiliriz,
ki bu hash değeri bir sayıdır. Bu sayının en fazla kaç olabileceğinden hareke-
tle (hatta bu sayıya bir limit koyarak) özellik vektörümüzün boyutunu önceden
saptamış oluruz. Sonra kelimeye bakarız, hash üretiriz, sonuç mesela 230 geldi,
o zaman özellik vektöründeki 230’uncu kolonun değerini 1 yaparız.
d_input = dict()
4
def add_word(word):
hashed_token = hash(word) % 127
d_input[hashed_token] = d_input.setdefault(hashed_token, 0) + 1
add_word("obama")
print d_input
{48: 1}
add_word("politics")
print d_input
{48: 1, 91: 1}
Üstteki kodda bunun örneğini görüyoruz. Hash sonrası mod uyguladık (yüzde
işareti ile) ve hash sonucunu en fazla 127 olacak şekilde sınırladık. Potansiyel
problemler ne olabilir? Hashing mükemmel değildir, çarpışma (collision) olması
mümkündür yani nadiren farklı kelimelerin aynı numaraya eşlenebilmesi du-
rumu. Bu problemleri iyi bir anahtarlama algoritması kullanarak, mod edilen
sayıyı büyük tutarak çözmek mümkündür, ya da bu tür nadir çarpışmalar ”kabul
edilir hata” olarak addedilebilir.
Pandas kullanarak bir Dataframe’i otomatik olarak anahtarlamak istersek,
import pandas as pd
data = {'state': ['Ohio', 'Ohio', 'Ohio', 'Nevada', 'Nevada'],
'year': [2000, 2001, 2002, 2001, 2002],
'pop': [1.5, 1.7, 3.6, 2.4, 2.9]}
data = pd.DataFrame(data)
print data
Şimdi bu veri üzerinde sadece eyalet (state) için bir anahtarlama numarası ya-
palım
def hash_col(df,col,N):
for i in range(N): df[col + '_' + str(i)] = 0.0
df[col + '_hash'] = df.apply(lambda x: hash(x[col]) % N,axis=1)
for i in range(N):
idx = df[df[col + '_hash'] == i].index
df.ix[idx,'%s_%d' % (col,i)] = 1.0
df = df.drop([col, col + '_hash'], axis=1)
return df
print hash_col(data,'state',4)
5
0 1.5 2000 0.0 0.0 0.0 0.0
1 1.7 2001 0.0 0.0 0.0 0.0
2 3.6 2002 0.0 0.0 0.0 0.0
3 2.4 2001 0.0 0.0 0.0 1.0
4 2.9 2002 0.0 0.0 0.0 1.0
import numpy as np
import pandas as pd, os
import scipy.sparse as sps
import itertools
res = sps.hstack(mats)
return res
df = pd.DataFrame(data)
print df
vocabs = []
vals = ['Ohio','Nevada']
vocabs.append(dict(itertools.izip(vals,range(len(vals)))))
vals = ['2000','2001','2002']
vocabs.append(dict(itertools.izip(vals,range(len(vals)))))
print vocabs
6
[ 1.7 1. 0. 0. 1. 0. ]
[ 3.6 1. 0. 0. 0. 1. ]
[ 2.4 0. 1. 0. 1. 0. ]
[ 2.9 0. 1. 0. 0. 1. ]]
one_hot_column çağrısına bir ”sözlükler listesi” verdik, sözlük her kolon için o
kolonlardaki mümkün tüm değerleri bir sıra sayısı ile eşliyor. Sözlük listesinin
sırası kolon sırasına uyuyor olmalı.
Niye sözlük verdik? Bunun sebebi eğer azar azar (incremental) ortamda iş yapıyorsak,
ki Büyük Veri (Big Data) ortamında her zaman azar azar yapay öğrenim yap-
maya mecburuz, o zaman bir kategorik kolonun mevcut tüm değerlerine azar
azar ulaşamazdık (verinin başında isek, en sonundaki bir kategorik değeri nasıl
görelim ki?). Fakat önceden bu listeyi başka yollarla elde etmişsek, o zaman her
öne-hot işlemine onu parametre olarak geçiyoruz.
Sözlük niye one_hot_dataframe çağrısı dışında yaratıldı? Bu çağrı düz bir liste
alıp oradaki değerleri sırayla bir sayıyla eşleyerek her seferinde bir sözlük yarata-
bilirdi. Bunu yapmadık, çünkü sözlük yaratımının sadece bir kere, one_hot_dataframe
dışında olmasını istiyoruz. Yine Büyük Veri ortamını düşünenelim, eşleme (map)
için mesela bir script yazdık, bu script içinde (basında) hemen sözlükler yaratılırdı.
Daha sonra verinin tamamı için, azar azar sürekli one_hot_dataframe çağrısı yapılacaktır.
O zaman arka arkaya sürekli aynı veriyi (sözlükleri) sıfırdan tekrar yaratmamız
gerekirdi. Bu gereksiz performans kaybı demek olacaktı. Unutmayalım, Büyük
Veri ortamında tek bir kategorik kolonun milyonlarca değişik değeri olabilir!
Azar Azar İşlemek (Incremental, Minibatch Processing)
Çoğu zaman onlarca kategori, birkaç milyonluk satır içeren bir veriye bakmamız
gerekiyor; biliyoruz ki bu kadar veri için Büyük Veri teknolojilerine (mesela Spark,
Hadoop gibi) geçmek gereğinden fazla külfet getirecek, elimizdeki dizüstü, masaüstü
bilgisayarı bu işlemler için yeterli olmalı, fakat çoğu kütüphane tek makinada
azar azar işlem yapmak için yazılmamış. Mesela üstte görülen anahtarlama yöntemi
anahtarlama başlamadan önce tüm verinin hafızaya alınmasını gerektiriyor.
Bu durumda kendimiz çok basit Python kavramlarını, iyi bir anahtarlama ko-
dunu, ve lineer cebir hesaplarında seyreklik (sparsity) tekniklerini kullanarak
ufak veri parçaları işleyen bir ortamı yaratabiliriz.
Örnek veri olarak [4] yazısında görülen oy kalıpları verisini biraz değiştirerek
yeni bir analiz için kullanalım. Veri oy verenlerin ırk, cinsiyet, meslek, hangi
partiye oy verdikleri ve kazançlarını kaydetmiş, biz analizimizde bahsedilen kat-
egorilerin bu kişilerin kazancıyla bağlantılı olup olmadığına bakacağız. Veriyi
oluşturalım,
import pandas as pd
df = pd.read_csv('../stat_logit/nes.dat',sep=r'\s+')
df = df[['presvote','year','gender','income','race','occup1']]
df = df.dropna()
df.to_csv('nes2.csv',index=None)
7
Önce kategorilerden ne kadar var, sayalım. Basit toplam yani,
import pandas as pd
df = pd.read_csv('nes2.csv')
print u'tüm veri', len(df)
print 'cinsiyet', np.array(df['gender'].value_counts())
print u'ırk', np.array(df['race'].value_counts())
print 'parti', np.array(df['presvote'].value_counts())
print u'kazanç', df['income'].mean()
Mesela son sonuçtaki her hücre belli bir partiye verilen oyların sayısı; veriye göre
üç farklı kategori varmış demek ki, veri ABD için olduğuna göre bunlardan ilk
ikisi bilinen iki büyük parti, üçüncü hücre de herhalde bağımsız adaylar.
Kazanç 1 ile 5 arasında tam sayılar (1 az, 5 çok) bu sayıları kategorik olarak kabul
edip aslında çok çıktılı bir sınıflayıcı eğitmeyi de seçebilirdik, fakat bu örnek
için bu sayıları reel hedef olarak aldık: test verisinde tahminleri bakılırsa 2.5’lük
kazanç tahminleri görülebilir, bu yüzden.
Kategorik verileri ikileştirmeye gelelim. Burada üç nokta önemli, veriyi azar azar
işleyeceğiz demiştik, ve veriyi seyrek matris olarak almak istiyoruz, ve hangi kat-
egorik değerin hangi kolona eşleneceğini elle tanımlamak istemiyoruz (eşleme
otomatik olmalı). Seyreklik önemli çünkü eğer 1000 farklı kategorik değere sahip
olan 10 tane kolon varsa, bu 10000 tane yeni kolon yaratılması demektir - her
farklı kategori için o değere tekabül eden kolon 1 olacak gerisi 0 olacak. Bu
rakamlar orta ölçekte bile rahatlıkla milyonlara ulaşabilir. Eğer ikileştirme için
seyrek matris kullanırsak çoğu sıfır olan değerler hafızada bile tutulmaz. Eşleme
otomatik olmalı, zaten onun için anahtarlama yapacağız.
Anahtarlama icin sklearn.feature_extraction.text.HashingVectorizer var,
(0, 5) 1.0
(1, 19) 1.0
(2, 18) -1.0
Sonuçlar seyrek matris olarak, ve üç değer için üç ayrı satır olarak geldi. Anahtar-
lama niye bazen -1 bazen +1 veriyor? Aslında bu bizim için çok faydalı, çünkü
birazdan PCA işleteceğiz, ve PCA her veri kolonunun sıfırda ortalanmış olmasını
ister. Üstteki teknikte anahtar üreten fonksiyon -1,+1 arasında rasgele seçim yapıyor
8
gibi duruyor, bize göre bu üretilen anahtar kolonlarında -1, +1 değerlerinin doğal
olarak dengelenmesi için yapılmış, böylece otomatik olarak ortalamaları sıfıra in-
ecektir. Akıllıca bir teknik.
Devam edelim, sonucu tek satır olacak şekilde kendimiz tekrar düzenleyebiliriz.
O zaman Python yield kavramını [3] kullanarak (azar azar satır okumak için),
anahtarlama, ve seyrek matrisler ile şu şekilde bir kod olabilir,
HASH = 30
vect = HashingVectorizer(decode_error='ignore',n_features=HASH)
def get_row(cols):
with open("nes2.csv", 'r') as csvfile:
rd = csv.reader(csvfile)
headers = {k: v for v, k in enumerate(next(rd))}
for row in rd:
label = float(row[headers['income']])
rrow = [x + str(row[headers[x]]) for x in headers if x in cols]
X_train = vect.transform(rrow)
yield X_train.tocoo(), label
def get_minibatch(row_getter,size=10):
X_train = sps.lil_matrix((size,HASH))
y_train = []
for i in range(size):
cx,y = row_getter.next()
for dummy,j,val in zip(cx.row, cx.col, cx.data): X_train[i,j] = val
y_train.append(y)
return X_train, y_train
[4.0] [[ 0. 0. 0. -1. 0. 0. 0. 0. 0. 0. 0. 0. 1. 0. 0. 0. 0. 0.
0. 0. 0. 0. 0. 0. 0. 1. 0. 0. 1. 0.]]
X,y = get_minibatch(row_getter,size=10)
print len(y), X.shape, type(X)
9
PCA
Lineer Cebir’in temel bileşen analizi (PCA) tekniğini kullanarak boyut azaltması
yapabiliriz. Veriyi yine satır satır işleyerek PCA hesabı yapan teknikler var, kod
veriyi seyrek formatta da alabiliyor. Bu kod lineer cebir PCA yazısında işlendi.
varyans orani
[ 0.36086926 0.16186391 0.13377998 0.09440711 0.0702763 0.05113956
0.04768294 0.0343724 0.02336052 0.02224802]
y_predict = []
y_real = []
for i in range(1000):
X_test,y_test = get_minibatch(row_getter,1)
Xp = np.dot((X_test-pca.mean_),P)
y_predict.append(clf.predict(Xp)[0])
y_real.append(y_test[0])
y_predict = np.array(y_predict)
y_real = np.array(y_real)
10
ortalama tahmin hatasi 0.0105872845541
maksimum deger 5.0
1 ile 5 arasında gidip gelen değerlerin tahmininde 0.01 civarı ortalama hata var.
Fena değil. Peki verinin kendisini olduğu gibi alıp regresyonda kullansaydık?
Hedef verisi kazanç, kaynak kolonları geri kalan kategoriler. Üstte olduğu gibi
veri parçaları 1000’er satır, 10 parça olarak alacağız, yani 10,000 satır modeli
eğitmek için kullanılacak. Geri kalanlar test verisi olacak.
sklearn.linear_model.SGDRegressor ufak seyrek matris parçaları ile eğitilebiliyor,
for i in range(10):
X_train, y_train = get_minibatch(row_getter,1000)
clf.partial_fit(X_train, y_train)
X_test,y_test = get_minibatch(row_getter,1000)
y_predict = clf.predict(X_test)
Bu sonuç ta hiç fena değil. Sonuç olarak veri içinde bazı kalıplar olduğunu
gördük, tahmin yapabiliyoruz. Hangi kolonların daha önemli olduğunu bulmak
için her kolonu teker teker atıp hatanın yukarı mı aşağı mı indiğine bakabilirdik.
Tekrar vurgulamak gerekirse: üstteki analizde aslında çok fazla kategorik veri
yok, yani statsmodels.formula.api üzerinden güzel formüllerle, regresyon çıktısında
her kategorik değerin güzelce listelendiği türden bir kullanıma da gidebilirdik.
Bu yazıda göstermeye çalıştığımız çok fazla veri, çok fazla kolon / kategori olduğunda
ve tek makina ortamında takip edilebilecek çözümler.
Zaman Karşılaştırmak
Eğer 23:50 ile sabah 00:10 zamanını karşılaştırmak istersek ne yaparız? Eğer saat
ve dakika farkını direk hesaplasak bu iki zamanın çok uzak olduğunu düşünebilirdik.
Fakat aslında aralarında 20 dakika var, zaman dönüp başa gelen bir kavram.
11
Bu hesabı yapmak için bir yöntem çember, açılar kullanmak. Gün içindeki za-
manı 0 ile 1 arasında kodlarız, sonra bu büyüklüğü 2π ile çarparız, bu bize çember
üzerindeki bir noktayı verir, yani zamanı açıya çevirmiş oluruz. Sonra açının sin,
cos değerini hesaplayıp iki rakam elde ederiz, bu iki sayı bize gün içindeki za-
manı temsil eden bir büyüklük verir.
Bu büyüklükleri birbirleri ile karşılaştırmak daha kolay, üstteki şekilde θ2 ve θ3
birbirine yakın, karşılaştırma yaparken sin bize dikey eksendeki izdüşümü, cos
yatay eksendeki izdüşümünü verir, θ2 , θ3 için y eksenindeki yansıma birbirine
çok yakın. Eksen x üzerindeki yansıma farklı biri eksi biri artı yönde fakat yine
de mutlak değer bağlamında birbirlerine çok yakınlar. İstediğimiz de bu zaten.
t1 = 0.12 * 2*np.pi
t2 = 0.97 * 2*np.pi
t3 = 0.03 * 2*np.pi
d1 = (np.cos(t1), np.sin(t1))
d2 = (np.cos(t2), np.sin(t2))
d3 = (np.cos(t3), np.sin(t3))
0.728969 0.684547
0.982287 -0.187381
0.982287 0.187381
uzaklık 1-2 = 0.907980999479
12
uzaklık 2-3 = 0.374762629171
Kaynaklar
[1] Teetor, R Cookbook
[2] Scikit-Learn Documentation, 4.2. Feature extraction, http://scikit-learn.
org/dev/modules/feature_extraction.html
[3] Bayramli, Fonksiyon Gezmek ve Yield, https://burakbayramli.github.
io/dersblog/sk/2011/02/fonksiyon-gezmek-ve-yield.html
[4] Bayramli, Istatistik, Lineer Regresyon
13
İlişkisel Madencilik (Association Mining)
İkisel Matris Ayrıştırması (Binary Matrix Factorization)
Veri madenciliği denince pek çok kişinin aklına gelen ilk örnek, aslında, sık bulu-
nan öğe kümeleri (frequent itemsets) örneğidir: ”filanca ülkeden sitemize gelen
müşterilerin aynı zamanda vs özelliklerinin olduğunu da keşfettik” gibi.
Benzer bir örnek, ki bu alan öğe kümelerinin aslında en önemli çıkış sebeplerinden
birisidir, alışveriş sepeti analizidir. Müşterinin her alışverişinde sepetinde belli
mallar vardır, ve bu malların hangilerinin aynı anda, aynı sepette olduğu analiz
edilmeye uğraşılır. Eğer sürekli ekmek ve reçel aynı anda alınıyorsa, bu bilgi kul-
lanılarak belki malların daha iyi konumlandırılması yapılacaktır, vs. Sık bulunan
öğe kümeleri teknikleri bazen değişik adlar altında da geçebiliyor, mesela ilişki
madenciliği (association mining) gibi. Algoritma olarak kullanılan pek çok teknik
var, APriori iyi bilinenlerden, FPGrowth ondan daha hızlı çalışan ve daha tercih
edilen bir teknik. İstatistiki bir teknik olan Çok Boyutlu Bernoulli Karışımları da
bu alanda kullanılan bir yaklaşım.
Bir diğer alternatif ikisel matris ayrıştırması (binary matrix factorızation -BMF-)
kullanmaktır [3]. Aynen SVD’de olduğu gibi BMF de bir matrisi ayrıştırır, fakat
üç matris yerine iki matrise ayrıştırır ve hem sonuç matrisi hem de ayrıştırılan
matrisler sadece 0 ya da 1 değerini taşıyabilirler. Yani bu ayrıştırma sonuç ma-
trislerinin ikisel olmasını mecbur tutar, negatif olmayan matris ayrıştırmasının
(non-negative matrix factorızation) sonuç matrisinin pozitif değerler taşımasını
mecbur kılması gibi. Bunlar birer kısıtlama (constraint) ve bu sonuç o kısıtlamalara
göre ortaya çıkıyor. Dikkat: BMF için toplama işlemi 1 + 0 = 1, 1 + 1 = 1, 0 + 0 = 0
olarak tekrar tanımlanır, yani mantıksal OR işlemi haline gelir.
Ayrıştırma öncesi hangi kerte (rank) k değerine geçmek istediğimizi biz belirti-
riz. BMF’nin öğe kümeleri madenciliği için faydası şurada: öğe kümeleri ararken
baktığımız öğeler kategorik şeylerdir, alışveriş sepeti örneğinde mesela ekmek,
reçel gibi. Kategorik öğeleri daha önce 1-hot kodlaması (encoding) ile 1/0 değerleri
taşıyan yeni kolonlara geçirebildiğimizi görmüştük. Yani tamamen kategorik
değerler taşıyan veriler tamamen 1/0 taşıyacak şekilde tekrar kodlanabilir, yani
ikisel matris haline getirilebilir. Bu ikisel matrisi ayrıştırdığımız zaman ve kendi-
leri de ikisel olan iki yeni matris elde ettiğimizde ise bir anlamda boyut indirgemesi
yapmış oluruz, yani sanki ana matrisi “özetleriz”. İşte bu özet, özellikle çarpılan
“baz” matris, öğe kümelerinin hangileri olduğu hakkında ipuçları içeriyor ola-
bilir.
Bir örnek üzerinde görelim, mesela altta Alice (A), Bob Marley (B) ve Prens Charles
(C) verileri var. Bu kişiler için saçı uzun mu (long-haired), ünlü mü (well-known)
ve bay mı (male) verileri var.
1
Bu matris üzerinde ikisel ayrıştırma yaparsak, k = 2
Eğer kontrol etmek istersek, matris çarpımı yapmamız gerekir, bunun için
a = np.array([[1, 0],
[1, 1],
[0, 1]], dtype=bool)
b = np.array([[1, 1, 0],
[0, 1, 1]], dtype=bool)
print np.dot(a,b)
print 1*np.dot(a,b)
[[1 1 0]
[1 1 1]
[0 1 1]]
Sonuç başlangıç matrisi ile aynı, demek ki bool tipi matris tanımlayınca Numpy
çarpımı dot, çarpım sırasındaki toplama işlemi için aritmetik toplama yerine VEYA
(OR) kullanması gerektiğini anladı.
Şimdi ayrıştırmayı analiz edelim, özellikle sol taraftaki çarpılan “baz” matrise
bakalım.. [6] yazısından hareketle, bu yazıdaki kolon kombinasyon bakışını kul-
lanalım (tabii toplamanın BMF için OR olduğunu unutmadan), o zaman soldaki
baz matrisin dikey, kolon bazlı olarak, bir özet olduğunu görebiliyoruz. Çünkü
çarpan sağ taraf bu kolonları alıp onları belli şekillerde “kombine ederek” nihai
(orijinal) matrisi ortaya çıkartabilmeli. Bu sebeple soldaki çarpılan matris bir özet
olmalı / baz oluşturmalı, ve bunun yan etkisi olarak kolonlardaki değerlerde belli
2
bir kalıp / örüntü (pattern) olmalı. O zaman her baz kolonunda birbiriyle alakalı
olan ögeler aynı anda 1 değeri taşıyor olacaktır.
Sonuca göre uzun saçlı ve ünlü olmak (1. kolon) arasında bağlantı varmış , ayrıca
erkek olmak ve ünlü olmak (2. kolon) arasında da bağlantı varmış :) Veriye göre
böyle en azından.. Bu sonucu orijinal matrise bakarak ta kontrol edebiliriz.
Ayrıştırma Kodlaması
BMF özel bir hesaptır ve Numpy / Scipy içinde mevcut değildir, ayrı bir kütüphane
kullanmak gereklidir, nimfa paketi içinde gerekli kodlar var. Kurduktan sonra
üstteki örneği şöyle çözebiliriz;
import nimfa
import pandas as pd
import scipy.sparse as sp
def __fact_factor(X):
return X.todense() if sp.isspmatrix(X) else X
fctr = nimfa.mf(A,
seed = "nndsvd",
rank = 2,
method = "bmf",
max_iter = 40,
initialize_only = True,
lambda_w = 1.1,
lambda_h = 1.1)
res = nimfa.mf_run(fctr)
threshold = 0.2
res1 = __fact_factor(res.basis())
res2 = __fact_factor(res.coef())
res1 = np.abs(np.round(res1 - 0.5 + threshold))
res2 = np.abs(np.round(res2 - 0.5 + threshold))
res1 = pd.DataFrame(res1, index=['long-haired','well-known','male'])
res2 = pd.DataFrame(res2, columns=['A','B','C'])
print res1
print '\n'
print res2
0 1
long-haired 1 0
well-known 1 1
male 0 1
A B C
0 1 0 0
1 0 1 1
3
Sonuç neredeyse tıpatıp aynı; sadece çarpan matriste [0,B] kordinatı 1 değil, fakat
bize lazım olan baz matris aynı çıktı.
BMF hakkında bazı ek bilgiler: [2]’ye göre en az hatalı BMF hesaplamak NP-hard
zorluğunda, yani 3SAT gibi, ya da Seyahat Eden Satış Elemanı (Traveling Sales-
man) problemi gibi ki bu problemler kombinatoryel (combinatorial) optimiza-
syon problemleridir; çözüm için tüm olasılıklar denendiği ve kısayolun mevcut
olmadığı çeşitten problemler. Fakat yaklaşıksal BMF metotları oldukça hızlıdır,
ayrıca seyreklik çok fark yaratıyor (pozitif anlamda) ki kategorik veriler gerçek
dünyada çoğunlukla seyrek olarak görülüyor. Eldeki 2000 tane mal çeşidi içinden
bir sepette ancak 5-10 tane ürün oluyor mesela, tüm 2000 tane malı bir sepete koy-
mak mümkün değil.
FPGrowth
Öğe kümeleri bulmak için BMF haricinde bir yöntem FPGrowth yöntemidir [1,2].
Bu yöntem önce her ögeden (tek başına) kaç tane olduğunu sayar, belli bir eşik
değeri minsup altında olanları atar, sonucu sıralar. Bu liste bir yapısına işaret
eden bir başlık yapısı haline gelir. Ağacın kendisini oluşturmak için veri satırları
teker teker işlenir, her satırdaki her öge için başlık yapısındaki en fazla değeri
taşıyan öğe önce olmak üzere tepeden başlanıp alta doğru uzayan bir ağaç yapısı
oluşturulur. Ağaçtaki her düğüm altındaki düğümün sayısal toplamını taşır.
Madencilik için alttan başlanarak yukarı doğru çıkılır (amaç en üste ulaşmak) ve
bu sırada öğeler minsup altında ise, atılırlar. Sonuçta ulaşılan ve atılmayan yollar
bir öğe kümesini temsil ederler.
Örnek verisi olarak alttakini kullanalım,
data = [
['outlook=sunny', 'temparature=hot', 'humidity=high', 'windy=false', 'play=no'],
['outlook=sunny', 'temparature=hot', 'humidity=high', 'windy=true', 'play=no'],
['outlook=overcast', 'temparature=hot', 'humidity=high', 'windy=false', 'play=yes'],
['outlook=rainy', 'temparature=mild', 'humidity=high', 'windy=false', 'play=yes'],
['outlook=rainy', 'temparature=cool', 'humidity=normal', 'windy=false', 'play=yes'],
['outlook=rainy', 'temparature=cool', 'humidity=normal', 'windy=true', 'play=no'],
['outlook=overcast', 'temparature=cool', 'humidity=normal', 'windy=true', 'play=yes'],
['outlook=sunny', 'temparature=mild', 'humidity=high', 'windy=false', 'play=no'],
['outlook=sunny', 'temparature=cool', 'humidity=normal', 'windy=false', 'play=yes'],
['outlook=rainy', 'temparature=mild', 'humidity=normal', 'windy=false', 'play=yes'],
['outlook=sunny', 'temparature=mild', 'humidity=normal', 'windy=true', 'play=yes'],
['outlook=overcast', 'temparature=mild', 'humidity=high', 'windy=true', 'play=yes'],
['outlook=overcast', 'temparature=hot', 'humidity=normal', 'windy=false', 'play=yes'],
['outlook=rainy', 'temparature=mild', 'humidity=high', 'windy=true', 'play=no']
]
Hava ile alakalı bazı veriler [1] bunlar; bu veriler tahmin (outlook), sıcaklık (tem-
parature), nem (humidity), rüzgar (windy), dışarıda oyun oynayan var mı (play).
Mesela ilk satırda tahmin güneşli, ısı sıcak, nem yüksek, rüzgar yok ve oyun
oynayan yok. Bu şekilde bir sürü satır. Biz bu veride bir kalıp olup olmadığına
bakacağız. [2]’deki kodu [1]’den aldığımız üstteki veriye uygularsak, sonuç şöyle:
4
import fp
items = fp.fpgrowth(data, minsup=6)
for x in items:
if len(x) > 1: print x
Bulunan sonuçlar iki tane (tek öğeli sonuçlar da var ama onları eledik). Bunlar
hakikaten veri içindeki kalıpları temsil ediyorlar. Fena değil.
Kıyas için BMF üzerinden madencilik yapalım. Önce 1-hot kodlaması yapalım,
ve örnek için bir veri satırını ekrana basalım,
5
cols = ['outlook','temparature','humidity','windy','play']
df = pd.DataFrame(data,columns=cols)
# kolon ismini veriden cikart, cunku tekrar geri koyulacak
# fpgrowth icin veri icinde olmasi lazim
df = df.applymap(lambda x: re.sub('.*?=','',x))
df2, _, _ = one_hot_dataframe(df, cols, replace=True)
# tek ornek ekrana bas
print df2.ix[0]
humidity=high 1
humidity=normal 0
outlook=overcast 0
outlook=rainy 0
outlook=sunny 1
play=no 1
play=yes 0
temparature=cool 0
temparature=hot 1
temparature=mild 0
windy=false 1
windy=true 0
Name: 0, dtype: float64
import nimfa
import scipy.sparse as sp
def __fact_factor(X):
return X.todense() if sp.isspmatrix(X) else X
res = nimfa.mf_run(fctr)
threshold = 0.2
res1 = __fact_factor(res.basis())
res2 = __fact_factor(res.coef())
res1 = np.abs(np.round(res1 - 0.5 + threshold))
res2= np.abs(np.round(res2 - 0.5 + threshold))
res1 = pd.DataFrame(res1,index=df2.columns)
print res1
0 1 2 3
humidity=high 1 0 0 1
humidity=normal 0 1 0 0
outlook=overcast 0 0 1 0
outlook=rainy 1 0 0 0
outlook=sunny 0 0 0 1
play=no 0 0 0 1
play=yes 0 1 1 0
temparature=cool 0 0 0 0
temparature=hot 0 0 0 0
6
temparature=mild 1 0 0 0
windy=false 0 0 1 0
windy=true 1 0 0 0
for i in range(4):
print np.array(df2.columns)[res1.ix[:,i] == 1]
['humidity=high' 'outlook=rainy' 'temparature=mild' 'windy=true']
['humidity=normal' 'play=yes']
['outlook=overcast' 'play=yes' 'windy=false']
['humidity=high' 'outlook=sunny' 'play=no']
1. sonuç atlanabilir, buradaki “kalabalık” orada bir kalıp olmadığına dair bir
işaret. Ayrıştırma sonucu bu tür kolonlar ortaya çıkabilir, diğer kolonlardaki
kalıplar bütünü temsil etmeye tam yetmemişse, arta kalan her türlü gereklilik
bir yerlere tıkılabiliyor, bu normal. 2. sonuç FPGrowth sonucunda var, güzel. 3.
sonuç ta neredeyse aynı, sadece ek olarak outlook=overcast var. Fakat, 3. sonuç
aslında önemli bir kalıp içeriyor olabilir, yani kalması daha iyi olur.
4. sonuç ise çok önemli bir kalıp ve FPGrowth bunu tamamen kaçırmış!
Sebep FPGrowth’un çözüme lokal olarak erişmeye çalışıyor olması, kıyasla BMF
bütüne (global) bakıyor [3]. Bu ne demektir? Bir ayrıştırmanın ne olduğunu
düşünürsek, bir matrisi oluşturan çarpımı ayrıştırıyoruz ve bu ayrıştırma olduk-
tan sonra iki matris elde ediyoruz. Bu iki matris özgündür (unique). Yani belli bir
ikisel matrisi oluşturan çarpım sadece tek bir şekilde olabilir. Buradan hareketle
diyebiliriz ki bu ayrıştırma bütünü göze alarak yapılmalıdır, sağı, solu tutan ama
köşesi tutmayan bir ayrıştırma olmaz. Bu sebeptendir ki ayrıştırma çözümünden
belli bir kapsayıcılık bekleyebiliriz.
FPGrowth ise olaya yerel bakıyor; ağaç oluştururken değişik bir sıra takip edilirse
mesela değişik ağaçlar ortaya çıkabilir. Ayrıca her önemli ilişki muhakkak özgün
bir dal yapısında olmayabilir. Madencilik algoritması alt dallardan başlar ve
yukarıya doğru çıkar, fakat bu her zaman iyi bir yöntem midir?
Kodlama Notları
Şu kod np.round(num - 0.5 + threshold) kullanımı yuvarlama (rounding) yapıyor,
çünkü Nimfa 1 değeri yerine 0.9, 0.8 gibi değerler üretebiliyor, ayrıca 0.1 gibi
değerler de oluyor. Biz bildiğimiz yuvarlama .5 sonrası üzerini 1 yapmak yerine
belli bir eşik değeri (threshold) üzerinden yuvarlama yaptık. Yani eşik=0.2 ise 0.7
alta yuvarlanır ve 0 olur, 0.9 eşik üstünde olduğu için üste yuvarlanır 1 olur.
BMF için kerte k kullanıcı tarafından seçilmeli, ama bu durum SVD, ya da GMM
ile kümeleme gibi diğer yapay öğrenim metotlarından farklı değildir. Bu oynan-
ması gereken, keşfedilmesi gereken bir değer.
Çok Değişkenli Bernoulli Karışımı Kümelemesi ile İlişkisel Madencilik
Bir diger yaklasim kümeleme üzerinden kural çıkartmak. Örnek veri olarak [7]
yazısındanki Movielens 1M verisini kullanacağız. Ayrıca bu verideki posta kodu
7
(zip) ve meslek (occupation) verisine README’ye ve bir Internet sitesine [4]
danışarak sözel açıklamalarını koyduk. Böylece sonuçları yorumlamak çok daha
kolay olacak.
İlişkilerin keşfi için çok değişkenli Bernoulli modelini kullanacağız, ki [8] yazısında
bu kümeleme yöntemi işlendi. CDBK kullanmak için veriyi 0/1 bazına indirgeyeceğiz
(ki verinin büyük bir kısmı zaten bu durumda) ardından CDBK’yı veriye uydu-
racağız, ve karışım öğeleri θk ’lerin bir nevi “şablon” oluşturması sebebiyle ilişki
keşfini bu şablonlar üzerinden yapmaya uğraşacağız.
occup_map = \
{ 0: "other" or not specified,1: "academic/educator",
2: "artist",3: "clerical/admin",
4: "college/grad student",5: "customer service",
6: "doctor/health care",7: "executive/managerial",
8: "farmer",9: "homemaker",
10: "K-12 student", 11: "lawyer",
12: "programmer",13: "retired",
14: "sales/marketing",15: "scientist",
16: "self-employed",17: "technician/engineer",
18: "tradesman/craftsman",19: "unemployed",
20: "writer"}
zip_map = \
{ 0: 'Northeast', 1: 'NY Area', 2: 'DC', 3: 'Florida', 4: 'Michigan/Ohio',
5: 'North', 6: 'Illinois', 7: 'Texas / Arkansas', 8: 'Nevada / Utah',
9: 'California / Alaska'}
df = users.copy()
df['occupation'] = df.apply(lambda x: occup_map[x['occupation']], axis=1)
8
df['zip2'] = users['zip'].map(lambda x: int(str(x)[0]))
df['zip2'] = df.apply(lambda x: zip_map[x['zip2']], axis=1)
df['age2'] = pd.qcut(df['age'],5)
df = one_hot_dataframe(df,['occupation','gender','zip2','age2'])
df = df.drop(['zip','age'],axis=1)
df = df.set_index('user_id')
Şimdi hangi film genre’sinin (türünün) kullanıcı tarafından kaç kez alınmış olduğunu
özetleyip kullanıcı verisine bitişik olarak ekleyeceğiz.
(6040, 56)
En iyi küme sayısı nedir? Bunun için mümkün tüm küme sayılarını deneriz, AIC
sonuçlarına bakarız, sonuçlar arasından düşüş ardından ilk çıkış olduğu anı en
iyi küme sayısı olarak kullanırız.
5,173126.633281
9
6,172007.606772
7,170285.383519
8,169043.301004
9,168457.12051
10,167463.532805
11,167253.486012
12,166290.598818
13,165764.506989
14,164964.964083
15,164989.85056
16,164321.25051
def print_rule(j):
for i,r in enumerate(rules[j]):
if r > 0.5: print X.columns[i], r
print_rule(0)
25 ila 35 yaş arasındaki erkekler komedi ve aksiyon çok seviyorlar, en çok beğendiklerinin
arasında en alt sırada Western var. İlginç.
print_rule(1)
10
gender=M 1.0
Genre_Action 0.999999916342
Genre_Adventure 0.968035357641
Genre_Animation 0.618607301467
Genre_Children's 0.733114850427
Genre_Comedy 1.0
Genre_Crime 0.895303009556
Genre_Drama 1.0
Genre_Fantasy 0.621607330213
Genre_Horror 0.826409070694
Genre_Mystery 0.667105230382
Genre_Romance 0.962487486107
Genre_Sci-Fi 0.981703990034
Genre_Thriller 0.999998477836
Genre_War 0.884260074733
Daha dar bir yaş aralığı 18-25 yaş grubu, komedi, dram, aksiyon, gerilim var, en
az sevilen filmler bu sefer animasyon.
print_rule(2)
gender=F 1.0
Genre_Action 1.0
Genre_Adventure 0.997753376918
Genre_Animation 0.925605697933
Genre_Children's 0.989223061984
Genre_Comedy 0.999411653044
Genre_Crime 0.978893423529
Genre_Drama 1.0
Genre_Fantasy 0.890898944372
Genre_Film-Noir 0.810452619282
Genre_Horror 0.901607018088
Genre_Musical 0.93690169152
Genre_Mystery 0.949990841295
Genre_Romance 1.0
Genre_Sci-Fi 0.999467975234
Genre_Thriller 0.997148167548
Genre_War 0.987837234705
Genre_Western 0.801075654907
Bayanlar için (yaş grubu yok dikkat), üstte aksiyon var, ama romantik filmler de
en üstte.
Şu da ilginç bir bulgu; meslek kolları ve adres verilerini analize dahil etmiş ol-
mamıza rağmen kümelerin şablonu içinde hiçbiri yok! Demek ki meslekler, adresler
film beğenisinde fark yaratmıyor.
Üstteki analiz müşteri bilgisine müşteri seviyesinde baktı. Eğer işlemsel (trans-
actional) bir analiz yapıyor olsaydık, yaklaşım benzer olacaktı, sadece veri odağı
biraz farklı olurdu; müşterilerin her alışveriş sepetlerine bakılacaktı mesela, bir
sepete koyulan mesela ekmek, çikolata, su, bir diğerine koyulan ekmek, su, biberon
gibi alımlar bir satırda 1 ile işaretli, diğerleri 0 ile işaretli olacaktı, ve kümeleme
algoritması bu çok boyutlu Bernoulli veriye bir uyum yapıp şablonları raporlay-
acaktı.
11
İlginçlik - İstatistiki Ölçüt
Kümeleri uydurduktan sonra bile bu kümelerin içinde hangisinin “daha iyi” olduğunu
bulmak için istatistiki ölçüt kullanmak faydalı olabilir. Hatta birazdan bahsedeceğimiz
teknik aslında her türlü ilişki madenciliği yaklaşımı için faydalı, çünkü hangi
teknik olursa olsun bize verinin belli bir grubunu “önemli” olarak gösterecek.
Ardından biz bu grubu alıp onun ne kadar önemli olduğunun ölçütünü hesaplaya-
bileceğiz.
Teknik şöyle: İstatistiki testlerden [9] yazı bölümünü hatırlarsak, bir ideal dağılım
vardı, ve eldeki verinin bu ideale olan yakınlığını ölçüyorduk. Chi Kare testi
ayrıksal bazda işliyordu, eğer eldeki sürekli fonksiyon bazlı bir dağılım ise onun
ideal hesaplarını kutucuklara bölüştürüyorduk.
İlişkisel madencilikte elde ettiğimiz kural bir vektör içinde 0/1 değerleri olacak.
Yaklaşım şöyle; önce verideki her kolonun tek başına oranını buluruz. Bu oran-
lar her kolon “dağılımının” birbirinden bağımsız farz edildiği “idealize” ortamın
ölçütleri olacaklar. Veri mesela şöyle,
data = [[1,1,0,0,1],
[1,0,0,0,0],
[1,0,0,1,1],
[1,1,0,1,1],
[1,1,1,0,1],
[0,0,1,1,0],
[0,1,1,0,0]
]
data = np.array(data)
sums = data.sum(axis=0)
means = data.mean(axis=0)
print 'toplam', sums
print 'ortalama', means
toplam [5 4 3 3 4]
ortalama [ 0.71428571 0.57142857 0.42857143 0.42857143 0.57142857]
X (Oi − Ei )2
χ2 =
i
Ei
χ2 ’nin serbestlik derecesi 3-1=2 (çünkü kuralda 3 tane kolon var, 1. kolonu alt
12
kümeyi bulmak için kullandık). p-değeri ne kadar yüksek ise kural o kadar ilginç
diyebiliriz.
def interesting(rule):
idx = (sums*rule).argmax()
subset = data[data[:,idx] == 1]
print subset
print subset[:,rule==1]
obs = subset[:,rule==1].sum(axis=0)
exp = len(subset)*means[rule==1]
print 'gorunen (observed)', obs
print 'beklenen (expected)', exp
chi = np.sum((obs-exp)**2 / exp)
dof = rule.sum()-1
print 1-chi2.cdf(chi,dof)
rule = np.array([1,1,0,0,1])
interesting(rule)
[[1 1 0 0 1]
[1 0 0 0 0]
[1 0 0 1 1]
[1 1 0 1 1]
[1 1 1 0 1]]
[[1 1 1]
[1 0 0]
[1 0 1]
[1 1 1]
[1 1 1]]
gorunen (observed) [5 3 4]
beklenen (expected) [ 3.57142857 2.85714286 2.85714286]
0.595795886519
rule = np.array([1,0,0,0,1])
interesting(rule)
[[1 1 0 0 1]
[1 0 0 0 0]
[1 0 0 1 1]
[1 1 0 1 1]
[1 1 1 0 1]]
[[1 1]
[1 0]
[1 1]
[1 1]
[1 1]]
gorunen (observed) [5 4]
beklenen (expected) [ 3.57142857 2.85714286]
0.310494434317
Bu daha az ilginçmiş. Hakikaten de ilk kuralın veriye bakarak daha ilginç olduğunu
söyleyebiliriz.
13
Gösterdiğimiz tekniği film sonuçlarında kullanmadık, bunu ödev olarak okuyu-
cuya bırakıyoruz.
Kaynaklar
[1] Ian H. Witten, Eibe Frank, Mark A. Hall, Data Mining Practical Machine Learn-
ing Tools and Techniques
[2] Harrington, P., Machine Learning in Action
[3] Miettinen, Boolean Matrix Factorizations, http://www.mpi-inf.mpg.de/
˜pmiettin/slides/BooleanMatrixFactorizationsForDataMining_Antwerp_
slides.pdf
[4] Zip boundary, ZIP Code FAQs, http://www.zipboundary.com/zipcode_
faqs.html
[5] Rao, Linear Statistical Inference and Its Applications
[6] Bayramli, Lineer Cebir, Matris Çarpımı, Ders 1
[7] Bayramli, Istatistik, Pivotlama
[8] Bayramli, Istatistik, Çok Değişkenli Bernoulli Karışımı
[9] Bayramli, Istatistik, Pearson Chi Kare Uyum Derecesi Testi
14
Toplu Tavsiye (Collaborative Filtering), Filmler, SVD ile Boyut İndirgeme
Film tavsiye verilerine kullanarak bazı analizler ve tavsiye yaklaşımlarına bakacağız.
Diyelim ki Star Trek (ST) dizisini ne kadar beğendiğini 4 tane kullanıcı sezonlara
göre işaretlemiş. Bu örnek veriyi alttaki gibi gösterelim.
d = np.array(
[[5, 5, 0, 5],
[5, 0, 3, 4],
[3, 4, 0, 3],
[0, 0, 5, 3],
[5, 4, 4, 5],
[5, 4, 5, 5]])
1
Bu benzerlik 1/(1 + mesafe) olarak hesaplanır. Mesafe karelerin toplamının
karekökü (yani Öklitsel mesafe, ki isim buradan geliyor). Bu yüzden mesafe 0
ise (yani iki ”şey” arasında hiç mesafe yok, birbirlerine çok yakınlar), o zaman
hesap 1 döndürür (mükemmel benzerlik). Mesafe arttıkça bölen büyüdüğü için
benzerlik sıfıra yaklaşır.
Pearson Benzerliği
Bu benzerliğin Öklit’ten farklılığı, sayı büyüklüğüne hassas olmamasıdır. Diye-
lim ki birisi her sezonu 1 ile beğenmiş, diğeri 5 ile beğenmiş, bu iki vektörün
Pearson benzerliğine göre birbirine eşit çıkar. Pearson -1 ile +1 arasında bir değer
döndürür, alttaki hesap onu normalize ederek 0 ile 1 arasına çeker.
Kosinüs Benzerliği (Cosine Similarity)
İki vektörü geometrik vektör olarak görür ve bu vektörlerin arasında oluşan açıyı
(daha doğrusu onun kosinüsünü) farklılık ölçütü olarak kullanır.
A·B
cos θ =
||A||||B||
def pearson(inA,inB):
if len(inA) < 3 : return 1.0
return 0.5+0.5*np.corrcoef(inA, inB, rowvar = 0)[0][1]
def cos_sim(inA,inB):
num = float(np.dot(inA.T,inB))
denom = la.norm(inA)*la.norm(inB)
return 0.5+0.5*(num/denom)
print np.array(data.ix['Fred'])
print np.array(data.ix['John'])
print np.array(data.ix['Ben'])
print pearson(data.ix['Fred'],data.ix['John'])
print pearson(data.ix['Fred'],data.ix['Ben'])
[5 4 3 3 5 5]
[0 3 0 5 4 5]
[5 5 3 0 5 5]
0.551221949943
0.906922851283
print cos_sim(data.ix['Fred'],data.ix['John'])
print cos_sim(data.ix['Fred'],data.ix['Ben'])
0.898160909799
0.977064220183
2
Şimdi tavsiye mekaniğine gelelim. En basit tavsiye yöntemi, mesela kişi bazlı
olarak, bir kişiye en yakın diğer kişileri bulmak (matrisin tamamına bakarak) ve
onların beğendikleri ürünü istenilen kişiye tavsiye etmek. Benzerlik için üstteki
ölçütlerden birini kullanmak.
Kosinüs Benzerliği ile Tavsiye Örneği
Büyük ölçekte basit kosinüs benzerliği üzerinden tavsiyeleri alttaki gibi hesaplaya-
biliriz. Önce [8]’den en son tam dosyayı indirelim, ve zip dosyasını açalım, base_dir
içinde açılmış olsun. Veride kaç kullanıcı, kaç film olduğu altta raporlandı,
import pandas as pd
base_dir = "/tmp/ml-latest"
ratings = pd.read_csv(base_dir + "/ratings.csv")
print (ratings.userId.nunique(), ratings.movieId.nunique())
283228 53889
Büyük bir veri dosyası bu. Şimdi beğenilerden kullanıcı-film şeklinde olacak
şekilde bir matris yaratacağız. Çoğu kişi çoğu filmi seyretmediği için matris
seyrek olacak, bu sebeple seyrek matris kodu csr_matrix kullanılacak,
Artık sps içinde kullanıcı-film kordinatlarından oluşan bilgiler var. Mesela 1’inci
kullanıcının 307’üncü film beğenisi için
print (sps[1,307])
3.5
Şimdi kendi beğenilerimi bir vektör üzerine kodlamanın zamanı geldi, böylece
bu vektör ile tüm kullanıcı-film matrisi üzerinde bir kosinüs benzerliği hesaplayınca
bizim beğenilere en yakın olan diğer kullanıcıların mesafesini bir diğer vektör
içinde edebiliriz.
(283229, 1)
3
Bu vektörün büyüklüğü verideki kullanıcı sayısı kadar, bu mantıklı.
Artık tavsiye vermek için bu kullanıcılara olan uzaklığa göre yakından-uzağa
şekilde vektörü sıralayacağız, argsort ile sıralama yapınca bize sonuçlar indis
vektörü olarak verilecek (yani en yakın öğenin indisi, indis vektöründe en sonda)
böylece bu vektörü gezip en yakın kullanıcıları bulabiliriz, ve eğer istersek, on-
ların en çok beğendiği filmleri toplayıp bir tavsiye listesi oluşturabiliriz.
m = np.argsort(similarities[:,0])
print (sps[m[-10],:])
Bu iyi bir tavsiye; ben beğeni listeme koymamıştım ama filmi biliyorum, ve ak-
siyon filmi olarak güzeldi.
Nihai listeyi oluşturma, tekrarlananları, zaten seyredilmiş olanları filtreleme kod-
larını okuyuculara ödev olsun. Bazı tiyolar seyrek matris, ya da vektör üzerinde
nonzero çağrısı içi dolu öğelerin indisini ve değerini döndürür, bunları kulla-
narak bir nihai tavsiye sonucu oluşturabiliriz.
Not: Üstte hazır cosine_similarity çağrısı kullanıldı, bu kod bazı ek servisler
sunuyor bize, mesela normalize etmek, seyrek matrislerle iş yapabilmek gibi.
Fakat o fonksiyonun kodlamasının detayına baksak daha önce gösterdiğimiz cos_sim
çağrısı ile benzer olduğunu görürdük.
SVD
Eğer boyut azaltma tekniği kullanmak istiyorsak SVD yöntemi burada da işimize
yarar.
A = USV
4
bize iki boyuttaki sezon kümelerini verebilir, V’nin en önemli iki (en üst) satırı
bize iki boyutta bir kişi kümesi verebilir.
O zaman beğeni matrisi üzerinde SVD uygulayalım,
(4, 6)
(4, 4) (4,) (4, 6)
u [[-0.57098887 -0.22279713]
[-0.4274751 -0.51723555]
[-0.38459931 0.82462029]
[-0.58593526 0.05319973]]
vt [[-0.44721867 -0.53728743]
[-0.35861531 0.24605053]
[-0.29246336 -0.40329582]
[-0.20779151 0.67004393]
[-0.50993331 0.05969518]
[-0.53164501 0.18870999]]
(4, 2) (6, 2)
def label_points(d,xx,yy,style):
for label, x, y in zip(d, xx, yy):
plt.annotate(
label,
xy = (x, y), xytext = style,
textcoords = 'offset points', ha = 'right', va = 'bottom',
bbox = dict(boxstyle = 'round,pad=0.5', fc = 'yellow', alpha = 0.5),
arrowprops = dict(arrowstyle = '->', connectionstyle = 'arc3,rad=0'))
plt.plot(u[:,0],u[:,1],'r.')
label_points(data.index, u[:, 0], u[:, 1],style=(-10, 30))
plt.plot(vt[:,0],vt[:,1],'b.')
label_points(data.columns, vt[:, 0], vt[:, 1],style=(20, 20))
plt.savefig('svdrecom_1.png')
5
Çok güzel! SVD bize ürün bazında sezon 5 ve 6’nin bir küme oluşturduğunu,
Ben ve Fred’in de kişi bazında ayrı bir küme olduğunu gösterdi.
Azaltılmış boyutları nasıl kullanırız? Yeni bir kişiyi (mesela Bob) ele alınca, bu
kişinin verisini öncelikle aynen diğer verilerin indirgendiği gibi azaltılmış boyuta
”indirgememiz” gerekiyor. Çünkü artık işlem yaptığımız boyut orası. Peki bu
indirgemeyi nasıl yaparız? SVD genel formülünü hatırlarsak,
A = USV
Azaltılmış ortamda
A = Uk Sk Vk
Diyelim ki gitmek istediğimiz nokta azaltılmış U, o zaman Uk ’yi tek başına bırakalım
(dikkat, mesela V’nin tersini aldık, fakat bir matrisin tersini almak için o matrisin
kare matris olması gerekir, eğer kare değilse, ters alma işlemi taklit ters alma
işlemi -pseudoinverse- ile gerçekleştirilir, daha fazla detay için [6])
AVk−1 = Uk S
Benzer şekilde
AVk−1 S−1 = Uk
Çok fazla ters alma işlemi var, her iki tarafın devriğini alalım
6
(S−1 )T (Vk−1 )T AT = UTk
Vk−1 = VkT olduğunu biliyoruz. Nasıl? Çünkü VkT Vk = I, aynı şekilde Vk−1 Vk = I.
Ters alma işleminin özgünlüğü (üniqueness) sebebiyle Vk−1 = VkT olmak zorun-
dadır 2
Demek ki üstteki formül devriğin devriğini almak demektir, yani tekrar başa
dönmüş oluyoruz, demek ki Vk değişmeden kalıyor
(S−1 )T Vk AT = UTk
S ise köşegen matris, onun tersi yine köşegen, köşegen matrisin devriği yine ken-
disi
S−1 Vk AT = UTk
print np.dot(u.T,u)
[[ 1.00000000e+00 4.83147593e-18]
[ 4.83147593e-18 1.00000000e+00]]
Doğal olarak 1e-17 gibi bir sayı sıfıra çok yakın, yani sıfır kabul edilebilir. Devrik
ve tersin aynı olduğunu gösterelim: İki matrisi birbirinden çıkartıp, çok küçük
bir sayıdan büyüklüğe göre filtreleme yapalım, ve sonuç içinde bir tane bile True
olup olmadığını kontrol edelim,
True
bob = np.array([5,5,0,0,0,5])
O zaman
print bob.T.shape
print u.shape
S_k = np.eye(2)*Sigma[:2]
bob_2d = np.dot(np.dot(la.inv(S_k),vt.T),bob.T)
print bob_2d
(6,)
(4, 2)
[-0.37752201 -0.08020351]
7
Not: bob.T üstteki formüldeki AT yerine geçecek; formülü tekrar düzenlerken
A üzerinden işlem yaptık, fakat formülü “A’ya eklenen herhangi bir yeni satır”
olarak ta görebiliriz, ki bu örneğimizde Bob’un verisi olurdu.
Üstte eye ve Sigma ile ufak bir takla attık, bunun sebebi svd çağrısından gelen
Sigma sonucunun bir vektör olması ama üstteki işlem için köşegen bir ”matrise”
ihtiyacımız olması. Eğer birim (identity) matrisini alıp onu Sigma ile çarparsak,
bu köşegen matrisi elde ederiz.
Şimdi mesela kosinüs benzerliği kullanarak bu izdüşümlenmiş yeni vektörün
hangi diğer vektörlere benzediğini bulalım.
Ben 0.993397525045
Tom 0.891664622942
John 0.612561691287
Fred 0.977685793579
Sonuca göre yeni kullanıcı Bob, en çok Ben ve Fred’e benziyor. Sonuca eriştik!
Artık bu iki kullanıcının yüksek not verdiği ama Bob’un hiç not vermediği se-
zonları alıp Bob’a tavsiye olarak sunabiliriz.
SVD ile Veriyi Oluşturmak
import pandas as pd
import numpy.linalg as lin
import numpy as np
import scipy.sparse.linalg as lin
import scipy.sparse as sps
d = np.array(
[[ 5., 5., 3., np.nan, 5., 5.],
[ 5., np.nan, 4., np.nan, 4., 4.],
[ np.nan, 3., np.nan, 5., 4., 5.],
[ 5., 4., 3., 3., 5., 5.],
[ 5., 5., np.nan, np.nan, np.nan, 5.]
])
users = ['Ben','Tom','John','Fred','Bob']
seasons = ['0','1','2','3','4','5']
data = pd.DataFrame (d, columns=seasons,index=users)
print data
avg_movies_data = data.mean(axis=0)
print avg_movies_data
data_user_offset = data.apply(lambda x: x-avg_movies_data, axis=1)
A = sps.coo_matrix(np.nan_to_num(np.array(data_user_offset)))
U,S,VT = lin.svds(A,k=3)
def predict(u,i):
offset = np.dot(U[u,:],VT[:,i])
r_ui_hat = offset + avg_movies_data.ix[i]
return r_ui_hat, offset
8
print 'Bob', predict(users.index('Bob'),2)
print 'Tom', predict(users.index('Tom'),1)
0 1 2 3 4 5
Ben 5 5 3 NaN 5 5
Tom 5 NaN 4 NaN 4 4
John NaN 3 NaN 5 4 5
Fred 5 4 3 3 5 5
Bob 5 5 NaN NaN NaN 5
0 5.000000
1 4.250000
2 3.333333
3 4.000000
4 4.500000
5 4.800000
dtype: float64
Bob (3.3115641365499888, -0.021769196783344661)
Tom (4.295419370813935, 0.045419370813934629)
Alternatif Yöntem
Bir diğer yöntem [1] yeni Bob verisi y’yi alıp
z = VV T y
olarak z’ye çevirmek. Bu durumda aslında cebirsel olarak hiçbir şey yapmamış
oluyoruz,
z = VV T y = Iy = y
9
print z
z[y>0] = y[y>0]
print z
(4, 6)
(4, 4) (4,) (4, 6)
S1 S2 S3 S4 S5 S6
Ben 5 5 3 0 5 5
Tom 5 0 4 0 4 4
John 0 3 0 5 4 5
Fred 5 4 3 3 5 5
bob [5 5 0 0 0 5]
[ 3.26615993 2.27206826 2.16256132 1.04609626 3.37952362 3.45858088]
[ 3.26615993 2.27206826 2.16256132 1.04609626 3.37952362 3.45858088]
[ 3.26615993 2.27206826 2.16256132 1.04609626 3.37952362 3.45858088]
[ 5. 5. 2.16256132 1.04609626 3.37952362 5. ]
Sonuca göre Bob büyük ihtimalle S5’i sevecektir, not tahminleri arasında en yüksek
puan orada tahmin edilmiş, ki bu daha önceki Ben ve Fred benzerlik tahminleri
ile uyumlu.
Not: Döngüde z’nin hep aynı satır olması kafa karışıklığı yaratmasın, bu çok ufak
bir veri seti, daha büyük veri setlerdinde bu değişim görülecektir.
İteratif işlem sözde kod (pseudocode) olarak,
Algoritma imputed_svd
2. z = VV T y
10
bir yeni kullanıcı / film kombinasyonu için bu diğer benzer kullanıcının o filme
verdiği not baz alınacak.
Veriyi eğitim ve test olarak iki parçaya böleceğiz. SVD eğitim bölümü üzerinde
işletilecek.
Bu bağlamda, önemli bir diğer konu eksik veri noktalarının SVD sonuçlarını nasıl
etkileyeceği. Sonuçta eksik yerler nan, oradan sıfır yapılıp ardından seyrek matris
kodlaması üzerinden ”atlanıyor” olabilir, fakat bu değerler atlanıyor (yani hızlı
işleniyor, depolanıyor) olsa bile, onların sıfır olmasının bir anlamı yok mudur?
Evet vardır. Not bakımından sıfır da bir not’tur, ve bu sebeple sonuçları isten-
meyen biçimde etkileyebilir.
O zaman mevcut veriyi öyle bir değiştirelim ki verilmemiş notlar, yani sıfır değerleri
sonucu fazla değiştirmesin.
Bunu yapmanın yollarından biri her film için bir ortalama not değeri hesaplamak,
ve bu ortalama değeri o filme verilen tüm not değerlerinden çıkartmaktır. Bu
işleme ”sıfır çevresinde merkezlemek” ismi de verilir, hakikaten mesela film j için
ortalama 3 ise, 5 değeri 2, 3 değeri sıfır, 2 değeri -1 haline gelecektir. Bu bir iler-
lemedir çünkü ortalama 3 değeri zaten bizim için ”önemsiz” bir değerdir, tavsiye
problemi bağlamında bizim en çok ilgilendiğimiz sevilen filmler, ve sevilmeyen
filmler. Bu değerler sırasıyla artı ve eksi değerlere dönüşecekler, ve SVD bu
farklılığı matematiksel olarak kullanabilme yeteneğine sahip.
Altta Pandas mean çağrısı ile bu işlemin yapıldığını görüyoruz, dikkat, Pandas
dataframe içinde nan değerleri olacaktır, ve Pandas bu değerleri atlaması gerektiğini
bilir, yani bu değerler ortalamaya etki etmez. Ardından merkezleme işlemi eğitim
verisi üzerinde uygulanıyor.
df_train = np.array(df_train)
df_test = np.array(df_test)
print df_train.shape
print df_test.shape
__top_k__ = 10
import scipy.sparse.linalg as slin
import scipy.linalg as la
11
U,Sigma,V=slin.svds(dfs_train,k=__top_k__)
print U.shape, Sigma.shape, V.shape
Sigma = np.diag(Sigma)
(6040, 3731)
(5001, 3700)
(1039, 3700)
(5001, 10) (10,) (10, 3700)
Altta test verisi üzerinde satır satır ilerliyoruz, ve her satır (test kullanıcısı) içinde
film film ilerliyoruz. ”Verilmiş bir not” arıyoruz (çoğunlukla not verilmemiş
oluyor çünkü), ve bulduğumuz zaman artık elimizde test edebileceğimiz bir şey
var, o notu ”sıfırlayıp” vektörün geri kalanını azaltılmış boyuta yansıtıyoruz,
ve sonra o boyuttaki tüm diğer U vektörleri içinde arama yapıyoruz, en yakın
diğer kullanıcıyı buluyoruz ve onun bu filme verdiği notu tahminimiz olarak
kullanıyoruz.
Altta eğer bulunan diğer kullanıcı o filme not vermemişse, basitleştirme amaçlı
olarak, o filmi atladık. Gerçek dünya şartlarında filme not vermiş ve yakın olan
(en yakın olmasa da) ikinci, üçüncü kullanıcılar bulunup onların notu kullanılabilir.
Hatta en yakın k tane kullanıcının ortalaması alınabilir (o kullanıcılar kNN gibi
bir metotla bulunur belki), vs.
def euclid(inA,inB):
return 1.0/(1.0 + la.norm(inA - inB))
rmse = 0; n = 0
for i,test_row in enumerate(df_test):
for j, test_val in enumerate(test_row):
# nan olmayan bir not buluncaya kadar ara
if np.isnan(test_val): continue
# bulduk, test satirini tamamen kopyala ve bulunan notu silerek
# onu nan / sifir haline getir cunku yansitma (projection) oncesi
# o notu 'bilmiyormus gibi' yapmamiz lazim.
curr = test_row.copy()
curr[j] = np.nan
curr[np.isnan(curr)] = 0.
proj_row = np.dot(np.dot(la.inv(Sigma),V),curr)
# gercek not
real = df_test[i, j]
print i, 'icin en yakin', isim, 'urun',j, 'icin oy', est, 'gercek', real
12
rmse += (real-est)**2
n += 1
break # her kullanici icin tek film test et
if i == 20: break # 20 kullanici test et
Sonuç fena değil. Tavsiye programlarında RMSE 0.9 civarı iyi olarak bilinir, Net-
flix yarışmasında [3] mesela kazanan algoritma RMSE 0.85’e erişmiştir.
Kaynaklar
[1] Grigorik, SVD Recommendation System in Ruby, http://www.igvita.com/
2007/01/15/svd-recommendation-system-in-ruby
[2] Harrington, P., Machine Learning in Action
[3] Wikipedia, Netflix Prize, http://en.wikipedia.org/wiki/Netflix_Prize
[4] Stack Exchange, How do I use the SVD in collaborative filtering?, http://stats.
stackexchange.com/questions/31096/how-do-i-use-the-svd-in-collaborative
filtering
[5] Anand, MORE ON LINEAR STRUCTURE IN DATA, AND SINGULAR VALUE
DECOMPOSITION, https://anandoka.wordpress.com/tag/imputed-svd
[6] Bayramli, Lineer Cebir, Ders 33
[8] Bayramli, Netflix / Movielens Film Verisi, https://burakbayramli.github.
io/dersblog/sk/2015/04/pandas-movielens-netflix-ratings.html
13
Naive Bayes
Reel sayılar arasında bağlantı kurmak için istatistikte regresyon kullanılır. Eğer
reel değerleri, (mesela) iki kategorik grup arasında seçmek için kullanmak is-
tenirse, bunun için lojistik regresyon gibi teknikler de vardır.
Fakat kategoriler / gruplar ile başka kategorik gruplar arasında bağlantılar ku-
rulmak istenirse, standart istatistik yöntemleri faydalı olamıyor. Bu gibi ihtiyaçlar
için yapay öğrenim (machine learning) dünyasından Naive Bayes gibi tekniklere
bakmamız lazım.
Not: Daha ilerlemeden belirtelim, bu tekniğin ismi Naive Bayes ama bu tanım
tam doğru değil, çünkü NB Olasılık Teorisi’nden bilinen Bayes Teorisini kul-
lanmıyor.
Öncelikle kategorik değerler ile ne demek istediğimizi belirtelim. Reel sayılar
0.3423, 2.4334 gibi değerlerdir, kategorik değerler ile ise mesela bir belge içinde
’a’,’x’ gibi harflerin mevcut olmasıdır. Ya da, bir evin ’beyaz’, ’gri’ renkli olması..
Burada öyle kategorilerden bahsediyoruz ki istesek te onları sayısal bir değere
çeviremiyoruz; kıyasla mesela bir günün ’az sıcak’, ’orta’, ’çok sıcak’ olduğu
verisini kategorik bile olsa regresyon amacıyla sayıya çevirip kullanabilirdik. Az
sıcak = 0, orta = 1, çok sıcak = 2 değerlerini kullanabilirdik, regresyon hala anlamlı
olurdu (çünkü arka planda bu kategoriler aslında sayısal sıcaklık değerlerine
tekabül ediyor olurlardı). Fakat ’beyaz’, ’gri’ değerlere sayı atamanın regresyon
açısından bir anlamı olmazdı, hatta bunu yapmak yanlış olurdu. Eğer elim-
izde fazla sayıda ’gri’ ev verisi olsa, bu durum regresyon sırasında beyaz evlerin
beyazlığını mı azaltacaktır?
İşte bu gibi durumlarda kategorileri olduğu gibi işleyebilen bir teknik gerekiyor.
Bu yazıda kullanacağımız örnek, bir belgenin içindeki kelimelere göre katego-
rize edilmesi. Elimizde iki türlü doküman olacak. Bir tanesi Stephen Hawking
adlı bilim adamının bir kitabından 3 sayfa, diğeri başkan Barack Obama’nın bir
kitabından 3 sayfa. Bu sayfalar ve içindeki kelimeler NB yöntemini ”eğitmek”
için kullanılacak, sonra NB tarafından hiç görülmemiş yeni sayfaları yöntemimize
kategorize ettireceğiz.
Çok Boyutlu Bernoulli ve Kelimeler
Bir doküman ile içindeki kelimeler arasında nasıl bağlantı kuracağız? Burada
olasılık teorisinden Çok Boyutlu Bernoulli (Multivariate Bernoulli) dağılımını kul-
lanacağız. Üstteki resimde görüldüğü gibi her doküman bir xi rasgele değişkeniyle
temsil edilecek. Tek boyutlu Bernoulli değişkeni ’1’ ya da ’0’ değerine sahip ola-
bilir, çok boyutlu olanı ise bir vektör içinde ’1’ ve ’0’ değerlerini taşıyabilir. İşte
1
bu vektörün her hücresi, önceden tanımlı bir kelimeye tekabül edecek, ve bu ke-
limeden bir doküman içinde en az bir tane var ise, o hücre ’1’ değerini taşıyacak,
yoksa ’0’ değerini taşıyacak. Üstteki örnekte 2. kelime ”hello” ve 4. doküman
içinde bu kelimeden en az bir tane var, o zaman x42 = 1. Tek bir dokümanı temsil
eden dağılımı matematiksel olarak şöyle yazabiliriz:
Y
D Y
D
p(x1 , ..., xD ) = p(xd ) = αxdd (1 − αd )1−xd
d=1 d=1
Bu formülde her d boyutu bir tek boyutlu Bernoulli, ve bir doküman için tüm bu
boyutların ortak (joint) dağılımı gerekiyor, çarpımın sebebi bu. Formüldeki αd
bir dağılımı ”tanımlayan” değer, α bir vektör, ve unutmayalım, her ”sınıf” için
NB ayrı ayrı eğitilecek, ve her sınıf için farklı α vektörü olacak. Yani Obama’nın
kitapları için α2 = 0.8 olabilir, Hawking kitabı için α2 = 0.3 olabilir. Birinin
kitabında ”hello” kelimesi olma şansı fazla, diğerinde pek yok. O zaman NB’yi
”eğitmek” ne demektir? Eğitmek her sınıf için yukarıdaki α değerlerini bulmak
demektir.
Bunun için istatistikteki ”olurluk (likelihood)” kavramını kullanmak yeterli. Olurluk,
bir dağılımdan geldiği farzedilen bir veri setini alır, tüm veri noktalarını teker
teker olasılığa geçerek olasılık değerlerini birbirine çarpar. Sonuç ne kadar yüksek
çıkarsa, bu verinin o dağılımdan gelme olasılığı o kadar yüksek demektir. Bizim
problemimiz için tek bir sınıfın olurluğu, o sınıf içindeki tüm (N tane) belgeyi
kapsamalıdır, tek bir ”veri noktası” tek bir belgedir, o zaman:
Y
N Y
D Y
N Y
D
xi i
L(θ) = p(xid ) = αdd (1 − αd )1−xd
i=1 d=1 i=1 d=1
X
N X
D
log(L) = xid log(αd ) + (1 − xid ) log(1 − αd )
i=1 d=1
Türevi alalım:
2
dlog(L) X
N
xid 1 − xid
= − =0
dαd i=1
αd 1 − αd
1- αd ’ye göre türev alırken xid ’ler sabit sayı gibi muamele görürler. 2- log’un
türevi alırken log içindeki değerlerin türev alınmış hali bölümün üstüne, ken-
disini olduğu gibi bölüm altına alınır, örnek dlog(−x)/dx = −1/x olur üstteki
eksi işaretinin sebebi bu.
P
Peki D d=1 nereye gitti? Türevi αd ’ye göre alıyoruz ve o türevi alırken tek bir αd
ile ilgileniyoruz, mesela α22 , bunun haricindeki diğer tüm α? değerleri türev alma
P
işlemi sırasında sabit kabul edilirler, türev sırasında sıfırlanırlar. Bu sebeple D d=1
içinde sadece bizim ilgilendiğimiz αd geriye kalır. Tabii ki bu aynı zamanda her
d = 1, 2, ..D, αd için ayrı bir türev var demektir, ama bu türevlerin hepsi birbirine
benzerler, yani tek bir αd ’yi çözmek, hepsini çözmek anlamına gelir.
Devam edelim:
X
N i
x 1 − xid
Nd N − N d
d
− = − =0
i=1
αd 1 − αd αd 1 − αd
PN
i=1 xid = Nd olarak kabul ediyoruz, Nd tüm veri içinde d boyutu (kelimesi)
’1’ kaç tane hücre olduğunu bize söyler. xid ya ’1’ ya ’0’ olabildiğine göre bir d
için, tüm N hücrenin toplamı otomatik olarak bize kaç tane ’1’ olduğunu söyler.
Sonra:
Nd N − Nd
− =0
αd 1 − αd
1 − αd N − Nd
=
αd Nd
1 N
−1= −1
αd Nd
1 N
=
αd Nd
Nd
αd =
N
Python Kodu
αd ’nin formülünü buldumuza göre artık kodu yazabiliriz. İlk önce bir dokümanı
temsil eden çok boyutlu Bernoulli vektörünü ortaya çıkartmamız lazım. Bu vektörün
her hücresi belli bir kelime olacak, ve o kelimelerin ne olduğunu önceden kararlaştırmamız
3
lazım. Bunun için her sınıftaki tüm dokümanlardaki tüm kelimeleri içeren bir
sözlük yaratırız:
import re
import math
words = {}
hawking_alphas = words.copy()
for file in ['a1.txt','a2.txt','a3.txt']:
words_hawking = set()
f = open (base + file)
s = f.read()
tokens = re.split('\W+', s)
for x in tokens:
words_hawking.add(x)
for x in words_hawking:
hawking_alphas[x] += 1.
obama_alphas = words.copy()
for file in ['b1.txt','b2.txt','b3.txt']:
words_obama = set()
f = open (base + file)
s = f.read()
tokens = re.split('\W+', s)
for x in tokens:
words_obama.add(x)
for x in words_obama:
obama_alphas[x] += 1.
for x in hawking_alphas.keys():
hawking_alphas[x] = hawking_alphas[x] / 3.
for x in obama_alphas.keys():
obama_alphas[x] = obama_alphas[x] / 3.
def test(file):
test_vector = words.copy()
words_test = set()
f = open (base + file)
s = f.read()
tokens = re.split('\W+', s)
4
for x in tokens:
words_test.add(x)
for x in words_test:
test_vector[x] = 1.
ob = 0.
ha = 0.
for x in test_vector.keys():
if x in obama_alphas:
ob += prob(test_vector[x], obama_alphas[x])
if x in hawking_alphas:
ha += prob(test_vector[x], hawking_alphas[x])
hawking test
obama -34048.7734496 hawking -32192.3692113 obama False hawking True
hawking test
obama -33027.3182425 hawking -32295.7149639 obama False hawking True
obama test
obama -32531.9918709 hawking -32925.037558 obama True hawking False
obama test
obama -32205.4710748 hawking -32549.6924713 obama True hawking False
Test için yeni dokümanı kelimelerine ayırıyoruz, ve her kelimeye tekabül eden
alpha vektörlerini kullanarak bir yazar için toplam olasılığı hesaplıyoruz. Nasıl?
Her kelimeyi αxdd (1 − αd )1−xd formülüne soruyoruz, yeni dokümanı temsilen
elimizde bir [1, 0, 0, 1, 0, 0, ..., 1] şeklinde bir vektör olduğunu farz ediyoruz, buna
göre mesela x1 = 1, x2 = 0. Eğer bir d kelimesi yeni belgede ”var” ise o kelime
için xd = 1 ve bu durumda αxdd = α1d = αd haline gelir, ama formülün öteki tarafı
yokolur, (1 − αd )1−xd = (1 − αd )0 = 1, o zaman αd · 1 = αd .
Çarpım diyoruz ama biz aslında sınıflama sırasında αxdd (1 − αd )1−xd çarpımı yer-
ine yine log() numarasını kullandık; çünkü olasılık değerleri hep 1’e eşit ya da
ondan küçük sayılardır, ve bu küçük değerlerin birbiriyle sürekli çarpımı nihai
sonucu aşırı fazla küçültür. Aşırı ufak değerlerle uğraşmamak için olasılıkların
log’unu alıp birbirleri ile toplamayı seçtik, yani hesapladığımız değer xd ·log(αd )+
(1 − xd ) · log(1 − αd )
Fonksiyon prob içindeki 1e-7 kullanımı neden? Bu kullanım log numarasını ya-
pabilmek için – sıfır değerinin log değeri tanımsızdır, bir kelime olmadığı za-
man log’a sıfır geleceği için hata olmaması için log içindeki değerlere her se-
ferinde yeterince küçük bir sayı ekliyoruz, böylece pür sıfırla uğraşmak zorunda
5
kalmıyoruz. Sıfır olmadığı zamanlarda çok eklenen çok küçük bir sayı sonuçta
büyük farklar (hatalar) yaratmıyor.
Toparlarsak, yeni belge a4.txt için iki tür alpha değerleri kullanarak iki farklı
log toplamını hesaplatıyoruz. Bu iki toplamı birbiri ile karşılaştırıyoruz, hangi
toplam daha büyükse, dokümanın o yazardan gelmesi daha olasıdır, ve o seçimimiz
o yazar olur.
Kaynaklar
[1] Jebara, T., Columbia U. COMS 4771 Machine Learning Lecture Notes, Lecture 7
6
Kalıcı CD (Persistent Contrastive Divergence -PCD-)
Kısıtlı Boltzman Makinaları (RBM) yazısında gösterilen eğitim CD (contrastive
divergence) üzerinden idi. Amaç alttaki formülde, özellikle eksiden sonraki ter-
imi yaklaşıksal olarak hesaplamaktır.
X
N
< yi yj >P(h|xn ;W) − < yi yj >P(x,h;W)
n=1
Bu terime basında eksi olduğu için negatif parçacıklar (negatıve partıcles) ismi
de veriliyor.
Şimdi RBM’de gördüğümüz CD’yi hatırlayalım, CD bir tür “tek adımlık Gibbs
örneklemesi” yapıyordu; bu tek adım örnekleme sonrasında bir sonraki adım
öncesi, veri, tekrar başlangıç noktası olarak zincire veriliyordu. Yani her CD
adımının başlangıcı illa ki verinin kendisi olacaktır. Bu usul Gibbs’in veriden
uzaklaşma şansı çok azdır. Fakat çoğu ilginç yapay öğrenim verisi çok doruk-
ludur (multimodal), optimizasyon bağlamında düşünülürse birden fazla tepe (ya
da çukur) noktası içerir. Eğer eldeki veri, eğitimi bu noktalara yeterince kanal-
ize edemiyorsa o noktalar öğrenilmemiş olur. Bazen verinin (bile) söylediğinden
değişik yönleri gezebilen bir prosedür bu çokdoruklu alanı gezmesi açısından
daha başarılı olabilecektir.
PCD bu eksikleri düzeltmeye çabalar. PCD’ye göre modelden gelen “negatif
parçacıkların” örneklemesi arka planda, kendi başlarına ilerler, ve bu zincir hiçbir
zaman veriye, ya da başka bir şeye set edilmez (hatta zincirin başlangıç nok-
tası bile veriden alakasız olarak, rasgele seçilir). Bu yönteme göre h0 , x0 , h1 , x1 , ...
üretimi neredeyse tamamen “kapalı devre” kendi kendine ilerleyen bir süreç ola-
caktır. Diğer yanda pozitif parçacıklar veriden geliyor (ve tabii ki her gradyan
adımı sonrası değişen W hem pozitif hem negatif parçacıkları etkiler), ve bu
al/ver ilişkisi, hatta bir bakıma model ile verinin kapışmasının PCD’yi daha avan-
tajlı hale getirdiği iddia edilir, ki PCD, CD’den genellikle daha iyi öğrenim sağlar
[5].
CD’ye kıyasla PCD’nin Gibbs ya da genel olarak MCMC örneklemesinin pren-
sibine daha yakın durduğu iddia edilebilir, çünkü PCD ile bir örneklem zinciri
kesintisiz olarak devam ettirilir.
class RBM:
def __init__(self, num_hidden, num_visible, learning_rate,max_epochs=10,
batch_size=10):
self.num_hidden = num_hidden
self.num_visible = num_visible
self.learning_rate = learning_rate
self.weights = 0.1 * np.random.randn(self.num_visible, self.num_hidden)
1
self.weights = np.insert(self.weights, 0, 0, axis = 0)
self.weights = np.insert(self.weights, 0, 0, axis = 1)
self.max_epochs = max_epochs
self.batch_size = batch_size
visible_states = visible_states[:,1:]
return visible_states
2
self.h_samples_ = np.zeros((self.batch_size, self.num_hidden))
n_batches = int(np.ceil(float(num_examples) / self.batch_size))
batch_slices = list(gen_even_slices(n_batches * self.batch_size,
n_batches, num_examples))
if __name__ == "__main__":
import numpy as np
X = np.array([[0, 0, 0], [0, 1, 1], [1, 0, 1], [1, 1, 1]])
model = RBM(num_hidden=2, num_visible=3, learning_rate=0.1,batch_size=2)
model.fit(X)
print model.weights
Üstte görülen kod daha önce RBM için kullanılan kodla benzeşiyor, sadece fit
değişik, ve _fit eklendi. Bu kodda miniparça (minibatch) kavramı da var, her
gradyan adımı ufak verinin mini parçaları üzerinden atılır. Bu parçalar hakikaten
ufak, mesela 10 ila 100 satırlık veri arasındadırlar ve bu ilginç bir durumu ortaya
çıkartır, özellikle negatif parçacıklar için, ki bu parçacıklar W bağlantısı haricinde
kendi başlarına ilerler, çok az veri noktası ile işlem yapabilmektedirler.
Metot fit içinde self.h_samples_ değişkenine dikkat, bu değişken PCD’nin “kalıcı”
olmasını sağlar, her _fit çağrı sonrası negatif parçacık örneklemesi self.h_samples_
’in bıraktığı yerden başlar.
RBM için kullandığımız aynı veri seti üzerine k-katlama ile test edelim,
X = np.loadtxt('../../stat/stat_mixbern/binarydigits.txt')
Y = np.ravel(np.loadtxt('../../stat/stat_mixbern/bindigitlabels.txt'))
np.random.seed(0)
scores = []
cv = KFold(n=len(X),n_folds=3)
for train, test in cv:
X_train, Y_train = X[train], Y[train]
X_test, Y_test = X[test], Y[test]
r = rbmp.RBM(num_hidden=40, learning_rate=0.1, max_epochs=100,
num_visible=64, batch_size=10)
r.fit(X_train)
clf = LogisticRegression(C=1000)
clf.fit(r.run_visible(X_train), Y_train)
res3 = clf.predict(r.run_visible(X_test))
scores.append(np.sum(res3==Y_test) / float(len(Y_test)))
print np.mean(scores)
! python test_rbmkfold.py
3
0.989898989899
Daha çetrefil bir veri seti MNIST veri setine [2] bakalım. Veri 28x28 boyutunda
ikisel veri olarak kodlanmış rakamların el yazısından alınmış resimlerini içerir.
Veri seti ünlü çünkü Derin Öğrenim’in ilk büyük başarıları bu veri seti üzerinde
paylaşıldı. MNIST’i aldıktan sonra eğitim / test kısımlarının ilk 1000 tanesi üzerinde
algoritmamızı kullanırsak, tek komşulu KNN (yani 1-NN) yüzde 85.4 başarı sonu-
cunu verir. Alttaki parametreler üzerinden PCD ile RBM’in başarısı yüzde 86
olacaktır.
np.random.seed(0)
S = 1000
f = gzip.open('/tmp/mnist.pkl.gz', 'rb')
train_set, valid_set, test_set = cPickle.load(f)
f.close()
X_train,y_train = train_set
X_test,y_test = valid_set
X_train = X_train[:S]; y_train = y_train[:S]
X_test = X_test[:S]; y_test = y_test[:S]
print X_train.shape
clf = neighbors.KNeighborsClassifier(n_neighbors=1)
clf.fit(X_train, y_train)
print 'KNN', clf.score(X_test, y_test)
import rbmp
r = rbmp.RBM(num_hidden=500, learning_rate=0.1, max_epochs=200,
num_visible=784,batch_size=20)
r.fit(X_train)
clf = LogisticRegression(C=1000)
clf.fit(r.run_visible(X_train), y_train)
res3 = clf.predict(r.run_visible(X_test))
print 'RBM', np.sum(res3==y_test) / float(len(y_test))
Kaynaklar
[1] Tieleman, Using Fast Weights to Improve Persistent Contrastive Divergence,http:
//videolectures.net/icml09_tieleman_ufw/
[2] Montreal Institute for Learning Algorithms, MNIST Data, http://www.iro.
umontreal.ca/˜lisa/deep/data/mnist/mnist.pkl.gz
[3] Bengio, Y., Learning Deep Architectures for AI
[4] Larochelle, H., Neural networks [5.6] : Restricted Boltzmann machine - persistent
CD, https://www.youtube.com/watch?v=S0kFFiHzR8M
4
[5] Murphy, K. Machine Learning A Probabilistic Perspective
5
Boltzman Makinaları (Rasgele Hopfield Ağları)
Alttaki ifade bir Boltmann dağılımını gösterir,
1 1 T
P(x; W) = exp x Wx (3)
Z(W) 2
Y
N
1
1 (n)T
(n) (n)
P(x ; W) = exp x Wx
n=1
Z(W) 2
Log olurluk
Y
N X
N
1
(n)T
L = ln (n) (n)
P(x ; W) = x Wx − ln Z(W) (1)
n=1 n=1
2
∂L
Birazdan ∂w ij
türevini alacağız, o sırada ln Z(W)’nin türevi lazım, daha doğrusu
Z(W)’yi nasıl türevi alınır hale getiririz?
Z(W) normalizasyon sabiti olduğuna göre, dağılımın geri kalanının sonsuzlar
üzerinden entegrali (ya da toplamı) normalizasyon sabitine eşittir,
X 1
Z(W) = exp xT Wx
x
2
X
1 T
ln Z(W) = ln exp x Wx
x
2
Log bazlı türev alınca log içindeki herşey olduğu gibi bölüme gider, ve log içindekinin
türevi alınırak bölüme koyulur. Fakat log içine dikkatli bakarsak bu zaten Z(W)’nin
tanımıdır, böylece denklemi temizleme şansı doğdu, bölüme hemen Z(W) deriz,
ve türevi log’un içine uygularız,
X
∂ 1 ∂ 1 T
ln Z(W) = exp x Wx
∂wij Z(W) x ∂wij 2
1
∂ 1 1 1 ∂ T
exp xT Wx = exp xT Wx x Wx (2)
∂wij 2 2 2 ∂wij
∂ T
x Wx = xi xj
∂wij
1 1
exp xT Wx xi xj
=
2 2
X
∂ 1 1 1 T
ln Z(W) = exp x Wx xi xj
∂wij Z(W) x 2 2
1X 1 1
exp xT Wx xi xj
=
2 x Z(W) 2
1X
= P(x; W)xi xj
2 x
X
P(x; W)xi xj =< xi , xj >P(x;W) (4)
x
Artık ln Z(W)’nin türevini biliyoruz. O zaman tüm log olurluğun türevine (1)
dönebiliriz,
∂L X
N
∂ 1 (n)T ∂
(n)
= x Wx − ln Z(W)
∂wij n=1 ∂wij 2 ∂wij
X
N
1 (n)T (n) ∂
= xi xj − ln Z(W)
n=1
2 ∂wij
X
N
1 (n)T (n) 1
= xi xj − < xi xj >P(x;W)
n=1
2 2
2
X
N
(n)T (n)
= xi xj − < xi xj >P(x;W)
n=1
Eğer
1 X (n)T (n)
N
< xi xj >Data = x xj
N n=1 i
olarak alırsak, eşitliğin sağ tarafı verisel kovaryansı (empirical covariance) temsil
eder. Düzenleyince,
X
N
(n)T (n)
N· < xi xj >Data = xi xj
n=1
∂L
= N < xi xj >Data − < xi xj >P(x;W)
∂wij
Her ne kadar N veri noktası sayısını gösteriyor olsa da, üstteki ifade bir gradyan
güncelleme formülü olarak ta görülebilir, ve N yerine bir güncelleme sabiti alınabilir.
Gradyan güncelleme olarak görülebilir çünkü wij ’ye göre türev aldık, o zaman
bizi L’in minimumuna götürecek w adımları üstte görüldüğü gibidir.
(4)’te görülen < xi xj >P(x;W) ’in anlamı nedir? Bu ifade mümkün tüm x değerleri
üzerinden alınıyor ve ikisel ilişkilerin olasılığını “mevcut modele” göre hesaplıyor.
Yani bu ifade de bir korelasyon hesabıdır, sadece veriye göre değil, tüm mümkün
değerler ve model üzerinden alınır. Bu hesabı yapmak oldukça zordur, fakat
yaklaşıksal olarak Monte Carlo yöntemi ile hesaplanabilir. Nihayet MC ve MCMC
metotlarının kullanılma sebebini görmeye başlıyoruz; bu metotlar zaten aşırı yüksek
boyutlu, analitik çözümü olmayan, hesaplanamaz (intractable) entegraller (ya da
toplamlar) için keşfedilmiştir.
Yani bu ifadeyi hesaplamak için Monte Carlo simulasyonu kullanacağız. Tüm
değerleri teker teker ziyaret etmek yerine (ki bu çok uzun zaman alırdı) mev-
cut modele en olası x değerleri “ürettireceğiz”, ve bu değerleri alıp sanki gerçek
veriymiş gibi sayısal korelasyonlarını hesaplayacağız. Eğer veriler dağılımın en
olası noktalarından geliyorlarsa, elimizde veri dağılımı “iyi” temsil eden bir veri
setidir. Daha sonra bu korelasyon hesabını değeri gerçek veri korelasyonunun-
dan çıkartıp bir sabit üzerinden gradyan adımı atmamız mümkün olacak.
Gibbs Örneklemesi (Sampling)
Gibbs örneklemesinin detayları için [5]. Bolzmann dağılımından örneklem al-
mak için bize tek bir değişken (hücre) haricinde diğer hepsinin bilindiği durumun
3
olasılık hesabı lazım, yani koşulsal olasılık P(xi = 1|xj , j 6= i). Yani x üzerinde, biri
hariç tüm öğelerin bilindiği durumda bilinmeyen tek hücre i’nin 1 olma olasılık
değeri,
1
P(xi = 1|xj , j 6= i) =
1 + e−ai
ve,
X
ai = wij xj
j
Bu koşulsal olasılığın temiz / basit bir formül olması önemli, üstteki görülen
bir sigmoid fonksiyonu bu türden bir fonksiyondur... Bu fonksiyonlar hakkında
daha fazla bilgi [6] yazısında bulunabilir.
Ama, ana formül (3)’ten bu noktaya nasıl eriştik? Bu noktada biraz türetme yap-
mak lazım. x vektörü içinde sadece xi öğesinin b olmasını xb olarak alalım. Önce
koşulsal dağılımda “verili” olan kısmı elde etmek lazım. O uzaman
Bu bir marjinalizasyon ifadesi, tüm olası i değerleri üzerinde bir toplam alınca
geri kalan j değerlerinin dağılımını elde etmiş oluruz.
P(x1 )
P(xi = 1|xj , j 6= i) =
P(x0 ) + P(x1 )
çünkü P(A|B) = P(A, B)/P(B) bilindiği gibi, ve P(x1 ) içinde x1 = 1 setini içeren
tüm veriler üzerinden.
Eşitliğin sağ tarafında P(x1 )’i bölen olarak görmek daha iyi, ayrıca ulaşmak istediğimiz
1/1 + e−ai ifadesinde +1’den kurtulmak iyi olur, böylece sadece e−ai olan eşitliği
ispatlarız. Bunun her iki denklemde ters çevirip 1 çıkartabiliriz,
P(x0 ) + P(x1 )
1/P(xi = 1|xj , j 6= i) =
P(x1 )
P(x0 )
=1+
P(x1 )
P(x0 )
Bir çıkartırsak, P(x1 )
kalır. Bu bize ulaşmak istediğimiz denklemde e−ai ibaresini
P(x0 )
bırakır. Artık sadece P(x1 )
’in e−ai ’e eşit olduğunu göstermek yeterli.
4
P(x0 ) T T
1
= exp(x0 Wx0 − x1 Wx1 )
P(x )
Şimdi xT Wx gibi bir ifadeyi indisler bazında açmak için şunları yapalım,
X
xT Wx = xk xj wkj
k,j
X X
x xj wij = Ykj
| k {z }
k,j Ykj k,j
XX X
= Ykj + Yij
k6=i j j
XX X
= ( Ykj + Yki ) + Yij
k6=i j6=i j
X X X
= Ykj + Yki + Yij
k6=i,j6=i k6=i j
X X X
= Ykj + Yki + Yij + Yii
k6=i,j6=i k j
T T
Üstteki ifadeyi exp(x0 Wx0 − x1 Wx1 ) için kullanırsak,
X X X X
0 0 0 1 1 1
exp Yki + Yij + Yii −( Yki + Yij + Yii )
k j k j
P
Ykj teriminin nereye gittiği merak edilirse, bu ifade i’ye dayanmadığı
k6=i,j6=i
için bir eksi bir artı olarak iki defa dahil edilip iptal olacaktı.
X X
1 1 1
= exp 0 − ( Yki + Yij + Yii )
k j
5
P 1
P 1
W’nin simetrik matris olduğunu düşünürsek, k Yki ile j Yij aynı ifadedir,
X
1 1
= exp − (2 Yij + Yii )
j
1
W sıfır çaprazlı bir matristir, o zaman Yii = 0,
X
1
= exp 2 Yij = exp(−2ai )
j
Orijinal dağılım denkleminde 1/2 ifadesi vardı, onu başta işlemlere dahil etmemiştik,
edilseydi sonuç exp(−ai ) olacaktı.
import numpy as np
class Boltzmann:
def __init__(self,n_iter=100,eta=0.1,sample_size=100,init_sample_size=10):
self.n_iter = n_iter
self.eta = eta
self.sample_size = sample_size
self.init_sample_size = init_sample_size
6
def normc(self, X):
"""
normalizasyon sabitini dondur
"""
def f(x): return np.exp(0.5 * np.dot(np.dot(x,self.W), x))
S = 2*self.sample(self.W)-1
# sozluk icinde anahtar tek x degeri boylece bir
# olasilik degeri sadece bir kere toplanir
res = dict((tuple(s),f(s)) for s in S)
return np.sum(res.values())
Fonksiyon draw içinde, tek bir veri satırı için ve sırayla her değişken (hücre)
için, diğer değişkenleri baz alıp diğerinin koşulsal olasılığını hesaplıyoruz, ve
sonra bu olasılığı kullanarak bir sayı üretimi yapıyoruz. Üretimin yapılması için
np.random.rand’dan gelen 0 ve 1 arasındaki birörnek (uniform) dağılımdan bir
rasgele sayıyı geçip geçmeme irdelemesi yeterli. Bir Bernoulli olasılık hesabını
üretilen bir rasgele değişkene bu şekilde çevirebilirsiniz. Bu niye işler? Üstte be-
lirttiğimiz irdelemeyi rasgele değişken olarak kodlarsak (ki bu da bir Bernoulli
rasgele değişkeni olur), ve birörnek rasgele değişken U olsun,
1 U<p
Y=
0 U>p
Bu durumda P(X = 1) = P(U < p) = p olurdu. Neden? Çünkü üstte bir sürekli
(continuous) bir birörnek değişken yarattık, ve P(U < p) = Fu (p) = p.
Devam edelim; Çağrı sample ise draw’u kullanarak pek çok veri satırını içeren
ve dağılımı temsil eden bir örneklem yaratmakla sorumlu. Bunu her örneklem
satırını baz alarak bir sonrakini ürettirerek yapıyor, böylelikle MCMC’nin dağılımı
“gezmesi” sağlanmış oluyor.
Normalizasyon Sabiti
Birazdan göreceğimiz örnek için normalizasyon sabitini de hesaplamamız gereke-
cek. Niye? Mesela iki farklı BM dağılımını farklı etiketli verilerden öğreniyoruz,
7
sonra test veri noktasını her iki ayrı dağılıma “soruyoruz”? Olasılığı nedir? Bu
noktada kesin bir olasılık hesabı istediğimiz için artık Z bilinmek zorunda. Bu
sabitin hesaplanması için ise < xi xj >P(x;W) P için olduğu gibi, tüm mümkün x’ler
T
üzerinden bir toplam gerekir, bu toplam x exp 1/2x Wx toplamı. Bu toplamın
hesaplanması çok zor olduğu için, yine MCMC’ye başvuracağız. Tek fark alınan
örneklemi (3) formülüne geceğiz, ve bir olasılık hesabı yapacağız, ve bu olasılıkları
toplayacağız. Tabii aynı x’i (eğer tekrar tekrar üretilirse -ufak bir ihtimal ama
mümkün-) tekrar tekrar toplamamak için hangi x’lerin üretildiğini bir sözlük
içinde hatırlayacağız, yani bir x olasılığı sadece bir kere toplanacak.
Şimdi ufak bir örnek üzerinde BM’i işletelim.
import boltz
A = np.array([\
[0.,1.,1.,1],
[1.,0.,0,0],
[1.,1.,1.,0],
[0, 1.,1.,1.],
[1, 0, 1.,0]
])
A[A==0]=-1
clf = boltz.Boltzmann(n_iter=50,eta=0.01,sample_size=200,init_sample_size=50)
clf.fit(A)
print 'W'
print clf.W
print 'normalizasyon sabiti', clf.C
Iteration 0
Iteration 10
Iteration 20
Iteration 30
Iteration 40
W
[[ 0. -0.065 -0.06 -0.055]
[-0.065 0. 0.17 0.105]
[-0.06 0.17 0. -0.09 ]
[-0.055 0.105 -0.09 0. ]]
normalizasyon sabiti 16.4620358997
Sonuç W üstte görüldüğü gibi. Örnek veriye bakarsak 2. satır 3. kolonda artı bir
değer var, 1. satır 4. kolonda eksi değer var. Bu beklediğimiz bir şey çünkü 2. ve
3. değişkenlerin arasında bir korelasyon var, x2 ne zaman 1/0 ise x3 te 1/0. Fakat
x1 ile x4 ters bir korelasyon var, birbirlerinin zıttı değerlere sahipler.
Şimdi yeni test verisini dağılıma “soralım”,
test = np.array([\
[0.,1.,1.,1],
[1.,1.,0,0],
[0.,1.,1.,1]
])
print clf.predict_proba(test)
8
[ 0.0730905 0.05692294 0.0730905 ]
Görüntü Tanıma
Elimizde el yazısı tanıma algoritmaları için kullanılan bir veri seti var. Veride
0,5,7 harflerinin görüntüleri var. Mesela 5 için bazı örnek görüntüler,
Y = np.loadtxt('../../stat/stat_mixbern/binarydigits.txt')
label = np.ravel(np.loadtxt('../../stat/stat_mixbern/bindigitlabels.txt'))
Y5 = Y[label==5]
plt.imshow(Y5[0,:].reshape((8,8),order='C'), cmap=plt.cm.gray)
plt.savefig('boltzmann_01.png')
plt.imshow(Y5[1,:].reshape((8,8),order='C'), cmap=plt.cm.gray)
plt.savefig('boltzmann_02.png')
plt.imshow(Y5[2,:].reshape((8,8),order='C'), cmap=plt.cm.gray)
plt.savefig('boltzmann_03.png')
Y = np.loadtxt('../../stat/stat_mixbern/binarydigits.txt')
labels = np.ravel(np.loadtxt('../../stat/stat_mixbern/bindigitlabels.txt'))
X_train, X_test, y_train, y_test = train_test_split(Y, labels, test_size=0.4,random_st
X_train[X_train==0]=-1
X_test[X_test==0]=-1
clfs = {}
for label in [0,5,7]:
x = X_train[y_train==label]
clf = boltz.Boltzmann(n_iter=30,eta=0.05,sample_size=500,init_sample_size=100)
clf.fit(x)
clfs[label] = clf
res = []
9
for label in [0,5,7]:
res.append(clfs[label].predict_proba(X_test))
res3 = np.argmax(np.array(res).T,axis=1)
res3[res3==1] = 5
res3[res3==2] = 7
print 'Boltzmann Makinasi', np.sum(res3==y_test) / float(len(y_test))
clf = neighbors.KNeighborsClassifier()
clf.fit(X_train,y_train)
res3 = clf.predict(X_test)
print 'KNN', np.sum(res3==y_test) / float(len(y_test))
!python testbm.py
Iteration 0
Iteration 10
Iteration 20
Iteration 0
Iteration 10
Iteration 20
Iteration 0
Iteration 10
Iteration 20
Boltzmann Makinasi 0.975
KNN 0.975
Sonuç yüzde 97.5, oldukça yüksek, ve KNN metotu ile aynı sonucu aldık, ki bu
aslında oldukça temiz / basit bir veri seti için fena değil.
Biraz Hikaye
Boltzman Makinalarıyla ilgilenmemizin ilginç bir hikayesi var. Aslında bu metot-
tan haberimiz yoktu, ayrıca mevcut işimizde 0/1 içeren ikisel verilerle çok hasır
neşirdik, ve bu tür verilerde ikisel ilişkiler (coöccürence) hesabı iyi sonuçlar verir,
ki bu hesap basit bir matris çarpımı ile elde edilir.
import numpy as np
A = np.array([\
[0.,1.,1.,0],
[1.,1.,0, 0],
[1.,1.,1.,0],
[0, 1.,1.,1.],
[0, 0, 1.,0]
])
c = A.T.dot(A).astype(float)
print c
[[ 2. 2. 1. 0.]
[ 2. 4. 3. 1.]
[ 1. 3. 4. 1.]
[ 0. 1. 1. 1.]]
10
bir kenara koysak bir dağılım gibi kullanamaz mıyız, sonra yeni veri noktasını bu
“dağılıma sorabiliriz” diye düşündük. Biraz matris çarpım cambazlığı sonrası,
yeni veri noktası için
x = np.array([0,1,1,0])
print np.dot(np.dot(x.T,c), x) / 2
7.0
11
Kısıtlı Boltzmann Makinaları (Restricted Boltzmann Machines -RBM-)
RBM aynen Boltzman Makinalarında (BM) örneğinde olduğu gibi bir dağılımdır.
Verilen x, h için bir olasılık değeri geri döndürebilir.
E(x, h) = −hT Wx − cT x − bT h
XX X X
=− Wj,k hj xk − ck xk − b j hj
j k k j
1
Tekrar vurgulayalım, h, x değişkenleri olasılık teorisinden bilinen rasgele değişkenlerdir,
yani hem x’e hem de h’e “zar attırabiliriz” / bu değişkenler üzerinden örneklem
toplayabiliriz.
Ayrıca, RBM’ler aynen BM’ler gibi bir olasılık yoğunluk fonksiyonu üzerinden
tanımlanırlar, önceki formülde gördüğümüz gibi, tüm mümkün değerleri üzerinden
entegralleri (ya da toplamları) alınınca sonuç 1 olur, vs.
Devam edelim, ana formülden hareketle cebirsel olarak şunlar da doğrudur,
çünkü bir toplam üzerindeki exp, ayrı ayrı exp’lerin çarpımı olur. Aynı mantıkla,
eğer ana formülü matris / vektör yerine ayrı değişkenler olarak görmek istersek,
1 YY Y Y
p(x, h; W) = exp(Wjk hj xk ) exp(ck xk ) exp(bj hj )
Z j k k j
E(x, h) = −hT Wx
XX
=− Wj,k hj xk
j k
ve
2
p(x, h; W) = exp(hT Wx)/Z
X 1
1 T
P(x; W) = exp y Wy
h
Z(W) 2
1 X
1 T
P(x; W) = exp y Wy (1)
Z(W) h 2
Ve Z(W)
X
1
Z(W) = exp yT Wy
h,x
2
(1) denkleminde bölümünden sonraki kısma Zx (W) dersek, sanki aynı exp den-
kleminin x’ler üzerinden marjinalize edilmiş hali olarak gösterebiliriz onu, ve
böylece daha kısa bir formül kullanabiliriz,
1 X
1 T
P(x; W) = exp y Wy
Z(W) h 2
| {z }
Zx (W)
O zaman
Zx (W)
P(x; W) =
Z(W)
elde ederiz. Veri üzerinden maksimum olurluk için, yine log üzerinden bir hesap
yaparız, BM için yapmıştık bunu,
3
Y
N X
N
L = ln n
ln P(xn ; W)
P(x ; W) =
n=1 n=1
X
N
Zx(n) (W) X
N
= ln = ln Zx(n) − ln Z
n=1
Z(W) n=1
∂L X ∂ ln Z (n) ∂ ln Z
N
x
= − (3)
∂wij n=1 ∂wij ∂wij
1 X 1 nT
y Wyn yi yj
= exp
Zx(n) h
2
X 1 1 nT
y Wyn yi yj
= exp
h
Zx(n) 2
Üst kısım P(y; W) yani P(x, h; W) alt kısım P(x; W) olmaz mı? Evet! Ve,
P(xn , h; W)
P(h|xn ; W) =
P(xn ; W)
4
olduğuna göre,
X
= P(h|xn ; W)yi yj
h
∂ ln Z X 1 1 X
exp yT Wy yi yj =
= P(y; W)yi yj
∂wij h,x
Z 2 h,x
ki bu son ifadeyi de < yi yj >P(y;W) olarak yazabiliriz. Tamamını, yani (3) ifadesini,
artık şöyle yazabiliriz,
XN
∂ ln Zx(n) ∂ ln Z X
N
− = < yi yj >P(h|xn ;W) − < yi yj >P(y;W) (4)
n=1
∂w ij ∂w ij
n=1
X
m
P(hi = 1|x) = σ wij xj
j=1
X
n
P(xi = 1|h) = σ wij hi
i=1
5
ve tabii ki σ(x) = 1/(1 + e−x ). Daha önce 1 olma olasılığını nasıl örnekleme
çevireceğimizi de görmüştük zaten.
Şimdi CD’nin ne olduğuna gelelim. Eğer RBM için gereken örneklemeyi klasik
Gibbs ile yaparsak örnekleme zincirini “yeterince uzun süre” işletmek gerekir
ki dağılımın olası noktaları gezilmiş olsun. Fakat, özellikle yüksek boyutlu du-
rumlarda, tüm x, h kombinasyonlarını düşünürsek bu çok büyük bir alandır ve
gezme işlemi çok, çok uzun zaman alabilir. Bunun yerine, ve üstteki bağımsızlık
formüllerinden hareketle CD yöntemi bulunmuştur, bu yönteme göre örnekleme
verinin kendisinden başlatılır (kıyasla pür Gibbs rasgele bir noktadan), döngünün
mesela ilk adımında x0 (ki bu tüm verinin tamamı), baz alınarak p(h0 |v0 ) hesa-
planır (üstteki sigmoid), onun üzerinden h0 örneklemi alınır, sonra h0 baz alınır
ve x1 üretilir, bu böyle devam eder. Böylece mümkün h ve x’ler gezilmiş olur.
Not: Sürekli verinin kendisine dönmenin de bazı dezavantajları var, ki bunu yap-
madan pür Gibbs örneklemesine daha yakın bir yaklaşım Kalıcı (Persistent) CD
adlı yöntemdir (tabii başka yaklaşıksal numaralar kullanarak).
Literatürde şu şekildeki resim bolca görülebilir,
Bu yöntem pür Gibbs örneklemesine kıyasla çok daha hızlı işler ve iyi sonuçlar
verir. Teorik olarak niye işlediği [1,2,4] makalelerinde bulunabilir. CD aslında
(4) hedef formülünü değil başka bir hedefi optimize ediyor, fakat sonuç orijinal
gradyan adımlarının yapmak istediğine yakın. [3] baz alınarak, şu şekilde kod-
lanabilir,
import numpy as np
import itertools
class RBM:
6
self.weights = np.insert(self.weights, 0, 0, axis = 1)
self.max_epochs = max_epochs
Parametreler
----------
data: Her satirin "gorunen" veri oldugu bir matris
"""
num_examples = data.shape[0]
tmp = np.array(pos_hidden_states).astype(float)
pos_visible_states = self.run_hidden(tmp[:,1:])
# Agirliklari guncelle
self.weights += self.learning_rate * \
((pos_associations - neg_associations) / num_examples)
7
Parametreler
----------
data: Her satirin gorunen veri oldugu bir matris
Returns
-------
hidden_states: data icindeki her satira tekabul eden gizli h verisi
"""
num_examples = data.shape[0]
num_examples = data.shape[0]
visible_states = visible_states[:,1:]
return visible_states
if __name__ == "__main__":
import numpy as np
X = np.array([[0, 0, 0], [0, 1, 1], [1, 0, 1], [1, 1, 1]])
model = RBM(num_hidden=2,learning_rate=0.1,max_epochs=10,num_visible=3)
model.fit(X)
print model.weights
RBM ve Sınıflama
Sınıflama (classification) işlemi yapmak için BM örneğinde bir normalizasyon
8
sabiti hesaplamıştık. Burada değişik bir yoldan gideceğiz; ki bu yol ileride Derin
Öğrenim için faydalı olacak.
Eğittikten sonra bir RBM, içindeki W’ye göre, herhangi bir “görünür” veri nok-
tası x için bir gizli bir h üretebilir. Bunu üstteki formülasyondan zaten biliy-
oruz. Ayrıca, h genellikle daha az boyutta olduğuna göre (hatta olmasa bile)
bu h üretiminin bir tür transformasyon olduğu, veri üzerinde bir “özetleme”
yaptığı iddia edilebilir. O zaman teorik olarak, görünür veri yerine, görünür
veriden üretilen gizli veriyi kullanırsak ve bu veriyi alıp başka bir sınıflayıcıya
verirsek, mesela lojistik regresyon gibi, bu h’ler ve etiketler üzerinden denetimli
(supervised) bir eğitim yapabiliriz. Yani, önce RBM eğitiyoruz, tüm verinin h
karşılığını alıyoruz, sonra bunları lojistik regresyona veriyoruz. Alttaki kodda
bunun örneğinin görebiliriz.
Bu kod, ayrıca, k-Katlama (k-fold) tekniğini uyguluyor, veriyi 3 parçaya bölüp
sırasıyla tüm parçaları birer kez test, diğerlerini eğitim verisi yapıyor, böylece
verinin tamamı üzerinden eğitim/test yapmış olunuyor. Sonuç,
X = np.loadtxt('../../stat/stat_mixbern/binarydigits.txt')
Y = np.ravel(np.loadtxt('../../stat/stat_mixbern/bindigitlabels.txt'))
print X.shape, Y.shape
np.random.seed(0)
scores = []
cv = KFold(n=len(X),n_folds=3)
for train, test in cv:
X_train, Y_train = X[train], Y[train]
X_test, Y_test = X[test], Y[test]
r = rbm.RBM(num_hidden=40, learning_rate=0.3,max_epochs=500, num_visible=64)
r.fit(X_train)
clf = LogisticRegression(C=1000)
clf.fit(r.run_visible(X_train), Y_train)
res3 = clf.predict(r.run_visible(X_test))
scores.append(np.sum(res3==Y_test) / float(len(Y_test)))
print np.mean(scores)
! python test_rbmkfold.py
1.0
9
X = np.loadtxt('../../stat/stat_mixbern/binarydigits.txt')
Y = np.ravel(np.loadtxt('../../stat/stat_mixbern/bindigitlabels.txt'))
print np.mean(scores)
! python test_knnkfold.py
0.98009506833
Kaynaklar
[1] Hinton, G., Training Products of Experts by Minimizing Contrastive Divergence
[2] Louppe, G., Collaborative filtering, Scalable approaches using restricted Boltzmann
machines, Master Tezi, 2010
[3] https://github.com/echen/restricted-boltzmann-machines
[4] Tieleman, Hinton, Using Fast Weights to Improve Persistent Contrastive Diver-
gence
[5] Larochelle, H., Neural networks [5.1] : Restricted Boltzmann machine - definition,
https://www.youtube.com/watch?v=p4Vh_zMw-HQ
10
Asal Bileşen Analizi (Principal Component Analysis -PCA-)
PCA yöntemi boyut azaltan yöntemlerden biri, denetimsiz (unsupervised) işleyebilir.
Ana fikir veri noktalarının izdüşümünün yapılacağı yönler bulmaktır ki bu yönler
bağlamında (izdüşüm sonrası) noktaların arasındaki sayısal varyans (empirical
variance) en fazla olsun, yani noktalar grafik bağlamında düşünürsek en ”yayılmış”
şekilde bulunsunlar. Böylece birbirinden daha uzaklaşan noktaların mesela daha
rahat kümelenebileceğini umabiliriz. Bir diğer amaç, hangi değişkenlerin varyansının
daha fazla olduğunun görülmesi üzerine, o değişkenlerin daha önemli olabileceğinin
anlaşılması. Örnek olarak alttaki grafiğe bakalım,
plt.scatter(data.ix[:,0],data.ix[:,1])
plt.plot(data.ix[1,0],data.ix[1,1],'rd')
plt.plot(data.ix[4,0],data.ix[4,1],'rd')
plt.savefig('pca_1.png')
PCA ile yapmaya çalıştığımız öyle bir yön bulmak ki, x veri noktalarının tamamının
o yöne izdüşümü yapılınca sonuç olacak, ”izdüşümü yapılmış” z’nin varyansı en
büyük olsun. Bu bir maksimizasyon problemidir. Fakat ondan önce x nedir, z
nedir bunlara yakından bakalım.
Veri x ile tüm veri noktaları kastedilir, fakat PCA probleminde genellikle bir
”vektörün diğeri üzerine” yapılan izdüşümü, ”daha optimal bir w yönü bulma”,
ve ”o yöne doğru izdüşüm yapmak” kelimeleri kullanılır. Demek ki veri nokta-
larını bir vektör olarak görmeliyiz. Eğer üstte kırmızı ile işaretlenen iki noktayı
alırsak (bu noktalar verideki 1. ve 4. sıradaki noktalar),
1
gibi bir görüntüden bahsediyoruz. Hayali bir w kullandık, ve noktalardan biri
veri noktası, w üzerine izdüşüm yapılarak yeni bir vektörü / noktayı ortaya
çıkartılıyor. Genel olarak ifade edersek, bir nokta için
zi = xTi w = xi · w
1X
(xi · w)2
n i
Toplama işlemi yerine şöyle düşünelim, tüm xi noktalarını istifleyip bir x matrisi
haline getirelim, o zaman xw ile bir yansıtma yapabiliriz, bu yansıtma sonucu bir
vektördür. Bu tek vektörün karesini almak demek onun devriğini alıp kendisi ile
çarpmak demektir, yani
1 1
= (xw)T (xw) = wT xT xw
n n
xT x
= wT w
n
= wT Σw
2
yönü gösteriyorlar, bilahere aynı çizgi üzerindeki noktalara dönüşüyorlar. Aynı
çizgi üzerinde olmak ne demek? Tek boyuta inmiş olmak demek.
Ufak bir sorun wT Σw’i sürekli daha büyük w’lerle sonsuz kadar büyütebilirsiniz.
Bize ek bir kısıtlama şartı daha lazım, bu şart ||w|| = 1 olabilir, yani w’nin norm’u
1’den daha büyük olmasın. Böylece optimizasyon w’yi sürekli büyüte büyüte
maksimizasyon yapmayacak, sadece yön bulmak ile ilgilenecek, iyi, zaten biz
w’nin yönü ile ilgileniyoruz. Aradığımız ifadeyi yazalım, ve ek sınırı Lagrange
ifadesi olarak ekleyelim, ve yeni bir L ortaya çıkartalım,
L(w, λ) = wT Σw − λ(wT w − 1)
Niye eksiden sonraki terim o şekilde eklendi? O terim öyle şekilde seçildi ki,
∂L/∂λ = 0 alınınca wT w = 1 geri gelsin / ortaya çıksın [2, sf 340]. Bu Lagrange’in
dahice buluşu. Bu kontrol edilebilir, λ ’ya göre türev alırken w1 sabit olarak
yokolur, parantez içindeki ifadeler kalır ve sıfıra eşitlenince orijinal kısıtlama
ifadesi geri gelir. Şimdi
max L(w, λ)
w
∂L
= 2wΣ − 2λw = 0
∂w
2wΣ = 2λw
Σw = λw
Üstteki ifade özdeğer, özvektör ana formülüne benzemiyor mu? Evet. Eğer w,
Σ’nin özvektörü ise ve eşitliğin sağındaki λ ona tekabül eden özdeğer ise, bu
eşitlik doğru olacaktır.
Peki hangi özdeğer / özvektör maksimal değeri verir? Unutmayalım, maksimize
etmeye çalıştığımız şey wT Σw idi
Eger Σw = λw yerine koyarsak
wT λw = λwT w = λ
Çünkü wT1 w’nin 1 olacağı şartını koymuştuk. Neyse, maksimize etmeye çalıştığımız
değer λ çıktı, o zaman en büyük λ kullanırsak, en maksimal varyansı elde ederiz,
bu da en büyük özdeğerin ta kendisidir. Demek ki izdüşüm yapılacak ”yön” ko-
varyans Σ’nin en büyük özdeğerine tekabül eden özvektör olarak seçilirse, temel
3
bileşenlerden en önemlisini hemen bulmuş olacağız. İkinci, üçüncü en büyük
özdeğerin özvektörleri ise diğer daha az önemli yönleri bulacaklar.
Σ matrisi n×n boyutunda bir matris, bu sebeple n tane özvektörü olacak. Her ko-
varyans matrisi simetriktir, o zaman lineer cebir bize der ki özvektörler birbirine
dikgen (orthogonal) olmalı. Yıne Σ bir kovaryans matrisi olduğu için pozitif bir
matris olmalı, yani herhangi bir x için xΣx > 0. Bu bize tüm özvektörlerin > 0
olması gerektiğini söylüyor.
Kovaryansın özvektörleri verinin asal bileşenleridir (principal components), ki
metotun ismi burada geliyor.
Örnek
Şimdi tüm bunları bir örnek üzerinde görelim. İki boyutlu örnek veriyi üstte
yüklemiştik. Şimdi veriyi ”sıfırda ortalayacağız” yani her kolon için o kolo-
nun ortalama değerini tüm kolondan çıkartacağız. PCA ile işlem yaparken tüm
değerlerin sıfır merkezli olması gerekiyor, çünkü bu sayısal kovaryans için gerekli.
Daha sonra özdeğer / vektör hesabı için kovaryansı bulacağız.
means = data.mean()
meanless_data = data - means
cov_mat = np.cov(meanless_data, rowvar=0)
print (cov_mat.shape)
eigs,eigv = lin.eig(cov_mat)
eig_ind = np.argsort(eigs)
print (eig_ind)
(1000, 2)
0 1
0 10.235186 11.321997
1 10.122339 11.810993
2 9.190236 8.904943
3 9.306371 9.847394
4 8.330131 8.340352
5 10.152785 10.123532
6 10.408540 10.821986
7 9.003615 10.039206
8 9.534872 10.096991
9 9.498181 10.825446
(2, 2)
[0 1]
print (eigs[1],eigv[:,1].T)
print (eigs[0],eigv[:,0].T)
2.8971349561751887 [-0.52045195 -0.85389096]
0.36651370866931066 [-0.85389096 0.52045195]
4
En büyük olan yönü quiver komutunu kullanarak orijinal veri seti üzerinde gösterelim,
plt.scatter(data.ix[:,0],data.ix[:,1])
# merkez 9,9, tahminen secildi
plt.quiver(9,9,eigv[1,1],eigv[0,1],scale=10,color='r')
plt.savefig('pca_2.png')
plt.scatter(data.ix[:,0],data.ix[:,1])
plt.quiver(9,9,eigv[1,0],eigv[0,0],scale=10,color='r')
plt.quiver(9,9,eigv[1,1],eigv[0,1],scale=10,color='r')
plt.savefig('pca_3.png')
Bu ikinci yön birinciye dik olmalıydı, ve o da bulundu. Aslında iki boyut olunca
başka seçenek kalmıyor, 1. yön sonrası ikincisi başka bir şey olamazdı, fakat çok
daha yüksek boyutlarda en çok yayılımın olduğu ikinci yön de doğru şekilde geri
getirilecekti.
Artımsal PCA (Incremental PCA)
Toptan işlem yapmak yerine ufak parçalar üzerinde PCA işletebilmek için [9]’deki
fikir kullanılabilir. Böylece elimize yeni bir veri geçince tüm önceki veriler +
yeni veriyi birarada işlememize gerek kalmıyor. Eldeki son PCA durumunu yeni
veriyi kullanarak güncelliyoruz. Bu sekilde isleyen bir PCA teknigi CCIPCA.
5
import scipy.sparse as sp
import numpy as np
from scipy import linalg as la
import scipy.sparse as sps
from sklearn import datasets
class CCIPCA:
def __init__(self, n_components, n_features, amnesic=2.0, copy=True):
self.n_components = n_components
self.n_features = n_features
self.copy = copy
self.amnesic = amnesic
self.iteration = 0
self.mean_ = None
self.components_ = None
self.mean_ = np.zeros([self.n_features], np.float)
self.components_ = np.ones((self.n_components,self.n_features)) / \
(self.n_features*self.n_components)
# update mean
self.mean_ = w1*self.mean_ + w2*u
# mean center u
u = u - self.mean_
# update components
for j in range(0,self.n_components):
if j > n: pass
elif j == n: V[j,:] = u
else:
# update the components
V[j,:] = w1*V[j,:] + w2*np.dot(u,V[j,:])*u / la.norm(V[j,:])
normedV = V[j,:] / la.norm(V[j,:])
normedV = normedV.reshape((self.n_features, 1))
u = u - np.dot(np.dot(u,normedV),normedV.T)
self.iteration += 1
self.components_ = V / la.norm(V)
return
def post_process(self):
6
self.explained_variance_ratio_ = np.sqrt(np.sum(self.components_**2,axis=1))
idx = np.argsort(-self.explained_variance_ratio_)
self.explained_variance_ratio_ = self.explained_variance_ratio_[idx]
self.components_ = self.components_[idx,:]
self.explained_variance_ratio_ = (self.explained_variance_ratio_ / \
self.explained_variance_ratio_.sum())
for r in range(0,self.components_.shape[0]):
d = np.sqrt(np.dot(self.components_[r,:],self.components_[r,:]))
self.components_[r,:] /= d
df = pd.read_csv('../../stat/stat_cov_corr/iris.csv')
df = np.array(df)[:,:4].astype(float)
pca = ccipca.CCIPCA(n_components=2,n_features=4)
S = 10
print (df[0, :])
for i in range(150): pca.partial_fit(df[i, :])
pca.post_process()
print ('varyans orani',pca.explained_variance_ratio_)
print ('sonuc', pca.components_.T)
A = USV T
7
U matrisi n × n dikgen (orthogonal), V ise m × m dikgen. S’in sadece köşegeni
üzerinde değerler var ve bu σj değerleri A’nin eşsiz değerleri (singular values)
olarak biliniyor.
Şimdi A yerine AAT koyalım, ve bu matrisin SVD ayrıştırmasını yapalım, acaba
elimize ne geçecek?
= (USV T )(VST UT )
= USST UT
S bir köşegen matrisi, o zaman SST matrisi de köşegen, tek farkla köşegen üzerinde
artık σ2j değerleri var. Bu normal.
SST yerine Λ sembolünü kullanalım, ve denklemi iki taraftan (ve sağdan) U ile
çarparsak (unutmayalım U ortanormal bir matris ve UT U = I),
AAT U = UΛUT U
AAT U = UΛ
Son ifadeye yakından bakalım, U’nun tek bir kolonuna, uk diyelim, odaklanacak
olursak, üstteki ifadeden bu sadece kolona yönelik nasıl bir eşitlik çıkartabilirdik?
Şöyle çıkartabilirdik,
(AAT )uk = σ2 uk
Bu ifade tanıdık geliyor mu? Özdeğer / özvektör klasik yapısına eriştik. Üstteki
eşitlik sadece ve sadece eğer uk , AAT ’nin özvektörü ve σ2 onun özdeğeri ise
geçerlidir. Bu eşitliği tüm U kolonları için uygulayabileceğimize göre demek ki
U’nun kolonlarında AAT ’nin özvektörleri vardır, ve AAT ’nin özdeğerleri A’nin
eşsiz değerlerinin karesidir.
Bu müthiş bir buluş. Demek ki AAT ’nin özektörlerini hesaplamak için A üzerinde
SVD uygulayarak U’yu bulmak ise yarar, kovaryans matrisini hesaplamak gerekli
değil. AAT özdeğerleri üzerinde büyüklük karşılaştırması için ise A’nin eşsiz
değerlerine bakmak yeterli!
Dikkat, daha önce kovaryansı AT A olarak tanımlamıştık, şimdi AAT ifadesi görüyoruz,
bir devrik uyuşmazlığı var, bu sebeple, aslında AT ’nin SVD’si alınmalı (altta
görüyoruz).
8
Örnek
İlk bölümdeki örneğe dönelim, ve özvektörleri SVD üzerinden hesaplatalım.
U,s,Vt = svd(meanless_data.T,full_matrices=False)
print U
[[-0.52045195 -0.85389096]
[-0.85389096 0.52045195]]
print np.dot(U.T,U)
[[ 1.00000000e+00 3.70255042e-17]
[ 3.70255042e-17 1.00000000e+00]]
9
Yüklemeyi yapıp sadece etiketleri aldık ve onları bir kenara koyduk. Şimdi önemli
bir normalizasyon işlemi gerekiyor - ki bu işleme ters doküman-frekans ağırlıklandırması
(inverse document-frequency weighting -IDF-) ismi veriliyor - her dokümanda
aşırı fazla ortaya çıkan kelimelerin önemi özellikle azaltılıyor, ki diğer kelimelerin
etkisi artabilsin.
IDF kodlaması alttaki gibidir. Önce class.labels kolonunu atarız. Sonra ”her-
hangi bir değer içeren” her hücrenin 1 diğerlerinin 0 olması için kullanılan DataFrame
üzerinde astype(bools) işletme numarasını kullanırız, böylece aşırı büyük değerler
bile sadece 1 olacaktır. Bazı diğer işlemler sonrası her satırı kendi içinde tekrar
normalize etmek için o satırdaki tüm değerlerin karesinin toplamının karekökünü
alırız ve satırdaki tüm değerler bu karekök ile bölünür. Buna Öklitsel (Euclidian)
normalizasyon denebilir.
Not: Öklitsel norm alırken toplamın hemen ardından çok ufak bir 1e-16 değeri
eklememize dikkat çekelim, bunu toplamın sıfır olma durumu için yapıyoruz, ki
sonra sıfırla bölerken NaN sonucundan kaçınalım.
nyt2 = nyt.drop('class.labels',axis=1)
freq = nyt2.astype(bool).sum(axis=0)
freq = freq.replace(0,1)
w = np.log(float(nyt2.shape[0])/freq)
nyt2 = nyt2.apply(lambda x: x*w,axis=1)
nyt2 = nyt2.apply(lambda x: x / np.sqrt(np.sum(np.square(x))+1e-16), axis=1)
nyt2=nyt2.ix[:,1:] # ilk kolonu atladik
print nyt2.ix[:8,102:107]
import pandas as pd
df = pd.DataFrame([[1.,1.,np.nan],
[1.,2.,0.],
[1.,3.,np.nan]])
print df
print df.div(df.sum(axis=0), axis=1)
0 1 2
0 1 1 NaN
1 1 2 0
2 1 3 NaN
0 1 2
10
0 0.333333 0.166667 NaN
1 0.333333 0.333333 NaN
2 0.333333 0.500000 NaN
SVD yapalım
print u.shape
(4430, 102)
SVD’nin verdiği u içinden iki özvektörü seçiyoruz (en baştakiler, çünkü Numpy
SVD kodu bu özvektörleri zaten sıralanmış halde döndürür), ve veriyi bu yeni
kordinata izdüşümlüyoruz.
Şimdi aynı veriyi bir de etiket bilgisini devreye sokarak çizdirelim. Sanat kırmızı
müzik mavi olacak.
11
Görüldüğü gibi veride ortaya çıkan / özvektörlerin keşfettiği doğal ayırım, hakikaten
doğruymuş.
Metotun ne yaptığına dikkat, bir sürü boyutu bir kenara atmamıza rağmen geri
kalan en önemli 2 boyut üzerinden net bir ayırım ortaya çıkartabiliyoruz. Bu PCA
yönteminin iyi bir iş becerdiğini gösteriyor, ve kelime sayılarının makalelerin
içeriği hakkında ipucu içerdiğini ispatlıyor.
Not: Lineer Cebir notlarımızda SVD türetilmesine bakınca özdeğer/vektör mantığına
atıf yapıldığını görebiliriz ve akla şu gelebilir; ”özdeğer / vektör rutini işletmekten
kurtulalım dedik, SVD yapıyoruz, ama onun içinde de özdeğer/vektör hesabı
var”. Fakat şunu belirtmek gerekir ki SVD sayısal hesabını yapmanın tek yöntemi
özdeğer/vektör yöntemi değildir. Mesela Numpy Linalg kütüphanesi içindeki
SVD, LAPACK dgesdd rutinini kullanır ve bu rutin iç kodlamasında QR, ve bir
tür böl / istila et (divide and conquer) algoritması işletmektedir.
Kaynaklar
[1] Alpaydın, E., Introduction to Machine Learning, 2nd Edition
[2] Strang, G., Linear Algebra and Its Applications, 4th Edition
[3] Wood, Principal Component Analysis, Lecture,http://www.robots.ox.ac.
uk/˜fwood/teaching/index.html
[4] Cosma Shalizi, Advanced Data Analysis from an Elementary Point of View
[5] The New York Times Annotated Corpus, http://www.ldc.upenn.edu/Catalog/
CatalogEntry.jsp?catalogId=LDC2008T19
[6] Shalizi, Statistics 36-350: Data Mining Lecture,http://www.stat.cmu.edu/
˜cshalizi/350/
[7] Goodman, Risk and Portfolio Management with Econometrics, http://www.
math.nyu.edu/faculty/goodman/teaching/RPME/notes/Section3.pdf
[8] Collins, Introduction to Computer Vision, http://www.cse.psu.edu/˜rtc12/
CSE486/
12
[9] Weng, Candid Covariance-free Incremental Principal Component Analysis, https:
//pdfs.semanticscholar.org/4e22/d6b9650a4ff9ccc8c9b860442d162d559025.
pdf
[10] Bayramli, Lineer Cebir Ders 29
13
Dairesel Baz Fonksiyonları (Radial Basis Functions -RBF-), Yükseklik Verisi, Dağlar
Ara değerlemek (interpolation), yani elde olan veriyi kullanıp olmayan hakkında
tahmin yapmaya uğraşmak için çok boyutlu ortamda RBF iyi işleyen bir yaklaşım.
Belki de zihinde en rahat canlandırılabilecek örnek yeryüzünde dağlara ovalara
tekabül eden yükseklik (elevation) verilerini alarak onlara sürekli tepe fonksiy-
onları “uydurmak” böylece dağların nerede olduğunu sürekli şekilde saptamak.
Temsil etmek istediğimiz (ama bilmediğimiz) fonksiyon z = g(x, y) olarak gösterilebilecek
bir fonksiyon, bir düzlemde herhangi bir x, y noktasındaki yükseklik z. Bu fonksiyon-
dan örneklenerek alınmış verilerle onu yaklaşık olarak temsil etmek istiyoruz.
Düz verinin kendisini kullanmak bağlamında düşük çözünürlükte yükseklik verisi
ise yaramayabilir, mesela bir örneklem noktası dağın bir eteğinden diğeri öteki
yanındaki eteğinden alınmışsa bu dağ yok anlamına gelecektir. Peki o zaman
niye yükseklik verisinin geldiği yerden daha yüksek çözünürlüklü veri almıyoruz?
Bu hem erişim hem de tutacağı yer bağlamında pahalı olabilir. 1 derecelik enlem
/ boylam içinde, mesela 36-37 ve 32-33 arası diyelim, 100 metrelik çözünürlük
demek 0.001 derece değişimine tekabül eder, ve bu durumda 1 milyon veri nok-
tası alınması gerekecektir. Halbuki yükseklik verisinden yüzde 3 miktarında bile
[2] bir rasgele örneklem alırsak, bu noktalara RBF ile tepe fonksiyonları uydu-
rarak matematiksel, sürekli olan bir genel fonksiyon elde ederiz, ve uydurma iyi
işlerse artık istediğimiz çözünürlükte yükseklik verisi elde edebiliriz çünkü elim-
izdeki sürekli fonksiyona istediğimiz her nokta için yükseliğin ne olduğunu artık
hesaplattırabiliriz.
Bu örneği 3 boyutta herhangi bir başka veri için de düşünmek mümkün; ama
yükseklik verisinde daha rahat, her örneklem noktasına konulan tepeler ve on-
ların birleşimi bize pürüzsüz, sürekli bir engebe şekli verir. RBF baz fonksiyonları
Φ(x) = f(||x − c||) şeklindedir, f tepe, ya da farklı bir fonksiyon olabilir, || · || norm
fonksiyonudur, Öklitsel norm olabilir mesela.
Burada c üstüne baz fonksiyon konulan nokta, her örneklem veri noktası yani.
RBF eğitimi / uydurma metadolijisine göre herhangi bir veri noktası dışındaki
tüm diğer örneklem verileri o veri noktasının oluşumunu etkiler. Bu anormal
bir faraziye değil, bir dağın başında, ortasında, tepesinden alınmış örneklemler
varsa, mesela en alt ve en tepedeki veri ortadakini etkiler, yani o bağlantıyı,
ilişkiyi farzetmek normaldir. Orta nokta zirveyi tanımlayan fonksiyona belli bir
ağırlıkla bağlı, en alttakine başka bir şekilde bağlı, vs. Bu ağırlıkların ne olacağını
genel çözüm belirleyecektir. Eğer f için Gaussian’ımsı bir tepe fonksiyonu seçersek,
yeni gözlemin baz fonksiyonları ile arasındaki ilişki,
X
N
h(x) = wn × exp(−γkx − mi k2 )
i=1
1
ya da xi , yi verisine bakarak bu fonksiyonları bulacağız.
İki üstteki formüldeki x − c kullanımına dikkat, bu aslında “diğer noktaları” tem-
sil etmenin akıllıca bir yolu, c üzerinde x − c sıfır değerdedir, bu o noktayı tem-
sil için diğer noktalar üzerindeki bazların devreye girmesi gerektiğini modelde
söyler.
Her bazın etkisi wn ağırlığı üzerinden modele yansıtılır. Bu ağırlıkların ne olduğunu
bulmak, nihai genel fonksiyonu bulmuş olmak anlamına gelir. Farklı indislerle
tekrar belirtmek gerekirse her veri noktası için şu doğru olmalı,
Bu bize N tane veri noktası için N tane denklem ve N tane bilinmeyen sağlar. El-
deki (x1 , y1 ), ..., (xN , yN ) verileri ile w’yi bulmamızı sağlayacak regresyonu matris
formunda şöyle gösterebiliriz,
exp(−γkx1 − m1 k2 ) · · · exp(−γkx1 − mN k2 ) w1 y1
exp(−γkx2 − m1 k2 ) · · · exp(−γkx2 − mN k2 ) w2 y2
=
.. . . .. .. ..
. . . . .
exp(−γkxN − m1 k2 ) · · · exp(−γkxN − mN k2 ) wN yN
| {z } | {z } | {z }
Φ w y
Tabii aslında verilerin kendisi RBF merkezleriyle aynı şey olduğu için şunu da
söyleyebilirdik,
exp(−γkx1 − x1 k2 ) · · · exp(−γkx1 − xN k2 ) w1 y1
exp(−γkx2 − x1 k2 ) · · · exp(−γkx2 − xN k2 ) w2 y2
=
.. . . .. .. ..
. . . . .
2 2
exp(−γkxN − x1 k ) · · · exp(−γkxN − xN k ) wN yN
| {z } | {z } | {z }
Φ w y
Şimdi direk bilinen iki RBF kullanalım, böylece her şeyin nasıl biraraya geldiği
ileride daha iyi anlaşılır. Bizim tanımladığımız ağırlıklar, ve iki RBF ile şu şekilde
bir grafik oluşturabilirdik,
2
D = 50
gamma = 2.0
x = np.linspace(36,37,D)
y = np.linspace(32,33,D)
xx,yy = np.meshgrid(x,y)
xm = np.array([[36.06122449],
[36.71428571]])
ym = np.array([[32.67346939],
[32.32653061]])
X = np.hstack((xm,ym))
Phi = np.exp(-gamma*cdist(X,X,metric='euclid'))
w = np.array([[0.5],[0.5]])
xxx = xx.reshape(D*D)
yyy = yy.reshape(D*D)
a = np.vstack((xxx,yyy))
d = cdist(X,a.T)
d = np.exp(-gamma * d)
dd = np.dot(w.T,d)
znew = dd.reshape(D,D)
fig = plt.figure()
ax = fig.gca(projection='3d')
surf = ax.plot_surface(xx, yy, znew, cmap=cm.coolwarm,linewidth=0, antialiased=False)
plt.savefig('linear_app88rbf_04.png')
3
xm1 = [36.06, 32.67], xm2 = [36.71, 32.32], xtest = [36.16, 32.77]
[0.6637959]
Gerçek dünya şartlarına yaklaşırsak; bu tür durumlarda çok daha fazla baz fonksiyon,
örneklem kullanılır, altta func fonksiyonu örneklem üretmek için kullanılacak,
normal şartlarda bu fonksiyonu bilmiyoruz, sadece ondan gelen örneklem veri-
lerini biliyoruz. Bir örnek amaçlı, belli bir şekli zorlamak için bunu yaptık.
np.random.seed(0)
D = 50
S = 100
gamma = 2.0
x = np.linspace(36,37,D)
y = np.linspace(32,33,D)
xx,yy = np.meshgrid(x,y)
zz = func(xx,yy)
fig = plt.figure()
ax = fig.gca(projection='3d')
surf = ax.plot_surface(xx, yy, zz, cmap=cm.coolwarm,linewidth=0, antialiased=False)
plt.savefig('linear_app88rbf_01.png')
4
İki tane tepe var. Şimdi bu fonksiyondan rasgele örneklem alalım, ve Φ üzerinden
RBF ağırlıklarını hesaplayalım,
xxx = xx.reshape(D*D)
yyy = yy.reshape(D*D)
zzz = zz.reshape(D*D)
idx = np.random.choice(range(D*D),S)
xr = xxx[idx].reshape(S,1)
yr = yyy[idx].reshape(S,1)
zr = zzz[idx].reshape(S,1)
X = np.hstack((xr,yr))
Phi = np.exp(-gamma*cdist(X,X,metric='euclid'))
w = np.dot(lin.pinv(Phi),zr)
a = np.vstack((xxx,yyy))
d = cdist(X,a.T)
d = np.exp(-gamma * d)
dd = np.dot(w.T,d)
znew = dd.reshape(D,D)
fig = plt.figure()
ax = fig.gca(projection='3d')
surf = ax.plot_surface(xx, yy, znew, cmap=cm.coolwarm,linewidth=0, antialiased=False)
plt.savefig('linear_app88rbf_02.png')
5
Pek optimizasyon yapmadık, ama orijinale benzidiği söylenebilir.
Not: cdist bir veri matrisindeki her satır ile her diğer satır arasında (tüm kombi-
nasyonlar) mesafe hesabı yapar.
Yeni tek bir veri noktası için
xnew = np.array([[36.5,32.5]])
print (np.multiply(w.T,np.exp(-gamma*lin.norm(X-xnew,axis=1))).sum())
0.6423871447150892
Bu yaklaşımı tüm dünyanın yeryüzü dağ, tepe veri tabanını oluşturmak için
kullanabiliriz. 1 milyon veri yerine onun yüzden 3’u üzerinden RBF işlettikten
sonra x, y, w değerlerini tutarız, gerisini atarız. Bu üç değer geniş bir bölgeyi
pürüzsüz fonksiyonlarla yaklaşık temsil etmenin en iyi yolu. Veri tabanı sadece
bu değerleri taşıyacak.
Bizim bu konuya girmemizin sebebi Google Elevation API ile aldığımız yükseklik
verilerini verimli şekilde kullanma ihtiyacı idi.
Simdi scipy ile ayni isleri yapalim,
np.random.seed(0)
S = 200
x = np.linspace(36,37,D)
y = np.linspace(32,33,D)
xx,yy = np.meshgrid(x,y)
znew = func(xx,yy)
xx = xx.reshape(D*D)
yy = yy.reshape(D*D)
znew = znew.reshape(D*D)
6
rbfi = Rbf(xx,yy,znew,function='gaussian')
znew = rbfi(xx,yy)
xx = xx.reshape(D,D)
yy = yy.reshape(D,D)
znew = znew.reshape(D,D)
fig = plt.figure()
ax = fig.gca(projection='3d')
surf = ax.plot_surface(xx, yy, znew, cmap=cm.coolwarm,linewidth=0, antialiased=False)
plt.savefig('linear_app88rbf_05.png')
Not: scipy ile bize döndürülen ve ara değerleme için direk çağırılabilen objeyi
gerekli her türlü bilgiyi içinde taşıyor. Yani modeli çıkartıp veriyi atıp, sadece bu
objeyi (mesela pickle ile) diskte saklayabiliriz, bu tek başına yeterlidir.
Modelleme scipy İle, Tekrar Yaratmak Elle Yazılan Fonksiyon İle
Bir diğer yaklaşım veriyi örneklemek, scipy ile RBF’leri yaratmak, ama sciy
parametrelerini kullanarak modeli kendimizin tekrar yaratması. Bunun değişik
sebepleri olabilir, belki veriyi modelleyen bir yükseklik fonksiyonu üzerinde otomatik
türev almak istiyoruz, ama scipy içindeki versiyon ile bunu yapamıyoruz. Ya da
motor kapağı altında nelerin olup bittiğini daha iyi anlamak istiyoruz.
Her neyse, yine iki tepeli ortamı yaratıyoruz,
np.random.seed(0)
7
D = 100
x = np.linspace(36,37,D)
y = np.linspace(32,33,D)
xx,yy = np.meshgrid(x,y)
zz = func(xx,yy)
Ve grafiklemeyi yapıyoruz,
xx = xx.reshape(D,D)
yy = yy.reshape(D,D)
zz = func(xx,yy)
fig = plt.figure()
ax = fig.gca(projection='3d')
ax.view_init(elev=29, azim=29)
surf = ax.plot_surface(xx, yy, zz, cmap=cm.coolwarm,linewidth=0, antialiased=False)
plt.savefig('linear_app88rbf_03.png')
S = 50
np.random.seed(0)
idx = np.random.choice(range(D*D),S)
xr = xx.reshape(D*D)[idx].reshape(S,1)
yr = yy.reshape(D*D)[idx].reshape(S,1)
zr = zz.reshape(D*D)[idx].reshape(S,1)
rbfi = Rbf(xr,yr,zr,function='gaussian',epsilon=0.15)
ifadesini görüyoruz, burada r yeni nokta ile bir RBF baz fonksiyonu arasındaki
mesafe. Bir test noktası ile üstteki RBF’leri (D*D tane) arasındaki mesafe şöyle
hesaplanabilir,
8
return D
test_1 = np.array([[36.0,32.0]])
test_1_dist = dist_matrix(test_1, rbfi.xi.T)
print (test_1_dist.shape)
print (test_1_dist[0][:10])
(1, 50)
[0.4229176 1.08927112 0.72276945 0.76827462 0.96299239 1.21064725
0.85578867 0.94970984 0.80965755 0.76794254]
O mesafeyi alıp eksi karesini hesaplayıp exp’ye vermek lazım. Tüm RBF’leri de
bir şekilde dahil etmek lazım tabii, o da hesaplanan ağırlıklar ile üstteki sonucu
çarpıp hepsini toplamakla olur. Gerekli parametreler rbfi içinde,
print (rbfi.epsilon)
print (rbfi.smooth)
print (rbfi.xi.shape)
print (rbfi.nodes.shape)
0.15
0.0
(2, 50)
(50,)
Ağırlıklar nodes, RBF merkezleri xi, epsilon genel bir pürüz parametresi. İki test
noktası üzerinde görelim, dikkat burada tüm RBF’ler gözönüne alınacak,
nodes = rbfi.nodes.reshape(1,len(rbfi.nodes))
def gaussian(r,eps): return np.exp(-(r/eps)**2)
test_2 = np.array([[36.0,32.0],[36.1,31.9]])
print (f_interp(test_2,rbfi))
[[-0.00387063]
[-0.00337065]]
fig = plt.figure()
ax = fig.gca(projection='3d')
ax.view_init(elev=29, azim=29)
surf = ax.plot_surface(xx, yy, znewnew, cmap=cm.coolwarm,linewidth=0, antialiased=Fals
plt.savefig('linear_app88rbf_06.png')
9
RBF Türev ve Hessian Matrisi
Ana formülü hatırlayalım,
X
m
f(x) = βi φ(||x − xi ||)
i=1
∂g X
m
∂f(x) ∂ri
= βT = βi φ 0 (ri )
∂x ∂x i=1
∂x
ri (x) = ||x − xi || =
p
(x − xi )T (x − xi ) (1)
Ayrıca
∂ri 1
= (x − xi )T
∂x ri (x)
∂f(x) X βi φ 0 (ri )
m
= (x − xi )T
∂x i=1
ri (x)
10
Hessian’ı alttaki gibi hesaplayabiliriz [3]. [4]’teki formül
m
∂2 f(x) X φ 0 (ri )
0 00 ∂ri
= φ (ri )I + φ (ri ) − (x − xi ) (2)
∂x2 i=1
ri (x) ∂x
Ω = w1 w2 . . . wm ∈ Rn×m
dΩ = dx dx . . . dx = dx 1T
wk = Ω ek , dx = dΩ ek , rj = eTj r
şeklinde yazmamıza izin veriyor. RBF’i öğesel bazda uygulayarak indisli toplam
notasyonundan kurtulmuş oluyoruz. Şimdi türevleri, diferansiyelleri
dg = g 0 dr, dg 0 = g 00 dr ∈ Rm
r = diag(R), g = diag(G), g 00 = . . .
r = R1, g = G1, g 00 = . . .
dg = G 0 dr, dg 0 = G 00 dr
11
P = R−1 =⇒ PR = I, p r = 1
r r = diag(ΩT Ω)
R dr = diag(ΩT dx 1T ) = ΩT dx
dr = PΩT dx
∂r
= PΩT
∂x
∂ri 1 T T wTi
= ei Ω =
∂x ri kwi k
f = bT g = b : g
İki nokta üst üste iz (trace) için Frobenius çarpım notasyonudur, mesela A : B =
Tr(AT B).
Şimdi Hessian
dJ = dΩ PG 0 B1 + ΩPdG 0 B1 + Ω dP G 0 B1
12
= (G 0 : PB) dx + ΩPBG 00 dr − ΩPG 0 PB dr
= (G 0 : PB)I + ΩPB(G 00 − PG 0 )PΩT dx
∂J
H= = (G 0 : PB)I + ΩPB(G 00 − PG 0 )PΩT
∂x
T ∂r
0
∂r 00 0
= (p b) : g I + BG − BPG
∂x ∂x
nodes = rbfi.nodes.reshape(1,len(rbfi.nodes))
def gaussian(r,eps): return anp.exp(-(r/eps)**2)
def f_interp(newp):
nodes = rbfi.nodes.reshape(1,len(rbfi.nodes))
newp_dist = dist_matrix(newp, rbfi.xi.T)
return anp.dot(gaussian(newp_dist, rbfi.epsilon), nodes.T)
test_1 = anp.array([36.0,32.0])
test_1_dist = dist_matrix(test_1, rbfi.xi.T)
print ('f',f_interp(test_1))
grbf = autograd.grad(f_interp)
hrbf = autograd.hessian(f_interp)
print ('gradyan',grbf(test_1))
print ('hessian',hrbf(test_1))
13
f [[-0.00387063]]
gradyan [0.02331737 0.08191414]
hessian [[[[0.6466522 0.74921925]
[0.74921925 1.92847522]]]]
import hammer
print (hammer.hammersley([2,3],10))
[[0. 0. ]
[0.1 0. ]
[0.2 0.5 ]
[0.3 0.25 ]
[0.4 0.75 ]
[0.5 0.125 ]
[0.6 0.625 ]
[0.7 0.375 ]
[0.8 0.875 ]
[0.9 0.0625]]
Mesela
def peaks(x,y):
z = (3*(1-x)**2 * np.exp(-(x**2) - (y+1)**2)
- 10*(x/5 - x**3 - y**5) * np.exp(-x**2 - y**2)
- 1/3 * np.exp(-(x+1)**2 - y**2))
return(z)
n = 20
x = -3 + 6*hammer.hammersley([2,3],n)
z = peaks(x[:,0],x[:,1])
xx, yy = np.mgrid[-3:3:150j,-3:3:150j]
zz = peaks(xx,yy)
fig=plt.figure()
ax = fig.add_subplot(111,projection='3d')
ax.plot_surface(xx,yy,zz,rstride=1,cstride=1,color='c',alpha=0.3,linewidth=0)
ax.scatter(x[:,0],x[:,1],z,color='k',s=20)
plt.savefig('linear_app88rbf_07.png')
14
Görüldüğü gibi oldukca çetrefil bir fonksiyon bu,
2 −x21 −(−x22 +1)2 x1 3 5 2 2 1 2 2
f(x1 , x2 ) = 3(1 − x1 ) e − 10 − x1 − x2 e−x1 −x2 − e−(x1 +1) −x2
5 3
15
Uygulama - Yağmur Yağış Verisi
Yağış verisini nasıl analiz ederiz? Bir örnek üzerinde görelim, [1]’den alınan Sin-
gapur yağış verisi,
import pandas as pd
df = pd.read_csv('rainfall.csv',index_col=0,parse_dates=['dt'])
df.columns = ['rain']
print (df)
rain
dt
2015-01-01 0.6
2015-01-02 0.0
2015-01-03 0.0
2015-01-04 0.0
2015-01-05 0.0
... ...
2022-01-27 0.0
2022-01-28 0.0
2022-01-29 0.0
2022-01-30 3.8
2022-01-31 0.0
Yağış verisi milimetre yağış miktarı olarak gösterilmiş. Bazı günlerde hiç yağış
yok, o günlerde su sıfır milimetre.
Bu verinin dağılımını görmek ilginç olabilir. Tabii her ayın yağış dağılımı farklı
olabilir, mesela altta Mart ayına bakalım,
x = df[df.index.month == 3]['rain']
Bu veriye ne tür dağılım uygun olur? Literatürde pek çok kullanım var. Bazıları
Gamma, bazıları Weibull diyor. Biz altta ikisini de test edeceğiz.
1
Hem veriden gelen histogramı hem de olasılık yoğunluk fonksiyonunu aynı grafikte
gösterdik, kabaca ilk kontrol bu şekilde yapılabilir.
Daha detayli veriye olan uygunluğu kontrol için olasılık dağılımları arasında bir
yakınlık ölçüsü olan Kullback-Leibler mesafesini [2] kullanalım. Veri histogramı
ve tahmin edilen dağılım üzerinden üretilenlerin histogramı arasında mesafeyi
alttaki fonksiyon kl ile ölçebiliriz,
b = range(0,50)
eps = 1e-5
s = 4000
dh = np.histogram(df.rain, bins=b, density=True)[0]+eps
r1 = gamma.rvs(a,loc,scale,size=s)
h1 = np.histogram(r1, bins=b, density=True)[0]+eps
print ('Gamma', kl(h1, dh))
Gamma 0.288253598547884
2
r2 = weibull_min.rvs(a,loc,scale,size=s)
h2 = np.histogram(r2, bins=b, density=True)[0]+eps
print ('Weibull Min', kl(h2, dh))
Weibull Min 0.06795850872796806
df = pd.read_csv('rainfall.csv',index_col=0,parse_dates=['dt'])
df.columns = ['rain']
3
df['r1ago'] = df.rain.shift(1)
df['r2ago'] = df.rain.shift(2)
df['D1'] = df.apply(lambda row: (row.r1ago > 0.0).astype(int), axis=1)
df['D2'] = df.apply(lambda row: (row.r2ago > 0.0).astype(int), axis=1)
df['D0'] = df.apply(lambda row: (row.rain > 0.0).astype(int), axis=1)
pd.set_option('display.max_columns', None)
print (df)
g = df.groupby(['D1','D2','D0']).size().reset_index()
print (g)
D1 D2 D0 0
0 0 0 0 633
1 0 0 1 269
2 0 1 0 268
3 0 1 1 228
4 1 0 0 244
5 1 0 1 253
6 1 1 0 253
7 1 1 1 440
Bu sayıları nasıl Markov matrisine çevireceğimizi anlamak için [1, sf. 193].
Konumları etiketlemek için alttakini yapalım,
D1 D2 0
D0 0 1
0 0 0 633 269
1 0 1 268 228
2 1 0 244 253
3 1 1 253 440
Böylece konum 0,1,2,3 elde ettik. İki gün önce ve bir gün önce yağmadı kon-
umu 0, iki gün önce yağdı bir gün önce yağmadı konum 1, böyle gidiyor. Şimdi
dikkat, buradan bir Markov matrisi çıkartmak için geçiş hedefinde iki kolonlu
4
bir matris (yağdı,yağmadı) kullanamayız. O durumda matris 4 x 2 boyutunda
olurdu, bu bir Markov matrisi olmaz. Boyutlar 4 x 4 olmalı. Peki o zaman mesela
yağdı, yağmadı konumundan bugün yağdı konumuna nasıl geçeceğiz? Ufak bir
numara kullanarak; yağdı-yağmadı (2 etiketi) konumundan yağmadı-yağdı kon-
umuna (1 etiketi) geçişi yapacağız. Öyle ya, yağdı, yağmadı konumundan geçiş
yaptıktan sonra yeni bir gündeyiz, artık bir gün öncesi iki gun oncesi oldu, bugün
de ’yağdı’ durumu var, gelinen yer yağmadı-yağdı.
Olasılık verisini oluşturalım. Üstteki matristeki toplamları her satırın nihai toplamı
ile bölelim,
MC = np.array(pivot).astype(float)
probs = MC[:,[2,3]] / MC.sum(axis=1).reshape(4,1)
MC[:,[2,3]] = probs
MC = pd.DataFrame(MC)
MC.columns = ['D1','D2','norain','rain']
print (MC)
D1 D2 norain rain
0 0.0 0.0 0.701774 0.298226
1 0.0 1.0 0.539235 0.458753
2 1.0 0.0 0.489960 0.508032
3 1.0 1.0 0.364029 0.633094
Ufak bir matris olduğu için bu olasılıkları elle gerekli yerlere kodlayabiliriz,
MCfinal = np.zeros((4,4))
MCfinal[0,0] = MC.loc[0]['norain']
MCfinal[0,2] = MC.loc[0]['rain']
MCfinal[1,0] = MC.loc[1]['norain']
MCfinal[1,2] = MC.loc[1]['rain']
MCfinal[2,1] = MC.loc[2]['norain']
MCfinal[2,3] = MC.loc[2]['rain']
MCfinal[3,1] = MC.loc[3]['norain']
MCfinal[3,3] = MC.loc[3]['rain']
print (MCfinal)
[[0.70177384 0. 0.29822616 0. ]
[0.53923541 0. 0.45875252 0. ]
[0. 0.48995984 0. 0.50803213]
[0. 0.36402878 0. 0.63309353]]
5
[[0.49248652 0.14611884 0.20928732 0.15150847]
[0.3784213 0.22477031 0.16081411 0.23306102]
[0.2642037 0.18493831 0.22477031 0.32163185]
[0.19629721 0.23046426 0.16699912 0.40080741]]
print (MCfinal[3,3])
print (P2[3,3])
print (P3[3,3])
0.6330935251798561
0.40080741162465705
0.33858949401527094
Peki önümüzdeki üç günün herhangi birinde yağma olasılığı nasıl hesaplanır? Her
üç matris içinde yağdı-yağdı konumundan bu sefer yağmadı-yağdı konumuna
(etiket 1) geçiş olasıklarına bakarız, bu olasılıkları birbiri ile çarparız, böylece
sırasıyla üç gün hiç yağmama olasılığı elde edilir. 1 değerinden bu değeri çıkartınca
herhangi bir gün yağma olasılığı çıkar.
norain = MCfinal[3,1]*P2[3,1]*P3[3,1]
print (1-norain)
0.9808945929621133
Kaynaklar
[1] Meteorological Service Singapore, http://www.weather.gov.sg/climate-
historical-daily/
[2] Bayramli, Kullback-Leibler (KL) Mesafesi
[3] Ross, Introduction to Probability Models, 10th Ed
[4] Bayramli, Istatistik, Markov Zincirleri
6
Azar Azar İstatistik (Incremental Statistics)
Artımsal Ortalama (Mean)
Eldeki bir verinin yaş, boy, kilo gibi kolonlarını özetlemenin yollarından biri orta-
lama. Ortalama hesabının pek çok kütüphanede çağrısı var, mesela numpy.mean,
ya da Pandas Series.mean.
import pandas as pd
from io import StringIO
data = """
Name,Height
Ali,160
Veli,170
Musa,150
Mustafa,200
Cem,180
"""
df = pd.read_csv(StringIO(data),sep=',')
print (df)
Name Height
0 Ali 160
1 Veli 170
2 Musa 150
3 Mustafa 200
4 Cem 180
Ortalamayı alırsak
df['Height'].mean()
Out[1]: 172.0
Matematiksel olarak eldeki xi verisi için klasik ortalama hesabı x̄ basit, tüm değerleri
topla, ve değer sayısına böl,
1X
n
x̄ = xi (2)
n i=1
Kod ile
print (np.array(df.Height))
mean = df.Height.sum() / len(df)
print ('ortalama',mean)
Şimdi artımsal hesabı düşünelim. Üstteki klasik hesabı yapmak için tüm veri-
leri toplamak gerekti, eğer ilk akla gelen yöntemle artımsal ortalama hesaplasak,
1
her adımda o ana kadar olan toplamı takip edip o ana kadar olan veri sayısına
bölmek gerekirdi, ama elde çok fazla veri varsa bu toplamın çok büyük rakamlara
erişmesi mümkündür, bu da taşma, veri hataları ortaya çıkartabilir.
Başka bir şekilde azar azar ortalama hesabı mümkün müdür acaba? Sadece or-
talamayı güncellesek, toplamlarla uğraşmasak? O ana kadar bakılan verinin or-
talaması fazla büyümez, ayrıca paralel işletim açısından azar azar işletim daha
ölçeklenebilir bir yaklaşımdır. Bu tür bir hesap için matematikte biraz değişim
yapmak lazım [3]. Üstteki toplam formülünde ilk n − 1 toplamını ayıralım,
X
n−1
!
1
x̄ = xi + xi (1)
n i=1
Pn
xi
i=1
x̄n−1 =
n−1
Tekrar düzenlersek,
X
n
xi = (n − 1)x̄n−1
i=1
1
x̄ = x̄n = ((n − 1)x̄n−1 + xn )
n
Sağ tarafı açalım,
nx̄n−1 − x̄n−1 + xn
x̄n =
n
nx̄n−1 xn − x̄n−1
x̄n = +
n n
İlk terimdeki n’ler iptal olur,
xn − x̄n−1
x̄n = x̄n−1 +
n
Yani bir sonraki ortalama hesabı için eldeki yeni veri xn ’den o ana kadar elde olan
ortalamayı çıkartıp n’ye bölüp bu sonucu önceki ortalamaya ekliyoruz. Böylece
sürekli daha ufak sayılarla uğraşıyoruz, patlama olmuyor ayrıca elde sürekli bir
ortalama hesabı oluyor.
2
barx = 160 # ilk degeri ilk ortalama olarak kullan
for n,xn in enumerate(np.array(df.Height)):
barx = barx + (xn - barx) / (n+1)
print (xn, barx)
160 160.0
170 165.0
150 160.0
200 170.0
180 172.0
Pn
2 i=1 (xi − x̄n )2
s =
n−1
X
n
2
(n − 1)s = (xi − x̄n )2
i=1
Sağdaki değeri d2n diye tanımlayalım, bu cebirde ilerlerken bize faydalı olacak.
X
n
d2n = (xi − x̄n )2
i=1
X
n
d2n = (x2i − 2xi x̄n + x̄2n )
i=1
X
n X
n X
n
d2n = x2i − 2xi x̄n + x̄2n
i=1 i=1 i=1
X
n X
n X
n
d2n = x2i − 2x̄n xi + x̄2n 1
i=1 i=1 i=1
Pn
Şimdi toplam ve ortalama x̄n arasındaki ilişki i=1 xi = nx̄n formülünden hareke-
tle, üstteki formülü
3
X
n X
n
d2n = x2i − 2x̄n · nx̄n + x̄2n 1
i=1 i=1
Pn
Ayrıca n = i=1 1 olduğu için
X
n
d2n = x2i − 2nx̄2n + nx̄2n
i=1
X
n
d2n = x2i − nx̄2n
i=1
X
n−1
d2n−1 = x2i − (n − 1)x̄2n−1
i=1
X X
n n−1
!
d2n − d2n−1 = x2i − nx̄2n − x2i − (n − 1)x̄2n−1
i=1 i=1
X
n X
n−1
d2n − d2n−1 = x2i − nx̄2n − x2i + (n − 1)x̄2n−1
i=1 i=1
X
n X
n−1
x2n = x2i − x2i
i=1 i=1
Sıralamayı değiştirirsek,
4
d2n − d2n−1 = x2n − x̄2n−1 + n(x̄2n−1 − x̄2n )
[3] yazısından biliyoruz ki şöyle bir eşitlik mevcut n(x̄n−1 − x̄n ) = x̄n−1 − xn , onu
üstte kullanırsak,
(x − a)(x − b) = x2 − bx − ax + ab
Nihai sonuç,
Biraz zaman aldı ama güzel bir artımsal formül elde ettik. Yeni d2n büyüklüğünü
bir önceki büyüklüğü kullanarak hesaplamak artık mümkün. Varyansı elde et-
mek için n − 1 ile bölmek yeterli,
d2n
s2n =
n−1
Onun karekökünü alınca da standart sapma elde edilir,
r
d2n
sn =
n−1
5
dns = 0; barx = 160
for n,xn in enumerate(np.array(df.Height)):
barxprev = barx
barx = barx + (xn - barx) / (n+1)
dns = dns + (xn - barx)*(xn-barxprev)
print (xn, dns/n)
160 nan
170 50.0
150 100.0
200 466.6666666666667
180 370.0
print (df.Height.var())
370.0
X
n
1
X
n 2
S= x2i − xi
i=1
n i=1
Bu formülü her yeni veri geldikçe eldeki mevcut varyansı “güncelleme” amaçlı
olarak tekrar düzenleyebilirdik, böylece veri üzerinden bir kez geçmekle kalmayıp
en son bakılan veriye göre en son varyansı hesaplayabilmiş olurduk. Ortalama
için mesela her yeni veri bir toplama eklenebilir, ayrıca kaç veri noktası görüldüğü
hatırlanır, ve o andaki en son ortalama en son toplam bölü bu en son sayıdır.
P P
Fakat varyans için (5)’in bir problemi var, x2i ve ( xi )2 sayıları uygulamalarda
aşırı büyüyorlar, ve yuvarlama hataları (rounding errors) hataları ortaya çıkmaya
başlıyor. Eğer varyans küçük ise bu aşırı büyük sayılardaki tüm basamaklar
birbirini iptal eder, geriye hiçbir şey kalmaz. Bu hatalardan uzak durmak için
varyansı farklı bir artımsal yöntemle hesaplamak istiyoruz.
Youngs ve Cramer’in yöntemine göre [2, sf. 69] bu hesap şöyle yapılabilir. Tij ,
Mij ve Sij , veri noktaları xi xj arasındaki verileri kapsayacak şekilde sırasıyla
toplam, ortalama ve verinin karesinin toplamı olsun,
X
j
1 X
j
Tij = xk , Mij = , Sij = (xk − Mij )2
k=i
(j − 1 + 1) k=i
T1,j = Ti,j−1 + xj
6
1
S1,j = Si,j−1 + (jxj − T1,j )2
j(j − 1)
Xj
1
X j
1
2
xk − T1j = xk − (T1,j−1 + xj )
k=1
j k=1
j
X
j
1
1 1
2
= xk − T1,j−1 + T1,j−1 − xj
k=1
j−1 j(j − 1) j
1 1 1
çünkü j
= j−1
− j(j−1)
X
j−1
1
2
1
2
= xk − T1,j−1 xj − T1,j−1 +
k=1
j−1 j−1
X
j
1
1 1
2 xk − T1,j−1 T1,j−1 − xj +
k=1
j−1 j(j − 1) j
1 1
j T1,j−1 − xj
j(j − 1) j
X
j−1
1
2
1
2
2
1 1
2
= xk − T1,j−1 + xj − T1,j−1 1− +j T1,j−1 − xj
k=1
j−1 j−1 j j(j − 1) j
Pj−1 1
çünkü k=1 (xk − T
j−1 1,j−1
) =0
2
1 2 1
= S1,j−1 + xj − (T1j − xj ) 1− +
j−1 j j
1 2j − 1
= S1,j−1 + (jxj − T 1j )
(j − 1)2 j
7
N = 10
arr = np.array(range(N)) # basit veri, 0..N-1 arasi sayilar
print arr
last_sum = arr[0]; last_var = 0.
for j in range(2,N+1):
last_sum,last_var = incremental_mean_and_var(arr[j-1], last_sum, last_var, j)
[0 1 2 3 4 5 6 7 8 9]
YC = 8.25 Standart = 8.25
45 45
Kaynaklar
[1] Bayramlı, Istatistik, Beklenti, Varyans, Kovaryans ve Korelasyon
[2] Weihs, Foundations of Statistical Algorithms With References to R Packages
[3] Nested Software, Calculating a Moving Average on Streaming Data, https://
nestedsoftware.com/2018/03/20/calculating-a-moving-average-
on-streaming-data-5a7k.22879.html
[4] Nested Software, Calculating Standard Deviation on Streaming Data, https://
nestedsoftware.com/2018/03/27/calculating-standard-deviation-
on-streaming-data-253l.23919.html
8
Ekler
Binom ve p İçin Maksimum Olurluk Tahmini [1]
Y
n Yn
n x
L(p; x) = f(xi ; p) = p (1 − p)1−x
i=1 i=1
x
Log alalım
X
n
n
log L(p; x) = log + x log p + (1 − x) log(1 − p)
i=1
x
n
p’ye göre türevi alalım, bu sırada kombinasyon ifadesi x
içinde p olmadığı için
o yokolacaktır,
x n−x
0= −
p 1−p
x n−x
=
p 1−p
p(n − x) = x(1 − p)
pn − px = x − px
pn = x
x
p=
n
1
Bayes ile bu hesabı yapmak için bir dağılımı baz almak lazım. Eğer sonuç olarak
bir tek sayı değil, bir dağılım elde edersek bu dağılım üzerinde güvenlik hesaplarını
yaparız. Mesela sonuç, sonsal dağılım (posterior) bir Gaussian dağılım ise, bu
dağılımın yüzde 95 ağırlığının nerede olduğu, ve nasıl hesaplandığı bellidir.
Bayes Teorisi
P(B | A)P(A)
P(A | B) =
P(B)
∝ işareti orantılı olmak (proportional to) anlamına geliyor. Böleni attık çünkü
o bir sabit (tamamen veriye bağlı, tahmini hesaplamak istediğimiz parametreye
bağlı değil). Tabii bu durumda sol ve sağ taraf birbirine eşit olmaz, o yüzden
eşitlik yerine orantılı olmak işaretini kullandık. Bu çerçevede ”belli bir sayısal
sabit çerçevesinde birbirine eşit (equal within a numeric constant)” gibi cümleler
de görülebilir.
Örnek
Diyelim ki bir bozuk para ile 10 kere yazı-tura attık, ve sonuç altta
THHHHTTHHH
Bu veriye bakarak paranın hileli olup olmadığını anlamaya çalışacağız. Bayes
ifadesini bu veriye göre yazalım,
2
ama bu ifadeyi ayrı ayrı P({T|p) ve P({H|p) çarpımları olarak görebiliriz. P({T|p) =
p ve P({H|p) = 1 − p olduğunu biliyoruz. O zaman
Grafiklersek,
Böylece p için bir sonsal dağılım elde ettik. Artık bu dağılımın yüzde 95 ağırlığının
nerede olduğunu rahatça görebiliriz / hesaplayabiliriz. Dağılımın tepe noktasının
p = 0.7 civarında olduğu görülüyor. Bir dağılımla daha fazlasını yapmak ta
mümkün, mesela bu fonksiyonu p’ye bağlı başka bir fonksiyona karşı entegre
etmek mümkün, mesela beklentiyi bu şekilde hesaplayabiliriz.
Onsel dağılımın her noktaya eşit ağırlık veren birörnek (uniform) seçilmiş olması,
yani problemi çözmeye sıfır bilgiden başlamış olmamız, yöntemin bir zayıflığı
olarak görülmemeli. Yöntemin kuvveti elimizdeki bilgiyle başlayıp onu net bir
şekilde veri ve olurluk üzerinden sonsal tek dağılıma götürebilmesi. Başlangıç ve
sonuç arasındaki bağlantı gayet net. Fazlası da var; ilgilendiğimiz alanı (domain)
öğrendikçe, başta hiç bilmediğimiz onsel dağılımı daha net, bilgili bir şekilde
seçebiliriz ve bu sonsal dağılımı da daha olması gereken modele daha yaklaştırabilir.
Moment
Olasılık matematiğinde ”moment üreten işlevler” olarak adlandırılan, başlangıçta
pek yararlı gibi gözükmesede bir takım matematiksel özellikleri olduğu için, is-
patlarda oldukça işe yarayan bir kavram vardır.
Her rasgele değişkenin bir dağılımı olduğunu biliyoruz. Her rasgele değişkenin
de ayrıca bir moment üreten fonksiyonu da vardır. Ayrıca, moment üreten fonksiyon
ile rasgele değişken arasında bire-bir olarak bir ilişki mevcuttur. ”Bu neye yarar?”
diye sorulabilir; Cevap olarak, mesela cebirsel olarak türete türete bir moment’e
geldiğimiz düşünelim, ve tekrar başka bir taraftan, başka bir formülden gene
türete türete tekrar aynı moment işlevine geliyorsak, bu demektir ki, iki taraftan
gelen rasgele değişkenler (ve tekabül eden dağılımları) birbirine eşittir. Bazı şartlarda
moment üreten işlevler ile cebir yapmak, dağılım fonksiyonlarından daha rahat
3
olmaktadır.
Her rasgele değişken için, moment üreten işlev şöyle bulunur.
X rasgele degiskenin moment ureten operasyonu
M(t) = E(etX ) olarak gösterilir
Ayrıksal operasyonlar için
X
M(t) = etx p(x)
x
Kuram
Gelelim yazımızın esas konusu olan kuramımıza.
Eğer X1 , X2 ...Xn bağımsız rasgele değişken ise, ve her değişkenin Mi (t) i = 1, 2, 3, ...n
olarak, öz olarak aynı olan birer moment üreten işlevi var ise, o zaman,
X
n
Y= aXi
i=1
açılımı
Y
n
My (t) = M(ai t)
i=1
olacaktır.
İspat
4
Daha önce belirttiğimiz gibi
Mi (t) = E[exp(tXi )]
Y
n
My (t) = My (ai t)
i=1
olacaktır.
Bunu My (t) = (Mi (ai t))n şeklinde de gösterebiliriz.
Markov’un Eşitsizliği (Markov’s Inequality)
X bir negatif olmayan rasgele değişken olsun ve farz edelim ki E(X) mevcut [1].
O zaman her t > 0 için
E(X)
P(X > t) 6
t
doğru olmalıdır.
İspat
X > 0 olduğuna göre,
Z∞ Zt Z∞
E(X) = xf(x) dx = xf(x) dx + xf(x) dx =
0 0 t
Z∞ Z∞
> xf(x) dx > t f(x) dx = tP(X > t)
t t
σ2
P(|X − µ| > t) 6
t2
ve
1
P(|Z| > k) 6
k2
5
İspat
1. Yöntem
Üstteki Markov’un eşitsizliğini kullanırız, oradan şu sonuca varırız,
E(X − µ)2 σ2
P(|X − µ| > t) = P(|X − µ|2 > t2 ) 6 =
t2 t2
R = x : |x − µ| > t
Yani R uzayı, x ile ortalamasının farkının, t’den büyük olduğu bütün sayıların
kümesidir.
O zaman,
Z
P(|X − µ| > t) = f(x) dx
R
Dikkat edelim P(..) içindeki formül, küme tanımı ile aynı. O yüzden P() hesabı
ortada daha olmayan, ama varolduğu kesin bir dağılım fonksiyonu tanımlamış
da oluyor. Buna f(x) deriz. P()’in, f(x) fonksiyonunun R üzerinden entegral
olduğunu olasılığa giriş dersinden bilmemiz lazım.
Eger x ∈ R dersek o zaman
|x − µ|2
>1
t2
t’nin denkleme bu şekilde nereden geldiği şaşkınlık yaratabilir. Daha önce tanımlanan
şu ibareye dikkat edelim, x : |x − u| > t diye belirtmiştik. Bu ifadeyi değiştirerek,
yukarıdaki denkleme gelebiliriz.
Devam edersek, elimizdeki 1’den büyük bir değer var. Bu değeri kullanarak,
aşağıdaki tanımı yapmamız doğru olacaktır.
6
Z Z Z∞
(x − µ)2 (x − µ)2
f(x) dx 6 f(x) dx 6 f(x) dx
R R t2 −∞ t2
Ortadaki entegral niye birinci entegralden büyük? Çünkü orta entegraldeki f(x)dx
ibaresinden önce gelen kısmın, her zaman 1’den büyük olacağını belirttiğimize
göre, ikinci entegralin birinciden büyük olması normaldir, çünkü birinci entegral
f(x) olasılık dağılımına bağlı, entegral ise bir alan hesabıdır ve olasılık dağılımlarının
sonsuzlar arasındaki entegrali her zaman 1 çıkar, kaldı ki üstteki x’in uzayını
daha da daralttık.
Evet...Üçüncü entegral ispata oldukça yaklaştı aslında. Standart sapma işaretini
hala ortada göremiyoruz, fakat son entegraldeki ibare standart sapma değerini
zaten içeriyor. Önce daha önceki olasılık natematiği bilgimize dayanarak, stan-
dart sapmanın tanımını yazıyoruz. Dikkat edelim, bu ibare şu anki ispatımız
dahilinden değil, haricinden önceki bilgimize dayanarak geldi. Standart sap-
manın tanımı şöyledir.
Z∞
2
σ = (x − µ)2 f(x) dx
−∞
O zaman
Z∞
σ2 (x − µ)2
= f(x) dx
t2 −∞ t2
yani
Z Z∞
σ2 (x − µ)2
f(x) dx 6 2 = f(x) dx
R t −∞ t2
R
ki R f(x) dx zaten P(|X − µ| > t) olarak tanımlanmıştı.
Örnek
Diyelim ki bir tahmin edicimiz var, onu test etmek istiyoruz, bu bir yapay sinir
ağı (YSA) olabilir, ve elimizde n tane test verisi var. Eğer tahmin edici, yani YSA,
hatalı ise Xi = 1 olsun, haklı isePXi = 0 olsun. O zaman gözlenen hata oranı
(observed error rate) Xn = n−1 n i=1 Xi olacaktır. Rasgele değişken çıktılarına
bakarak bunu bir p’si bilinmeyen bir Bernoulli dağılımından geliyormuş gibi
kabul edebileceğimizi görebiliriz. İstediğimiz gerçek -ama bilinmeyen- p hakkında
irdeleme yapmak. Xn ’in gerçek p’nin yakınında olmama olasılığı nedir?
Bernoulli’lerin özelliklerinden biliyoruz ki
Çebişev uygulayınca,
7
V(Xn ) p(1 − p) 1
P(|Xn − p| > ) 6 = 6
2 n2 4n2
Hatırlarsak Bernoulli için E(X) = p. Son geçiş mümkün oldu çünkü her p için
p(1 − p) 6 41 olmak zorundadır. Öyle değil mi? p(1 − p)’nin alabileceği en büyük
değer p = 1/2 içindir, bundan farklı her p değeri 1/4’ten küçük bir çarpım verir,
mesela p = 1/3 için 1/3 · 2/3 = 2/9.
O zaman, ve diyelim ki = .2 ve n = 100 için 0.0625 sınırını elde ederiz.
Hoeffding’in Eşitsizliği
Bu eşitsizlik Markov’un eşitsizliğine benziyor, ama daha keskin sonuçlar vere-
biliyor, yani ufak güven aralıkları elde edebiliyoruz, ki bu daha fazla kesinlik
demektir. Bu eşitsizliği iki bölüm olarak vereceğiz,
Y1 , Y2 , .., Yn bağımsız gözlemler olsunlar, ki E(Yi ) = 0 ve ai 6 Yi 6 bi doğru
olacak şekilde. O zaman herhangi bir t > 0 için
1. Teori
X
n Y
n
−t t2 (bi −ai )2 /8
P Yi > 6 e e
i=1 i=1
2. Teori
X1 , .., Xn ∼ Bernoulli(p) olsun. O zaman herhangi bir > 0 icin
2
P(|Xn − p| > ) 6 2e−2n
Pn
doğru olmalıdır ki, daha önce gördüğümüz gibi, Xn = n−1 i=1 Xi olacak şekilde.
İspat için bkz [1, sf. 67].
Örnek
Diyelim ki X1 , .., Xn ∼ Bernoulli(p). n = 100 ve = .2 olsun. Çebişev esitsizligi
ile
2
P(|Xn − p| > ) 6 2e−2(100)(.2) = 0.00067
elde ederiz, ki bu Cebisev’den gelen 0.0625’e göre çok daha ufak bir değerdir.
Jensen’in Esitsizligi (Jensen’s Inequality)
8
Teori
Eğer g fonksiyonu dışbükey (convex) ise o zaman
O zaman
Birinci geçiş basit beklenti matematiği. Son formül L(x)’in E(X) üzerindeki formu
olurdu, o zaman
a + bE(X) = L(E(X))
diyebiliriz.
Şimdi hatırlıyoruz ki teğet çizgi g ile tam E(X) noktasında kesişiyor, o noktada
değerleri aynı yani, o zaman
9
L(E(X)) = g(E(X))
Demek ki
Kısaca
10
z-Tablosu
Nasıl okunur? Z-değeri -0.8994 için z kolonundan aşağı inilir, ve -0.8 bulunur,
x.x9xx yani 9 için .09 kolonuna gidilir ve bu kesişmedeki değer okunur, .1867,
yuvarlanarak .19 da kabul edilebilir.
11
-1.4 .0808 .0793 .0778 .0764 .0749 .0735 .0721 .0708 .0694 .0681
-1.3 .0968 .0951 .0934 .0918 .0901 .0885 .0869 .0853 .0838 .0823
-1.2 .1151 .1131 .1112 .1093 .1075 .1056 .1038 .1020 .1003 .0985
-1.1 .1357 .1335 .1314 .1292 .1271 .1251 .1230 .1210 .1190 .1170
-1.0 .1587 .1562 .1539 .1515 .1492 .1469 .1446 .1423 .1401 .1379
-0.9 .1841 .1814 .1788 .1762 .1736 .1711 .1685 .1660 .1635 .1611
-0.8 .2119 .2090 .2061 .2033 .2005 .1977 .1949 .1922 .1894 .1867
-0.7 .2420 .2389 .2358 .2327 .2296 .2266 .2236 .2206 .2177 .2148
-0.6 .2743 .2709 .2676 .2643 .2611 .2578 .2546 .2514 .2483 .2451
-0.5 .3085 .3050 .3015 .2981 .2946 .2912 .2877 .2843 .2810 .2776
-0.4 .3446 .3409 .3372 .3336 .3300 .3264 .3228 .3192 .3156 .3121
-0.3 .3821 .3783 .3745 .3707 .3669 .3632 .3594 .3557 .3520 .3483
-0.2 .4207 .4168 .4129 .4090 .4052 .4013 .3974 .3936 .3897 .3859
-0.1 .4602 .4562 .4522 .4483 .4443 .4404 .4364 .4325 .4286 .4247
0.0 .5000 .4960 .4920 .4880 .4840 .4801 .4761 .4721 .4681 .4641
12
z .00 .01 .02 .04 .05 .06 .07 .08 .09
0.0 .5000 .5040 .5080 .5120 .5160 .5199 .5239 .5279 .5319 .5359
0.1 .5398 .5438 .5478 .5517 .5557 .5596 .5636 .5675 .5714 .5753
0.2 .5793 .5832 .5871 .5910 .5948 .5987 .6026 .6064 .6103 .6141
0.3 .6179 .6217 .6255 .6293 .6331 .6368 .6406 .6443 .6480 .6517
0.4 .6554 .6591 .6628 .6664 .6700 .6736 .6772 .6808 .6844 .6879
0.5 .6915 .6950 .6985 .7019 .7054 .7088 .7123 .7157 .7190 .7224
0.6 .7257 .7291 .7324 .7357 .7389 .7422 .7454 .7486 .7517 .7549
0.7 .7580 .7611 .7642 .7673 .7704 .7734 .7764 .7794 .7823 .7852
0.8 .7881 .7910 .7939 .7967 .7995 .8023 .8051 .8078 .8106 .8133
0.9 .8159 .8186 .8212 .8238 .8264 .8289 .8315 .8340 .8365 .8389
1.0 .8413 .8438 .8461 .8485 .8508 .8531 .8554 .8577 .8599 .8621
1.1 .8643 .8665 .8686 .8708 .8729 .8749 .8770 .8790 .8810 .8830
1.2 .8849 .8869 .8888 .8907 .8925 .8944 .8962 .8980 .8997 .9015
1.3 .9032 .9049 .9066 .9082 .9099 .9115 .9131 .9147 .9162 .9177
1.4 .9192 .9207 .9222 .9236 .9251 .9265 .9279 .9292 .9306 .9319
1.5 .9332 .9345 .9357 .9370 .9382 .9394 .9406 .9418 .9429 .9441
1.6 .9452 .9463 .9474 .9484 .9495 .9505 .9515 .9525 .9535 .9545
1.7 .9554 .9564 .9573 .9582 .9591 .9599 .9608 .9616 .9625 .9633
1.8 .9641 .9649 .9656 .9664 .9671 .9678 .9686 .9693 .9699 .9706
1.9 .9713 .9719 .9726 .9732 .9738 .9744 .9750 .9756 .9761 .9767
2.0 .9772 .9778 .9783 .9788 .9793 .9798 .9803 .9808 .9812 .9817
2.1 .9821 .9826 .9830 .9834 .9838 .9842 .9846 .9850 .9854 .9857
2.2 .9861 .9864 .9868 .9871 .9875 .9878 .9881 .9884 .9887 .9890
2.3 .9893 .9896 .9898 .9901 .9904 .9906 .9909 .9911 .9913 .9916
2.4 .9918 .9920 .9922 .9925 .9927 .9929 .9931 .9932 .9934 .9936
2.5 .9938 .9940 .9941 .9943 .9945 .9946 .9948 .9949 .9951 .9952
2.6 .9953 .9955 .9956 .9957 .9959 .9960 .9961 .9962 .9963 .9964
2.7 .9965 .9966 .9967 .9968 .9969 .9970 .9971 .9972 .9973 .9974
2.8 .9974 .9975 .9976 .9977 .9977 .9978 .9979 .9979 .9980 .9981
13
2.9 .9981 .9982 .9982 .9983 .9984 .9984 .9985 .9985 .9986 .9986
3.0 .9987 .9987 .9987 .9988 .9988 .9989 .9989 .9989 .9990 .9990
3.1 .9990 .9991 .9991 .9991 .9992 .9992 .9992 .9992 .9993 .9993
3.2 .9993 .9993 .9994 .9994 .9994 .9994 .9994 .9995 .9995 .9995
3.3 .9995 .9995 .9995 .9996 .9996 .9996 .9996 .9996 .9996 .9997
3.4 .9997 .9997 .9997 .9997 .9997 .9997 .9997 .9997 .9997 .9998
Kaynaklar
[1] Gullickson, Sociology G4075: Introduction to Social Data Analysis II, https://
web.archive.org/web/20160312151715/http://pages.uoregon.edu/
aarong/teaching/G4075_Outline/node13.html
14
Yunan Harfleri