---
title: 'Boyut Azaltmanın Öznitelik Rolü'
source: 'https://academia.sh/tr/kurslar/oznitelik-muhendisligi/boyut-azaltmanin-oznitelik-rolu'
course: 'Veri Hazırlama ve Öznitelik Mühendisliği'
language: tr
updated: '2026-08-17T18:10:11+00:00'
license: 'CC BY-SA 4.0'
---

# Boyut Azaltmanın Öznitelik Rolü

On üç ham özniteliğin yerine bileşen temelli bir temsil konduğunda ayrılmış küme sayısının ve yorumlanabilirliğin ne olduğunun ölçülmesi: ham sütunlar sınamada 0,8254 verirken iki bileşen 0,8175, üç bileşen 0,8056, beş bileşen 0,7778, sekiz bileşen 0,7460 veriyor ve hiçbir bileşen sayısında ham temsile yetişilemiyor. En büyük bileşen payını taşıyan bileşen tek başına 0,7381 ile tabanın altında kalırken payı 0,093 olan beşinci bileşen 0,7659 veriyor. Ham temsilde bölmelerin 0,35'i ortalama tüketimden okunurken bileşen temsilinde aynı pay adı olmayan bir karışıma düşüyor.

Önceki ders sütun sayısını azaltmanın bir yolunu ölçtü: sütunları teker teker tutmak ya da atmak.
Gömülü yöntem yirmi beş adaydan on dördünü tuttu ve ayrılmış kümede 0,8254 verdi; iki dersin elle
ölçerek kurduğu on üç sütunluk küme de aynı sayıyı verdi. Tutulan sütunların hepsinin bir adı var
ve ne anlama geldikleri biliniyor.

Sütun sayısını azaltmanın ikinci yolu sütunları atmak yerine **karıştırmaktır**. On üç sütun,
her biri on üçünün ağırlıklı toplamı olan birkaç yeni sütuna dönüştürülebilir; bunlara **bileşen**
denir ve bileşenler kümedeki değişkenliği en çok taşıyan yönlerden başlayarak sıralanır. M26/K05'in
keşifsel analiz kursu bileşen payını orada ölçmüştü ve kuram burada tekrarlanmaz. Bu dersin
sorduğu tek soru şudur: bileşenler bir **öznitelik** olarak ne yapıyor — kaç bileşende ham
özniteliklerin ayrılmış küme sayısına yetişiliyor ve karşılığında ne kaybediliyor.

- **OS22.** Ham temsil on üç sütundur: M27/K01'in on bir sütunu, `kisi_basi` ve `a_muhur`.
  Ayrılmış kümedeki sayısı 0,8254'tür ve bu dersin karar öncesi çizgisidir.
- **OS23.** Ölçek ve bileşen yönleri **yalnız eğitim kümesinden** öğrenilir, üç kümeye de aynı
  sayılarla uygulanır. Bütün kümeden öğrenilseydi ölçüm şişerdi.
- **OS24.** Bileşenler ders içinde yazılır: standartlaştırılmış eğitim sütunlarının eşdeğişim
  dizeyi kurulur, en büyük yönü yineleme ile bulunur, bulunan yön dizeyden çıkarılır ve işlem
  on üç kez yinelenir. Kitaplık çağrılmaz.
- **OS25.** Yineleme sayısı her bileşen için 200'dür; bu sayı sonuca bakılarak seçilmemiştir.
  Kalan büyüklüğü $10^{-12}$'nin altına düşerse yineleme erken durur.
- **OS26.** Bileşen payı, bileşenin taşıdığı değişkenliğin toplam değişkenliğe oranıdır.
- **OS27.** Bileşenler **etiketi görmez**. Sıralamaları değişkenliğe göredir, ayrım gücüne göre
  değildir.
- **OS28.** Model değişmez: derinlik 6 karar ağacı. Taban çizgisi 0,7579'dur.
- **OS29.** Yorumlanabilirlik ölçüsü, ağacın bölmelerinin hangi sütundan okunduğudur; her bölme
  böldüğü satır sayısıyla ağırlıklandırılır.

## On Üç Sütun, On Üç Bileşen

