İçeriğe geç
academia.sh

Ders 09 / 15

Kısmi Bağımlılık ve Etkileşim

Bir sütunun modele bütün olarak ne yaptığının sayı olarak basılması ve ortalamanın ne gizlediğinin sayılması: karar ağacında beş sütunun üçü bütünde düz görünüyor, bunların ikisinde alt gruplar ters yönde eğimli. Hane büyüklüğünün kısmi bağımlılığı bütünde -0,0069 ile düzdür, üçüncü tarife basamağında +0,1301, doğu bölgesinde -0,1891 ve açıklık 0,3192'dir. Memnuniyette açıklık 0,2189'dur. Okuma sayısı hem bütünde hem on iki alt grupta tam olarak 0,0000 eğimlidir: düz görünen her sayı bir etkileşim gizlemiyor.

İçindekiler

Önceki iki ders açıklamayı ya modelin bütününe ya da tek bir aboneye bağladı. Aradaki soru sorulmadı: bir sütunun değeri bir uçtan öbür uca gezdirilirken modelin çıktısı ortalamada nasıl davranıyor. Bu, kısmi bağımlılıktır ve tek bir sütunun modeldeki etkisini bir eğri olarak özetler. Burada eğri çizilmez, ızgara noktalarındaki sayılar basılır — çünkü bu dersin sorusu tam olarak o ortalamanın içinde kaybolan şeyle ilgilidir.

Kısmi bağımlılık bir ortalamadır ve her ortalama gibi ters yönlü iki hareketi birbirine götürebilir. Bir sütun bir alt grupta puanı yukarı, başka bir alt grupta aşağı itiyorsa bütündeki eğri düz çıkar ve sütunun modelde hiçbir rolü yokmuş gibi görünür. Bu dersin ölçüsü budur: bütünde düz görünen kaç sütunda alt gruplar ters yönde eğimli.

  • YO19. Kurulum önceki derslerinkidir: aynı kurgu abone tablosu, tohum 20260218, bölme 756/252/252, sınama kümesinde taban çizgisi 0,7579. Alt gruplar ve 25 kayıtlık okuma eşiği sürer; bakılan alt grup sayısı 13’tür.
  • YO20. Bu ders açıklanan modeli değiştirir. Doğrusal model sütunları birbiriyle çarpmaz, dolayısıyla bir sütunun kısmi bağımlılığı her alt grupta aynı işareti taşır ve bu dersin sorusu orada sorulamaz. Açıklanan model M27/K03’ün karar ağacı ailesidir; burada budanmamış derinlik 6 ağacı kullanılır ve sınamada 0,7897 verir. Ailenin M27/K03’te budamayla ulaştığı sayı 0,7857’dir.
  • YO21. Kısmi bağımlılık şöyle hesaplanır: bir sütun ızgaradaki değere çekilir, öbür sütunlar kümenin kendi değerlerinde bırakılır, puanların ortalaması alınır. Izgara eğitim kümesindeki farklı değerlerin en fazla beş noktasıdır; farklı değeri beşten az olan sütunda nokta sayısı o kadardır.
  • YO22. Türetilmiş kişi başına tüketim her ızgara noktasında kaynağıyla birlikte yeniden hesaplanır.
  • YO23. Eğim, ızgaranın son noktasındaki kısmi bağımlılıktan ilk noktasındakinin çıkarılmasıdır. Bütünde mutlak eğimi 0,05’in altında olan sütun düz sayılır; bir alt grupta mutlak eğimi 0,02’yi geçen sütun eğimli sayılır. İki eşik de puan ölçeğindedir ve puan 0 ile 1 arasında değişir.
  • YO24. Grafik çizilmez; kısmi bağımlılık ızgara noktalarındaki sayılarla basılır.

Kısmi Bağımlılık Sayı Olarak

Kurulum önceki derslerinkiyle aynıdır.

# yorum.py — MODELDIR. M27/K01–K07'nin KURGU abone tablosu ayni tohumla uretilir;
# on iki sutunluk oznitelik kumesi ve bolme kurs boyunca sabittir.
import math
import statistics

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),
         "bolge": k["bolge"][0]}
    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"]
TABAN = sum(x["supheli"] == 0 for x in SIN) / len(SIN)


def basamak(x):
    return ("tarife 10" if x["ort_tuketim"] <= 10 else
            "tarife 25" if x["ort_tuketim"] <= 25 else "tarife 40")


