Matrisler İle Kovaryans Hesabı
Eğer verinin kolonları arasındaki ilişkiyi görmek istersek, en hızlı yöntem matristeki 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. Pozitif sonucun pozitif korelasyon, negatif ise tersi şekilde ilinti olduğu sonucuna böylece kolayca erişebiliriz.
Tanım
\[ S = \frac{1}{n} (X-E(X))^T(X-E(X))) \]
Pandas ile cov çağrısı bu hesabı hızlı bir şekilde
yapar,
import pandas as pd
df = pd.read_csv('iris.csv')
df = df[['Sepal Length', 'Sepal Width', 'Petal Length', 'Petal Width']]
print (df.cov()) Sepal Length Sepal Width Petal Length Petal Width
Sepal Length 0.685694 -0.039268 1.273682 0.516904
Sepal Width -0.039268 0.188004 -0.321713 -0.117981
Petal Length 1.273682 -0.321713 3.113179 1.296387
Petal Width 0.516904 -0.117981 1.296387 0.582414
Eger kendimiz bu hesabi yapmak istersek,
means = df.mean()
n = df.shape[0]
df2 = df.apply(lambda x: x - means, axis=1)
print (np.dot(df2.T,df2) / n)[[ 0.68112222 -0.03900667 1.26519111 0.51345778]
[-0.03900667 0.18675067 -0.319568 -0.11719467]
[ 1.26519111 -0.319568 3.09242489 1.28774489]
[ 0.51345778 -0.11719467 1.28774489 0.57853156]]
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
noktalarındaki grafiğe bakmak lazım.
#df = df.iloc[:,0:4]
pd.plotting.scatter_matrix(df)
plt.savefig('stat_summary_01.png')

İ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,
\[ Cov(X,Y) = E(X-E(X))(Y-E(Y)) \]
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 beklentisini 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\) olsun yani \(m\) veri noktası ve \(n\) boyut (özellik, öğe) var, tanımı şöyle ifade edebiliriz,
\[ \Sigma = Cov(X) = E((X-E(X))^T(X-E(X))) \]
Phi Korelasyon Katsayısı
Phi katsayısı iki tane ikisel değişkenin birbiriyle ne kadar alakalı, bağlantılı olduğunu hesaplayan bir ölçüttür. Mesela \(x,y\) değişkenleri için elde olan \((x_1,y_1),(x_2,y_2),..\) verilerini kullanarak hem \(x=1\) hem \(y=1\) olan verileri sayıp toplamı \(n_{11}\)’e yazarız, \(y=1,x=0\) icin \(n_{10}\), aynı şekilde diğer kombinasyonlara bakarak alttaki tabloyu oluştururuz [5],

