---
title: 'Çok Değişkenli İnceleme'
source: 'https://academia.sh/tr/kurslar/kesifsel-analiz/cok-degiskenli-inceleme'
course: 'İstatistiksel Analiz ve Keşifsel Veri Analizi'
language: tr
updated: '2026-08-17T18:08:47+00:00'
license: 'CC BY-SA 4.0'
---

# Çok Değişkenli İnceleme

Altı sütunluk bir korelasyon matrisi 15 çift taşır ve eşik dağılım tablosundan değil karıştırmadan gelir: 2.000 karıştırmada katsayı dağılımının yüzde 95'i 0,0354 çıkar ve 15 çiftin 5'i bu eşiği aşar — ama beşinden üçü tanım gereği, ikisi de abone numarası sütunu yüzünden aşar. Birbirinden tümüyle bağımsız üretilmiş sütunlarda çift sayısı 6'dan 190'a çıktığında eşiği aşan çift sayısı 0'dan 12'ye çıkar ve beklenen değer 9,5'tir; en yüksek katsayı 0,049 ile eşiğin belirgin üstündedir. Boyut azaltma tek soruya indirgenir: ölçüm ağı sütunlarında ilk iki bileşen değişimin yüzde 49,3'ünü, iki gizli sürücüden üretilen kümede yüzde 82,1'ini, bağımsız sütunlarda yalnız yüzde 35,0'ını taşır.

Önceki ders iki sütunu birlikte inceledi ve tek bir çiftin katsayısına payını yazdı. Gerçek
bir çözümlemede ise çiftler tek tek sorulmaz; bir tablo alınır ve bütün sayısal sütunların
katsayıları aynı anda hesaplanır. Altı sütun 15 çift üretir, yirmi sütun 190 çift. Her çift
ayrı bir sorudur ve her soru rastlantıya bir şans daha tanır.

Bu dersin ölçüsü **karşılaştırma sayısının ürettiği sahte ilişkidir**. Tümüyle bağımsız
üretilmiş sütunlarda kaç çiftin eşiği aştığı sayılır ve bu sayının sütun sayısıyla nasıl
büyüdüğü gösterilir. İkinci ölçü boyut azaltmanın kazancıdır ve tek bir soruya indirgenir:
kaç bileşen değişimin ne kadarını taşıyor.

- **EA16.** Çok değişkenli inceleme (multivariate) ikiden çok sütuna aynı anda bakar.
  $k$ sütunlu bir **korelasyon matrisi** $k(k-1)/2$ çift taşır; çift sayısı sütun sayısıyla
  karesel büyür.
- **EA17.** Matristeki her hücre ayrı bir sorudur. Tek bir çift için savunulabilir olan eşik,
  bütün çiftlere aynı anda uygulandığında **eşiği aşan çift sayısını** kendiliğinden büyütür.
- **EA18.** Eşik burada dağılım tablosundan değil **karıştırmadan** gelir: bir sütun kendi
  içinde 2.000 kez karıştırılır ve elde edilen katsayı dağılımının yüzde 95'i eşik alınır.
- **EA19. Boyut azaltma (dimensionality reduction)** bu derste tek bir soruyla geçer: **kaç
  bileşen değişimin ne kadarını taşıyor**. Yöntem seçimi, döndürme ve bileşenlerin yorumu
  yazılmaz.
- **EA20.** Bileşen payları **korelasyon matrisinin özdeğerlerinden** okunur; özdeğerlerin
  toplamı sütun sayısına eşittir ve pay olarak yazıldığında toplam 100 olur. Sütunlar
  birbirini tekrarlamıyorsa paylar eşite yakın dağılır.

## Matris ve Eşiği