def hane_grup(x):
    return "hane 1-2" if x["hane"] <= 2 else ("hane 3-4" if x["hane"] <= 4
                                              else "hane 5+")


def okuma_grup(x):
    return "okuma az" if x["donem"] <= 2 else "okuma tam"


def esitse(f, deger):
    return lambda x: f(x) == deger


ALTGRUP = ([("bolge " + b[0], esitse(lambda x: x["bolge"], b[0])) for b in BOLGE]
           + [(t, esitse(basamak, t)) for t in ("tarife 10", "tarife 25", "tarife 40")]
           + [(h, esitse(hane_grup, h)) for h in ("hane 1-2", "hane 3-4", "hane 5+")]
           + [(o, esitse(okuma_grup, o)) for o in ("okuma az", "okuma tam")])
ENAZ = 25
BOY = {ad: sum(1 for x in SIN if f(x)) for ad, f in ALTGRUP}
print(f"egitim {len(EGT)}, dogrulama {len(DOG)}, sinama {len(SIN)}; alt grup "
      f"sayisi {len(ALTGRUP)}, esigin altinda {[a for a in BOY if BOY[a] < ENAZ]}")
egitim 756, dogrulama 252, sinama 252; alt grup sayisi 13, esigin altinda ['tarife 10']

Ağaç M27/K03’teki biçimiyle kurulur ve kısmi bağımlılık beş sütun için ızgara noktalarında basılır.

def oran(s):
    return sum(x["supheli"] for x in s) / len(s) if s else 0.0


def safliksizlik(s):
    p = oran(s)
    return 2 * p * (1 - p)


def en_iyi_bolme(s, enaz=2):
    en = None
    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 = safliksizlik(s) - (len(sol) * safliksizlik(sol)
                                   + len(sag) * safliksizlik(sag)) / len(s)
            if en is None or k > en[0]:
                en = (k, a, v, sol, sag)
    return en


def agac(s, derinlik, enaz=2):        # MODELDIR: karar agaci, M27/K03'un ailesi
    p = oran(s)
    en = (en_iyi_bolme(s, enaz) if derinlik and len(s) >= 2 * enaz
          and 0.0 < p < 1.0 else None)
    if en is None or en[0] <= 1e-9:
        return {"oran": p}
    return {"alan": en[1], "esik": en[2], "sol": agac(en[3], derinlik - 1, enaz),
            "sag": agac(en[4], derinlik - 1, enaz)}


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


AGAC = agac(EGT, 6)
AD = sum((agac_puan(AGAC, x) > 0.5) == x["supheli"] for x in SIN) / len(SIN)
print(f"taban cizgisi {TABAN:.4f}, karar agacinin sinama dogrulugu {AD:.4f}")

IZGARA_SUTUN = ["ort_tuketim", "oynaklik", "hane", "memnuniyet", "donem"]


def izgara(a, nokta=5):
    d = sorted({x[a] for x in EGT})
    k = min(nokta, len(d))
    return [d[int(i * (len(d) - 1) / (k - 1))] for i in range(k)]


def kismi(st, a, gr):                 # kismi bagimlilik: sayi olarak, cizilmez
    p = []
    for v in gr:
        t = 0.0
        for x in st:
            d = dict(x)
            d[a] = v
            d["kisi_basi"] = round(d["ort_tuketim"] / max(1, d["hane"]), 3)
            t += agac_puan(AGAC, d)
        p.append(t / len(st))
    return p


DUZ, EGIM = 0.05, {}
IZG = {a: izgara(a) for a in IZGARA_SUTUN}
for a in IZGARA_SUTUN:
    p = kismi(SIN, a, IZG[a])
    EGIM[a] = p[-1] - p[0]
    print(f"{a:<13}" + "  ".join(f"{v:g}:{q:.4f}" for v, q in zip(IZG[a], p))
          + f"   egim {EGIM[a]:+.4f}")
YASSI = [a for a in IZGARA_SUTUN if abs(EGIM[a]) < DUZ]
print(f"\nbutunde duz gorunen sutun ({DUZ} esigiyle) {YASSI}")
taban cizgisi 0.7579, karar agacinin sinama dogrulugu 0.7897
ort_tuketim  0:0.0848  15.23:0.1380  19.51:0.2234  23.81:0.2250  42.9:0.3838   egim +0.2990
oynaklik     0:0.1374  5.52:0.1374  9.89:0.1945  15.64:0.3158  40.57:0.7731   egim +0.6357
hane         1:0.2546  2:0.2510  3:0.2274  4:0.2165  6:0.2477   egim -0.0069
memnuniyet   1:0.2926  2:0.2588  3:0.2315  4:0.2354  5:0.2460   egim -0.0466
donem        1:0.2491  2:0.2491  3:0.2491   egim +0.0000

