İçeriğe geç
academia.sh

Ders 05 / 12

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.

İçindekiler

Ö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.

# 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.

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.

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.

İlerlemeni kaydetmek ve not almak için Giriş yap

Notlarım

Not almak için giriş yapmalısın.

Aramak için yazmaya başlayın.

↑↓ Esc gezin · aç · kapat