```python
# ORTAK — MODELDIR. M27/K01'in KURGU abone tablosu ayni tohumla yeniden uretilir;
# model derinlik 6 karar agacidir. Onceki dersten kalan tek yeni sutun kisi_basi.
import math

TOHUM, HAM, M32 = 20260218, 1400, 0xFFFFFFFF
BOLGE = [("kuzey", 0.28, 21, 0.00), ("guney", 0.22, 17, -0.10),
         ("dogu", 0.18, 26, 0.30), ("bati", 0.14, 14, -0.05),
         ("merkez", 0.18, 23, 0.05)]


def uretec(t):
    x = ((t ^ (t >> 16)) * 2246822507) & M32
    x = ((x ^ (x >> 13)) * 3266489909) & M32
    s = [(x ^ (x >> 16)) & M32]

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


def ayrik(u, w):
    t = 0.0
    for i, x in enumerate(w):
        t += x
        if u < t:
            return i
    return len(w) - 1


ABONE, VERI = [], []
for i in range(HAM):
    r = uretec(TOHUM + i)
    b = BOLGE[ayrik(r(), [x[1] for x in BOLGE])]
    hane = 1 + ayrik(r(), [0.06, 0.24, 0.30, 0.24, 0.11, 0.05])
    memnun = 1 + ayrik(r(), [0.08, 0.14, 0.27, 0.34, 0.17])
    if r() >= 0.046:
        ABONE.append({"no": 10001 + i, "bolge": b, "hane": hane, "memnuniyet": memnun})
for k in ABONE:
    r, v = uretec(TOHUM + 7000 + k["no"]), []
    for d in range(ayrik(r(), [0.05, 0.12, 0.21, 0.62])):
        v.append(0.0 if r() < 0.038 else math.floor(
            k["bolge"][2] * math.exp((r() + r() + r() - 1.5) * 0.62)
            * (1 - d * 0.05) * 100 + 0.5) / 100)
        r()
    if not v:
        continue
    ort, oyn, r = sum(v) / len(v), max(v) - min(v), uretec(TOHUM + 51000 + k["no"])
    z = (0.052 * (ort - 20) + 0.85 * (min(v) == 0.0) + 0.026 * oyn
         + 0.24 * (k["hane"] >= 5) - 0.20 * (k["memnuniyet"] >= 4) + k["bolge"][3]
         + 0.9 * (k["no"] - 10001) / 1399 + (r() + r() + r() - 1.5) * 1.30)
    x = {"no": k["no"], "hane": k["hane"], "memnuniyet": k["memnuniyet"],
         "donem": len(v), "ort_tuketim": round(ort, 2), "oynaklik": round(oyn, 2),
         "sifir_okuma": int(min(v) == 0.0), "supheli": int(z > 1.35),
         "bolge_ad": k["bolge"][0]}
    for b in BOLGE:
        x["b_" + b[0]] = int(k["bolge"][0] == b[0])
    VERI.append(x)

TEMEL = ["ort_tuketim", "oynaklik", "hane", "memnuniyet", "donem", "sifir_okuma",
         "b_kuzey", "b_guney", "b_dogu", "b_bati", "b_merkez"]
TABAN_ALAN = TEMEL + ["kisi_basi"]
for x in VERI:
    x["kisi_basi"] = round(x["ort_tuketim"] / x["hane"], 3)


def karistir(veri, tohum):
    r, s = uretec(tohum), list(range(len(veri)))
    for i in range(len(s) - 1, 0, -1):
        j = int(r() * (i + 1))
        s[i], s[j] = s[j], s[i]
    return [veri[i] for i in s]


K = karistir(VERI, TOHUM + 90000)
EGT, DOG, SIN = K[:756], K[756:1008], K[1008:]


def gini(s):
    p = sum(x["supheli"] for x in s) / len(s) if s else 0.0
    return 2 * p * (1 - p)


def agac(s, derinlik, alanlar, enaz=2):
    p, en = sum(x["supheli"] for x in s) / len(s), None
    if derinlik and len(s) >= 2 * enaz and 0.0 < p < 1.0:
        for a in alanlar:
            d = sorted({x[a] for x in s})
            for v in (d[1:] if len(d) < 10 else
                      [d[int(i * len(d) / 10)] for i in range(1, 10)]):
                sol = [x for x in s if x[a] < v]
                sag = [x for x in s if x[a] >= v]
                if min(len(sol), len(sag)) < enaz:
                    continue
                k = gini(s) - (len(sol) * gini(sol) + len(sag) * gini(sag)) / len(s)
                if en is None or k > en[0]:
                    en = (k, a, v, sol, sag)
    if en is None or en[0] <= 1e-9:
        return {"tahmin": int(p > 0.5)}
    return {"alan": en[1], "esik": en[2],
            "sol": agac(en[3], derinlik - 1, alanlar, enaz),
            "sag": agac(en[4], derinlik - 1, alanlar, enaz)}


def tahmin(d, x):
    while "tahmin" not in d:
        d = d["sol"] if x[d["alan"]] < d["esik"] else d["sag"]
    return d["tahmin"]


def dogruluk(d, s):
    return sum(tahmin(d, x) == x["supheli"] for x in s) / len(s)


def taban(egt, s):
    c = int(sum(x["supheli"] for x in egt) * 2 > len(egt))
    return sum(x["supheli"] == c for x in s) / len(s)


def olc(alanlar, derinlik=6):
    m = agac(EGT, derinlik, alanlar)
    return dogruluk(m, EGT), dogruluk(m, SIN)
```

