---
title: 'Karışıklık Matrisi'
source: 'https://academia.sh/tr/kurslar/denetimli-ogrenme/karisiklik-matrisi'
course: 'Denetimli Öğrenme'
language: tr
updated: '2026-08-17T18:10:19+00:00'
license: 'CC BY-SA 4.0'
---

# Karışıklık Matrisi

Aynı doğruluğu veren iki modelin hata dağılımının ayrılması: kırk dokuz aday arasında on dört doğruluk değeri birden çok aday tarafından paylaşılır, 0,7817 veren iki aday 61 şüpheliden birinde 16'sını diğerinde 32'sini yakalar ve işaretlenen abone sayısı 26 ile 58 arasında değişir. Saha ziyareti 1, kaçırılan kaçak 6 birim sayıldığında bedel 296 ile 232 olur, taban çizgisinin bedeli 366'dır ve herkesi şüpheli demek 252 ile taban çizgisinden ucuzdur. Doğrulukta en iyi aday bedelde 263 verirken bedelde en iyi aday doğrulukta kırk dokuz aday içinde yirminci sıradadır.

Önceki konu yedi model ailesini aynı ayrılmış küme üzerinde denedi ve her sayının yanına o
sayıyı bulmak için kaç aday denendiğini yazdı. Karşılaştırmanın tamamı tek bir sayı üzerinden
yürüdü: **doğruluk**. Ailenin kattığı fark da, ayar bütçesinin şişirdiği fark da bu tek sayıda
okundu. O sayının **hangi hataları sakladığı** hiç sorulmadı.

Sınama kümesindeki 252 abonenin 61'i şüpheli. Doğruluğu 0,80 olan bir model elli abonede
yanılıyor demektir, ama bu elli yanılgının yönü yazmıyor: şüpheli olmayana şüpheli demek ile
şüpheliyi gözden kaçırmak aynı hücreye düşüyor. İkisi birbirinin yerine geçmez — birinin bedeli
boşa giden bir saha ziyareti, ötekinin bedeli fark edilmemiş bir kaçaktır.

- **MD1.** Küme, bölme ve öznitelikler kurs boyunca sabittir: kurgu abone tablosu, 756/252/252
  bölme, öznitelik mühendisliği kursunun bıraktığı on iki öznitelik. Değişen tek şey modeldir.
- **MD2.** Taban çizgisi değişmez: eğitim kümesinin en sık sınıfını her aboneye söylemek. Bu
  yordam sınama kümesinde 0,7579 verir.
- **MD3.** Olumlu sınıf **şüpheli abonedir**. Olumlu/olumsuz sözcükleri değer yargısı değil,
  sayılan sınıfın adıdır.
- **MD4.** Model bir olasılık üretir ve bu derste karar eşiği **0,5'te sabittir**. Eşiğin kendisi
  bu konunun üçüncü dersine bırakılır.
- **MD5.** Kırk dokuz aday denenir: altı derinlik ile yedi sınıf ağırlığının çarpımı olarak kırk
  iki karar ağacı, yedi sınıf ağırlığında eğim temelli doğrusal model. Sınıf ağırlığı öznitelik
  mühendisliği kursundaki biçimiyle kullanılır.
- **MD6.** Bu ders **model seçmez**; kırk dokuz adayın hepsinin sınama kümesindeki sayısı basılır.
  Doğrulama kümesinden seçim yapmak üçüncü dersin işidir.
- **MD7.** Bedel iki kalemden oluşur: işaretlenen her abone için bir **saha ziyareti**, kaçırılan
  her şüpheli için bir **kaçırılmış kaçak**. Ziyaret bedeli işaretlenen bütün abonelere yazılır,
  ziyaretin sonucu bedeli değiştirmez. Birim değerleri kurgudur ve veriden okunmaz.

## Dört Hücre

**Karışıklık matrisi (confusion matrix)** iki sınıflı bir kararda dört sayı tutar. Model şüpheli
dediğinde abone gerçekten şüpheliyse **doğru olumlu (true positive)**, değilse **yanlış olumlu
(false positive)**. Model şüpheli demediğinde abone şüpheliyse **yanlış olumsuz (false negative)**,
değilse **doğru olumsuz (true negative)**. Doğruluk bu dört sayının ikisini toplayıp dörde
böler; kalan bilgi atılır.

