Ders 04 / 20
Lojistik Bağlanım
Doğrusal bir düzlemin çıktısının olasılığa sıkıştırılması ve o olasılığın eşikten önce sürekli olduğunun ölçülmesi: on iki sabit sütunla model sınama kümesinde 0,8016 verir ve taban çizgisini 0,0437, yani on bir aboneyi geçer. Dokuz aday denendiğinde doğrulama kümesinde beşi 0,8373 ile berabere kalır ve o beşin sınama sayıları 0,7937 ile 0,8016 arasında bölünür; doğrulamadan okunan ayar sınamada 0,7937 verir, fark iki abonedir. Sınama kümesindeki 252 abonenin 252'si farklı bir olasılık alır; eşik 0,20'den 0,80'e süpürüldüğünde tek bir model doğrulukta 0,7183 ile 0,8016 arasında yedi ayrı sayı verir, işaretlenen abone 102'den 5'e iner ve 0,40 ile 0,60 arasında 27 abone sınıf değiştirir.
İçindekiler
Üç derste hedef sürekli bir sayıydı ve model o sayıyı doğrudan söyledi. Kursun through-line problemi ise bir sınıflandırmadır: bir abone kaçak ya da arıza şüphesi taşıyor mu, ve oradaki taban çizgisi 0,7579. Aynı doğrusal düzlem bu problemde doğrudan kullanılamaz. Düzlemin çıktısı eksi sonsuzdan artı sonsuza uzanır; etiket ise yalnız sıfır ile birdir. Bir aboneye “-3,4 şüphelidir” demek anlamsızdır.
Köprü, düzlemin çıktısını sıfır ile bir arasına sıkıştıran S biçimli bir işlevdir. Sıkıştırılmış
sayı bir olasılık gibi okunur ve model bu haliyle lojistik bağlanım adını alır — bağlanım
yordamıdır, çünkü sürekli bir sayı kestirir; sınıflandırıcı olması ancak o sayıya bir eşik
uygulandıktan sonradır. Bu dersin ölçüsü tam olarak buradadır: eşik uygulanmadan önce çıktının
ne taşıdığı. Eşiği seçmek ayrı bir iştir ve model-degerlendirme konusuna bırakılır.
- DM27. Küme, bölme ve tohum önceki üç dersteki gibidir. Hedef şüpheli etiketidir ve taban çizgisi en sık sınıfı söylemektir: sınama kümesinde 0,7579.
- DM28. Öznitelik kümesi M27/K02’nin bıraktığı on iki sütundur ve kurs boyunca sabit kalır: ortalama tüketim, oynaklık, hane büyüklüğü, memnuniyet, dönem sayısı, sıfır okuma göstergesi, kişi başına tüketim ve beş bölge göstergesi. Bağlanım derslerinin dışarıda bıraktığı sütunlar burada kullanılır, çünkü hedef artık tüketim değil etikettir.
- DM29. Sütunlar eğitim kümesinden öğrenilen ortalama ve değişkenlikle ölçeklenir. M27/K02’nin Hazırlama Adımları konusu bu adımın eğim temelli bir modelde zorunlu olduğunu ölçmüştü; burada varsayılır.
- DM30. Beş bölge göstergesinin hepsi kullanılır. Bağlanım derslerinde biri referans olarak dışarıda bırakılmıştı; eğim temelli çözüm tekil takım çözmediği için burada gerekmiyor.
- DM31. Çözüm eğim inişidir: ağırlıklar kayıp yüzeyinin eğimi yönünde adım adım güncellenir. Ayar değişkenleri öğrenme adımı ve tur sayısıdır.
- DM32. Denenen aday sayısı 9’dur: üç öğrenme adımı, üç tur sayısı.
- DM33. Ölçü doğruluktur ve sınama kümesi 252 abonedir; bir abone 0,0040 eder. Doğruluğun
neyi sakladığı ve hangi ölçütle değiştirilmesi gerektiği
model-degerlendirme/01–02’ye bırakılır. - DM34. Eşik süpürmesi bu derste seçim yapmaz; tek bir modelin eşikten bağımsız olduğunu
göstermek için basılır. İşletme noktasının bir bedel hesabıyla seçilmesi
model-degerlendirme/03’ün konusudur. - DM35. Söylenen olasılığın gerçekleşen orana oturup oturmadığı ayrı bir sorudur ve
model-degerlendirme/04’e bırakılır.
Düzlemden Olasılığa
Kurulum kümeyi üretir, on iki sütunu sabitler ve iki oranı basar.
# lojistik.py — MODELDIR. Ayni KURGU abone tablosu, ayni tohum ve ayni bolme; # hedef bu derste kacak ya da ariza suphesi etiketidir. 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)} 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"] ORTALAMA = {a: statistics.fmean(x[a] for x in EGT) for a in ALAN} SAPMA = {a: max(1e-9, statistics.pstdev([x[a] for x in EGT])) for a in ALAN} TABAN = sum(x["supheli"] == 0 for x in SIN) / len(SIN) def olcekli(x): # OGRENME egitimden, UYGULAMA her kumeye return [1.0] + [(x[a] - ORTALAMA[a]) / SAPMA[a] for a in ALAN] print(f"egitim {len(EGT)}, dogrulama {len(DOG)}, sinama {len(SIN)}, sutun {len(ALAN)}") print(f"supheli orani egitimde {sum(x['supheli'] for x in EGT) / len(EGT):.4f}, " f"sinamada {sum(x['supheli'] for x in SIN) / len(SIN):.4f}") print(f"taban cizgisi (en sik sinif) sinamada {TABAN:.4f}")
egitim 756, dogrulama 252, sinama 252, sutun 12 supheli orani egitimde 0.2222, sinamada 0.2421 taban cizgisi (en sik sinif) sinamada 0.7579
Sıkıştırma ve eğim inişi birlikte durur. Sıkıştırılan sayı, doğrusal puanın logit (log-odds) olarak okunmasıyla aynı şeydir: puan sıfırken olasılık 0,5, puan büyüdükçe bire, küçüldükçe sıfıra gider ve hiçbir zaman uçlara değmez.
def sikistir(z): # S bicimli islev, tasma korumali 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) X = [olcekli(x) for x in EGT] Y = [x["supheli"] for x in EGT] P = len(X[0]) def lojistik(adim, tur): # MODELDIR: lojistik baglanim w = [0.0] * P for _ in range(tur): g = [0.0] * P for i in range(len(X)): h = sikistir(sum(w[j] * X[i][j] for j in range(P))) - Y[i] for j in range(P): g[j] += h * X[i][j] for j in range(P): w[j] -= adim * g[j] / len(X) return w def olasilik(w, x): return sikistir(sum(a * b for a, b in zip(w, olcekli(x)))) def dogruluk(w, s, esik=0.5): return sum((olasilik(w, x) > esik) == x["supheli"] for x in s) / len(s) SONUC = [] print(f"{'ogrenme adimi':>14} {'tur':>5} {'egitimde':>9} {'dogrulama':>10} {'sinama':>8}") for adim in (0.1, 0.3, 1.0): for tur in (100, 300, 600): w = lojistik(adim, tur) SONUC.append((adim, tur, dogruluk(w, DOG), dogruluk(w, SIN), w)) print(f"{adim:>14} {tur:>5} {dogruluk(w, EGT):>9.4f} " f"{SONUC[-1][2]:>10.4f} {SONUC[-1][3]:>8.4f}") en_d = max(SONUC, key=lambda t: t[2]) en_s = max(SONUC, key=lambda t: t[3]) print(f"\ntaban cizgisi {TABAN:.4f}, denenen aday sayisi {len(SONUC)}") print(f"dogrulamadan okunan ayar ({en_d[0]}, {en_d[1]}): dogrulama {en_d[2]:.4f}, " f"sinama {en_d[3]:.4f}") print(f"sinamadan okunsaydi ayar ({en_s[0]}, {en_s[1]}): dogrulama {en_s[2]:.4f}, " f"sinama {en_s[3]:.4f}") print(f"iki secim arasindaki fark {en_s[3] - en_d[3]:.4f}, yani " f"{round((en_s[3] - en_d[3]) * len(SIN))} abone") print(f"dogrulamada ayni en yuksek sayiyi veren aday " f"{sum(1 for t in SONUC if abs(t[2] - en_d[2]) < 1e-12)}") W = en_d[4]
ogrenme adimi tur egitimde dogrulama sinama
0.1 100 0.8175 0.8056 0.8016
0.1 300 0.8201 0.8373 0.7937
0.1 600 0.8188 0.8373 0.8016
0.3 100 0.8201 0.8373 0.7937
0.3 300 0.8175 0.8333 0.8016
0.3 600 0.8148 0.8333 0.8016
1.0 100 0.8161 0.8333 0.8016
1.0 300 0.8148 0.8373 0.8016
1.0 600 0.8148 0.8373 0.8016
taban cizgisi 0.7579, denenen aday sayisi 9
dogrulamadan okunan ayar (0.1, 300): dogrulama 0.8373, sinama 0.7937
sinamadan okunsaydi ayar (0.1, 100): dogrulama 0.8056, sinama 0.8016
iki secim arasindaki fark 0.0079, yani 2 abone
dogrulamada ayni en yuksek sayiyi veren aday 5
Üçlü tamamlandı: taban çizgisi 0,7579, ailenin sayısı 0,8016, denenen aday sayısı 9. Fark 0,0437, yani sınama kümesinde on bir abone. Dokuz adayın sınama sütunu yalnız iki ayrı değer alıyor — 0,7937 ve 0,8016 — ve aradaki fark iki abonedir. Öğrenme adımı ile tur sayısı bu problemde birbirinin yerine geçiyor: küçük adımla altı yüz tur, büyük adımla üç yüz tur aynı yere varıyor.
Son satır kursun kuralını beklenmedik bir yerden gösteriyor. Dokuz adayın beşi doğrulama kümesinde tam olarak aynı sayıyı, 0,8373’ü veriyor. Doğrulama kümesi 252 satırdır ve 0,0040’lık adımlarla ölçer; beş farklı ayarın aynı basamağa düşmesi olağandır. Ama o beş aday sınama kümesinde aynı sayıyı vermiyor. Beraberliği bozan kural — tablodaki ilk sırayı almak — modelin hiçbir özelliği değildir ve iki abone ediyor.
Çıktı Eşikten Önce Süreklidir
Seçilen model tek bir ayardır, ama tek bir sayı vermez. Verdiği şey 252 olasılıktır ve o olasılıklardan bir sınıf çıkarmak ayrı bir karardır.
esit = [t for t in SONUC if abs(t[2] - en_d[2]) < 1e-12] print(f"dogrulamada berabere kalan {len(esit)} adayin sinama sayilari: " f"{sorted({round(t[3], 4) for t in esit})}") p = sorted((olasilik(W, x), x["supheli"]) for x in SIN) print(f"sinamada farkli olasilik degeri {len({round(q, 9) for q, _ in p})}/{len(SIN)}, " f"en dusuk {p[0][0]:.4f}, en yuksek {p[-1][0]:.4f}\n") print(f"{'olasilik araligi':<18} {'abone':>6} {'supheli':>8} {'supheli orani':>15}") for k in range(5): a, b = k / 5, (k + 1) / 5 d = [q for q in p if a <= q[0] < b or (k == 4 and q[0] >= b)] g = sum(t[1] for t in d) print(f"[{a:.1f}, {b:.1f})".ljust(18) + f" {len(d):>6} {g:>8} {g / len(d) if d else 0.0:>15.4f}") print(f"\n{'esik':>6} {'dogruluk':>9} {'isaretlenen':>12} {'yakalanan':>10} " f"{'kacirilan':>10}") for e in (0.20, 0.30, 0.40, 0.50, 0.60, 0.70, 0.80): isaret = sum(1 for q, _ in p if q > e) yakalanan = sum(1 for q, y in p if q > e and y) print(f"{e:>6.2f} {dogruluk(W, SIN, e):>9.4f} {isaret:>12} {yakalanan:>10} " f"{sum(t[1] for t in p) - yakalanan:>10}") print(f"\n0,40 ile 0,60 arasinda sinif degistiren abone " f"{sum(1 for q, _ in p if 0.40 < q <= 0.60)}") print(f"esik 0,5 sabit tutulunca dogruluk {dogruluk(W, SIN):.4f}, " f"taban cizgisi {TABAN:.4f}, en iyi esik 0,60'ta {dogruluk(W, SIN, 0.60):.4f}")
dogrulamada berabere kalan 5 adayin sinama sayilari: [0.7937, 0.8016] sinamada farkli olasilik degeri 252/252, en dusuk 0.0196, en yuksek 0.9838 olasilik araligi abone supheli supheli orani [0.0, 0.2) 150 15 0.1000 [0.2, 0.4) 52 18 0.3462 [0.4, 0.6) 27 11 0.4074 [0.6, 0.8) 18 12 0.6667 [0.8, 1.0) 5 5 1.0000 esik dogruluk isaretlenen yakalanan kacirilan 0.20 0.7183 102 46 15 0.30 0.7659 68 35 26 0.40 0.7817 50 28 33 0.50 0.7937 31 20 41 0.60 0.8016 23 17 44 0.70 0.7897 16 12 49 0.80 0.7778 5 5 56 0,40 ile 0,60 arasinda sinif degistiren abone 27 esik 0,5 sabit tutulunca dogruluk 0.7937, taban cizgisi 0.7579, en iyi esik 0,60'ta 0.8016
İkinci satır dersin en yalın bulgusudur: 252 abonenin 252’si farklı bir olasılık alıyor. Model bir etiket üretmiyor, bir sıralama üretiyor. En düşük olasılık 0,0196, en yükseği 0,9838; sıkıştırma uçlara değmiyor, çünkü S biçimli işlev sıfıra ve bire ancak sonsuzda ulaşır.
Aralık tablosu o sıralamanın boş olmadığını gösteriyor. En alt aralıktaki 150 abonenin 15’i,
yani onda biri şüpheli; en üst aralıktaki beş abonenin beşi de şüpheli. Sıralama etiketle aynı
yönde gidiyor. Söylenen olasılığın gerçekleşen orana oturup oturmadığı — örneğin 0,4–0,6
aralığındaki oranın 0,4074 çıkması — ayrı bir sorudur ve model-degerlendirme/04’e bırakılır.
Eşik tablosu dersin başlığını taşıyan sayıyı veriyor. Tek bir model, tek bir ağırlık kümesi, tek bir eğitim — ve yedi ayrı doğruluk sayısı: 0,7183’ten 0,8016’ya. Eşik 0,20’de model 102 aboneyi işaretliyor ve 61 şüphelinin 46’sını yakalıyor; eşik 0,80’de yalnız beş abone işaretleniyor ve beşi de gerçekten şüpheli, ama 56 şüpheli kaçıyor. Bunların hiçbiri farklı bir model değil.
Bu yüzden “modelin doğruluğu 0,7937’dir” cümlesi eksiktir. Doğru cümle şudur: 0,5 eşiğiyle
0,7937’dir. Eşik bir model özelliği değil, bir karardır ve karar 0,40 ile 0,60 arasında
gezdirilirse 27 abone sınıf değiştirir. Hangi eşiğin seçileceği yakalanan kaçakla boşa giden
saha ziyaretinin bedeline bağlıdır; o hesap model-degerlendirme/03’ün konusudur ve burada
yapılmaz.
Özet
- Lojistik bağlanım bir sınıflandırıcı değil, olasılık kestiren bir bağlanım yordamıdır; sınıflandırıcı olması ancak bir eşik uygulandıktan sonradır.
- On iki sabit sütunla model sınama kümesinde 0,8016 veriyor; taban çizgisi 0,7579, fark 0,0437 ve denenen aday sayısı 9’dur.
- Dokuz adayın beşi doğrulama kümesinde tam olarak 0,8373 ile berabere kalıyor ama sınamada 0,7937 ile 0,8016’ya bölünüyor; beraberliği bozan kural modelin özelliği değildir ve iki abone eder.
- Sınama kümesindeki 252 abonenin 252’si farklı bir olasılık alıyor, en düşüğü 0,0196, en yükseği 0,9838. Model bir etiket değil, bir sıralama üretiyor ve sıralama etiketle aynı yönde gidiyor.
- Aynı model eşik 0,20’den 0,80’e süpürüldüğünde 0,7183 ile 0,8016 arasında yedi ayrı doğruluk veriyor; işaretlenen abone 102’den 5’e iniyor ve 0,40 ile 0,60 arasında 27 abone sınıf değiştiriyor.
Sonraki Adım
Bu dersin modeli on iki katsayı taşıyor ve o katsayılar okunabilir: her biri bir sütuna aittir, işareti ve büyüklüğü vardır. Doğrusal modellerin en çok anılan üstünlüğü budur. Sonraki ders o üstünlüğü bir övgü olarak değil bir sayı olarak ele alır: okunabilir katsayılı bir modelin ayrılmış kümedeki sayısı ile bu konudaki en iyi ailenin sayısı arasındaki fark kaç abonedir, ve katsayıya bakarak ne söylenebilir, ne söylenemez. Konunun kapanışı da oradadır.
İlerlemeni kaydetmek ve not almak için Giriş yap
Notlarım
Not almak için giriş yapmalısın.