İçeriğe geç
academia.sh

Ders 07 / 15

Öznitelik Önemi

Aynı model üzerinde iki küresel önem sıralamasının yan yana ölçülmesi: katsayılardan okunan sıra ile sütunu bozarak ölçülen sıra on iki sütunun onunda ayrışıyor ve en büyük kayma beş sıradır. Oynaklık katsayı sırasında üçüncü, bozma sırasında sekizincidir. İlişkili iki sütun önemi bölüşüyor: kişi başına tüketimin önemi tam modelde 0,0018, ortalama tüketim çıkarılıp model yeniden eğitildiğinde 0,0387'ye çıkıyor. On üç alt grupta ölçülen en önemli sütunun kayıp artışı 0,0162 ile 0,1882 arasında değişiyor ve bir alt grupta ilk sıra değişiyor.

İçindekiler

Önceki derste beş açıklama sorusundan üçünün her abone için kapandığı söylendi ve gerekçesi doğrusal modelin puanının sütun başına bir terime ayrılabilmesiydi. O terimlerin büyüklüğüne göre sıralanması, modelin hangi sütuna dayandığının küresel açıklaması olarak okunur: tek bir aboneye değil, modelin bütününe ait bir cevaptır.

Bu sıralamanın kendisi yeni değildir. M27/K02’nin Öznitelik Seçimi konusu önemi bir seçim ölçütü olarak kullandı, M27/K03’ün Doğrusal Modeller konusu katsayının değerinin yanındaki sütun kümesine bağlı olduğunu ölçtü. İkisi de burada tekrarlanmaz. Bu dersin sorusu farklıdır ve öncekilerin cevabını girdi olarak alır: önem tek bir yolla ölçülmez. Sütunu modelden okumak bir sıralama verir; sütunu bozup başarımın ne kadar düştüğüne bakmak ikinci bir sıralama verir. İki sıralamanın aynı çıkması için hiçbir neden yoktur ve ne kadar ayrıştıkları ölçülebilir.

  • YO8. Kurulum önceki dersinkidir: aynı kurgu abone tablosu, tohum 20260218, bölme 756/252/252, taban çizgisi 0,7579, on iki sütunlu doğrusal model sınamada 0,8016. Alt gruplar ve 25 kayıtlık okuma eşiği aynen sürer; bakılan alt grup sayısı 13’tür.
  • YO9. Modelden okunan önem, ölçekli sütunların katsayılarının mutlak değerine göre sıralamasıdır. Bu sıralamanın nasıl üretildiği önceki kurslarda ölçüldü; burada girdi alınır.
  • YO10. Bozarak ölçülen önem, tek bir sütunun değerlerinin sınama kümesi içinde birbirine karıştırılması ve başarımdaki düşüşün ölçülmesidir. Karıştırma satır sırasını değiştirir, sütunun değer kümesini değiştirmez; model yeniden eğitilmez.
  • YO11. Düşüş doğrulukta değil ortalama kayıpta ölçülür. 252 kayıtlık bir kümede doğruluk 0,004’lük adımlarla değişir ve tek bir abone sıralamayı oynatabilir; kayıp sürekli bir sayıdır ve küçük alt gruplarda da okunabilir.
  • YO12. Karıştırma 10 tekrarla yapılır ve ortalaması alınır; tohumlar 20260218’den türetilir.
  • YO13. Önem sıralaması modelin neye dayandığını gösterir, bir nedensel etkiyi göstermez. Nedensel yorumun sınırı M26’nın Uygulamalı İstatistik konusunda ayrıca ölçülmüştü.

İki Sıralama

Kurulum önceki dersle aynıdır ve alt gruplar aynı yerde tanımlanı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 sikistir(z):
    if z >= 0:
        return 1.0 / (1.0 + math.exp(-z)) if z < 700 else 1.0
    e = math.exp(z) if z > -700 else 0.0
    return e / (1.0 + e)


def olcek(egt, alan):
    return ({a: statistics.fmean(x[a] for x in egt) for a in alan},
            {a: max(1e-9, statistics.pstdev([x[a] for x in egt])) for a in alan})


def egit(egt, alan, o, s, adim=0.3, tur=300):    # MODELDIR: lojistik baglanim
    X = [[1.0] + [(x[a] - o[a]) / s[a] for a in alan] for x in egt]
    Y = [x["supheli"] for x in egt]
    w = [0.0] * len(X[0])
    for _ in range(tur):
        g = [0.0] * len(w)
        for i in range(len(X)):
            h = sikistir(sum(w[j] * X[i][j] for j in range(len(w)))) - Y[i]
            for j in range(len(w)):
                g[j] += h * X[i][j]
        for j in range(len(w)):
            w[j] -= adim * g[j] / len(X)
    return w


