İçeriğe geç
academia.sh

Ders 12 / 20

Topluluk Yöntemleri

Torbalama, artırma ve yığınlamanın kattığı farkın ve maliyetinin yan yana sayılması: üç temel model sınama kümesinde 0,7778, 0,7897 ve 0,7738 verirken maliyetleri 43, 568 ve 30 bölmedir. 252 abonenin 45'inde üçü birden yanılıyor, torbalama ile artırma yalnız 6 aboneyi ayrı sınıflıyor ve üç etiketten başka bir şey görmeyen hiçbir birleştirme 0,7897'yi geçemez. Yığınlamanın ikinci katmanı doğrulama kümesinden öğrenildiğinde 0,8254 rapor edip 0,7778 veriyor, eğitim kümesinden öğrenildiğinde 0,8532 rapor edip yine 0,7778 veriyor: şişme 0,0476'dan 0,0754'e çıkıyor ve ağırlık en çok ezberleyen modele kayıyor. Konunun toplam ayar bütçesi 1.313 adaydır.

İçindekiler

Önceki iki ders aynı aileyi iki ayrı biçimde çoğalttı. Torbalama ağaçları paralel kurup oylattı ve sınama kümesinde 0,7897 verdi; artırma onları ardışık bir toplama yığıp 0,7738 verdi. İkisi de tek tip bir öğreniciyi çoğaltıyordu. Üçüncü biçim, farklı modellerin çıktılarını girdi kabul eden ikinci bir katman kurmaktır ve hemen bir soru doğurur: o katman hangi kümeden öğrenilecek.

Bu ders üç birleştirmeyi yan yana koyar. Ölçü üç sayıdır: ayrılmış kümedeki fark, bölme sayısı olarak maliyet ve denenen aday. Dördüncü bir ölçü eklenir, toplulukların birbirine benzeyen hataları: üç model aynı abonelerde yanılıyorsa birleştirmenin kazanacağı bir şey yok demektir ve bu bir sezgi değil, hesaplanabilir bir tavandır.

  • DO45. Küme, bölme, taban çizgisi ve öznitelikler önceki iki derstekiyle aynıdır: 1.260 abone, 756/252/252, tohum 20260218, taban çizgisi sınamada 0,7579 ve doğrulamada 0,8135.
  • DO46. Üç temel model önceki derslerden olduğu gibi taşınır ve burada yeniden ayarlanmaz: derinlik 6 tek ağaç, 41 ağaçlık torbalanmış topluluk (m altı, derinlik 4) ve adım 0,15 / derinlik 2 / 10 turluk artırma.
  • DO47. Her temel modelin çıktısı [0, 1] aralığındadır: yaprak oranı, oy oranı, artırmanın olasılığı. Karar eşiği 0,5’tir ve M27/K02’den sabittir.
  • DO48. Yığınlamanın ikinci katmanı üç çıktıyı girdi alan eğim temelli bir doğrusal modeldir: üç ağırlık ve bir sabit, 400 yineleme, adım 2,0. Ayarları ölçümden önce sabitlendi.
  • DO49. Maliyet ölçüsü bölme sayısıdır; yığınlamanın maliyeti üç temel modelin bölmeleri artı öğrenilen dört sayıdır.
  • DO50. Ortak hata sayımı sınama kümesinde ve etiket düzeyinde yapılır.
  • DO51. Etiket desenine bakan bir birleştirmenin tavanı, her desende o desenin çoğunluk etiketini söyleyen kuralın doğruluğudur; üç etiketten başkasını görmeyen hiçbir birleştirme bunu geçemez.
  • DO52. Bu derste yeni ayar aranmaz; denenen aday üçtür. Konunun toplam bütçesi taşınan sayılarla birlikte 1.313 adaydır.

Üç Birleştirme ve Üç Temel Model

Kurulum tabloyu üretir, iki birleştirmeyi yeniden kurar ve üç temel modelin sayılarını maliyetiyle birlikte basar.