Bileşenleri bulmak için üç adım gerekir: sütunları ortak bir ölçeğe getirmek, eşdeğişim dizeyini
kurmak ve en büyük değişkenliği taşıyan yönü bulup dizeyden çıkarmak. Üçüncü adım on üç kez
yinelenince on üç bileşen çıkar. Ölçek ve yönlerin hepsi yalnız eğitim kümesinden okunur.

```python
for x in VERI:
    r = uretec(TOHUM + 61000 + x["no"])
    r(), r()
    x["a_muhur"] = int(r() < (0.42 if x["supheli"] else 0.10))
HAM_ALAN = TABAN_ALAN + ["a_muhur"]

ORT = {a: sum(x[a] for x in EGT) / len(EGT) for a in HAM_ALAN}
SAC = {a: max(1e-9, (sum((x[a] - ORT[a]) ** 2 for x in EGT) / len(EGT)) ** 0.5)
       for a in HAM_ALAN}
for x in VERI:
    x["_z"] = [(x[a] - ORT[a]) / SAC[a] for a in HAM_ALAN]

n = len(HAM_ALAN)
C = [[sum(x["_z"][i] * x["_z"][j] for x in EGT) / len(EGT) for j in range(n)]
     for i in range(n)]


def carp(m, v):
    return [sum(m[i][j] * v[j] for j in range(len(v))) for i in range(len(m))]


BILESEN, PAY = [], []
A = [satir[:] for satir in C]
for _ in range(n):
    v = [1.0 / (i + 1) for i in range(n)]
    for _ in range(200):
        w = carp(A, v)
        u = sum(q * q for q in w) ** 0.5
        if u < 1e-12:
            break
        v = [q / u for q in w]
    lam = sum(v[i] * carp(A, v)[i] for i in range(n))
    BILESEN.append(v)
    PAY.append(max(0.0, lam))
    A = [[A[i][j] - lam * v[i] * v[j] for j in range(n)] for i in range(n)]

TOP = sum(PAY)
for x in VERI:
    for i, v in enumerate(BILESEN):
        x["c" + str(i)] = round(sum(x["_z"][j] * v[j] for j in range(n)), 4)

HAM = olc(HAM_ALAN)
print(f"{'temsil':<22} {'sutun':>5} {'pay':>7} {'egitimde':>9} {'ayrilmis':>9} {'fark':>8}")
print(f"{'ham oznitelikler':<22} {n:>5} {'':>7} {HAM[0]:>9.4f} {HAM[1]:>9.4f}")
for k in (1, 2, 3, 5, 8, 11, 13):
    e, s = olc(["c" + str(i) for i in range(k)])
    print(f"{'bilesen ' + str(k):<22} {k:>5} {sum(PAY[:k]) / TOP:>7.3f} {e:>9.4f} "
          f"{s:>9.4f} {s - HAM[1]:>+8.4f}")
print(f"\ntaban cizgisi {taban(EGT, SIN):.4f}")
```

```
temsil                 sutun     pay  egitimde  ayrilmis     fark
ham oznitelikler          13            0.8876    0.8254
bilesen 1                  1   0.177    0.8003    0.7381  -0.0873
bilesen 2                  2   0.323    0.8651    0.8175  -0.0079
bilesen 3                  3   0.432    0.8677    0.8056  -0.0198
bilesen 5                  5   0.630    0.9074    0.7778  -0.0476
bilesen 8                  8   0.877    0.9074    0.7460  -0.0794
bilesen 11                11   0.990    0.8995    0.7817  -0.0437
bilesen 13                13   1.000    0.9048    0.7897  -0.0357

taban cizgisi 0.7579
```