def puan(w, alan, o, s, x):
    return sikistir(w[0] + sum(w[j + 1] * (x[a] - o[a]) / s[a]
                               for j, a in enumerate(alan)))


def karar(w, alan, o, s, x):
    return int(puan(w, alan, o, s, x) > 0.5)


O, S = olcek(EGT, ALAN)
W = egit(EGT, ALAN, O, S)
DOGRULUK = sum(karar(W, ALAN, O, S, x) == x["supheli"] for x in SIN) / len(SIN)
print(f"egitim {len(EGT)}, dogrulama {len(DOG)}, sinama {len(SIN)}")
print(f"taban cizgisi {TABAN:.4f}, dogrusal modelin sinama dogrulugu {DOGRULUK:.4f}")


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"alt grup sayisi {len(ALTGRUP)}, esik {ENAZ} kayit, esigin altinda "
      f"{[a for a in BOY if BOY[a] < ENAZ]}")
egitim 756, dogrulama 252, sinama 252
taban cizgisi 0.7579, dogrusal modelin sinama dogrulugu 0.8016
alt grup sayisi 13, esik 25 kayit, esigin altinda ['tarife 10']

Bozarak ölçülen önem tek bir işlemdir: bir sütunun değerleri sınama kümesi içinde birbirine karıştırılır, böylece sütun kendi dağılımını korur ama satırla bağını yitirir; model o bozulmuş kümede yeniden ölçülür ve kaybın ne kadar arttığına bakılır.

def kayip(w, alan, o, s, st):     # dogruluk 252 kayitta 0,004'luk adimlarla degisiyor
    t = 0.0
    for x in st:
        p = min(max(puan(w, alan, o, s, x), 1e-9), 1 - 1e-9)
        t -= math.log(p) if x["supheli"] else math.log(1 - p)
    return t / len(st)


def bozarak(w, alan, o, s, st, bozulan, tekrar=10, tohum=TOHUM + 400000):
    k0, t = kayip(w, alan, o, s, st), 0.0
    for r in range(tekrar):
        sira = karistir(list(range(len(st))), tohum + 977 * r)
        yeni = []
        for i, x in enumerate(st):
            d = dict(x)
            for a in bozulan:
                d[a] = st[sira[i]][a]
            yeni.append(d)
        t += kayip(w, alan, o, s, yeni)
    return t / tekrar - k0


BOZ = {a: bozarak(W, ALAN, O, S, SIN, [a]) for a in ALAN}
MODELDEN = sorted(ALAN, key=lambda a: -abs(W[ALAN.index(a) + 1]))
BOZARAK = sorted(ALAN, key=lambda a: -BOZ[a])
print(f"{'sutun':<13}{'katsayi':>9}{'model sirasi':>13}{'kayip artisi':>14}"
      f"{'bozma sirasi':>14}{'kayma':>7}")
ayrisan = 0
for a in MODELDEN:
    ra, rb = MODELDEN.index(a) + 1, BOZARAK.index(a) + 1
    ayrisan += ra != rb
    print(f"{a:<13}{W[ALAN.index(a) + 1]:>+9.3f}{ra:>13}{BOZ[a]:>14.4f}"
          f"{rb:>14}{rb - ra:>+7}")
print(f"\nayrisan sira sayisi {ayrisan}/{len(ALAN)}, en buyuk kayma "
      f"{max(abs(MODELDEN.index(a) - BOZARAK.index(a)) for a in ALAN)}")
print(f"model sirasinin ilk ucu {MODELDEN[:3]}")
print(f"bozma sirasinin ilk ucu {BOZARAK[:3]}")
sutun          katsayi model sirasi  kayip artisi  bozma sirasi  kayma
ort_tuketim     +0.772            1        0.1332             1     +0
sifir_okuma     +0.684            2        0.0564             2     +0
oynaklik        +0.380            3        0.0012             8     +5
b_dogu          +0.306            4        0.0146             3     -1
memnuniyet      -0.273            5        0.0016             7     +2
hane            +0.156            6        0.0053             5     -1
donem           +0.148            7       -0.0004            10     +3
b_bati          -0.147            8        0.0054             4     -4
b_guney         -0.109            9       -0.0011            11     +2
kisi_basi       +0.071           10        0.0018             6     -4
b_merkez        -0.048           11       -0.0014            12     +1
b_kuzey         -0.005           12        0.0002             9     -3

ayrisan sira sayisi 10/12, en buyuk kayma 5
model sirasinin ilk ucu ['ort_tuketim', 'sifir_okuma', 'oynaklik']
bozma sirasinin ilk ucu ['ort_tuketim', 'sifir_okuma', 'b_dogu']