```python
# degerlendirme.py — MODELDIR. Kurgu abone tablosu ayni tohumla yeniden uretilir.
import math

TOHUM, ADAY, 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, OKUMA = [], {}
for i in range(ADAY):
    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 = uretec(TOHUM + 7000 + k["no"])
    for d in range(ayrik(r(), [0.05, 0.12, 0.21, 0.62])):
        OKUMA.setdefault(k["no"], []).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()

VERI = []
for k in ABONE:
    v = OKUMA.get(k["no"])
    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 = {"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)}
    x["kisi_basi"] = round(x["ort_tuketim"] / x["hane"], 3)
    for b in BOLGE:
        x["b_" + b[0]] = int(k["bolge"][0] == b[0])
    VERI.append(x)


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:]
ALAN = ["ort_tuketim", "oynaklik", "hane", "memnuniyet", "donem", "sifir_okuma",
        "kisi_basi", "b_kuzey", "b_guney", "b_dogu", "b_bati", "b_merkez"]


def safsizlik(s):
    n = sum(x.get("w", 1.0) for x in s)
    p = sum(x.get("w", 1.0) * x["supheli"] for x in s) / n
    return 2 * p * (1 - p)


def agac(s, derinlik, alan, enaz=2):        # MODELDIR: agirlikli karar agaci
    n = sum(x.get("w", 1.0) for x in s)
    p = sum(x.get("w", 1.0) * x["supheli"] for x in s) / n
    en = None
    if derinlik and len(s) >= 2 * enaz and 0.0 < p < 1.0:
        for a in alan:
            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 = safsizlik(s) - (sum(x.get("w", 1.0) for x in sol) * safsizlik(sol)
                               + sum(x.get("w", 1.0) for x in sag) * safsizlik(sag)) / n
                if en is None or k > en[0]:
                    en = (k, a, v, sol, sag)
    if en is None or en[0] <= 1e-9:
        return {"p": p}
    return {"alan": en[1], "esik": en[2], "sol": agac(en[3], derinlik - 1, alan, enaz),
            "sag": agac(en[4], derinlik - 1, alan, enaz)}


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


def agirlikla(egt, w):
    return [dict(x, w=(w if x["supheli"] else 1.0)) for x in egt]


def matris(skor, veri, esik=0.5):           # do, yo, yn, dn
    m = [0, 0, 0, 0]
    for x in veri:
        i = (0 if x["supheli"] else 1) + (0 if skor(x) >= esik else 2)
        m[i] += 1
    return m


NS = sum(x["supheli"] for x in SIN)
print(f"sinama kumesi {len(SIN)} abone, supheli {NS}, "
      f"taban cizgisi {1 - NS / len(SIN):.4f}")
t6 = agac(EGT, 6, ALAN)
m6 = matris(lambda x: olasilik(t6, x), SIN)
print(f"derinlik 6 karar agaci: dogruluk {(m6[0] + m6[3]) / len(SIN):.4f}")
print(f"{'':>18}{'gercek supheli':>16}{'gercek degil':>14}")
print(f"{'supheli dendi':>18}{m6[0]:>16}{m6[1]:>14}")
print(f"{'supheli denmedi':>18}{m6[2]:>16}{m6[3]:>14}")
```

```
sinama kumesi 252 abone, supheli 61, taban cizgisi 0.7579
derinlik 6 karar agaci: dogruluk 0.7937
                    gercek supheli  gercek degil
     supheli dendi              24            15
   supheli denmedi              37           176
```

Doğruluk 0,7937 ve taban çizgisinin üstünde. Matris aynı modeli başka türlü okutuyor: model 61
şüphelinin 24'ünü yakalıyor, 37'sini kaçırıyor, 15 aboneyi de boşuna işaretliyor. Doğruluğun
büyük bölümü sağ alt hücreden geliyor — kümede çoğunluk zaten onlar. Taban çizgisinin 0,7579'u
tamamen o hücreden gelir: hiç kimseye şüpheli demeyen yordam 191 doğru olumsuz toplar ve 61
yanlış olumsuz biriktirir.