Phi korelasyon katsayısı
\[ \phi = \frac{n_{11}n - n_{1\bullet}n_{\bullet 1}} {\sqrt{n_{0\bullet} n_{1\bullet} n_{\bullet 0} n_{\bullet 1}}} \tag{6} \]
ile hesaplanır. Bu ifadeyi türetmek için iki rasgele değişken arasındaki korelasyonu hesaplayan formül ile başlıyoruz,
\[ Corr(X,Y) = \frac{E (x-E(X)) (y-E(Y)) }{\sqrt{Var(X) \cdot Var(Y) } } \]
\[ = \frac{E(XY) - E(X)E(Y)}{ \sqrt{Var(X) \cdot Var(Y)} } \]
\(X,Y\) değişkenlerinin Bernoulli dağılımına sahip olduğunu düşünelim, çünkü 0/1 değerlerine sahip olabilen ikisel değişkenler bunlar, o zaman
\[ E[X]= \frac{n_{1\bullet}}{n}, \quad Var[X]= \frac{n_{0\bullet}n_{1\bullet}}{n^2}, \quad E[Y]= \frac{n_{\bullet 1}}{n}, \quad Var[Y]= \frac{n_{\bullet 0}n_{\bullet 1}}{n^2}, \quad E[XY]= \frac{n_{11}}{n^2} \]
olacaktır. \(E(XY)\) nasıl hesaplandı? Ayrıksal dağılımlar için beklenti formülünün iki değişken için şöyle ifade edildiğini biliyoruz,
\[ E[XY] = \sum_i\sum_j x_i\cdot y_j \cdot P\{X = x_i, Y = y_j\} \]
Bu ifadeyi tabloya uyarlarsak, ve tablodaki hesapların üstteki ifadeler için tahmin ediciler olduğunu biliyoruz, iki üstteki sonucu elde edebileceğimizi görürüz, çünkü tek geçerli toplam \(x_i y_i\) her iki değişken de aynı anda 1 olduğunda geçerlidir. Bu değerleri yerine geçirince (6) elde edilir.
Phi katsayısının bir diğer ismi Matthews korelasyon katsayısı. Bu hesabı mesela bir 0/1 tahmini üreten sınıflayıcının başarısını ölçmek için kullanabiliriz, gerçek, test 0/1 verileri bir dizinde, üretilen tahminler bir diğerinde olur, ve Phi katsayısı ile aradaki uyumu raporlarız. Sonuç -1,+1 arasında olacağı için sonuca bakarak irdeleme yapmak kolaydır, bu bir başarı raporu olarak algılanabilir. Ayrıca Phi hesabının, AUC hesabı gibi, dengesiz veri setleri üzerinde (mesela 0’a kıyasla çok daha fazla 1 olan veriler, ya da tam tersi) üzerinde bile hala optimal olarak çalıştığı [4] bulunmuştur.
Bazı örnekler,
from sklearn.metrics import matthews_corrcoef
y_true = [+1, +1, +1, -1]
y_pred = [+1, -1, +1, +1]
print ((matthews_corrcoef(y_true, y_pred) ))-0.333333333333
Ya da
a = [[0, 0],[0, 0],[0, 0],[0, 0],[0, 0],[1, 0],\
[1, 0],[1, 0],[0, 1],[0, 1],[1, 1],[1, 1],\
[1, 1],[1, 1],[1, 1],[1, 1],[1, 1],[1, 1],\
[1, 1], [1, 1],[1, 1],[1, 1],[1, 1],[1, 1],\
[1, 1],[1, 1],[1, 1]]
a = np.array(a)
print ((matthews_corrcoef(a[:,0], a[:,1])))0.541553390893
Medyan ve Yüzdelikler (Percentile)
Üstteki hesapların çoğu sayıları toplayıp, bölmek üzerinden yapıldı. Medyan ve diğer yüzdeliklerin hesabı (ki medyan 50. yüzdeliğe tekabül eder) için eldeki tüm değerleri “sıraya dizmemiz” ve sonra 50. yüzdelik için ortadakine bakmamız gerekiyor. Mesela eğer ilk 5. yüzdeliği arıyorsak ve elimizde 80 tane değer var ise, baştan 4. sayıya / vektör hücresine / öğeye bakmamız gerekiyor. Eğer 100 eleman var ise, 5. sayıya bakmamız gerekiyor, vs.
Bu sıraya dizme işlemi kritik. Kıyasla ortalama hesabı hangi sırada
olursa olsun, sayıları birbirine topluyor ve sonra bölüyor. Zaten
ortalama ve sapmanın istatistikte daha çok kullanılmasının tarihi sebebi
de aslında bu; bilgisayar öncesi çağda sayıları sıralamak (sorting) zor
bir işti. Bu sebeple hangi sırada olursa olsun, toplayıp, bölerek
hesaplanabilecek özetler daha makbuldü. Fakat artık sıralama işlemi
kolay, ve veri setleri her zaman tek tepeli, simetrik olmayabiliyor.
Örnek veri seti olarak ünlü dellstore2 tabanındaki satış
miktarları kullanırsak,
data = np.loadtxt("glass.data",delimiter=",")
print (np.mean(data))213.948899167
print (np.median(data))214.06
print (np.std(data))125.118481954
print (np.mean(data)+2*np.std(data))464.185863074
print (np.percentile(data, 95))410.4115
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 ortalamanı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 gerekebilir. 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 = \{ x_1, x_2,.., x_N\}\) olsun, ki \(N\) veri noktası sayısı. Bu verinin
ortalaması \(a = (x_1 + x_2 + .. + x_N) /
N\), varyansı \(v = ((x_1 - a)^2 + (x_2
- a)^2 + ... + (x_N - a)^2 ) / N\).
Standart sapma tabii ki \(\sigma_N =
\sqrt{v}\).
Veriyi ayrı işledik diyelim, veri şu şekilde ayrıldı \(D_1 = \{ x_1, x_2,..,x_j\}\), \(D_2 = \{ x_{j+1}, x_{j+2},..,x_{j+k}\}\), \(D_3 = \{ x_{j+k+1}, x_{j+k+2},..,x_{j+k+m}\}\). Yani her veri grubunun büyüklüğü sırasıyla \(j,k,m\) ve toplam veri noktaları \(n = j+k+m\).
\(D_P\)’nin ortalaması \(a_P = \frac{1}{n} \sum_{i=1}^{n} x_i\). Her grup \(D_1,D_2,D_3\)’un ortalaması \(a_1,a_2,a_3\) benzer şekilde bulunabilir. Bu durumda “ortalamaların ortalaması’’, yani nihai ortalama \(a_P\) şöyle bulunabilir,
\[ a_P = (j a_1 + k a_2 + m a_3 ) / n \]
Varyansa ulaşmak için kareler toplamı, grup varyanslarına bakalım şimdi, \(D_P\) için kareler toplamı
\[ S_P = \sum_{i=1}^{n} x_i^2 \tag{7} \]
Gruplar \(D_1,D_2,D_3\) için toplamlar \(S_1,S_2,S_3\) benzer şekilde tanımlanıyor, ve nihai toplam bu gruplar üzerinden \(S_P = S_1 + S_2 + S_3\) olarak tanımlanabiliyor.
Tum veri \(D_P\) icin varyans
\[ v_P = \frac{1}{n} \sum_{i=1}^{n} (x_i - a_P)^2 \]
Bu ifadeyi acarsak
\[ = \frac{1}{n} \sum_{i=1}^{n} ( x_i^2 - 2 x_i a_p + a_p^2 ) \]
\[ = \frac{1}{n} \sum_{i=1}^{n} x_i^2 - \frac{1}{n} \sum_{i=1}^{n} 2 x_i a_p + \frac{1}{n} \sum_{i=1}^{n} a_p^2 \]
\(\frac{1}{n} \sum_{i=1}^{n} x_i = a_p\) olduğunu hatırlarsak, ve \(\frac{1}{n} \sum_{i=1}^{n} a_p\) tabii ki yine \(a_p\) o zaman
\[ = S_p / n - 2 a_p^2 + \frac{1}{n} \sum_{i=1}^{n} a_p^2 \]
\(\frac{1}{n} \sum_{i=1}^{n} a_p^2\) benzer sekilde tekrar \(a_p\),
\[ = S_p / n - 2 a_p^2 + a_p^2 \]
\[ v_P = S_p / n - a_p^2 \tag{8} \]
Bu durumda parçaların ayrı varyans formülleri de üstteki gibi yazılabilir,
\[ v_1 = S_1 / j - a_1^2, \quad v_2 = S_2 / k - a_2^2, \quad v_3 = S_3 / m - a_3^2 \tag{9} \]
Amacımız \(v_p\)’yi ufak parçaların varyansları \(v_1,v_2,v_3\) üzerinden hesaplamak.
Simdi (7,8,9) formullerini kullanarak \(v_p\) su sekilde de yazilabilirdi,
\[ v_p = (S_1 + S_2 + S_3) / n \]
Ya da
\[ n v_p = S_1 + S_2 + S_3 - n a_p^2 \]
Açarsak
\[ n v_p = j (v_1 + a_1)^2 + k (v_2 + a_2)^2 + m (v_3 + a_3)^2 - n a_p^2 \tag{10} \]
Şu da söylenebilir,
\[ n v_p = j v_1 + k v_2 + m v_3 + j a_1^2 + k a_2^2 + m a_3^2 - n a_p^2 \]
Şimdi (10) formülüne nasıl erisebileceğimizi düşünelim. Alttaki iki kavramdan hareketle bunu yapabilir miyiz acaba?
Varyansların ortalamasını
\[ a_v = (j v_1 + k v_2 + m v_3) / n \tag{11} \]
ve ortalamaların varyansını
\[ v_a = [ j(a_1-a_p)^2 + k(a_2-a_p)^2 + m(a_3-a_p)^2 ] / n \]
diye tanımlayalım. Üstteki formülü açalım,
\[ n v_a = j(a_1-a_p)^2 + k(a_2-a_p)^2 + m(a_3-a_p)^2 \]
\[ = j a_1^2 + k a_2^2 + m a_3^2 - 2 a_p (ja_1 + ka_2 + ma_3) + n a_p^2 \]
Ortadaki terim \(n a_p = ja_1 + ka_2 + ma_3\) olduguna gore
\[ = j a_1^2 + k a_2^2 + m a_3^2 - 2 a_p (n a_p) + n a_p^2 \]
\[ = j a_1^2 + k a_2^2 + m a_3^2 - 2 n a_p^2 + n a_p^2 \]
\[ n v_a = j a_1^2 + k a_2^2 + m a_3^2 - n a_p^2 \]
Varyansların ortalaması (11) formülünü hatırlayalım şimdi
\[ n a_v = j v_1 + k v_2 + m v_3 \]
Üstteki iki formülü toplarsak \(n v_p\)’ye erisebilir miyiz acaba?
\[ n v_a + n a_v = j a_1^2 + k a_2^2 + m a_3^2 - n a_p^2 + j v_1 + k v_2 + m v_3 \]
\(j,k,m\)’nin çarptığı terimleri onların altında gruplarsak,
\[ = j (a_1^2 + v_1) + k (a_2^2 + v_2) + m (a_3^2 + v_3) - n a_p^2 + \]
Evet bu hakikaten mümkün, (10) formülüne erişmiş olduk. Demek ki ayrı gruplardan elde edilen varyanslar ve ortalamarını alıp, bu varyansların ortalamasını 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,
d1 = np.array([32, 36, 27, 28, 30, 31])
d2 = np.array([32, 34, 30, 33, 29, 36, 24])
d3 = np.array([39, 40, 42])
n1,n2,n3 = len(d1),len(d2),len(d3)
dp = np.hstack([d1,d2,d3])
m1,m2,m3,mp = d1.mean(), d2.mean(), d3.mean(),dp.mean()
v1,v2,v3,vp = d1.var(), d2.var(), d3.var(),dp.var()
print (m1,m2,m3,mp)
print (v1,v2,v3,vp)
ap = (n1*m1 + n2*m2 + n3*m3) / (n1+n2+n3)
mean_of_var = (n1*v1 + n2*v2 + n3*v3) / (n1+n2+n3)
var_of_means = (n1*(m1-ap)**2 + n2*(m2-ap)**2 + n3*(m3-ap)**2) / (n1+n2+n3)
print (mean_of_var)
print (var_of_means)
print (mean_of_var + var_of_means)30.666666666666668 31.142857142857142 40.333333333333336 32.6875
8.555555555555554 13.26530612244898 1.5555555555555554 22.83984375
9.303571428571427
13.536272321428578
22.839843750000007
Not: Birleştirirken \(n_1\),\(n_2\) sayıları ile çarpım var, bu aşırı büyük sayılara sebep olmaz 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 \(n_1\),\(n_2\) ile çarpıp \(n_1+n2\) ile bölüyor olabiliriz, fakat bu hesapta tek gerekli olan aslında \(n_1\) ve \(n_2\)’nin birbirine olan izafi büyüklüğüdür. Eğer \(n_i/100\) kullansak birleştirme işlemi yine aynı çıkardı. O zaman bir teknik tüm \(n_i\)’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 faydalı araçlardır; medyan (median), dağılımın genişliğini ve sıradışı noktaları (outliers) 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 kedilerin 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.
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 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.
Python üzerinde basit bir BW grafiği
spread= np.random.rand(50) * 100
center = np.ones(25) * 50
flier_high = np.random.rand(10) * 100 + 100
flier_low = np.random.rand(10) * -100
data2 =np.concatenate((spread, center, flier_high, flier_low), 0)
plt.boxplot(data2)
plt.savefig('stat_feat_01.png')
Bir diğer örnek Glass veri seti üzerinde
head = data[data[:,10]==7]
tableware = data[data[:,10]==6]
containers = data[data[:,10]==5]
print (head[:,1])
data =(containers[:,1], tableware[:,1], head[:,1])
plt.yticks([1, 2, 3], ['containers', 'tableware', 'head'])
plt.boxplot(data,0,'rs',0)
plt.savefig('stat_feat_02.png')[ 1.51131 1.51838 1.52315 1.52247 1.52365 1.51613 1.51602 1.51623
1.51719 1.51683 1.51545 1.51556 1.51727 1.51531 1.51609 1.51508
1.51653 1.51514 1.51658 1.51617 1.51732 1.51645 1.51831 1.5164
1.51623 1.51685 1.52065 1.51651 1.51711]

Kaynaklar
[5] Cross Validated, Relation between the phi, Matthews and Pearson correlation coefficients?, https://stats.stackexchange.com/questions/59343/relation-between-the-phi-matthews-and-pearson-correlation-coefficients
[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