butunde duz gorunen sutun (0.05 esigiyle) ['hane', 'memnuniyet', 'donem']

Ortalama tüketim ve oynaklık okunması kolay iki satır: ızgara boyunca puan tek yönde artıyor, eğimler +0,2990 ve +0,6357. Kalan üç sütun düz. Hane büyüklüğünün eğimi -0,0069, yani puanın binde yedisi; memnuniyetinki -0,0466; okuma sayısınınki tam olarak sıfır.

Bu üç satıra bakan biri şu cümleyi yazar: model kararını hane büyüklüğüne, memnuniyete ve okuma sayısına dayandırmıyor. Cümle üç sütun için de aynı gerekçeyle yazılıyor ama üçünde de aynı şeyi anlatmıyor, ve hangisinde neyi anlattığı bütünden okunamaz.

Hesabın kendisi de bir varsayım taşır ve varsayım burada açıkça yazılmalıdır. Bir sütun ızgara noktasına çekilirken öbür sütunlar oldukları yerde bırakılıyor; yani sütunların birbirinden bağımsız oynatılabildiği varsayılıyor. Hane büyüklüğü 6’ya çekilen bir abonenin ortalama tüketimi değişmiyor, oysa kurguda ikisi birlikte hareket eder. Önceki dersin bozarak ölçülen önemi de aynı varsayıma dayanıyordu ve orada ilişkili iki sütunun önemi bölüşmüştü. Kısmi bağımlılık, kümede hiç görülmemiş bileşimler üzerinde de puan hesaplar; ızgara uçlarındaki sayılar bu yüzden ortadaki sayılardan daha az güvenilirdir.

Ortalamanın Gizlediği Etkileşim

Aynı hesap on iki okunabilir alt grupta ayrı ayrı yapılır.

ESIK = 0.02
E = {a: {} for a in YASSI}
for ad, f in ALTGRUP:
    if BOY[ad] < ENAZ:
        continue
    g = [x for x in SIN if f(x)]
    for a in YASSI:
        p = kismi(g, a, IZG[a])
        E[a][ad] = p[-1] - p[0]
KISA = [(ad.replace("bolge ", "").replace("tarife ", "t").replace("hane ", "h")
         .replace("okuma ", "ok "), ad) for ad in E[YASSI[0]]]
print("alt grup " + "".join(f"{a:>13}" for a in YASSI))
print("butun    " + "".join(f"{EGIM[a]:>+13.4f}" for a in YASSI))
for kisa, ad in KISA:
    print(f"{kisa:<9}" + "".join(f"{E[a][ad]:>+13.4f}" for a in YASSI))
KIRIK = [a for a in YASSI if max(E[a].values()) > ESIK and min(E[a].values()) < -ESIK]
print(f"\nokunan alt grup {len(E[YASSI[0]])}/{len(ALTGRUP)}, egim esigi {ESIK}")
print(f"butunde duz gorunen sutun {len(YASSI)}, bunlardan alt gruplarda ters "
      f"yonde egimli olan {len(KIRIK)}")
for a in KIRIK:
    y = max(E[a], key=lambda k: E[a][k])
    d = min(E[a], key=lambda k: E[a][k])
    print(f"  {a}: en yuksek {y} {E[a][y]:+.4f}, en dusuk {d} {E[a][d]:+.4f}, "
          f"aciklik {E[a][y] - E[a][d]:.4f}")
alt grup          hane   memnuniyet        donem
butun          -0.0069      -0.0466      +0.0000
kuzey          +0.0916      -0.1146      +0.0000
guney          -0.0477      -0.0108      +0.0000
dogu           -0.1891      +0.0278      +0.0000
bati           -0.0442      -0.0313      +0.0000
merkez         +0.0522      -0.0573      +0.0000
t25            -0.0264      -0.0143      +0.0000
t40            +0.1301      -0.1911      +0.0000
h1-2           -0.0354      -0.0665      +0.0000
h3-4           +0.0049      -0.0533      +0.0000
h5+            +0.0040      +0.0205      +0.0000
ok az          +0.0155      -0.0359      +0.0000
ok tam         -0.0183      -0.0520      +0.0000