```python

# kesif.py — MODELDIR: K03 ve K04'un kurgu olcum agi ayni tohumla yeniden
# uretilir. Kume kurgudur; hicbir gercek abone, sayac ya da bolge temsil edilmez.
import math

TOHUM, HAM, M32 = 20260218, 1400, 0xFFFFFFFF
DONEM = ["2026-01", "2026-02", "2026-03"]
TARIFE = [10, 25, 40]
BOLGE = [("kuzey", 0.28, 21), ("guney", 0.22, 17), ("dogu", 0.18, 26),
         ("bati", 0.14, 14), ("merkez", 0.18, 23)]


def uretec(t: int):
    """Dogrusal eslemeli uretec: tohum koda yazilidir, cikti kosumdan kosuma ayni."""
    x = ((t ^ (t >> 16)) * 2246822507) & M32
    x = ((x ^ (x >> 13)) * 3266489909) & M32
    s = [(x ^ (x >> 16)) & M32]

    def sonraki() -> float:
        s[0] = (s[0] * 1664525 + 1013904223) & M32
        return s[0] / 4294967296
    return sonraki


def ayrik(u: float, w: list[float]) -> int:
    t = 0.0
    for i, x in enumerate(w):
        t += x
        if u < t:
            return i
    return len(w) - 1


_abone, _elenen = [], []
for i in range(HAM):
    r = uretec(TOHUM + i)
    b = BOLGE[ayrik(r(), [x[1] for x in BOLGE])]
    k = {"abone_no": 10001 + i, "bolge": b[0], "taban": b[2],
         "hane_kisi": ayrik(r(), [0.06, 0.24, 0.30, 0.24, 0.11, 0.05]),
         "memnuniyet": ayrik(r(), [0.08, 0.14, 0.27, 0.34, 0.17]) + 1}
    (_elenen if r() < 0.046 else _abone).append(k)
_gecerli = {a["abone_no"] for a in _abone}

OKUMA = []
for k in _abone + _elenen:
    r = uretec(TOHUM + 7000 + k["abone_no"])
    for d in range(ayrik(r(), [0.05, 0.12, 0.21, 0.62])):
        t = 0.0 if r() < 0.038 else math.floor(k["taban"] * math.exp(
            (r() + r() + r() - 1.5) * 0.62) * (1 - d * 0.05) * 100 + 0.5) / 100
        if k["abone_no"] not in _gecerli:
            r()
            continue
        OKUMA.append({"abone_no": k["abone_no"], "bolge": k["bolge"],
                      "donem": DONEM[d], "tuketim_m3": t, "hane_kisi": k["hane_kisi"],
                      "memnuniyet": k["memnuniyet"],
                      "basamak": 1 if t < TARIFE[0] else 2 if t < TARIFE[1]
                      else 3 if t < TARIFE[2] else 4})
        r()

def ort(v: list[float]) -> float:
    return sum(v) / len(v)


def kor(x: list[float], y: list[float]) -> float:
    mx, my = ort(x), ort(y)
    sx = math.sqrt(sum((a - mx) ** 2 for a in x))
    sy = math.sqrt(sum((b - my) ** 2 for b in y))
    return sum((a - mx) * (b - my) for a, b in zip(x, y)) / (sx * sy)


def hiza(w: list[int], sol: int = 1):
    """Ilk `sol` sutun sola, kalanlar saga yaslanir."""
    return lambda h: "".join(str(v).ljust(w[i]) if i < sol else str(v).rjust(w[i])
                             for i, v in enumerate(h))


SUTUN = [("tuketim", [o["tuketim_m3"] for o in OKUMA]),
         ("basamak", [float(o["basamak"]) for o in OKUMA]),
         ("hane_kisi", [float(o["hane_kisi"]) for o in OKUMA]),
         ("memnuniyet", [float(o["memnuniyet"]) for o in OKUMA]),
         ("donem", [float(DONEM.index(o["donem"])) for o in OKUMA]),
         ("abone_no", [float(o["abone_no"]) for o in OKUMA])]
K = len(SUTUN)
m = hiza([12] + [11] * K)
print(m(["sutun"] + [a[:9] for a, _ in SUTUN]))
for i, (ad, x) in enumerate(SUTUN):
    print(m([ad] + [f"{kor(x, y):+.3f}" for _, y in SUTUN[:i + 1]]))

KOSUM = 2000


def esik_95(x: list[float], tohum: int) -> float:
    """Sutun kendi kendine karistirilir; |katsayi| dagiliminin yuzde 95'i esiktir."""
    r, n = uretec(tohum), len(x)
    mx = ort(x)
    d = [a - mx for a in x]
    kare = sum(a * a for a in d)
    deger = []
    for _ in range(KOSUM):
        h = d[:]
        for i in range(n - 1, 0, -1):
            j = int(r() * (i + 1))
            h[i], h[j] = h[j], h[i]
        deger.append(abs(sum(a * b for a, b in zip(d, h)) / kare))
    return sorted(deger)[int(0.95 * KOSUM)]


ESIK = esik_95(SUTUN[0][1], TOHUM + 901)
cift = [(SUTUN[i][0], SUTUN[j][0], kor(SUTUN[i][1], SUTUN[j][1]))
        for i in range(K) for j in range(i + 1, K)]
asan = [c for c in cift if abs(c[2]) >= ESIK]
print(f"\n{K} sutun, {len(cift)} cift; {KOSUM} karistirmada |katsayi| dagiliminin "
      f"yuzde 95'i {ESIK:.4f}")
print(f"esigi asan cift: {len(asan)} / {len(cift)}")
for a, b, v in sorted(asan, key=lambda c: -abs(c[2])):
    print(f"  {a} / {b}: {v:+.3f}")
```

