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.