# yiginlama.py — MODELDIR. M27/K01'in KURGU abone tablosu ayni tohumla yeniden
# uretilir; oznitelik kumesi K02'den gelir ve kurs boyunca sabit tutulur.
import bisect
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 = {"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, DOG, SIN = K[:756], K[756:1008], K[1008:]
ALAN = ["ort_tuketim", "oynaklik", "hane", "memnuniyet", "donem", "sifir_okuma",
        "b_kuzey", "b_guney", "b_dogu", "b_bati", "b_merkez"]
ESIK = {}
for a in ALAN:
    d = sorted({x[a] for x in EGT})
    ESIK[a] = d[1:] if len(d) <= 24 else [d[int(i * len(d) / 25)] for i in range(1, 25)]
KOVA = [len(ESIK[a]) + 1 for a in ALAN]


def kutula(s):                              # her satir: kova numaralari ve etiket
    return [(tuple(bisect.bisect_right(ESIK[a], x[a]) for a in ALAN), x["supheli"])
            for x in s]


KE, KD, KS = kutula(EGT), kutula(DOG), kutula(SIN)
KUME, TUM = (KE, KD, KS), list(range(len(ALAN)))


def agac(orn, derinlik, alanlar, enaz=2):   # MODELDIR: her ornek (kova, egim, egrilik)
    n, en = len(orn), None
    G, H = sum(o[1] for o in orn), sum(o[2] for o in orn)
    if derinlik and n >= 2 * enaz:
        for k in alanlar:
            sg, sh, ss = [0.0] * KOVA[k], [0.0] * KOVA[k], [0] * KOVA[k]
            for b, g, h in orn:
                sg[b[k]] += g
                sh[b[k]] += h
                ss[b[k]] += 1
            cg = ch = cs = 0
            for j in range(KOVA[k] - 1):
                cg, ch, cs = cg + sg[j], ch + sh[j], cs + ss[j]
                if cs < enaz or n - cs < enaz:
                    continue
                kazanc = cg * cg / ch + (G - cg) ** 2 / (H - ch) - G * G / H
                if en is None or kazanc > en[0]:
                    en = (kazanc, k, j)
    if en is None or en[0] <= 1e-9:
        return G / H
    _, k, j = en
    return (k, j, agac([o for o in orn if o[0][k] <= j], derinlik - 1, alanlar, enaz),
            agac([o for o in orn if o[0][k] > j], derinlik - 1, alanlar, enaz))


def deger(d, b):
    while type(d) is tuple:
        d = d[2] if b[d[0]] <= d[1] else d[3]
    return d


def sikistir(z):
    return 1.0 / (1.0 + math.exp(-z)) if z > -30 else 0.0


def bolme(d):
    return 0 if type(d) is not tuple else 1 + bolme(d[2]) + bolme(d[3])


def orman(tohum, sayi, m, derinlik):        # BIRLESTIRME 1: torbalama, paralel oy
    r, agaclar = uretec(tohum), []
    for _ in range(sayi):
        secim = [int(r() * len(KE)) for _ in range(len(KE))]
        havuz, alanlar = list(TUM), []
        for _ in range(min(m, len(TUM))):
            alanlar.append(havuz.pop(int(r() * len(havuz))))
        agaclar.append(agac([(KE[i][0], KE[i][1], 1.0) for i in secim],
                            derinlik, sorted(alanlar)))
    return agaclar


def artir(adim, tur, derinlik):             # BIRLESTIRME 2: artirma, ardisik toplam
    p = sum(y for _, y in KE) / len(KE)
    F, agaclar = [[math.log(p / (1 - p))] * len(k) for k in KUME], []
    for _ in range(tur):
        q = [sikistir(z) for z in F[0]]
        d = agac([(b, y - q[i], max(q[i] * (1 - q[i]), 1e-6))
                  for i, (b, y) in enumerate(KE)], derinlik, TUM)
        agaclar.append(d)
        for u, kume in enumerate(KUME):
            for i, (b, _) in enumerate(kume):
                F[u][i] += adim * deger(d, b)
    return agaclar, [[sikistir(z) for z in f] for f in F]


TEK = agac([(b, y, 1.0) for b, y in KE], 6, TUM)
ORMAN = orman(TOHUM, 41, 6, 4)
ARTIRMA, ARTIRMA_P = artir(0.15, 10, 2)
TEMEL = [("tek agac", [[deger(TEK, b) for b, _ in k] for k in KUME], bolme(TEK)),
         ("torbalama", [[sum(deger(x, b) > 0.5 for x in ORMAN) / 41 for b, _ in k]
                        for k in KUME], sum(map(bolme, ORMAN))),
         ("artirma", ARTIRMA_P, sum(map(bolme, ARTIRMA)))]


def dogruluk(cikti, kume):
    return sum((c > 0.5) == y for c, (_, y) in zip(cikti, kume)) / len(kume)


print(f"{'model':<12} {'dogrulama':>10} {'sinama':>8} {'bolme':>7}")
print(f"{'taban cizgisi':<12} {sum(y == 0 for _, y in KD) / len(KD):>10.4f} "
      f"{sum(y == 0 for _, y in KS) / len(KS):>8.4f} {0:>7}")
for ad, cikti, maliyet in TEMEL:
    print(f"{ad:<12} {dogruluk(cikti[1], KD):>10.4f} "
          f"{dogruluk(cikti[2], KS):>8.4f} {maliyet:>7}")
model         dogrulama   sinama   bolme
taban cizgisi     0.8135   0.7579       0
tek agac         0.8056   0.7778      43
torbalama        0.8413   0.7897     568
artirma          0.8373   0.7738      30

Üç satır üç ayrı takas gösteriyor. Torbalama en yüksek sayıyı veriyor, 0,7897, ve en pahalısı: 568 bölme. Artırma 30 bölmeyle, yani on dokuz kat ucuza, 0,7738 veriyor. Tek ağaç 43 bölmeyle 0,7778’de duruyor ve artırmanın üstünde. Asıl soru şu: bu üç model birbirinden ne kadar farklı yanılıyor.

def etiketler(u):
    return [tuple(c[u][i] > 0.5 for _, c, _ in TEMEL) for i in range(len(KUME[u]))]


E = etiketler(2)
Y = [sum(e[j] != y for j in range(3)) for e, (_, y) in zip(E, KS)]
DESEN = {}
for e, (_, y) in zip(E, KS):
    DESEN.setdefault(e, [0, 0])[y] += 1
print("sinamada yanilan model sayisi  " +
      "  ".join(f"{k}: {Y.count(k):>3}" for k in range(4)))
print(f"etiket desenine bakan bir birlestirmenin tavani "
      f"{sum(max(v) for v in DESEN.values()) / len(KS):.4f}, farkli desen {len(DESEN)}")
for i in range(3):
    for j in range(i + 1, 3):
        ayri = sum(e[i] != e[j] for e in E)
        ikisi = sum(e[i] != y and e[j] != y for e, (_, y) in zip(E, KS))
        print(f"{TEMEL[i][0]:>10} - {TEMEL[j][0]:<10} ayri sinifladigi {ayri:>3}, "
              f"ikisinin birden yanildigi {ikisi:>3}")
sinamada yanilan model sayisi  0: 185  1:  13  2:   9  3:  45
etiket desenine bakan bir birlestirmenin tavani 0.7897, farkli desen 7
  tek agac - torbalama  ayri sinifladigi  17, ikisinin birden yanildigi  46
  tek agac - artirma    ayri sinifladigi  21, ikisinin birden yanildigi  46
 torbalama - artirma    ayri sinifladigi   6, ikisinin birden yanildigi  52

İlk satır tavanı belirliyor. 252 abonenin 185’inde üçü de doğru, 45’inde üçü de yanlış; geriye kalan 22 abone birleştirmenin çalışabileceği tek bölge. O 45 abone hiçbir oyla, hiçbir toplamla ve hiçbir ikinci katmanla kurtarılamaz, çünkü üç girdi de aynı yanlış yönü gösteriyor.

İkinci satır bunu kesin bir sayıya çeviriyor. Üç etiket sekiz desen kurabilirdi, sınamada yalnız yedisi görülüyor ve her desende çoğunluk etiketini söyleyen kural 0,7897 veriyor. Üç etiketten başkasını görmeyen hiçbir birleştirme bunu geçemez ve bu sayı torbalamanın kendi sayısına eşit.

Son üç satır nedeni söylüyor. Torbalama ile artırma 252 abonenin yalnız 6’sını ayrı sınıflıyor. Biri paralel oy, öteki ardışık toplam; yapıları birbirinin tersi, kararları neredeyse aynı. Torbalama 53, artırma 57 abonede yanılıyor ve ikisi 52 abonede birlikte yanılıyor: artırmanın kaçırdığı neredeyse her aboneyi torbalama da kaçırıyor. Tek ağaç biraz daha uzakta (17 ve 21 abone), ama o da aynı aileden besleniyor.

İkinci Katman Hangi Kümeden Öğreniliyor

Yığınlama üç çıktıyı girdi alan bir model kurar. Bu modelin öğreneceği veri temel modellerin çıktılarıdır; o çıktıların hangi küme üzerinde üretildiği dersin sorusudur.

def ikinci_katman(u, adim=2.0, tur=400):    # BIRLESTIRME 3: yiginlama
    kume, w, sabit = KUME[u], [0.0] * len(TEMEL), 0.0
    for _ in range(tur):
        gw, gs = [0.0] * len(TEMEL), 0.0
        for i, (_, y) in enumerate(kume):
            h = sikistir(sum(w[j] * TEMEL[j][1][u][i]
                             for j in range(len(TEMEL))) + sabit) - y
            for j in range(len(TEMEL)):
                gw[j] += h * TEMEL[j][1][u][i]
            gs += h
        for j in range(len(TEMEL)):
            w[j] -= adim * gw[j] / len(kume)
        sabit -= adim * gs / len(kume)
    return w, sabit


def katman_dogruluk(model, u):
    w, sabit = model
    return sum((sum(w[j] * TEMEL[j][1][u][i] for j in range(len(TEMEL))) + sabit > 0)
               == y for i, (_, y) in enumerate(KUME[u])) / len(KUME[u])


DOGRU, YANLIS = ikinci_katman(1), ikinci_katman(0)
print(f"{'ikinci katman':<22} {'egitim':>8} {'dogrulama':>10} {'sinama':>8}   agirliklar")
for ad, model, u in (("dogrulamadan ogrenildi", DOGRU, 1), ("egitimden ogrenildi", YANLIS, 0)):
    print(f"{ad:<22}" + "".join(f"{katman_dogruluk(model, v):>{(8, 10, 8)[v]}.4f}"
                                for v in range(3))
          + "   " + " ".join(f"{q:+.2f}" for q in model[0]))
SON = [("torbalama", dogruluk(TEMEL[1][1][1], KD), dogruluk(TEMEL[1][1][2], KS),
        TEMEL[1][2], 31),
       ("artirma", dogruluk(TEMEL[2][1][1], KD), dogruluk(TEMEL[2][1][2], KS),
        TEMEL[2][2], 1279),
       ("yiginlama", katman_dogruluk(DOGRU, 1), katman_dogruluk(DOGRU, 2),
        sum(t[2] for t in TEMEL) + 4, 3)]
print(f"\n{'birlestirme':<12} {'rapor edilen':>13} {'sinama':>8} {'sisme':>8} "
      f"{'bolme':>7} {'aday':>6}")
for ad, d, s, maliyet, aday in SON:
    print(f"{ad:<12} {d:>13.4f} {s:>8.4f} {d - s:>8.4f} {maliyet:>7} {aday:>6}")
print(f"konunun toplam ayar butcesi {sum(t[4] for t in SON)} aday")
ikinci katman            egitim  dogrulama   sinama   agirliklar
dogrulamadan ogrenildi  0.8333    0.8254  0.7778   +1.99 +1.54 +1.45
egitimden ogrenildi     0.8532    0.7937  0.7778   +5.04 +2.38 +0.54

birlestirme   rapor edilen   sinama    sisme   bolme   aday
torbalama           0.8413   0.7897   0.0516     568     31
artirma             0.8373   0.7738   0.0635      30   1279
yiginlama           0.8254   0.7778   0.0476     645      3
konunun toplam ayar butcesi 1313 aday

İki satırın son sütunu aynı: 0,7778. Yanlış kümeden öğrenmek, bu tabloda teslim edilen sayıyı değiştirmedi. Değiştirdiği iki şey var ve ikisi de görünür.

Birincisi rapor edilen sayıdır. Katman eğitim kümesinden öğrenildiğinde o kümede 0,8532 okuyor; gerçek sayı 0,7778, yani şişme 0,0754. Doğrulamadan öğrenilen katman kendi kümesinde 0,8254 okuyor ve şişmesi 0,0476. İki sayı da şişmiştir, çünkü ikisi de katmanın öğrendiği kümeden okunmuştur; yanlış küme yalnız şişmeyi 0,0278, yani yedi abone büyütmüştür.

İkincisi ağırlıklardır. Doğrulamadan öğrenen katman dengeli ağırlık veriyor: +1,99, +1,54, +1,45. Eğitimden öğrenen katman ise +5,04’ü tek ağaca yazıyor ve artırmayı +0,54’e indiriyor. Nedeni eğitim sütunundadır: tek ağaç eğitim kümesinde 0,8426, torbalanmış topluluk 0,8175, artırma 0,8082 okuyor. İkinci katman en çok ezberlemiş modeli en iyi model sanıyor. Burada ezber ılımlı olduğu için zarar da ılımlı kaldı; temel modellerden biri eğitim kümesini birebir öğrenseydi katman bütün ağırlığı ona verirdi ve teslim edilen sayı da düşerdi.

Doğrulamadan öğrenmenin de bedeli var: o küme artık harcanmıştır. Harcamayan yol, ikinci katmanı temel modellerin kendilerini eğiten satırlarda görülmemiş çıktılarından öğrenmektir; torba dışı kestirim tam olarak bu biçimdir.

Son tablo konunun hesabıdır. Üç birleştirmenin şişmesi 0,0516, 0,0635 ve 0,0476; en yüksek sayıyı en küçük bütçe veriyor. Torbalama 31 adayla 0,7897’ye ulaşıyor, artırma 1.279 adayla 0,7738’de kalıyor. Konunun toplam bütçesi 1.313 aday ve karşılığı, taban çizgisinin 0,0318 üstünde bir sayı.

Özet

  • Üç temel model sınama kümesinde 0,7778, 0,7897 ve 0,7738 veriyor; maliyetleri 43, 568 ve 30 bölme, yani en ucuz birleştirme en pahalısının on dokuzda biri.
  • 252 abonenin 185’inde üçü de doğru, 45’inde üçü de yanlış; birleştirmenin çalışabileceği bölge 22 abone.
  • Üç etikete bakan bir birleştirmenin tavanı 0,7897’dir ve torbalamanın sayısına eşittir; torbalama ile artırma yalnız 6 aboneyi ayrı sınıflıyor.
  • İkinci katman eğitimden öğrenildiğinde 0,8532 rapor edip 0,7778 veriyor (şişme 0,0754), doğrulamadan öğrenildiğinde 0,8254 rapor edip yine 0,7778 (şişme 0,0476).
  • Yanlış küme ağırlığı en çok ezberleyen modele kaydırıyor: +5,04 tek ağaca karşı doğru kurulumda +1,99; üç birleştirmenin en yükseğini en küçük ayar bütçesi veriyor.

Sonraki Adım

Bu konu yedi derste yedi yapı denedi: örnek tabanlı yordam, koşullu bağımsızlık varsayımına dayanan olasılıksal sınıflandırıcı, marj temelli sınıflandırıcı, karar ağacı, torbalanmış ağaç topluluğu, ardışık artırma ve yığınlama. Hepsi aynı tabloyla, aynı bölmeyle ve aynı taban çizgisiyle karşılaştırıldı ve her sayının yanına kaç aday denendiği yazıldı. Ama karşılaştırmanın kendisi baştan sona tek bir sayıyla yapıldı: doğrulukla. O sayının neyi sakladığı hiç sorulmadı. Üçünün birden yanıldığı 45 abonenin kaçı gerçekten şüpheliydi, kaçı boş yere kapıya gönderilmiş bir ekip demekti, hiç sayılmadı. Aynı doğruluğu veren iki modelin bambaşka hatalar yapması olanaklıdır ve iki hata türünün bedeli aynı değildir. Sonraki konu, model değerlendirme, bu soruyla açılır.

İ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