```
sutun           tuketim    basamak  hane_kisi  memnuniye      donem   abone_no
tuketim          +1.000
basamak          +0.883     +1.000
hane_kisi        +0.010     +0.007     +1.000
memnuniyet       -0.010     -0.015     -0.004     +1.000
donem            -0.111     -0.116     +0.000     -0.006     +1.000
abone_no         +0.031     +0.041     +0.046     -0.001     -0.005     +1.000

6 sutun, 15 cift; 2000 karistirmada |katsayi| dagiliminin yuzde 95'i 0.0354
esigi asan cift: 5 / 15
  tuketim / basamak: +0.883
  basamak / donem: -0.116
  tuketim / donem: -0.111
  hane_kisi / abone_no: +0.046
  basamak / abone_no: +0.041
```

Altı sütun 15 çift üretti ve eşik 0,0354 çıktı. Eşik bir tablodan okunmadı: tüketim sütunu
kendi içinde 2.000 kez karıştırıldı, her koşumda katsayı yeniden hesaplandı ve elde edilen
dağılımın yüzde 95'i eşik olarak alındı. Bu eşiğin anlamı dardır ve tam olarak şudur — hiçbir
ilişki yokken, **tek bir çiftte**, yüz koşumun beşinde bu büyüklükte bir katsayı görülür.

Eşiği aşan beş çift var, ama beşi de aynı türden değil. Tüketim ile basamak arasındaki
+0,883 bir keşif değil bir tanımdır; basamak 10, 25 ve 40 m³ sınırlarıyla tüketimden
hesaplanır. Basamak ile dönem arasındaki −0,116, tüketim ile dönem arasındaki −0,111'in
aynısıdır, çünkü basamak tüketimin bir yeniden yazımıdır — iki satır aynı olguyu iki kez
sayar. Geriye abone numarasını içeren iki çift kalır: abone numarası bir kayıt numarasıdır,
hiçbir şeyin nedeni olamaz.

On beş çiftten beşi eşiği aştı ve rapora girecek bağımsız bulgu sayısı en fazla birdir.
Matris kendisi bir bulgu üretmez; sorulacak soruların sayısını büyütür ve büyüdükçe eşiği
aşan hücre bulmak kolaylaşır.

## Çift Sayısı Bulgu Üretir

```python
# cokluk.py — KURGU: birbiriyle hicbir ilgisi olmayan sutunlar uretilir ve ayni
# esik butun ciftlere uygulanir. Aranan sey, esigi asan cift sayisidir.
def bagimsiz(k: int, n: int, tohum: int) -> list[list[float]]:
    r = uretec(tohum)
    return [[r() + r() + r() for _ in range(n)] for _ in range(k)]


BAGIMSIZ = bagimsiz(20, len(OKUMA), TOHUM + 902)
_m = [ort(s) for s in BAGIMSIZ]
_d = [[a - t for a in s] for s, t in zip(BAGIMSIZ, _m)]
_n = [math.sqrt(sum(a * a for a in s)) for s in _d]
ikili = lambda i, j: sum(a * b for a, b in zip(_d[i], _d[j])) / (_n[i] * _n[j])

g = hiza([8, 8, 12, 12, 12])
print(g(["sutun", "cift", "esigi asan", "beklenen", "en buyuk"]) + "   en buyuk cift")
for k in (4, 6, 8, 12, 20):
    ciftler = [(i, j) for i in range(k) for j in range(i + 1, k)]
    deger = {(i, j): abs(ikili(i, j)) for i, j in ciftler}
    enb = max(deger, key=deger.get)
    print(g([k, len(ciftler), sum(1 for v in deger.values() if v >= ESIK),
             f"{0.05 * len(ciftler):.1f}", f"{deger[enb]:.3f}"])
          + f"   sutun{enb[0] + 1} / sutun{enb[1] + 1}")
print(f"\nesik {ESIK:.4f}; sutunlarin hicbiri digerinden turetilmemistir")
```