Sorunun ilk yarısının yanıtı tablodadır: **hiçbir bileşen sayısında ham özniteliklere
yetişilemiyor.** En yakın satır iki bileşendir; 0,8175 ile ham temsilin 0,0079 altında, yani iki
abone. On üç sütun iki sütuna indirilmiş ve iki abone kaybedilmiştir. Bu, bir sıkıştırma kararı
olarak savunulabilir bir dengedir.

Tablonun asıl bulgusu bundan sonra geliyor. Bileşen sayısı arttıkça sayı **iyileşmiyor**: üç
bileşende 0,8056, beşte 0,7778, sekizde 0,7460. Bileşen payı ise düzenli olarak büyüyor —
0,323'ten 0,877'ye. İki sütun aynı yöne gitmiyor. On üç bileşenin hepsi kullanıldığında bilgi
kaybı yoktur, temsil ham temsilin döndürülmüş hâlidir ve yine de sayı 0,7897'de kalıyor; fark
0,0357. Karar ağacı bölmelerini eksenlere dik yapar ve döndürülmüş bir eksende aynı ayrımı kurmak
için daha çok bölme gerekir. Bileşen temsili modelden bağımsız değildir.

## Pay Sıralaması Ayrım Sıralaması Değildir

Bileşenler etiketi hiç görmez; sıralamaları yalnız hangi yönde daha çok değişkenlik olduğuna
bakar. Etiketin o yönlerde durup durmadığı ayrı bir sorudur ve ölçülmesi gerekir.

```python
def kullanim(d, s):
    say = {}

    def gez(d, s):
        if "tahmin" in d:
            return
        say[d["alan"]] = say.get(d["alan"], 0) + len(s)
        gez(d["sol"], [x for x in s if x[d["alan"]] < d["esik"]])
        gez(d["sag"], [x for x in s if x[d["alan"]] >= d["esik"]])
    gez(d, s)
    t = sum(say.values())
    return ", ".join(f"{a} {say[a] / t:.2f}"
                     for _, a in sorted((-say[a], a) for a in say)[:4])


print("ham temsilde en cok bolunen:", kullanim(agac(EGT, 6, HAM_ALAN), EGT))
print("bilesen temsilinde        :",
      kullanim(agac(EGT, 6, ["c" + str(i) for i in range(13)]), EGT))
for i in (0, 1):
    y = sorted(((-abs(BILESEN[i][j]), HAM_ALAN[j], BILESEN[i][j]) for j in range(n)))
    print(f"c{i} yukleri (pay {PAY[i] / TOP:.3f}): " +
          ", ".join(f"{a} {w:+.2f}" for _, a, w in y[:4]) +
          f", ... kalan {n - 4} sutunun toplam agirligi "
          f"{sum(abs(w) for _, _, w in y[4:]):.2f}")
print()
print(f"{'tek bilesen':<14} {'pay':>7} {'egitimde':>9} {'ayrilmis':>9}")
for i in range(5):
    e, s = olc(["c" + str(i)])
    print(f"{'c' + str(i):<14} {PAY[i] / TOP:>7.3f} {e:>9.4f} {s:>9.4f}")
```

```
ham temsilde en cok bolunen: ort_tuketim 0.35, oynaklik 0.19, a_muhur 0.17, kisi_basi 0.14
bilesen temsilinde        : c0 0.29, c1 0.25, c8 0.12, c2 0.11
c0 yukleri (pay 0.177): kisi_basi +0.54, ort_tuketim +0.53, b_bati -0.34, b_dogu +0.30, ... kalan 9 sutunun toplam agirligi 1.16
c1 yukleri (pay 0.146): oynaklik +0.62, sifir_okuma +0.51, donem +0.42, a_muhur +0.29, ... kalan 9 sutunun toplam agirligi 0.86

tek bilesen        pay  egitimde  ayrilmis
c0               0.177    0.8003    0.7381
c1               0.146    0.8267    0.7421
c2               0.109    0.8188    0.7579
c3               0.105    0.7937    0.7579
c4               0.093    0.8148    0.7659
```

