---
title: 'Dengesiz Sınıflar'
source: 'https://academia.sh/tr/kurslar/oznitelik-muhendisligi/dengesiz-siniflar'
course: 'Veri Hazırlama ve Öznitelik Mühendisliği'
language: tr
updated: '2026-08-17T18:10:12+00:00'
license: 'CC BY-SA 4.0'
---

# Dengesiz Sınıflar

Sınıf dengesizliğine verilen üç yanıtın iki ölçüyle birden okunması: taban çizgisi doğrulukta 0,7579 verirken yakaladığı şüpheli sayısı sıfırdır, ham eğitim kümesiyle model 0,7778 doğruluk ve 61 şüpheliden 21'ini yakalar. Azınlığı iki kat çoğaltmak doğruluğu 0,7619'a indirip yakalananı 33'e çıkarır, çoğunluğu seyreltmek 0,7143 ve 36 verir, sınıf ağırlığı 3,5 ise 0,6349 ve 39 verir. Azınlığı iki kat çoğaltmak ile sınıf ağırlığı 2,0 sınama kümesindeki 252 abonenin hepsinde aynı tahmini üretir.

Önceki ders eksik satırların atılmasının azınlık sınıfının yarısından çoğunu götürdüğünü yan
etki olarak kaydetti. Sınıfların büyüklük farkının kendisi ise hiç ölçülmedi. Eğitim kümesinde 756
abonenin 168'i şüpheli, sınama kümesinde 252 abonenin 61'i. Bu tabloda **doğruluk** yanıltıcı bir
ölçüdür ve yanıltıcılığın büyüklüğü sayılabilir: hiç kimseyi şüpheli işaretlemeyen taban çizgisi
0,7579 okur ve yakaladığı şüpheli sayısı sıfırdır.

Bu ders dengesizliğe verilen üç yanıtı ölçer: azınlığı **çoğaltma**, çoğunluğu **seyreltme** ve
**sınıf ağırlığı** verme. Her yanıt iki sayıyla birden okunur; ölçüt kuramı bu kursun konusu
değildir. Doğru işaretlenen azınlık payına **kesinlik (precision)**, yakalanan azınlık payına
**duyarlılık (recall)** denir; ikisinin tanımı, birbirine karşı okunması ve eşik seçimi Denetimli
Öğrenme kursuna bırakılır. Burada yalnız ham sayılar basılır.

- **HA34.** Küme, bölme, öznitelikler ve model önceki derslerdekiyle aynıdır: 756/252/252,
  derinlik 6 karar ağacı, on bir öznitelik.
- **HA35.** İki ölçü basılır: **doğruluk** ve **yakalanan şüpheli sayısı** — sınama kümesindeki 61
  şüpheliden kaçının şüpheli işaretlendiği. Yanına iki ham sayı daha yazılır: kaçırılan şüpheli ve
  şüpheli işaretlenip şüpheli olmayan abone.
- **HA36.** Taban çizgisi değişmez: eğitim kümesinin en sık sınıfını her aboneye söylemek. Bu
  yordam doğrulukta 0,7579, yakalananda 0 verir.
- **HA37.** Çoğaltma azınlık satırlarını olduğu gibi yeniden yazar; yeni satır **üretilmez**.
- **HA38.** Seyreltme çoğunluk satırlarını rastgele azaltır ve eğitim kümesini küçültür; atılan
  satırlar geri gelmez.
- **HA39.** Sınıf ağırlığı, ağacın bölme ölçütünü ağırlıklı hesaplatır: her satırın katkısı
  kendi ağırlığıyla çarpılır. Model kodu bu derste ağırlık kabul edecek biçimde yazılır.
- **HA40.** Üç yanıt da **yalnız eğitim kümesine** uygulanır. Sınama kümesi hiçbir durumda
  çoğaltılmaz, seyreltilmez ya da ağırlıklandırılmaz; ölçü gerçek dağılım üzerinde okunur.

## İki Sayı, Bir Taban

Kurulum kümeyi üretir ve taban çizgisini iki ölçüde birden basar.