```
sutun       cift  esigi asan    beklenen    en buyuk   en buyuk cift
4              6           0         0.3       0.021   sutun1 / sutun2
6             15           1         0.8       0.037   sutun2 / sutun6
8             28           2         1.4       0.048   sutun1 / sutun8
12            66           5         3.3       0.049   sutun6 / sutun12
20           190          12         9.5       0.049   sutun6 / sutun12

esik 0.0354; sutunlarin hicbiri digerinden turetilmemistir
```

Bu tablodaki sütunların hiçbiri diğerinden türetilmemiştir; hepsi ayrı çekilişlerden gelir
ve aralarında hiçbir ilişki yoktur. Buna rağmen dört sütunda 0, altı sütunda 1, sekiz
sütunda 2, yirmi sütunda **12** çift eşiği aşıyor.

Sayının nereden geldiği eşiğin tanımında yazılı. Eşik, tek bir çiftte yüz koşumun beşinde
aşılan değerdir; 190 çifte aynı eşik uygulanınca yaklaşık 190 × 0,05 = 9,5 çiftin aşması
beklenir. Gözlenen 12, beklenen 9,5'in yakınındadır. Yani eşiği aşan çiftler bir kusur
değil, eşiğin kendi tanımının doğrudan sonucudur.

Tehlike, bu tablodan tek bir satırın çekilip alınmasındadır. "Altıncı ve on ikinci sütun
arasında 0,049'luk bir ilişki bulundu, eşik 0,0354" cümlesi doğru sayılar içerir ve tümüyle
uydurmadır: o çift 190 çift arasından **en büyüğü olduğu için** seçilmiştir. Bir katsayının
yanında yalnız payı değil, **kaç çift arasından seçildiği** de yazılmak zorundadır. "Tek
çiftten biri" ile "190 çiftten en büyüğü" aynı cümle değildir.

Karşılaştırma sayısını küçültmenin bir yolu da eşiği yükseltmek değil, **sütun sayısını**
düşürmektir. Bu, sonraki bölümün konusudur.

## Kaç Bileşen

```python
# bilesen.py — boyut azaltmanin tek sorusu: kac bilesen degisimin ne kadarini
# tasiyor. Paylar korelasyon matrisinin ozdegerlerinden okunur.
def ozdeger(A: list[list[float]]) -> list[float]:
    """Simetrik matrisin ozdegerleri: kose disi en buyuk oge sifira inene dek dondurulur."""
    n, M = len(A), [s[:] for s in A]
    for _ in range(200):
        p, q, en = 0, 1, 0.0
        for i in range(n):
            for j in range(i + 1, n):
                if abs(M[i][j]) > en:
                    p, q, en = i, j, abs(M[i][j])
        if en < 1e-12:  # kose disi ogeler bu esigin altina inince donme durur
            break
        th = (M[q][q] - M[p][p]) / (2 * M[p][q])
        t = (1.0 if th >= 0 else -1.0) / (abs(th) + math.sqrt(th * th + 1))
        c = 1 / math.sqrt(t * t + 1)
        s = t * c
        for k in range(n):
            kp, kq = M[k][p], M[k][q]
            M[k][p], M[k][q] = c * kp - s * kq, s * kp + c * kq
        for k in range(n):
            pk, qk = M[p][k], M[q][k]
            M[p][k], M[q][k] = c * pk - s * qk, s * pk + c * qk
    return sorted((M[i][i] for i in range(n)), reverse=True)


def ortak_surucu(tohum: int) -> list[list[float]]:
    """KURGU: alti sutun iki gizli surucuden ve gurultuden uretilir."""
    r = uretec(tohum)
    f1 = [r() + r() + r() - 1.5 for _ in range(len(OKUMA))]
    f2 = [r() + r() + r() - 1.5 for _ in range(len(OKUMA))]
    AGIRLIK = [(1.0, 0.0), (0.9, 0.2), (0.8, 0.3), (0.1, 1.0), (0.2, 0.9), (0.3, 0.8)]
    return [[a * x + b * y + 0.55 * (r() + r() + r() - 1.5) for x, y in zip(f1, f2)]
            for a, b in AGIRLIK]


KUME = [("olcum agi", [x for _, x in SUTUN]),
        ("ortak surucu", ortak_surucu(TOHUM + 903)),
        ("bagimsiz", bagimsiz(6, len(OKUMA), TOHUM + 904))]
b = hiza([14] + [9] * 6)
print(b(["kume"] + [f"b{i + 1}" for i in range(6)]) + "   ilk iki bilesen")
for ad, S in KUME:
    oz = ozdeger([[kor(a, c) for c in S] for a in S])
    toplam = sum(oz)
    print(b([ad] + [f"{100 * v / toplam:.1f}" for v in oz])
          + f"   {100 * (oz[0] + oz[1]) / toplam:.1f} yuzde")
print(f"\npaylarin toplami her satirda 100; ozdegerlerin toplami sutun sayisidir ({len(SUTUN)})")
```