## Aynı Sayı, Başka Matris

Doğruluğun bilgi attığı en açık biçimde iki modelin aynı sayıyı vermesiyle görülür. Kırk dokuz
aday denenir ve aynı doğruluk değerini paylaşan adaylar aranır.

```python
def olcek(egt, alan):
    o = {a: sum(x[a] for x in egt) / len(egt) for a in alan}
    s = {a: (sum((x[a] - o[a]) ** 2 for x in egt) / len(egt)) ** 0.5 or 1.0 for a in alan}
    return lambda x: [(x[a] - o[a]) / s[a] for a in alan]


def dogrusal(egt, alan, w, tur=300, adim=0.5):   # MODELDIR: egim temelli dogrusal model
    f, k, b = olcek(egt, alan), [0.0] * len(alan), 0.0
    X = [f(x) for x in egt]
    y = [x["supheli"] for x in egt]
    a = [(w if x["supheli"] else 1.0) for x in egt]
    n = sum(a)
    for _ in range(tur):
        gk, gb = [0.0] * len(alan), 0.0
        for i, xi in enumerate(X):
            z = b + sum(k[j] * xi[j] for j in range(len(k)))
            e = (1 / (1 + math.exp(-max(-30.0, min(30.0, z)))) - y[i]) * a[i]
            gb += e
            for j in range(len(k)):
                gk[j] += e * xi[j]
        b -= adim * gb / n
        for j in range(len(k)):
            k[j] -= adim * gk[j] / n

    def skor(x):
        v = f(x)
        z = b + sum(k[j] * v[j] for j in range(len(k)))
        return 1 / (1 + math.exp(-max(-30.0, min(30.0, z))))
    return skor


ADAYLAR = {}
for d in (3, 4, 5, 6, 7, 8):
    for w in (1.0, 1.5, 2.0, 2.5, 3.0, 3.5, 4.0):
        t = agac(agirlikla(EGT, w), d, ALAN)
        ADAYLAR[f"agac d{d} a{w}"] = matris(lambda x, t=t: olasilik(t, x), SIN)
for w in (1.0, 1.5, 2.0, 2.5, 3.0, 3.5, 4.0):
    s = dogrusal(EGT, ALAN, w)
    ADAYLAR[f"dogrusal a{w}"] = matris(s, SIN)

ESIT = {}
for ad, m in ADAYLAR.items():
    ESIT.setdefault(round((m[0] + m[3]) / len(SIN), 4), []).append(ad)
paylasilan = {d: v for d, v in ESIT.items() if len(v) > 1}
print(f"denenen aday {len(ADAYLAR)}, farkli dogruluk degeri {len(ESIT)}, "
      f"birden cok aday tarafindan paylasilan {len(paylasilan)}")
en = max(paylasilan.items(),
         key=lambda kv: max(ADAYLAR[a][0] for a in kv[1]) - min(ADAYLAR[a][0] for a in kv[1]))
print(f"\n{'aday':<14}{'dogruluk':>9}{'do':>5}{'yo':>5}{'yn':>5}{'dn':>5}{'isaretli':>10}")
for d in sorted(paylasilan, reverse=True)[:3]:
    for ad in paylasilan[d]:
        m = ADAYLAR[ad]
        print(f"{ad:<14}{d:>9.4f}{m[0]:>5}{m[1]:>5}{m[2]:>5}{m[3]:>5}{m[0] + m[1]:>10}")
    print()
print(f"en genis ayrisma dogruluk {en[0]:.4f}: {' / '.join(en[1])}")
```

```
denenen aday 49, farkli dogruluk degeri 26, birden cok aday tarafindan paylasilan 14

aday           dogruluk   do   yo   yn   dn  isaretli
agac d5 a1.0     0.8016   23   12   38  179        35
dogrusal a1.0    0.8016   22   11   39  180        33
dogrusal a1.5    0.8016   29   18   32  173        47

agac d3 a1.0     0.7937   17    8   44  183        25
agac d6 a1.0     0.7937   24   15   37  176        39

agac d4 a1.0     0.7817   16   10   45  181        26
agac d8 a1.0     0.7817   32   26   29  165        58

en genis ayrisma dogruluk 0.7817: agac d4 a1.0 / agac d8 a1.0
```