Son tablo pay sıralamasının ayrım sıralaması olmadığını sayıyla gösteriyor. Payı en büyük bileşen
`c0`, tek başına 0,7381 veriyor — taban çizgisinin 0,0198 **altında**. Payı yarısı kadar olan
`c4` ise 0,7659 veriyor ve tabanın üstünde kalıyor. "En çok değişkenliği taşıyan yön" ile "en çok
ayıran yön" iki ayrı şeydir, ve bileşenler yalnız birincisine göre sıralandığı için ilk k bileşeni
almak ayrım açısından keyfi bir kesmedir.

İki bileşenin birlikte 0,8175 vermesi de buradan anlaşılıyor: `c0` tüketim büyüklüğünü,
`c1` ise oynaklık ile sıfır okumayı taşıyor. Etiketin iki ayrı nedeni iki ayrı bileşene düşmüş
durumda ve model ikisini birleştirebiliyor.

## Yorumlanabilirlikten Kaybedilen

Kaybın ikinci yarısı sayıda değil, adlarda. Ham temsilde bölmelerin 0,35'i `ort_tuketim`'den,
0,19'u `oynaklik`'tan, 0,17'si mühür göstergesinden okunuyor. Bu üç satır bir saha ekibine
verilebilir: yüksek tüketim, oynak okuma ve mühür kaydı. Bileşen temsilinde aynı liste `c0` 0,29,
`c1` 0,25, `c8` 0,12 diye çıkıyor ve hiçbir şey söylemiyor.

Bileşenin ne olduğu ancak yükleri okunarak anlaşılır ve yükler tek bir sütuna işaret etmez. `c0`
kişi başı tüketim ile ortalama tüketimi ağırlıklı olarak taşıyor, ama geri kalan dokuz sütunun
toplam ağırlığı 1,16 — yani bileşenin yarıdan fazlası, dört büyük yükün dışındaki sütunlardan
geliyor. "Bu abone niçin şüpheli işaretlendi" sorusunun yanıtı ham temsilde bir sütun adı ve bir
eşiktir; bileşen temsilinde on üç sayının ağırlıklı toplamıdır.

Karar, iki kaybın karşılaştırılmasıdır. İki bileşene inmek 0,0079 sayı ve on bir sütunluk
saklama kazandırır; karşılığında modelin verdiği her kararın gerekçesini bir tabloya yazma
olanağı kaybedilir. Kaçak şüphesi gibi bir alanda ikinci kayıp genellikle daha pahalıdır, çünkü
bir aboneye yapılan işlemin gerekçesi sorulabilir. Bileşen temsilinin öznitelik rolü bu yüzden
dar bir roldür: sütun sayısı gerçekten yönetilemeyecek kadar büyükse ya da sütunlar birbirinin
kopyasıysa değerlidir, tek tek ölçülmüş on üç sütun varken değildir.

## Özet

- Ham on üç sütun ayrılmış kümede 0,8254 veriyor; hiçbir bileşen sayısı buna yetişemiyor, en yakın
  satır iki bileşenle 0,8175 (fark 0,0079, iki abone).
- Bileşen payı büyürken ayrılmış küme sayısı büyümüyor: üç bileşende 0,8056, beşte 0,7778, sekizde
  0,7460; on üç bileşende bilgi kaybı yokken sayı yine 0,7897'de kalıyor.
- Payı en büyük bileşen tek başına 0,7381 ile tabanın altında kalırken payı 0,093 olan beşinci
  bileşen 0,7659 veriyor; pay sıralaması ayrım sıralaması değildir.
- Yorumlanabilirlik ölçülebilir bir kayıptır: ham temsilde bölmelerin 0,35'i ortalama tüketimden
  okunuyor, bileşen temsilinde aynı pay adı olmayan bir karışıma düşüyor.
- Ölçek ve bileşen yönleri yalnız eğitim kümesinden öğrenilir; bütün kümeden öğrenilseydi ölçüm
  şişerdi.

## Sonraki Adım

Dört derste hazırlama adımlarının sayısı arttı ve her birinde aynı cümle tekrarlandı: bu adım
yalnız eğitim kümesinden öğrenilir. Ölçek ortalaması, bölge ortancası, seçilen sütun kümesi,
bileşen yönleri — dördü de eğitilmiş nesnelerdir ve dördü de elle, ayrı ayrı, doğru sırayla
uygulanmak zorundadır. Bu zincir elle uygulandığında kaç adımın yanlış kümeden öğrenildiğini
saymak gerekir. Sonraki ders hazırlama ile modeli tek bir nesnede birleştirir ve boru hattı
olmadan kaç adımın sızdığını ölçer.