```python
# dengesiz.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 v is None:
        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)}
    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, SIN = K[:756], K[1008:]
ALAN = ["ort_tuketim", "oynaklik", "hane", "memnuniyet", "donem", "sifir_okuma",
        "b_kuzey", "b_guney", "b_dogu", "b_bati", "b_merkez"]
NE, NS = sum(x["supheli"] for x in EGT), sum(x["supheli"] for x in SIN)
print(f"egitim {len(EGT)} abone, supheli {NE} ({NE / len(EGT):.4f}); "
      f"sinama {len(SIN)} abone, supheli {NS} ({NS / len(SIN):.4f})")
print(f"cogunluk / azinlik orani egitimde {(len(EGT) - NE) / NE:.2f}")
print(f"taban cizgisi (en sik sinif): dogruluk "
      f"{sum(x['supheli'] == 0 for x in SIN) / len(SIN):.4f}, "
      f"yakalanan supheli 0 / {NS}, supheli isaretlenen 0")
```

```
egitim 756 abone, supheli 168 (0.2222); sinama 252 abone, supheli 61 (0.2421)
cogunluk / azinlik orani egitimde 3.50
taban cizgisi (en sik sinif): dogruluk 0.7579, yakalanan supheli 0 / 61, supheli isaretlenen 0
```

Son satır kursun taban çizgisini ikinci bir ölçüde gösteriyor ve tablo değişiyor. Doğrulukta
0,7579 iyi görünen bir sayıdır; yakalanan şüpheli sayısında sıfır, kullanılamaz bir sonuçtur. Aynı
yordam, aynı küme, iki ölçü, iki ayrı yargı. Dengesiz bir kümede ölçünün seçilmemiş olması, taban
çizgisinin seçilmemiş olmasıyla aynı şeydir.

## Üç Yanıt

Aşağıdaki kod ağacı ağırlık kabul edecek biçimde yazar ve üç yanıtı sırayla ölçer.

```python
def gini(s):
    n = sum(x.get("w", 1.0) for x in s)
    if n <= 0:
        return 0.0
    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 = gini(s) - (sum(x.get("w", 1.0) for x in sol) * gini(sol)
                               + sum(x.get("w", 1.0) for x in sag) * gini(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 {"tahmin": int(p > 0.5)}
    return {"alan": en[1], "esik": en[2], "sol": agac(en[3], derinlik - 1, alan, enaz),
            "sag": agac(en[4], derinlik - 1, alan, 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 cogalt(egt, kat):                       # azinlik satiri kat kez yazilir
    out = []
    for x in egt:
        out += [x] * (kat if x["supheli"] else 1)
    return out


def seyrelt(egt, tohum):                    # cogunluk azinlik boyuna indirilir
    az = [x for x in egt if x["supheli"]]
    cok = karistir([x for x in egt if not x["supheli"]], tohum)[:len(az)]
    return karistir(az + cok, tohum + 1)


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


SONUC = {}


def olc(ad, egt):
    m = agac(egt, 6, ALAN)
    t = [tahmin(m, x) for x in SIN]
    d = sum(t[i] == SIN[i]["supheli"] for i in range(len(SIN))) / len(SIN)
    y = sum(1 for i, x in enumerate(SIN) if t[i] == 1 and x["supheli"] == 1)
    SONUC[ad] = (len(egt), d, y, sum(t))
    print(f"{ad:<30} {len(egt):>7} {d:>9.4f} {y:>10} {sum(t):>10}")


print(f"{'yordam':<30} {'egitim':>7} {'dogruluk':>9} {'yakalanan':>10} "
      f"{'isaretli':>10}")
print(f"{'taban (en sik sinif)':<30} {'-':>7} "
      f"{sum(x['supheli'] == 0 for x in SIN) / len(SIN):>9.4f} {0:>10} {0:>10}")
olc("ham egitim kumesi", EGT)
olc("cogaltma, azinlik iki kat", cogalt(EGT, 2))
olc("cogaltma, azinlik uc kat", cogalt(EGT, 3))
olc("seyreltme, cogunluk azinliga", seyrelt(EGT, TOHUM + 22000))
olc("sinif agirligi 2.0", agirlikla(EGT, 2.0))
olc("sinif agirligi 3.5", agirlikla(EGT, 3.5))
```