Kırk dokuz aday yalnız yirmi altı ayrı doğruluk değeri üretiyor ve bunların on dördü birden çok
aday tarafından paylaşılıyor. Tablonun ilk bloğu kümenin en yüksek doğruluğunu gösteriyor: 0,8016
değerini üç aday birden veriyor, üstelik iki ayrı model ailesinden. Yakaladıkları şüpheli sayısı
22, 23 ve 29; işaretledikleri abone sayısı 33, 35 ve 47. Doğrulukla bakan biri için üçü aynı
modeldir.

Son blok ayrışmanın en genişi. Doğruluğu 0,7817 olan iki aday 61 şüpheliden birinde 16'sını,
öbüründe 32'sini yakalıyor — tam iki katı — ve 26'ya karşı 58 abone işaretliyor. Toplam doğru
sayısı 197'de eşitleniyor çünkü ikinci modelin kazandığı 16 doğru olumlu, kaybettiği 16 doğru
olumsuzla tam takas oluyor. Doğruluk bu takasa kayıtsızdır; matris değildir.

## İki Hatanın Bedeli Bir Değil

Takasın kayıtsız kalmadığı yer, iki hata türünün karşılığının sayıldığı yerdir. Kurgu kümede
işaretlenen her abone için bir **saha ziyareti** yazılır, kaçırılan her şüpheli için bir
**kaçırılmış kaçak**. Ziyaretin birimi 1, kaçırılan kaçağınki 6 alınır; bu iki sayı veriden
okunmaz, dışarıdan verilir.

```python
ZIYARET, KACAK = 1.0, 6.0


def bedel(m):
    return ZIYARET * (m[0] + m[1]) + KACAK * m[2]


print(f"{'yordam':<24}{'dogruluk':>9}{'ziyaret':>9}{'kacirilan':>11}{'bedel':>8}")
for ad, m in (("taban (hicbiri supheli)", [0, 0, NS, len(SIN) - NS]),
              ("herkes supheli", [NS, len(SIN) - NS, 0, 0]),
              ("agac d4 a1.0", ADAYLAR["agac d4 a1.0"]),
              ("agac d8 a1.0", ADAYLAR["agac d8 a1.0"]),
              ("agac d5 a1.0", ADAYLAR["agac d5 a1.0"]),
              ("dogrusal a1.5", ADAYLAR["dogrusal a1.5"])):
    print(f"{ad:<24}{(m[0] + m[3]) / len(SIN):>9.4f}{m[0] + m[1]:>9}"
          f"{m[2]:>11}{bedel(m):>8.0f}")

a, b = ADAYLAR["agac d4 a1.0"], ADAYLAR["agac d8 a1.0"]
oran = ((a[0] + a[1]) - (b[0] + b[1])) / (b[2] - a[2])
print(f"\nesit bedel orani {oran:.2f}: kacirilan bir kacagin bedeli bir saha "
      f"ziyaretinin {oran:.2f} katini gecince siralama doner")
en_d = max(ADAYLAR, key=lambda k: (ADAYLAR[k][0] + ADAYLAR[k][3]))
en_b = min(ADAYLAR, key=lambda k: bedel(ADAYLAR[k]))
print(f"dogrulukta en iyi aday {en_d}, bedeli {bedel(ADAYLAR[en_d]):.0f}")
print(f"bedelde en iyi aday   {en_b}, dogrulugu "
      f"{(ADAYLAR[en_b][0] + ADAYLAR[en_b][3]) / len(SIN):.4f}")
print(f"bedelde en iyi adayin dogruluk sirasi "
      f"{sorted(ADAYLAR, key=lambda k: -(ADAYLAR[k][0] + ADAYLAR[k][3])).index(en_b) + 1}"
      f" / {len(ADAYLAR)}")
```

