Ders 10 / 11
Düzenlileştirme Sezgisi
Karmaşıklığın cezalandırılmasının iki sayıyı ters yönde oynatmasının ölçülmesi: 120 satıra 29 sütunlu doğrusal bir modelde ceza katsayısı 0,001'den 1000'e çıkarıldığında ağırlık büyüklüğü 10,040'tan 0,601'e, eğitim hatası 4,603'ten 5,453 m³'e kötüleşir, doğrulama hatası ise 5,924'ten 5,553'e inip 5,932'ye döner. Geri koyarak örneklemeyle ayrıştırıldığında değişkenlik 12,988'den 0,181'e düşer, yanlılık ise 30,976'da tabana vurup 35,295'e fırlar. Doğrulamadan okunan en iyi ceza 100'dür ve sınamada 5,559 m³ verir; taban 6,556, cezasız model 5,841 m³'tür.
İçindekiler
Önceki iki ders kapasiteyi kaba bir düğmeyle kıstı: ağacın derinliği tam sayıdır, 3 ile 5 arasında ara değer yoktur ve yaprak alt sınırı da öyle. Oysa modelin karmaşıklığı kesip atılmak yerine cezalandırılabilir. Hata ölçüsünün yanına modelin ne kadar iddialı olduğunu ölçen bir terim eklenir ve model, hatayı düşürmekle iddiasını düşürmek arasında bir anlaşmaya zorlanır. Ceza katsayısı sürekli bir sayıdır; iki tam sayı arasında istenildiği kadar durak vardır.
Bu ders o katsayıyı 0,001’den 1000’e çıkarır ve her adımda üç şeyi basar: ağırlıkların büyüklüğü, eğitim hatası ve ayrılmış küme hatası. Beklenen davranış tek yönlü değildir — eğitim hatası kesintisiz kötüleşir, ayrılmış küme hatası önce iyileşir sonra kötüleşir — ve en iyi noktanın hangi kümeden okunacağı dersin son sorusudur.
- GE23. Model doğrusaldır ve 29 sütunu vardır: beş bölge göstergesi, hane büyüklüğü, memnuniyet, dönem sayısı, bunların kareleri, ikişerli çarpımları ve her birinin bölgeyle çarpımı.
- GE24. Ceza karesel bir terimdir: hata ölçüsüne ağırlıkların kare toplamının katı eklenir. Sabit terim yerine hedeften eğitim ortalaması çıkarılır, böylece bütün ağırlıklar cezalanır ve ceza büyüdükçe model taban çizgisine yakınsar.
- GE25. Sütunlar eğitim kümesinin ortalaması ve saçılmasıyla ölçeklenir. Ceza ölçeğe duyarlıdır ve ölçeğin hangi kümeden hesaplandığı bir karardır.
- GE26. Eğitim kümesi bilerek 120 satıra düşürülür. Yirmi dokuz sütuna 120 satır, aşırı uyumu ölçülebilir kılan orandır.
- GE27. Doğrulama ve sınama kümeleri önceki derslerdeki 252’şer satırdır; tohum ve bölme aynıdır.
- GE28. Ölçü kök ortalama kare hatadır (m³); bileşenlere ayırma kare birimde yapılır.
- GE29. Taban çizgisi bütün ağırlıkların sıfır olduğu modeldir: her aboneye eğitim kümesinin ortalamasını söylemek.
- GE30. Sınama kümesine bu derste bir kez, seçim bittikten sonra bakılır.
Ceza İki Sayıyı Ters Yönde Oynatır
Kurulum kümeyi aynı tohumla üretir, doğrusal modeli kurar ve ceza katsayısını on bir adımda büyütür. Çözüm kapalı biçimdedir: kare hatanın en küçük olduğu ağırlıklar, köşegenine ceza eklenmiş bir denklem takımının çözümüdür.
# duzenlilestirme.py — MODELDIR. Ayni kurgu olcum agi, ayni tohum. Hedef abonenin # ortalama tuketimidir; model dogrusal, ceza karesel. import math TOHUM, HAM, M32 = 20260218, 1400, 0xFFFFFFFF BOLGE = [("kuzey", 0.28, 21), ("guney", 0.22, 17), ("dogu", 0.18, 26), ("bati", 0.14, 14), ("merkez", 0.18, 23)] 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 = [] 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}) VERI = [] 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 v: VERI.append({"no": k["no"], "bolge": k["bolge"][0], "hane": k["hane"], "memnuniyet": k["memnuniyet"], "donem": len(v), "hedef": round(sum(v) / len(v), 2)}) def sutunlar(x): t = [float(x["bolge"] == b[0]) for b in BOLGE] h, m, d = float(x["hane"]), float(x["memnuniyet"]), float(x["donem"]) return (t + [h, m, d, h * h, m * m, d * d, h * m, h * d, m * d] + [g * h for g in t] + [g * m for g in t] + [g * d for g in t]) 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[:120], K[756:1008], K[1008:] P = len(sutunlar(EGT[0])) HAM_EGT = [sutunlar(x) for x in EGT] ORTS = [sum(s[j] for s in HAM_EGT) / len(HAM_EGT) for j in range(P)] SAP = [max(1e-9, math.sqrt(sum((s[j] - ORTS[j]) ** 2 for s in HAM_EGT) / len(HAM_EGT))) for j in range(P)] ORT = sum(x["hedef"] for x in EGT) / len(EGT) def olcek(x): s = sutunlar(x) return [(s[j] - ORTS[j]) / SAP[j] for j in range(P)] def coz(A, b): n = len(b) for i in range(n): p = max(range(i, n), key=lambda k: abs(A[k][i])) A[i], A[p], b[i], b[p] = A[p], A[i], b[p], b[i] for k in range(i + 1, n): f = A[k][i] / A[i][i] for j in range(i, n): A[k][j] -= f * A[i][j] b[k] -= f * b[i] w = [0.0] * n for i in range(n - 1, -1, -1): w[i] = (b[i] - sum(A[i][j] * w[j] for j in range(i + 1, n))) / A[i][i] return w def egit(satirlar, ceza): X = [olcek(x) for x in satirlar] y = [x["hedef"] - ORT for x in satirlar] A = [[sum(X[i][a] * X[i][b] for i in range(len(X))) + (ceza if a == b else 0.0) for b in range(P)] for a in range(P)] return coz(A, [sum(X[i][a] * y[i] for i in range(len(X))) for a in range(P)]) def kok(w, s): return math.sqrt(sum((ORT + sum(a * b for a, b in zip(w, olcek(x))) - x["hedef"]) ** 2 for x in s) / len(s)) print(f"egitim {len(EGT)}, dogrulama {len(DOG)}, sinama {len(SIN)}, sutun {P}") print(f"taban: egitim {kok([0.0] * P, EGT):.3f} dogrulama {kok([0.0] * P, DOG):.3f} " f"sinama {kok([0.0] * P, SIN):.3f}") print(f"\n{'ceza':>8} {'agirlik':>9} {'egitimde':>9} {'dogrulama':>10} {'sinama':>8}") for c in (0.001, 0.01, 0.1, 0.3, 1, 3, 10, 30, 100, 300, 1000): w = egit(EGT, c) print(f"{c:>8} {math.sqrt(sum(v * v for v in w)):>9.3f} {kok(w, EGT):>9.3f} " f"{kok(w, DOG):>10.3f} {kok(w, SIN):>8.3f}")
egitim 120, dogrulama 252, sinama 252, sutun 29
taban: egitim 6.121 dogrulama 6.439 sinama 6.556
ceza agirlik egitimde dogrulama sinama
0.001 10.040 4.603 5.924 5.841
0.01 9.963 4.603 5.921 5.839
0.1 9.334 4.604 5.894 5.815
0.3 8.396 4.606 5.850 5.777
1 6.687 4.620 5.770 5.704
3 4.891 4.653 5.693 5.634
10 3.291 4.716 5.614 5.571
30 2.222 4.804 5.556 5.534
100 1.534 4.920 5.553 5.559
300 1.099 5.089 5.657 5.694
1000 0.601 5.453 5.932 6.008
Ağırlık sütunu cezanın ne yaptığını doğrudan gösteriyor: ağırlıkların büyüklüğü 10,040’tan 0,601’e, yani on altıda birine iniyor. Ceza modelin ağırlıklarını küçültmekten başka bir şey yapmıyor; sütunlara dokunmuyor, satır atmıyor, kural silmiyor.
Üçüncü sütun tek yönlüdür ve kötüleşiyor: eğitim hatası 4,603’ten 5,453 m³’e çıkıyor. Bu beklenendir, çünkü cezasız çözüm zaten eğitim kümesindeki kare hatayı en küçük yapan çözümdür; üzerine konan her ceza o sayıyı ancak bozar. Eğitim hatasının kötüleşmesi düzenlileştirmenin yan etkisi değil, çalıştığının kanıtıdır.
Dördüncü sütun iki yönlüdür: 5,924’ten 5,553’e iniyor, sonra 5,932’ye dönüyor. En düşük nokta ceza 100’dedir ve cezasız modele göre 0,371 m³ kazanç sağlıyor. İniş ile çıkış arasındaki mesafe dar değil: ceza 3 ile 300 arasındaki bütün değerler cezasız modelden iyidir, ama 1000’de model cezasız modelden de kötüdür.
Son satırın yönü dersin sezgisidir. Ceza büyüdükçe ağırlıklar sıfıra yaklaşır ve bütün ağırlıklar sıfır olduğunda model her aboneye eğitim ortalamasını söyler — yani taban çizgisinin kendisine dönüşür. Düzenlileştirme, modeli sürekli bir düğmeyle taban çizgisine doğru çeken bir kuvvettir. Ceza 1000’de ağırlık 0,601 ile hâlâ sıfır değildir ve doğrulama hatası 5,932 ile tabanın 6,439’unun altındadır; o düğme henüz sonuna kadar çevrilmemiştir.
Ağırlıkların kendisine bakınca cezanın neyi kovduğu görünür.
AD = ([b[0] for b in BOLGE] + ["hane", "memnuniyet", "donem", "hane^2", "memnuniyet^2", "donem^2", "hane*memnuniyet", "hane*donem", "memnuniyet*donem"] + [b[0] + "*hane" for b in BOLGE] + [b[0] + "*memnuniyet" for b in BOLGE] + [b[0] + "*donem" for b in BOLGE]) for c in (0.001, 100): w = egit(EGT, c) en = sorted(range(P), key=lambda j: -abs(w[j]))[:4] print(f"ceza {c}: en buyuk dort agirlik") for j in en: print(f" {AD[j]:<20} {w[j]:>8.3f}") t = sum(abs(w[j]) for j in range(P)) print(f" ilk dort agirligin toplam paydaki payi: " f"{sum(abs(w[j]) for j in en) / t:.3f}")
ceza 0.001: en buyuk dort agirlik
guney -4.138
donem 2.981
hane^2 2.965
hane -2.962
ilk dort agirligin toplam paydaki payi: 0.303
ceza 100: en buyuk dort agirlik
bati*donem -0.574
dogu*donem 0.553
bati -0.487
dogu 0.479
ilk dort agirligin toplam paydaki payi: 0.302
Cezasız çözümdeki hane ile hane^2 ağırlıkları -2,962 ve +2,965: neredeyse birbirini götürüyor.
İki sütun aynı bilginin iki biçimi olduğu için model ikisine büyük ve zıt ağırlıklar verebiliyor;
tahminler değişmiyor, ağırlıklar şişiyor. Ceza tam olarak bunu yasaklar. Ceza 100’de en büyük dört
ağırlık batı ve doğu bölgeleriyle bunların dönem sayısına bağlı terimleridir — kurgudaki gerçek
yapı budur, çünkü bölge taban tüketimini belirler.
Son satır cezanın nasıl çalıştığını söylüyor. İlk dört ağırlığın toplam ağırlık payındaki oranı iki cezada da aynı: 0,303 ve 0,302. Karesel ceza sütun elemiyor, hiçbirini sıfırlamıyor, dağılımın biçimini değiştirmiyor; hepsini birlikte küçültüyor. Kapasite kısmakla arasındaki fark budur — ağaç budaması bir kuralı siler, ceza bütün kuralları aynı oranda yumuşatır.
Ceza Hatanın Hangi Bileşenini Küçültüyor
Önceki dersin ayrıştırması aynen uygulanabilir. Ceza kapasiteyi kısan bir düğmeyse, hatanın değişkenlik bileşenini düşürüp yanlılık bileşenini yükseltmesi gerekir.
B = 30 ORNEK = [] for b in range(B): r = uretec(TOHUM + 61000 + b * 13) ORNEK.append([EGT[int(r() * len(EGT))] for _ in range(len(EGT))]) print(f"{B} geri koyarak ornek, her biri {len(EGT)} satir") print(f"\n{'ceza':>8} {'toplam':>9} {'degisken':>9} {'yanlilik':>9}") for c in (0.001, 1, 30, 100, 1000): T = [] for o in ORNEK: w = egit(o, c) T.append([ORT + sum(a * b for a, b in zip(w, olcek(x))) for x in DOG]) top = deg = yan = 0.0 for i, x in enumerate(DOG): p = [T[b][i] for b in range(B)] m = sum(p) / B top += sum((q - x["hedef"]) ** 2 for q in p) / B deg += sum((q - m) ** 2 for q in p) / B yan += (m - x["hedef"]) ** 2 n = len(DOG) print(f"{c:>8} {top / n:>9.3f} {deg / n:>9.3f} {yan / n:>9.3f}")
30 geri koyarak ornek, her biri 120 satir
ceza toplam degisken yanlilik
0.001 47.027 12.988 34.039
1 38.330 5.133 33.196
30 32.689 1.622 31.066
100 32.075 1.098 30.976
1000 35.476 0.181 35.295
Değişkenlik sütunu cezanın asıl hedefidir: 12,988’den 0,181’e, yani yetmiş ikide birine iniyor. Ceza katsayısı büyüdükçe hangi 120 satırın çekildiği modelin verdiği yanıtı daha az etkiliyor. Ceza 1000’de otuz model neredeyse aynı şeyi söylüyor, çünkü hepsi taban çizgisine yakın duruyor.
Yanlılık sütunu iki bölgeye ayrılıyor. Cezasız uçtaki 34,039 sayısı beklenenden yüksektir: 120 satıra 29 sütun düşen bir denklem takımı neredeyse tekildir ve çözüm o kadar oynaktır ki otuz modelin ortalaması bile bozulur. Ceza 100’e kadar bu sütun 30,976’ya iniyor. Sonra 35,295’e fırlıyor: orada ceza artık yalnız gürültüyü değil, kümedeki gerçek bölge yapısını da siliyor.
Toplam sütununun en küçük olduğu nokta ceza 100’dür ve bu, önceki tablodaki doğrulama sütununun en küçük olduğu noktayla aynıdır. İki bağımsız ölçüm — biri tek bir bölmede kök hata, öbürü otuz örneklemde bileşen ayrıştırması — aynı katsayıyı gösteriyor.
En İyi Nokta Hangi Kümeden Okunur
Ceza 100 tablodan okundu, ama hangi tablodan okunduğu kursun birinci dersinin sorusudur.
CEZA = [0.001, 0.01, 0.1, 0.3, 1, 3, 10, 30, 100, 300, 1000] SKOR = [(c, kok(egit(EGT, c), DOG), kok(egit(EGT, c), SIN)) for c in CEZA] d = min(SKOR, key=lambda t: t[1]) s = min(SKOR, key=lambda t: t[2]) print(f"dogrulamadan okunan en iyi ceza {d[0]}: dogrulama {d[1]:.3f}, sinama {d[2]:.3f}") print(f"sinamadan okunsaydi en iyi ceza {s[0]}: dogrulama {s[1]:.3f}, sinama {s[2]:.3f}") print(f"secim sinamada yapilsaydi rapor edilecek sayi {s[2]:.3f}, " f"durustu {d[2]:.3f}, fark {d[2] - s[2]:.3f} m3") print(f"\nsinama kumesinde: taban {kok([0.0] * P, SIN):.3f}, cezasiz " f"{kok(egit(EGT, 0.001), SIN):.3f}, secilen {d[2]:.3f}") print(f"cezanin kattigi {kok(egit(EGT, 0.001), SIN) - d[2]:.3f} m3, " f"modelin tabana gore kattigi {kok([0.0] * P, SIN) - d[2]:.3f} m3")
dogrulamadan okunan en iyi ceza 100: dogrulama 5.553, sinama 5.559 sinamadan okunsaydi en iyi ceza 30: dogrulama 5.556, sinama 5.534 secim sinamada yapilsaydi rapor edilecek sayi 5.534, durustu 5.559, fark 0.025 m3 sinama kumesinde: taban 6.556, cezasiz 5.841, secilen 5.559 cezanin kattigi 0.282 m3, modelin tabana gore kattigi 0.997 m3
İki küme iki ayrı katsayı seçiyor: doğrulama 100, sınama 30. İkisinin de savunulabilir olması işin özüdür — aradaki fark gerçek bir kalite farkı değil, 252 satırlık iki kümenin kendi saçılmasıdır. Ama seçim sınama kümesinde yapılsaydı raporlanacak sayı 5,534 olurdu; dürüst sayı 5,559’dur. Fark 0,025 m³ ile küçüktür ve işareti sabittir: seçim yapılan kümedeki sayı hiçbir zaman daha kötü çıkamaz. Burada on bir aday vardı; birinci derste 48 aday farkı 2 puana çıkarmıştı. Seçim payı aday sayısıyla büyür, ama sıfır adayla bile sıfır olmaz.
Son iki satır dersin hesabını kapatıyor. Sınama kümesinde taban 6,556 m³, cezasız doğrusal model 5,841 m³, düzenlileştirilmiş model 5,559 m³. Modelin tabana göre kazancı 0,997 m³, yani yüzde 15,2. Bunun 0,282 m³’ü, yani yüzde 28,3’ü yalnız ceza katsayısından geliyor. Düzenlileştirme yeni bir öznitelik eklemedi, yeni bir kural öğretmedi; öğrenilmiş olanın ne kadarının tutulacağını seçti ve kazancın dörtte birinden fazlasını oradan çıkardı.
Özet
- Ceza katsayısı 0,001’den 1000’e çıkarıldığında ağırlık büyüklüğü 10,040’tan 0,601’e iniyor; eğitim hatası 4,603’ten 5,453 m³’e kesintisiz kötüleşiyor ve bu, cezanın çalıştığının kanıtıdır.
- Ayrılmış küme hatası 5,924’ten 5,553’e inip 5,932’ye dönüyor; en düşük nokta ceza 100’dedir ve ceza sonsuza götürülseydi model taban çizgisinin kendisine dönüşürdü.
- Ayrıştırma cezanın hedefini gösteriyor: değişkenlik 12,988’den 0,181’e iniyor, yanlılık ise 30,976’da tabana vurup ceza 1000’de 35,295’e fırlıyor; orada ceza gerçek bölge yapısını siliyor.
- Doğrulama kümesinden okunan en iyi ceza 100, sınama kümesinden okunsaydı 30 olurdu; sınamadan seçmek raporlanan sayıyı 5,559’dan 5,534’e indirirdi ve bu farkın işareti hiçbir zaman ters dönmez.
- Sınama kümesinde taban 6,556, cezasız model 5,841, düzenlileştirilmiş model 5,559 m³; modelin tabana göre kazancı 0,997 m³ ve bunun yüzde 28,3’ü yalnız ceza katsayısından gelir.
Sonraki Adım
Dört derste ayrım kuruldu ve her sayının yanına tabanı yazıldı. Bu dersin kurulumunda sessizce doğru yapılmış bir karar var: sütunların ölçeği yalnız eğitim kümesinden hesaplandı. Karar tersine çevrilebilir ve çevrildiğinde ayrılmış küme sayısı iyileşir — hem de model hiçbir şey öğrenmeden. Sonraki ders bu türden dört bozulmayı tek tek uygular ve her birinin ayrılmış küme sayısını ne kadar şişirdiğini basar. Kursun kapanışı da oradadır.
İlerlemeni kaydetmek ve not almak için Giriş yap
Notlarım
Not almak için giriş yapmalısın.