```
yordam                          egitim  dogruluk  yakalanan   isaretli
taban (en sik sinif)                 -    0.7579          0          0
ham egitim kumesi                  756    0.7778         21         37
cogaltma, azinlik iki kat          924    0.7619         33         65
cogaltma, azinlik uc kat          1092    0.7341         34         74
seyreltme, cogunluk azinliga       336    0.7143         36         83
sinif agirligi 2.0                 756    0.7619         33         65
sinif agirligi 3.5                 756    0.6349         39        109
```

İki sütun ters yönlerde ilerliyor. Doğruluk 0,7778'den 0,6349'a inerken yakalanan şüpheli sayısı
21'den 39'a çıkıyor. Ham eğitim kümesiyle model 61 şüpheliden 40'ını kaçırıyor; en sert
ağırlıkla 22'sini kaçırıyor ama şüpheli işaretlediği abone sayısı 37'den 109'a çıkıyor.

İşaretli sütunu tek başına da bir şey söylüyor. Sınama kümesinde 61 şüpheli var, ham eğitim
kümesiyle eğitilen model ise yalnız 37 abone işaretliyor. Model azınlığı **eksik** işaretliyor ve
bu bir ayar hatası değil, bölme ölçütünün doğrudan sonucudur: ölçüt yaprakta çoğunluğu söylemeyi
ödüllendirir ve azınlık oranı yüzde ellinin altında kaldığı sürece bir yaprağın azınlık demesi
ancak çok saf bir bölge bulunduğunda kârlıdır. Dengesizliğe verilen üç yanıt da tam olarak bu
hesabı bozar: kimi satırı ikinci kez yazarak, kimi karşı sınıfı azaltarak, kimi ağırlığı doğrudan
değiştirerek yaprakların azınlık deme eşiğini aşağı çeker. M26'nın İstatistiksel Analiz ve Keşifsel
Veri Analizi kursu dengesiz kümelerde oran okumanın tuzaklarını ölçmüştü; buradaki fark oranın
değil **kararın** değişiyor olmasıdır.

## Katkı Hangi Sayıda Ölçülür

Aynı kararlar ham eğitim kümesine göre okunduğunda tablonun anlamı netleşiyor.

```python
h = SONUC["ham egitim kumesi"]
print(f"{'yordam':<30} {'dogruluk katki':>15} {'yakalanan +':>12} "
      f"{'kacirilan':>10} {'yanlis isaret':>14}")
for ad in ("cogaltma, azinlik iki kat", "cogaltma, azinlik uc kat",
           "seyreltme, cogunluk azinliga", "sinif agirligi 2.0",
           "sinif agirligi 3.5"):
    v = SONUC[ad]
    print(f"{ad:<30} {v[1] - h[1]:>+15.4f} {v[2] - h[2]:>+12} "
          f"{NS - v[2]:>10} {v[3] - v[2]:>14}")
a = agac(cogalt(EGT, 2), 6, ALAN)
b = agac(agirlikla(EGT, 2.0), 6, ALAN)
print(f"\ncogaltma iki kat ile sinif agirligi 2.0 ayni tahmini veren abone "
      f"{sum(tahmin(a, x) == tahmin(b, x) for x in SIN)} / {len(SIN)}")
```

```
yordam                          dogruluk katki  yakalanan +  kacirilan  yanlis isaret
cogaltma, azinlik iki kat              -0.0159          +12         28             32
cogaltma, azinlik uc kat               -0.0437          +13         27             40
seyreltme, cogunluk azinliga           -0.0635          +15         25             47
sinif agirligi 2.0                     -0.0159          +12         28             32
sinif agirligi 3.5                     -0.1429          +18         22             70

cogaltma iki kat ile sinif agirligi 2.0 ayni tahmini veren abone 252 / 252
```

Doğruluk sütununda beş satırın beşi de eksidir. Kursun kuralı harfi harfine uygulanırsa bu beş
adımın da katkısı yoktur ve hiçbiri alınmamalıdır. Ama yakalanan sütunu on iki ile on sekiz abone
arasında artıyor ve o abonelerin her biri, gözden kaçmış bir kaçak ya da arıza şüphesidir. Çelişki
yordamlarda değil, ölçünün seçiminde. Doğruluk seçildiği sürece dengesizliğe verilen her yanıtın
katkısı eksidir; ölçü değiştiğinde işaret de değişir. Hangi sayının önemli olduğu veriden
okunmaz, işten okunur — bir denetim ekibinin kaç yanlış adrese gidebileceği bir kaynak sorusudur.