On iki sütunun onu iki sıralamada ayrı yerlerde duruyor. İlk iki sıra ortaktır, üçüncü sıradan itibaren ayrışma başlıyor. En büyük kayma oynaklıkta: katsayı sırasında üçüncü, bozma sırasında sekizinci. Katsayı 0,380 ile hatırı sayılır bir büyüklük taşıyor ama sütunu karıştırmak kaybı yalnız 0,0012 arttırıyor. İki sayı çelişmiyor, iki ayrı şey söylüyor. Katsayı, öbür sütunlar sabit tutulduğunda oynaklığın bir standart sapmalık artışının puana ne kattığını söyler. Bozma ise oynaklığın taşıdığı bilginin başka sütunlarda da bulunup bulunmadığını ölçer: oynaklık ortalama tüketimle birlikte hareket ettiği için karıştırıldığında model açığı kapatıyor.

Dört sütunun kayıp artışı eksi işaretli. Bir sütunu bozmak kaybı düşürmüşse o sütun modele zarar veriyor demektir; büyüklükleri 0,0014’ün altında olduğu için burada okunacak şey işaretin kendisi değil, dört sütunun sıfır civarında durmasıdır.

İlişkili İki Sütun Önemi Nasıl Bölüşüyor

Ortalama tüketim ile kişi başına tüketim aynı niceliğin iki biçimidir; ikincisi birincinin hane büyüklüğüne bölünmesiyle üretilir. Bozma sırasında biri birinci, öbürü altıncıdır.

IKI = ["ort_tuketim", "kisi_basi"]
birlikte = bozarak(W, ALAN, O, S, SIN, IKI)
print(f"tek tek {BOZ[IKI[0]]:.4f} ve {BOZ[IKI[1]]:.4f}, toplam "
      f"{BOZ[IKI[0]] + BOZ[IKI[1]]:.4f}, birlikte {birlikte:.4f}")
for cik in IKI:
    kalan = [a for a in ALAN if a != cik]
    o2, s2 = olcek(EGT, kalan)
    w2 = egit(EGT, kalan, o2, s2)
    dg = sum(karar(w2, kalan, o2, s2, x) == x["supheli"] for x in SIN) / len(SIN)
    obur = IKI[1] if cik == IKI[0] else IKI[0]
    print(f"{cik} cikarildi: sinama {dg:.4f}, {obur} onemi "
          f"{bozarak(w2, kalan, o2, s2, SIN, [obur]):.4f}")
tek tek 0.1332 ve 0.0018, toplam 0.1350, birlikte 0.1437
ort_tuketim cikarildi: sinama 0.7778, kisi_basi onemi 0.0387
kisi_basi cikarildi: sinama 0.8016, ort_tuketim onemi 0.1441

Kişi başına tüketimin önemi tam modelde 0,0018’dir ve bu sayıya bakan biri sütunun boşuna durduğu sonucuna varır. Ortalama tüketim modelden çıkarılıp model yeniden eğitildiğinde aynı sütunun önemi 0,0387’ye, yani yirmi bir katına çıkıyor. Sütun değişmedi; model değişti. Önem bir sütunun özelliği değil, bir sütunun belirli bir modeldeki özelliğidir.

İkisini birlikte bozmak 0,1437 veriyor; tek tek bozmaların toplamı 0,1350. Fark 0,0087, ikisinin artıklı biçimde taşıdığı paydır: her biri tek başına karıştırıldığında öbürü açığı kapattığı için o pay hiçbir tekil ölçüde görünmez. Bir önem sıralaması, ilişkili sütunlar arasında bir payı her zaman kaybeder.

Alt Gruplarda En Önemli Sütun

Bütün sıralama bir kümenin sıralamasıdır ve o küme alt gruplardan oluşur.

print(f"{'alt grup':<14}{'kayit':>6}{'en onemli sutun':>16}{'kayip artisi':>14}"
      f"{'ikinci sutun':>14}")
OKUNAN = []
for ad, f in ALTGRUP:
    g = [x for x in SIN if f(x)]
    d = {a: bozarak(W, ALAN, O, S, g, [a]) for a in ALAN}
    sira = sorted(ALAN, key=lambda a: -d[a])
    if BOY[ad] >= ENAZ:
        OKUNAN.append((ad, sira[0], d[sira[0]]))
    print(f"{ad:<14}{len(g):>6}{sira[0]:>16}{d[sira[0]]:>14.4f}{sira[1]:>14}")
eni, enk = max(OKUNAN, key=lambda t: t[2]), min(OKUNAN, key=lambda t: t[2])
print(f"\nokunan alt grup {len(OKUNAN)}/{len(ALTGRUP)}; ilk sirada "
      f"{BOZARAK[0]} disinda bir sutun bulunan alt grup "
      f"{sum(1 for t in OKUNAN if t[1] != BOZARAK[0])}")