okunan alt grup 12/13, egim esigi 0.02
butunde duz gorunen sutun 3, bunlardan alt gruplarda ters yonde egimli olan 2
  hane: en yuksek tarife 40 +0.1301, en dusuk bolge dogu -0.1891, aciklik 0.3192
  memnuniyet: en yuksek bolge dogu +0.0278, en dusuk tarife 40 -0.1911, aciklik 0.2189

Hane büyüklüğü bütünde -0,0069 ile düzdür. En üst tarife basamağında +0,1301, doğu bölgesinde -0,1891; açıklık 0,3192, yani bütündeki eğimin kırk altı katı. Yüksek tüketimli abonelerde hane büyüdükçe şüphe artıyor, doğu bölgesinde hane büyüdükçe azalıyor. İki hareket bütünde birbirini götürüyor ve geriye binde yedilik bir sayı kalıyor. Bütünde okunan düzlük bir yokluk değil, bir toplamdır.

Memnuniyette aynı şey daha küçük ölçekte oluyor: bütünde -0,0466, en üst tarife basamağında -0,1911, doğu bölgesinde +0,0278, açıklık 0,2189. İki sütunun da en uç değerleri aynı iki alt grupta ve ters sırada duruyor; bu, ağacın bu iki sütunu birbirinden bağımsız değil, tüketim düzeyi ve bölgeyle birlikte kullandığı anlamına gelir. Etkileşim tam olarak budur.

Okuma sayısı üçüncü tür bir düzlüktür ve bu dersin kontrolüdür. Hem bütünde hem on iki alt grubun hepsinde eğim tam olarak 0,0000: ağaç bu sütuna hiç bölme koymamış. Düz görünen her sayının altında bir etkileşim yoktur; bazen sütun gerçekten kullanılmamıştır. İki durumu ayırmanın yolu bütüne bakmak değil, alt gruplara bakmaktır — ve bakılmadığında ikisi aynı satır olarak okunur.

Kararın değişip değişmediği burada da okunur. Bütüne bakan biri üç sütunu birden modelden çıkarmayı önerir. Alt gruplara bakan biri bunu yalnız okuma sayısı için önerir; öbür ikisi kullanılıyor, yalnız kimin için ne yönde kullanıldığı bütünde görünmüyor.

Özet

  • Kısmi bağımlılık bir sütunu ızgara boyunca gezdirip puanların ortalamasını alır; burada eğri çizilmedi, ızgara noktalarındaki sayılar basıldı.
  • Hesap sütunların bağımsız oynatılabildiğini varsayar ve kümede hiç görülmemiş bileşimler üretir; ızgara uçlarındaki sayılar ortadakilerden daha az güvenilirdir.
  • Beş sütunun ikisi bütünde açıkça eğimli (+0,2990 ve +0,6357), üçü düz görünüyor.
  • Bütünde düz görünen üç sütunun ikisinde alt gruplar ters yönde eğimli: hane büyüklüğünde açıklık 0,3192, memnuniyette 0,2189.
  • Hane büyüklüğünün eğimi bütünde -0,0069 iken üçüncü tarife basamağında +0,1301, doğu bölgesinde -0,1891’dir; bütündeki düzlük bir yokluk değil, ters yönlü iki hareketin toplamıdır.
  • Okuma sayısı hem bütünde hem on iki alt grupta tam olarak 0,0000 eğimlidir: düz görünen her sayı bir etkileşim gizlemez, bazen sütun gerçekten kullanılmamıştır.

Sonraki Adım

Dört derste açıklama hep modelin dışından üretildi: kurulmuş bir modelin kararı sonradan okundu, bozuldu, taklit edildi ve ortalandı. Her seferinde açıklamanın kendisi bir yaklaşımdı ve sadakati ayrıca ölçülmek zorunda kaldı. Başka bir yol vardır: modeli baştan okunabilir kurmak. Kararı birkaç kuralın sırayla uygulanmasıyla veren bir model, açıklamayı ayrıca üretmez — modelin kendisi açıklamadır ve sadakati tanım gereği tamdır. Sonraki ders bu yolun bedelini ölçer: kaç kuralda M27/K03’ün en iyi ailesinin sayısına yaklaşılıyor, ve hangi alt grupta hiç yaklaşılamıyor.

İ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