Ders 08 / 11
Aşırı ve Eksik Uyum
Kapasite adım adım artırılırken eğitim ve ayrılmış küme sayılarının ayrışmasının ölçülmesi: karar ağacının derinliği 1'den 14'e çıkarken eğitim doğruluğu 0,7778'den 0,9352'ye yükselir, ayrılmış küme doğruluğu 0,8214'te tepe yapıp 0,7302'ye iner ve iki sayı arasındaki fark -0,0357'den +0,2050'ye açılır. On bir kapasitenin yalnız üçü ayrılmış kümede 0,8135'lik tabanı tutturabiliyor. Eğitim kümesi 100'den 756 satıra çıkarıldığında fark 0,2219'dan 0,1680'e iner, yaprak alt sınırı 2'den 80'e çıkarıldığında 0,1680'den -0,0198'e iner ve model tam olarak taban çizgisine dönüşür.
İçindekiler
Önceki ders bir karar ağacını üç kümede ölçtü ve üç sayı buldu, ama ağacın derinliğini gerekçesiz seçti. Derinlik 6 bir tercih değil bir boşluktu. Derinlik ağacın kapasitesidir: kaç ayrı kural öğrenebileceğini, kümeyi kaç parçaya bölebileceğini belirler. Kapasite tek başına iyi ya da kötü değildir; iki sayıyı birden oynatır ve ters yönlerde oynatır.
Bu ders kapasiteyi 1’den 14’e çıkarır, her adımda eğitim ve ayrılmış küme sayısını yan yana basar ve ikisinin ayrıştığı noktayı yazar. Ayrışmanın iki ucu iki ayrı bozulmadır: kapasite yetmediğinde eksik uyum, kapasite fazla geldiğinde aşırı uyum. Sınama kümesine bu derste hiç bakılmayacak; ayrılmış küme olarak doğrulama kümesi kullanılır.
- GE9. Küme, etiket ve bölme önceki dersten aynen sürer: 1.260 abone, 756 eğitim, 252 doğrulama, 252 sınama, tohum 20260218. Etiket kurgudur.
- GE10. Kapasitenin ölçüsü iki sayıdır: ağacın derinliği ve yaprak sayısı. Yaprak sayısı, modelin kümeyi kaç ayrı bölgeye ayırdığını verir.
- GE11. Taban çizgisi tek yapraklı bir ağaçtır: hiç bölmeyen, herkese eğitim kümesinin en sık sınıfını söyleyen yordam. Kapasite dizisinin sıfırıncı adımıdır.
- GE12. Ayrılmış küme doğrulama kümesidir. Sınama kümesi bu derste açılmaz; önceki dersin kuralı gereği ona kapanışta bir kez bakılır.
- GE13. Yaprak alt sınırı ikinci bir kapasite düğmesidir: bir yaprağın altına düşebilecek en az gözlem sayısı. Varsayılan 2’dir.
- GE14. Öğrenme eğrisi çizilmez, sayı olarak basılır: eğitim kümesi büyütülürken iki sayının aldığı değerler tablodur.
- GE15. Ayrılmış küme 252 satırlıktır; bir abone 0,0040 doğruluk eder. İki puanın altındaki farklar bu yüzden bir sıralama kanıtı sayılmaz.
Kapasite Arttıkça İki Sayı Ayrışır
Kurulum önceki dersle aynıdır ve aynı tohumla aynı kümeyi üretir. Üzerine tek bir ekleme yapılır: yaprak sayacı.
# genelleme.py — MODELDIR. M26'nin kurgu olcum agi ayni tohumla uretilir; okumalar # abone duzeyinde ozetlenir ve uzerine KURGU bir kacak/ariza suphesi etiketi eklenir. import math 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 = [] 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}) OKUMA = {} for k in ABONE: r = uretec(TOHUM + 7000 + k["no"]) for d in range(ayrik(r(), [0.05, 0.12, 0.21, 0.62])): OKUMA.setdefault(k["no"], []).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() VERI = [] for k in ABONE: v = OKUMA.get(k["no"]) if v is None: 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 = {"no": k["no"], "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)} for b in BOLGE: x["b_" + b[0]] = int(k["bolge"][0] == b[0]) VERI.append(x) ALAN = ["ort_tuketim", "oynaklik", "hane", "memnuniyet", "donem", "sifir_okuma", "b_kuzey", "b_guney", "b_dogu", "b_bati", "b_merkez"] 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:] def gini(s): p = sum(x["supheli"] for x in s) / len(s) if s else 0.0 return 2 * p * (1 - p) def agac(s, derinlik, enaz=2): p = sum(x["supheli"] for x in s) / len(s) en = None if derinlik and len(s) >= 2 * enaz and 0.0 < p < 1.0: 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 = gini(s) - (len(sol) * gini(sol) + len(sag) * gini(sag)) / len(s) if en is None or k > en[0]: en = (k, a, v, sol, sag) if en is None or en[0] <= 1e-9: return {"tahmin": int(p > 0.5)} return {"alan": en[1], "esik": en[2], "sol": agac(en[3], derinlik - 1, enaz), "sag": agac(en[4], derinlik - 1, enaz)} def tahmin(d, x): while "tahmin" not in d: d = d["sol"] if x[d["alan"]] < d["esik"] else d["sag"] return d["tahmin"] def dogruluk(d, s): return sum(tahmin(d, x) == x["supheli"] for x in s) / len(s) def taban(egt, s): c = int(sum(x["supheli"] for x in egt) * 2 > len(egt)) return sum(x["supheli"] == c for x in s) / len(s) def yaprak(d): return 1 if "tahmin" in d else yaprak(d["sol"]) + yaprak(d["sag"]) print(f"{'kapasite':>10} {'yaprak':>7} {'egitim':>8} {'ayrilmis':>9} {'fark':>8}") print(f"{'taban':>10} {1:>7} {taban(EGT, EGT):>8.4f} {taban(EGT, DOG):>9.4f} " f"{taban(EGT, EGT) - taban(EGT, DOG):>+8.4f}") for dr in (1, 2, 3, 4, 5, 6, 7, 8, 10, 12, 14): m = agac(EGT, dr) e, a = dogruluk(m, EGT), dogruluk(m, DOG) print(f"{'derinlik ' + str(dr):>10} {yaprak(m):>7} {e:>8.4f} {a:>9.4f} {e - a:>+8.4f}")
kapasite yaprak egitim ayrilmis fark
taban 1 0.7778 0.8135 -0.0357
derinlik 1 2 0.7778 0.8135 -0.0357
derinlik 2 4 0.8016 0.8214 -0.0198
derinlik 3 8 0.8135 0.8135 +0.0000
derinlik 4 16 0.8201 0.8175 +0.0026
derinlik 5 30 0.8360 0.8095 +0.0265
derinlik 6 46 0.8466 0.7897 +0.0569
derinlik 7 64 0.8611 0.7698 +0.0913
derinlik 8 81 0.8770 0.7778 +0.0992
derinlik 10 112 0.9061 0.7698 +0.1362
derinlik 12 133 0.9299 0.7619 +0.1680
derinlik 14 139 0.9352 0.7302 +0.2050
Üçüncü sütun tek yönlüdür: kapasite arttıkça eğitim doğruluğu 0,7778’den 0,9352’ye kesintisiz yükseliyor. Bu sütun bir başarı ölçüsü değil, bir kapasite ölçüsüdür — modele daha çok bölme izni verildikçe gördüğü veriyi daha çok ezberler ve sütun her koşulda yükselir.
Dördüncü sütun iki yönlüdür. Ayrılmış küme doğruluğu derinlik 2’de 0,8214 ile tepe yapıyor, sonra düşmeye başlıyor ve derinlik 14’te 0,7302’ye iniyor. Beşinci sütun ikisinin farkıdır ve ayrışmanın nerede başladığını verir: fark derinlik 3’te sıfırı geçiyor, derinlik 5’ten sonra hiç geri dönmeden büyüyor ve derinlik 14’te 0,2050’ye ulaşıyor. Ayrışmanın başladığı nokta derinlik 4 ile 5 arasındadır: dördüncü adımda fark hâlâ 0,0026 iken beşincide 0,0265’e, altıncıda 0,0569’a çıkıyor.
Taban çizgisiyle birlikte okununca tablo daha sert bir şey söylüyor. Ayrılmış kümede taban 0,8135. On bir kapasitenin yalnız üçü — derinlik 2, 3 ve 4 — bu sayıya erişiyor ya da onu geçiyor, ve en iyisi tabanı 0,0079 geçiyor. Derinlik 5’ten itibaren her model tabanın altındadır, üstelik eğitim sütunu hâlâ yükselmektedir. Derinlik 14’te modelin eğitim kümesinde 0,9352 okuduğu anda ayrılmış kümede “hiçbiri şüpheli değil” demekten 8,3 puan kötüdür.
Yaprak sütunu ezberin nasıl büyüdüğünü gösteriyor. Derinlik 14’te ağacın 139 yaprağı var ve eğitim kümesi 756 satır: yaprak başına ortalama 5,4 abone. Beş aboneye bakarak kurulmuş bir kural, o beş aboneyi doğru sınıflandırır ve başka hiçbir şey hakkında bir şey söylemez.
Ağacın Kurduğu Kural
Ayrışmanın nereden geldiği, modelin ne öğrendiğine bakınca görünür. Aşağıdaki kod tepedeki ağacın kurallarını açıkça yazıyor ve dipteki ağacın yapraklarının kaç aboneye baktığını sayıyor.
def kurallar(d, s, yol=""): if "tahmin" in d: print(f" {yol or '(bolme yok)':<44} {len(s):>4} abone -> {d['tahmin']}") return a, v = d["alan"], d["esik"] kurallar(d["sol"], [x for x in s if x[a] < v], f"{yol}{a} < {v} ") kurallar(d["sag"], [x for x in s if x[a] >= v], f"{yol}{a} >= {v} ") print("derinlik 2 agacinin kurallari") kurallar(agac(EGT, 2), EGT) def boyutlar(d, s, c): if "tahmin" in d: c.append(len(s)) return a, v = d["alan"], d["esik"] boyutlar(d["sol"], [x for x in s if x[a] < v], c) boyutlar(d["sag"], [x for x in s if x[a] >= v], c) c = [] boyutlar(agac(EGT, 14), EGT, c) c.sort() print(f"\nderinlik 14: {len(c)} yaprak, en kucuk {c[0]}, ortanca {c[len(c) // 2]}, " f"en buyuk {c[-1]} abone") print(f"5 aboneden az gorup kural kuran yaprak: {sum(1 for n in c if n < 5)}") print(f"bu yapraklarin kapsadigi egitim abonesi: {sum(n for n in c if n < 5)}")
derinlik 2 agacinin kurallari oynaklik < 11.69 ort_tuketim < 18.54 262 abone -> 0 oynaklik < 11.69 ort_tuketim >= 18.54 249 abone -> 0 oynaklik >= 11.69 b_dogu < 1 185 abone -> 0 oynaklik >= 11.69 b_dogu >= 1 60 abone -> 1 derinlik 14: 139 yaprak, en kucuk 2, ortanca 3, en buyuk 141 abone 5 aboneden az gorup kural kuran yaprak: 112 bu yapraklarin kapsadigi egitim abonesi: 300
Tepedeki ağacın dört yaprağından üçü taban çizgisiyle aynı şeyi söylüyor. Modelin tabandan ayrıldığı tek yer, oynaklığı 11,69 m³’ün üstünde olan doğu abonelerinden oluşan 60 satırlık yapraktır. Ayrılmış kümedeki 0,0079’luk kazancın tamamı bu tek kuraldan geliyor. Bir modelin tabanı geçmesi, çoğu zaman tabanı her yerde geçmesi değil, tabanın yanıldığı dar bir bölgeyi bulmasıdır.
Dipteki ağaç bunun tersidir. Yüz otuz dokuz yaprağın ortancası üç aboneye bakıyor, 112 yaprak beşten az abone görmüş ve bu yapraklar eğitim kümesinin 300 satırını, yani yüzde 40’ını kapsıyor. Eğitim sütunundaki 0,9352’nin büyük bölümü, üç aboneden çıkarılmış kurallarla o üç aboneyi doğru bilmekten ibarettir. Ayrılmış kümede bu kuralların karşılığı yoktur.
İki Bozulmanın İmzaları Ayrıdır
Tablonun iki ucu iki ayrı bozulmadır ve belirtileri karışmaz.
Eksik uyum üstteki satırlardadır. Derinlik 1 ağacı iki yaprak kuruyor, ama iki yaprak da aynı sınıfı söylüyor: ağaç bölünmüş, model bölünmemiştir. Sayıları taban çizgisiyle birebir aynıdır (0,7778 ve 0,8135). İmzası şudur: eğitim sayısı kendi tabanına yapışıktır. Model gördüğü veriyi bile açıklayamıyorsa görmediğini hiç açıklayamaz, ve bunu anlamak için ayrılmış kümeye bakmak bile gerekmez.
Aşırı uyum alttaki satırlardadır. İmzası iki sayının birden okunmasını gerektirir: eğitim sayısı yüksek, ayrılmış küme sayısı düşük, fark büyük. Tek başına 0,9352 hiçbir şey söylemez — ne iyidir ne kötüdür, çünkü hangi kapasiteyle üretildiği yazılmadıkça yorumlanamaz.
Farkın işareti tek başına da yetmez. Derinlik 1’de fark -0,0357 ile “güvenli” görünüyor, oysa o satır modelin hiçbir şey öğrenmediği satırdır. Negatif fark iyi haber değil, çoğu zaman eksik uyum haberidir. Üç sayı birlikte okunur: taban, eğitim, ayrılmış küme.
Düzeltmenin Ölçüsü
Aşırı uyumun iki bilinen düzeltmesi var: eğitim kümesini büyütmek ve kapasiteyi kısmak. İkisi de ölçülebilir. Aşağıdaki kod derinliği 12’de sabitleyip önce eğitim kümesini, sonra yaprak alt sınırını değiştiriyor.
print("egitim kumesi buyutulur, kapasite sabit (derinlik 12)") print(f"{'egitim satiri':>13} {'yaprak':>7} {'egitim':>8} {'ayrilmis':>9} {'fark':>8}") for n in (100, 200, 400, 756): m = agac(EGT[:n], 12) e, a = dogruluk(m, EGT[:n]), dogruluk(m, DOG) print(f"{n:>13} {yaprak(m):>7} {e:>8.4f} {a:>9.4f} {e - a:>+8.4f}") print("\nkapasite kisilir, egitim kumesi sabit (derinlik 12, yaprak alt siniri)") print(f"{'yaprak enaz':>13} {'yaprak':>7} {'egitim':>8} {'ayrilmis':>9} {'fark':>8}") for z in (2, 5, 10, 20, 40, 80): m = agac(EGT, 12, z) e, a = dogruluk(m, EGT), dogruluk(m, DOG) print(f"{z:>13} {yaprak(m):>7} {e:>8.4f} {a:>9.4f} {e - a:>+8.4f}")
egitim kumesi buyutulur, kapasite sabit (derinlik 12)
egitim satiri yaprak egitim ayrilmis fark
100 15 0.9600 0.7381 +0.2219
200 34 0.9500 0.7500 +0.2000
400 68 0.9450 0.7659 +0.1791
756 133 0.9299 0.7619 +0.1680
kapasite kisilir, egitim kumesi sabit (derinlik 12, yaprak alt siniri)
yaprak enaz yaprak egitim ayrilmis fark
2 133 0.9299 0.7619 +0.1680
5 81 0.8624 0.7540 +0.1085
10 44 0.8307 0.7937 +0.0370
20 23 0.8148 0.7500 +0.0648
40 13 0.8042 0.7897 +0.0146
80 7 0.7937 0.8135 -0.0198
Birinci tablo öğrenme eğrisidir ve yönü doğru, gücü sınırlıdır. Eğitim kümesi 100’den 756 satıra, yani 7,6 katına çıkarıldığında fark 0,2219’dan 0,1680’e iniyor: başlangıçtaki açıklığın yalnız dörtte biri kapanmış. Ayrılmış küme sayısı 0,7381’den 0,7619’a yükseliyor ama 0,8135’lik tabanın hâlâ 5,2 puan altında. Veri eklemek, fazla seçilmiş bir kapasitenin borcunun bir kısmını öder, tamamını ödemez. Aynı eğrinin ikinci okuması eğitim sütunudur: 0,9600’den 0,9299’a düşüyor, çünkü aynı kapasiteyle daha çok satır ezberlemek daha zordur.
İkinci tablo doğrudan kapasiteye dokunuyor ve iki ucu nettir. Yaprak alt sınırı 2’den 80’e çıkarıldığında yaprak sayısı 133’ten 7’ye, fark 0,1680’den -0,0198’e iniyor. Son satır dikkat çekicidir: kapasite yeterince kısıldığında model ayrılmış kümede tam olarak 0,8135 okuyor, yani taban çizgisinin kendisine dönüşüyor. Aşırı uyumu düzeltmek için kapasiteyi kısmak, yeterince ileri götürüldüğünde eksik uyuma çıkar. İki bozulma kullanılabilir bölgeyi iki yandan sınırlar.
Aradaki satırlar dikkatle okunur. Ayrılmış küme sütunu 0,7937’den 0,7500’e inip 0,7897’ye dönüyor; bu 11 ve 10 abonelik oynamalardır ve M26/K05’te ölçülen oynama payının içinde kalır. Bu sütunun ortasındaki sıralamayı bir kapasite kanıtı saymak, bir kez daha, seçilmiş bir sayıyı başarım sanmak olur. Güvenilir okuma iki uçtadır ve fark sütunundadır.
Özet
- Kapasite arttıkça eğitim doğruluğu tek yönlü yükseliyor (0,7778’den 0,9352’ye), ayrılmış küme doğruluğu derinlik 2’de 0,8214 ile tepe yapıp 0,7302’ye iniyor; iki sayının farkı -0,0357’den +0,2050’ye açılıyor ve ayrışma derinlik 4 ile 5 arasında başlıyor.
- On bir kapasiteden yalnız üçü ayrılmış kümede 0,8135’lik tabanı tutturuyor; derinlik 5’ten sonra her model tabanın altındadır, üstelik eğitim sütunu yükselmeye devam etmektedir.
- Eksik uyumun imzası eğitim sayısının kendi tabanına yapışık olmasıdır ve ayrılmış kümeye bakmadan görülür; aşırı uyumun imzası ancak iki sayı birlikte okununca görünür.
- Eğitim kümesini 7,6 katına çıkarmak farkı 0,2219’dan 0,1680’e indiriyor, yani açıklığın dörtte birini kapatıyor; veri eklemek fazla seçilmiş kapasitenin borcunun tamamını ödemez.
- Yaprak alt sınırını 2’den 80’e çıkarmak yaprak sayısını 133’ten 7’ye, farkı -0,0198’e indiriyor ve model ayrılmış kümede tam olarak taban çizgisine dönüşüyor: aşırı uyumun düzeltmesi yeterince ileri gidince eksik uyuma çıkar.
Sonraki Adım
Bu derste fark tek bir eğitim kümesi üzerinde ölçüldü. Oysa 756 satırlık o küme, 1.260 abone arasından çekilmiş bir örneklemdir; başka bir çekimde başka bir ağaç kurulurdu. Aşırı uyumun altında bu yatıyor: yüksek kapasiteli bir yordamın ürettiği model, eğitim örneklemi değiştiğinde çok oynar; düşük kapasiteli bir yordam ise hep aynı yerde durur ama hep aynı yerde yanılır. Sonraki ders hatayı bu iki bileşene ayırır — sistemli olarak sapma ile örneklemden örnekleme oynama — ve geri koyarak örneklemeyle birden çok eğitim kümesi kurup her ikisini ayrı ayrı sayar.
İlerlemeni kaydetmek ve not almak için Giriş yap
Notlarım
Not almak için giriş yapmalısın.