print(f"en yuksek {eni[0]} {eni[2]:.4f}, en dusuk {enk[0]} {enk[2]:.4f}, "
      f"aciklik {eni[2] - enk[2]:.4f}")
alt grup       kayit en onemli sutun  kayip artisi  ikinci sutun
bolge kuzey       68     ort_tuketim        0.0719   sifir_okuma
bolge guney       58     sifir_okuma        0.1882   ort_tuketim
bolge dogu        36     ort_tuketim        0.1753    memnuniyet
bolge bati        32     ort_tuketim        0.0162   sifir_okuma
bolge merkez      58     ort_tuketim        0.1879   sifir_okuma
tarife 10         12     sifir_okuma        0.1288        b_bati
tarife 25        193     ort_tuketim        0.0408   sifir_okuma
tarife 40         47     ort_tuketim        0.1033      oynaklik
hane 1-2          73     ort_tuketim        0.1339   sifir_okuma
hane 3-4         143     ort_tuketim        0.1215   sifir_okuma
hane 5+           36     ort_tuketim        0.1513   sifir_okuma
okuma az          85     ort_tuketim        0.1213   sifir_okuma
okuma tam        167     ort_tuketim        0.1181   sifir_okuma

okunan alt grup 12/13; ilk sirada ort_tuketim disinda bir sutun bulunan alt grup 1
en yuksek bolge guney 0.1882, en dusuk bolge bati 0.0162, aciklik 0.1720

On üç alt gruba bakıldı, eşiği geçen 12’si okundu. Okunan on iki alt grubun on birinde ilk sıra ortalama tüketim; güney bölgesinde ilk sıra sıfır okuma göstergesine geçiyor ve kayıp artışı 0,1882 ile bütündeki 0,1332’nin üstünde. Bütünde yazılan “model en çok ortalama tüketime dayanıyor” cümlesi güney bölgesinin abonelerine sorulduğunda yanlıştır.

Açıklık daha da keskin: en önemli sütunun kayıp artışı güney bölgesinde 0,1882, batı bölgesinde 0,0162 — aralarında on bir katlık bir fark var. Batı bölgesinde hiçbir sütunu bozmak kaybı kayda değer ölçüde arttırmıyor, çünkü oradaki aboneler karar sınırından uzakta duruyor ve puanları sütun oynamalarına karşı duyarsız. Önceki dersin karşıt örnek sayısı da aynı bölgede çökmüştü; iki ayrı ölçü aynı olguyu iki ayrı yerden gösteriyor.

Özet

  • Aynı model için katsayılardan okunan sıra ile bozarak ölçülen sıra on iki sütunun onunda ayrışıyor; en büyük kayma beş sıradır ve oynaklıktadır.
  • Katsayı öbür sütunlar sabitken bir sütunun kattığını, bozma ise o sütunun bilgisinin başka sütunlarda bulunup bulunmadığını ölçer; oynaklığın katsayısı 0,380 iken kayıp artışı 0,0012’dir.
  • Önem sütunun değil, sütunun belirli bir modeldeki durumunun özelliğidir: kişi başına tüketimin önemi 0,0018’den, ortalama tüketim çıkarılıp model yeniden eğitildiğinde 0,0387’ye çıkıyor.
  • İlişkili iki sütunu birlikte bozmak 0,1437, tek tek bozmaların toplamı 0,1350 veriyor; aradaki 0,0087 hiçbir tekil ölçüde görünmeyen artıklı paydır.
  • On üç alt gruba bakıldı, 12’si okundu: on birinde ilk sıra ortalama tüketim, güney bölgesinde sıfır okuma göstergesi; en önemli sütunun kayıp artışı 0,0162 ile 0,1882 arasında ve açıklık 0,1720’dir.

Sonraki Adım

İki sıralama da modelin bütününe aittir. Kurgudaki abone kendisine şüpheli işareti geldiğinde modelin genel olarak neye dayandığını değil, kendi kararının neye dayandığını sorar ve küresel sıralama o soruya cevap vermez: güney bölgesinde ilk sıranın değişmesi tam olarak bunu gösterdi. Sonraki ders tek bir tahmini açıklayan yöntemlere geçer. Asıl modelin bir örneğin çevresindeki davranışını taklit eden küçük bir vekil model kurulur, çıktı öznitelikler arasında paylaştırılarak katkı payları hesaplanır, ve iki yöntem aynı aboneye sorulur. Ölçülecek şey açıklamanın sadakatidir: vekil model asıl modelin kararını kaç örnekte doğru anlatıyor, ve aynı abone için iki yöntem kaç kez iki ayrı açıklama veriyor.

İ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