```
kume                 b1       b2       b3       b4       b5       b6   ilk iki bilesen
olcum agi          31.9     17.4     16.7     16.2     15.9      1.9   49.3 yuzde
ortak surucu       55.2     26.9      4.9      4.7      4.3      4.0   82.1 yuzde
bagimsiz           17.8     17.2     16.7     16.4     16.3     15.5   35.0 yuzde

paylarin toplami her satirda 100; ozdegerlerin toplami sutun sayisidir (6)
```

Üç satır boyut azaltmanın ne zaman iş yaptığını gösteriyor. Ortak sürücüden üretilen kümede
altı sütun iki gizli değişkenden geliyor ve ilk iki bileşen değişimin yüzde 82,1'ini taşıyor;
altı sütun yerine iki sayı yazmak değişimin yüzde 17,9'unu bırakmak demektir. Bağımsız
sütunlarda paylar 17,8'den 15,5'e kadar neredeyse eşittir ve ilk iki bileşen yalnız yüzde
35,0 taşır: azaltılacak bir şey yoktur, çünkü sütunlar birbirini hiç tekrarlamaz.

Ölçüm ağı satırı ikisinin arasındadır. İlk bileşen yüzde 31,9 taşır, sonraki dördü ise 17,4
ile 15,9 arasında sıkışır. Asıl bilgi son sütundadır: altıncı bileşenin payı yüzde 1,9'a
düşmüştür. Bu düşüş bir tekrarın işaretidir ve tekrarın ne olduğu ilk tablodan bilinir —
tüketim ile basamak aynı şeyi iki kez yazar. Pay tablosu, hangi sütunların birbirini
tekrarladığını söylemez, ama **tekrar olup olmadığını** tek bakışta verir.

İki bölüm burada birleşiyor. Altı sütun 15 çift üretir; sütunlar iki bileşene indirilirse
çift sayısı 1'e iner. Boyut azaltmanın ölçülebilir kazancı budur: bakılacak hücre sayısını
düşürür ve böylece rastlantının eşiği aşma şansını da düşürür. Bedeli, bileşenlerin artık
"tüketim" ya da "hane kişi sayısı" gibi bir adı olmamasıdır. Yöntem seçimi ve bileşenlerin
yorumlanması bu dersin dışındadır.

## Özet

- Altı sütunlu matris 15 çift taşır; eşik dağılım tablosundan değil karıştırmadan gelir ve
  2.000 koşumluk dağılımın yüzde 95'i olarak 0,0354 çıkar.
- Eşiği aşan beş çiftin üçü tanım gereği aşar (basamak tüketimden hesaplanır), ikisi abone
  numarası sütunundan gelir; bağımsız bulgu sayısı en fazla birdir.
- Birbiriyle hiç ilgisi olmayan sütunlarda çift sayısı 6'dan 190'a çıktığında eşiği aşan çift
  sayısı 0'dan 12'ye çıkar ve beklenen değer 9,5'tir.
- Bir katsayının yanına payıyla birlikte **kaç çift arasından seçildiği** yazılır; "tek
  çiftten biri" ile "190 çiftten en büyüğü" aynı iddia değildir.
- Bileşen payları boyut azaltmanın kazancını önceden söyler: ortak sürücülü kümede ilk iki
  bileşen yüzde 82,1, ölçüm ağında yüzde 49,3, bağımsız sütunlarda yüzde 35,0 taşır.

## Sonraki Adım

Bu konunun dört dersi kümeye hep hesapla yaklaştı: ortalama alındı, dağılım sayıldı, katsayı
hesaplandı, matris kuruldu. Hepsinin ortak varsayımı, kümedeki değerlerin ölçülmüş değerler
olduğuydu. Oysa keşif sırasında ilk yakalanan şeyler çoğu zaman hesapla değil, tabloya
bakarken görülür: aynı değerin şüpheli sıklıkta tekrarı, bir üst sınırda biriken kayıtlar,
birlikte bulunmaması gereken alan bileşimleri, bir dönemin diğerlerinden belirgin biçimde
seyrek olması. Sonraki ders bu ilk denetimi ele alır ve her yakalanan sorunun hangi özeti ne
kadar oynattığını sayar.