```
yordam                   dogruluk  ziyaret  kacirilan   bedel
taban (hicbiri supheli)    0.7579        0         61     366
herkes supheli             0.2421      252          0     252
agac d4 a1.0               0.7817       26         45     296
agac d8 a1.0               0.7817       58         29     232
agac d5 a1.0               0.8016       35         38     263
dogrusal a1.5              0.8016       47         32     239

esit bedel orani 2.00: kacirilan bir kacagin bedeli bir saha ziyaretinin 2.00 katini gecince siralama doner
dogrulukta en iyi aday agac d5 a1.0, bedeli 263
bedelde en iyi aday   dogrusal a3.5, dogrulugu 0.7460
bedelde en iyi adayin dogruluk sirasi 20 / 49
```

Tablonun ikinci satırı doğruluğun tek yönlü bir ölçü olduğunu tek başına gösteriyor. Herkese
şüpheli demek doğrulukta 0,2421 verir — kullanılamaz görünen bir sayı — ama bedelde 252 tutar ve
taban çizgisinin 366'sından ucuzdur. İki yordam da hiçbir şey öğrenmemiştir; biri doğrulukta,
öteki bedelde iyi görünür.

Aynı doğruluğu veren iki adayın bedeli 296 ile 232. Aradaki 64 birim, doğruluğun sakladığı
takasın karşılığıdır. Eşit bedel oranı 2,00 çıkıyor: kaçırılan bir kaçağın bedeli bir saha
ziyaretinin iki katının altındaysa az işaretleyen model, üstündeyse çok işaretleyen model
ucuzdur. Bu oran veriden okunamaz, ölçüm ağının işletmecisinden gelir — aynı iki sayı, oranın
2'nin hangi tarafında olduğuna göre iki ayrı karar.

Son iki satır kırk dokuz adayın tamamına bakıyor. Doğrulukta en iyi aday bedelde 263 veriyor;
bedelde en iyi aday doğruluk sıralamasında yirminci sırada. Bir ölçütte tepede olmak öteki
ölçütte tepede olmayı getirmiyor ve fark rastlantı düzeyinde değil. Doğruluk, iki hatayı eşit
sayan bir bedel hesabıdır; eşit saymayan her hesap başka bir aday seçer.

## Özet

- Karışıklık matrisi iki sınıflı kararı dört sayıya ayırır — doğru olumlu, yanlış olumlu, yanlış
  olumsuz, doğru olumsuz — ve doğruluk bu dördün ikisini toplayıp toplam gözlem sayısına böler.
- Kırk dokuz aday yalnız yirmi altı ayrı doğruluk değeri üretir; on dört değer birden çok aday
  tarafından paylaşılır, yani aynı sayı çoğu zaman birden fazla hata dağılımına karşılık gelir.
- Doğruluğu 0,7817 olan iki aday 61 şüpheliden 16'sını ve 32'sini yakalar, 26 ve 58 abone
  işaretler; kazanılan doğru olumlu sayısı kaybedilen doğru olumsuz sayısıyla tam takas olduğu
  için doğruluk aynı kalır.
- Saha ziyareti 1, kaçırılan kaçak 6 birim sayıldığında bu iki adayın bedeli 296 ile 232 olur;
  sıralamanın döndüğü eşit bedel oranı 2,00'dir ve bu sayı veriden değil işletmeden gelir.
- Herkese şüpheli demek doğrulukta 0,2421 ile taban çizgisinin çok altında kalırken bedelde 252
  ile taban çizgisinin 366'sını geçer; doğrulukta en iyi aday ile bedelde en iyi aday aynı değildir.

## Sonraki Adım

Bu ders dört hücreyi saydı ama hücrelerden türetilen ölçütleri adlandırmadı. Öznitelik
mühendisliği kursunun dengesiz sınıflar dersi, doğru işaretlenen azınlık payına **kesinlik**,
yakalanan azınlık payına **duyarlılık** dendiğini yazmış, ikisinin tanımını ve birbirine karşı
okunmasını bu kursa bırakmıştı. Sonraki ders o sözü öder: dört hücreden dört ölçüt türetir, beş
modeli bu ölçütlerde ayrı ayrı sıralar ve kaç ölçütte sıralamanın başının değiştiğini sayar. F1
ölçütünün niçin iki sayının ortalaması değil **uyumlu ortalaması** olduğu, ortalamanın hangi
durumda yanıltıcı bir yüksek değer verdiği ile birlikte sayıyla gösterilir.