Seyreltme satırı ayrıca bir kararlılık sorusu açıyor. Aynı seyreltme başka bir tohumla
yapılsaydı hangi 168 çoğunluk satırının kalacağı değişirdi ve model onunla birlikte değişirdi;
çoğaltma ve ağırlık ise hiçbir rastgele seçim içermez, aynı kümede her koşumda aynı ağacı üretir.
Bir hazırlama adımının katkısı kadar, katkısının **koşumdan koşuma ne kadar oynadığı** da
sorulmalıdır.

Son iki satırın maliyet yüzü açık. Sınıf ağırlığı 3,5 on sekiz şüpheliyi daha yakalarken yanlış
işaretlenen abone sayısını 16'dan 70'e çıkarıyor. Seyreltme ise başka bir bedel ödüyor: eğitim
kümesi 756 satırdan 336'ya iniyor ve atılan 420 çoğunluk satırındaki bilgi geri gelmiyor. Küçük
kümelerde bu bedel doğrudan modelin kararlılığına yansır.

Son çıktı iki yordamın aynı şey olduğunu gösteriyor. Azınlığı iki kat çoğaltmak ile azınlığa 2,0
sınıf ağırlığı vermek sınama kümesindeki 252 abonenin hepsinde aynı tahmini üretiyor. Sebep
ağacın bölme ölçütündedir: ölçüt satırların ağırlıklı toplamıyla hesaplanır ve bir satırı iki kez
yazmak, o satırın ağırlığını iki yapmakla aynı toplamı verir. İkisinin ayrıldığı tek yer satır
sayısına bakan durdurma koşuludur — çoğaltmada küme 924 satıra çıkar, ağırlıkta 756'da kalır — ve
bu tabloda o koşul hiçbir düğümde bağlamamıştır. Bellek ve süre açısından ağırlık ucuzdur;
çoğaltma aynı sonucu daha büyük bir kümeyle üretir.

## Özet

- Taban çizgisi dengesiz kümede iki ayrı sayı verir: doğrulukta 0,7579, yakalanan şüpheli
  sayısında 61 üzerinden sıfır; doğruluk tek başına yanıltıcı bir tabandır.
- Ham eğitim kümesiyle model 0,7778 doğruluk verir ve 61 şüpheliden 21'ini yakalar, 40'ını
  kaçırır.
- Çoğaltma, seyreltme ve sınıf ağırlığının hepsi doğrulukta eksi katkı verir (−0,0159 ile −0,1429
  arası) ve yakalanan şüpheli sayısında on iki ile on sekiz abone arası artı verir; işaret ölçüyle
  birlikte döner.
- Seyreltme eğitim kümesini 756 satırdan 336'ya indirir ve atılan 420 çoğunluk satırındaki bilgi
  geri gelmez; çoğaltma ve ağırlık hiçbir satır atmaz.
- Azınlığı iki kat çoğaltmak ile sınıf ağırlığı 2,0 vermek sınama kümesindeki 252 abonenin
  hepsinde aynı tahmini üretir, çünkü ağacın bölme ölçütü ağırlıklı toplamla hesaplanır.

## Sonraki Adım

Bu derste şüpheli abonelerin sayısı azlığı yüzünden sorun oldu; sonraki derste birkaç abonenin
**değeri** yüzünden sorun olacak. Ortalama tüketim sütununda eğitim kümesinin çeyrekler açıklığından
hesaplanan çitin dışında kalan aboneler var ve bunların bir bölümü gerçek uçlar, bir bölümü takılı
kalmış sayaçların ürettiği kayıt hataları. İkisi tabloda birbirinin aynısı görünür. Sonraki ders
tek bir kırpma kararını iki model ailesinde ölçer, aynı kararın eğim temelli yordamda artı, ağaç
temelli yordamda eksi katkı verdiğini gösterir ve hiçbir satır silmeden aykırı değerin
yönetilebileceğini sayıyla ortaya koyar.
