Ders 19 / 20
Ayar Değişkeni Araması
Kursun kuralının ödendiği ders: aynı 50 adaylık bütçeyle ızgara, rastgele ve model temelli aramanın bulduğu en iyi aday ve o adayın sınama kümesindeki sayısı yan yana basılır. Aday sayısı 1'den 200'e çıkarken doğrulama kümesindeki en iyi sayı 0,7937'den 0,8452'ye tırmanıyor, aynı adayın sınama kümesindeki sayısı 0,7778'den 0,7976'ya gidiyor ve aradaki şişme +0,0159'dan +0,0476'ya açılıyor. Ayarsız varsayılan aday doğrulama kümesinde zaten 0,8452 veriyor, yani 200 aday hiçbir şey bulmadı. Bütçe 50 ve 200'de tek bölmeli karar kuralı doğrusal modeli sınama kümesinde geçiyor: aile farkı −0,0159 ve −0,0040 iken bütçenin şişirdiği fark +0,0516 ve +0,0476.
İçindekiler
Önceki ders tek bir modeli ölçtü ve denenen aday sayısı birdi. Kursun kuralı ise şudur: bir modelin sayısı, o sayıyı bulmak için kaç aday denendiği yazılmadan okunamaz; ayar bütçesi yazılmayan sayı ölçülmemiş sayılır. Bu ders o kuralın ödendiği yerdir.
Ölçü iki parçalıdır. Birincisi aramanın kendisidir: aynı uzay ve aynı bütçe verildiğinde üç yordam — ızgara, rastgele ve model temelli — hangi adayı buluyor. İkincisi bütçenin şişirdiğidir: aday sayısı 1’den 200’e çıkarken doğrulamadaki en iyi sayı ile o adayın sınama sayısı arasında ne açılıyor. Bu şişme sonunda aile değiştirmenin kattığı farkla yan yana konur.
- MD50. Ayar uzayı dört eksenlidir: ceza katsayısı (–, log ölçekte sürekli), karar eşiği (0,20–0,60 sürekli), polinom derecesi (1 ya da 2) ve sabit bir sıralamadan alınan sütun sayısı (3, 6 ya da 9). Üç arama da aynı uzayda çalışır.
- MD51. Aday seçimi yalnız doğrulama kümesinden okunur (252 satır); sınama kümesi hiçbir seçime girmez ve yalnız seçilmiş adayın sayısını bildirmek için okunur.
- MD52. Bütçe birimi eğitilen ve doğrulama kümesinde ölçülen aday sayısıdır; model temelli aramanın vekil model üzerinde denediği öneriler eğitim gerektirmez ve sayılmaz. Izgara arama ayrık eksenlerin çarpımı (2 derece × 3 sütun = 6) bütçeyi böldüğü için verilen bütçeyi tam dolduramaz.
- MD53. Model temelli arama, denenmiş adayların doğrulama sayılarından bir vekil model kurar: uzaklık ağırlıklı ortalama artı en yakın denenmiş adaya uzaklıkla orantılı bir keşif payı. Bu da bir modeldir.
- MD54. İkinci aile tek bölmeli karar kuralıdır: bir sütun, bir eşik, bir yön. Doğrusal modelden yapıca daha zayıftır ve aynı bütçeyle aranır.
- MD55. Taban çizgisi K01’den sürer: en sık sınıfı söyleyen yordam, sınama kümesinde 0,7579. Aday sayısı ders sonunda basılır ve yinelenen adaylar bir kez sayılır.
Aynı Uzay, Aynı Bütçe, Üç Arama
# ORTAK — MODELDIR. M27/K01'in KURGU abone tablosu ayni tohumla yeniden uretilir; # model, 0/1 etikete en kucuk karelerle uydurulan dogrusal bir siniflandiricidir. 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, 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 = {"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), "bolge_ad": k["bolge"][0]} 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:] SIRA = ["ort_tuketim", "sifir_okuma", "oynaklik", "hane", "memnuniyet", "donem", "b_dogu", "b_bati", "b_guney"] KARE = {"ort_tuketim", "oynaklik", "hane", "memnuniyet", "donem"} SUTUN = (3, 6, 9) def alanlar(j, derece): a = SIRA[:j] return a + ([q + "^2" for q in a if q in KARE] if derece == 2 else []) def deger(x, ad): return float(x[ad[:-2]]) ** 2 if ad.endswith("^2") else float(x[ad]) def coz(A, b): n = len(A) M = [list(A[i]) + [b[i]] for i in range(n)] for i in range(n): p = max(range(i, n), key=lambda r: abs(M[r][i])) M[i], M[p] = M[p], M[i] for r in range(n): if r != i: f = M[r][i] / M[i][i] for c in range(i, n + 1): M[r][c] -= f * M[i][c] return [M[i][n] / M[i][i] for i in range(n)] def ogren(s, alan, ceza): d = len(alan) + 1 A = [[0.0] * d for _ in range(d)] b = [0.0] * d for x in s: v = [1.0] + [deger(x, a) for a in alan] for i in range(d): b[i] += v[i] * x["supheli"] for j in range(i, d): A[i][j] += v[i] * v[j] for i in range(d): for j in range(i): A[i][j] = A[j][i] if i: A[i][i] += ceza return coz(A, b) def dogruluk(w, alan, esik, s): d = 0 for x in s: p = w[0] + sum(w[i + 1] * deger(x, a) for i, a in enumerate(alan)) d += (1 if p >= esik else 0) == x["supheli"] return d / len(s) ONBELLEK, DENENEN = {}, set() def olc(aday): ceza, esik, derece, j = aday k = (round(ceza, 9), derece, j) if k not in ONBELLEK: ONBELLEK[k] = (ogren(EGT, alanlar(j, derece), ceza), alanlar(j, derece)) DENENEN.add(("dogrusal", k, round(esik, 9))) w, alan = ONBELLEK[k] return dogruluk(w, alan, esik, DOG), dogruluk(w, alan, esik, SIN) def en_iyi(adaylar, olcum): e = None for a in adaylar: d, s = olcum(a) if e is None or d > e[0]: e = (d, s, a) return e c = int(sum(x["supheli"] for x in EGT) * 2 > len(EGT)) TABAN = sum(x["supheli"] == c for x in SIN) / len(SIN) VD, VS = olc((1.0, 0.5, 1, 9)) print(f"taban cizgisi {TABAN:.4f}") print(f"ayarsiz varsayilan aday: dogrulama {VD:.4f}, sinama {VS:.4f}")
taban cizgisi 0.7579 ayarsiz varsayilan aday: dogrulama 0.8452, sinama 0.7976
Ayarsız varsayılan aday — ceza 1, eşik 0,5, derece 1, dokuz sütun — doğrulama kümesinde 0,8452 veriyor. Aşağıdaki üç arama ve 200 adaylık süpürme bu sayıyı geçmeye çalışacak.
def rastgele_aday(r): return (10 ** (-3 + 6 * r()), 0.20 + 0.40 * r(), 1 + int(r() * 2), SUTUN[int(r() * 3)]) def izgara(butce): en = (1, 1) for nc in range(1, butce + 1): for ne in range(1, butce + 1): if nc * ne * 6 <= butce and (nc * ne, -abs(nc - ne), nc) > \ (en[0] * en[1], -abs(en[0] - en[1]), en[0]): en = (nc, ne) nc, ne = en return [(10 ** (-3 + 6 * (i + 0.5) / nc), 0.20 + 0.40 * (t + 0.5) / ne, derece, j) for i in range(nc) for t in range(ne) for derece in (1, 2) for j in SUTUN] def rastgele(butce, tohum=TOHUM + 4100): r = uretec(tohum) return [rastgele_aday(r) for _ in range(butce)] def uzaklik(a, b): return (((math.log10(a[0]) - math.log10(b[0])) / 6) ** 2 + ((a[1] - b[1]) / 0.4) ** 2 + (a[2] - b[2]) ** 2 + ((a[3] - b[3]) / 6) ** 2) def model_temelli(butce, tohum=TOHUM + 4200, ilk=8, oneri=40): r, gecmis = uretec(tohum), [] for _ in range(min(ilk, butce)): a = rastgele_aday(r) gecmis.append((a, olc(a)[0])) while len(gecmis) < butce: en, ena = None, None for _ in range(oneri): a = rastgele_aday(r) w = [1.0 / (uzaklik(a, g) + 0.01) for g, _ in gecmis] t = (sum(q * s for q, (_, s) in zip(w, gecmis)) / sum(w) + 0.02 * min(uzaklik(a, g) for g, _ in gecmis) ** 0.5) if en is None or t > en: en, ena = t, a gecmis.append((ena, olc(ena)[0])) return [g for g, _ in gecmis] print(f"{'arama':<16} {'aday':>5} {'dogrulama':>10} {'sinama':>8} {'sisme':>8} ayar") for ad, fn in (("izgara", izgara), ("rastgele", rastgele), ("model temelli", model_temelli)): A = fn(50) d, s, a = en_iyi(A, olc) print(f"{ad:<16} {len(A):>5} {d:>10.4f} {s:>8.4f} {d - s:>+8.4f} " f"ceza {a[0]:.3g}, esik {a[1]:.3f}, derece {a[2]}, sutun {a[3]}") print(f"\n{'butce':>6} {'dogrulama':>10} {'sinama':>8} {'sisme':>8}") R = rastgele(200) for b in (1, 2, 5, 10, 20, 50, 100, 200): d, s, a = en_iyi(R[:b], olc) print(f"{b:>6} {d:>10.4f} {s:>8.4f} {d - s:>+8.4f}")
arama aday dogrulama sinama sisme ayar
izgara 48 0.8452 0.7937 +0.0516 ceza 5.62, esik 0.500, derece 2, sutun 9
rastgele 50 0.8373 0.7857 +0.0516 ceza 0.00481, esik 0.495, derece 1, sutun 9
model temelli 50 0.8452 0.8016 +0.0437 ceza 0.00103, esik 0.540, derece 1, sutun 9
butce dogrulama sinama sisme
1 0.7937 0.7778 +0.0159
2 0.7937 0.7778 +0.0159
5 0.8254 0.8056 +0.0198
10 0.8294 0.7976 +0.0317
20 0.8294 0.7976 +0.0317
50 0.8373 0.7857 +0.0516
100 0.8373 0.7857 +0.0516
200 0.8452 0.7976 +0.0476
Birinci tabloda ızgara 50 bütçeye karşılık 48 aday kullanabiliyor. Ayrık eksenlerin çarpımı altıdır, sürekli eksenlere ancak 8 nokta düşer ve bunlar 4×2 dağılır: ceza ekseninde dört değer, yani altı büyüklük mertebesi dört noktayla temsil ediliyor. Rastgele arama aynı bütçeyle o eksende 50 ayrı değer deniyor.
Üç aramanın sınama sayıları 0,7937, 0,7857 ve 0,8016 — doğrulama sıralamasıyla aynı değil. Model temelli arama iki kümede de önde ve şişmesi en küçük (+0,0437), ama üçü arasındaki sınama farkı 0,0159, yani dört satır; bu büyüklükteki bir farkı aramaların niteliğine bağlamak için yeterli kanıt yok.
Asıl bulgu ikinci tablodadır. Doğrulama sütunu tanım gereği artıyor: bütçe büyüdükçe en iyi sayı büyüyen bir kümenin en büyüğüdür ve küçülemez. 0,7937’den 0,8452’ye, toplam +0,0515. Sınama sütunu bu tırmanışı izlemiyor: 0,7778’den 0,7976’ya, toplam +0,0198. Tırmanışın yüzde 62’si sınama kümesine hiç geçmiyor ve şişme sütununda +0,0159’dan +0,0476’ya açılıyor.
Nedeni doğrulama kümesinin 252 satır olmasıdır. Her satır 0,0040 ediyor; iki aday arasındaki gerçek fark bu çözünürlüğün altındayken kazananı hangi satırların o kümeye düştüğü belirliyor. 200 aday denendiğinde en yüksek sayıyı alan aday en iyi olan değil, doğrulama kümesinin gürültüsüne en iyi denk gelendir — M26/K05’te ölçülen seçim yanlılığının ayar uzayındaki biçimi.
Karşılaştırma noktası açılış bloğundadır: ayarsız varsayılan aday doğrulama kümesinde zaten 0,8452 veriyordu. 200 aday bu sayıyı geçemedi ve ona eriştiği yerde sınama kümesinde de aynı noktada (0,7976) durdu. Arama, 200 eğitim karşılığında sıfır kazanç üretti; bunu ancak sınama kümesi okunduğunda söyleyebiliyoruz.
Ailenin Kattığı ile Bütçenin Şişirdiği
Kursun ikinci iddiası burada sayıya döner: aile değiştirmenin kattığı fark çoğu zaman ayar bütçesinin şişirdiği farktan küçüktür. İkinci aile yapıca daha zayıftır — tek bölmeli bir karar kuralı: bir sütun, bir eşik, bir yön.
ESIK_TABLO = {} for a in SIRA: d = sorted({x[a] for x in EGT}) ESIK_TABLO[a] = (d[1:] if len(d) < 12 else [d[int(i * len(d) / 12)] for i in range(1, 12)]) def gudug_olc(aday): a, v, yon = aday DENENEN.add(("gudug",) + aday) def tah(x): return int((x[a] >= v) == (yon == 1)) return (sum(tah(x) == x["supheli"] for x in DOG) / len(DOG), sum(tah(x) == x["supheli"] for x in SIN) / len(SIN)) def gudug_rastgele(butce, tohum=TOHUM + 4300): r, out = uretec(tohum), [] for _ in range(butce): a = SIRA[int(r() * len(SIRA))] out.append((a, ESIK_TABLO[a][int(r() * len(ESIK_TABLO[a]))], 1 + int(r() * 2))) return out print(f"{'butce':>6} {'gudug sin':>10} {'dogrusal sin':>13} {'aile farki':>11} " f"{'butce sismesi':>14}") for b in (1, 10, 50, 200): gd, gs, ga = en_iyi(gudug_rastgele(b), gudug_olc) dd, ds, da = en_iyi(R[:b], olc) print(f"{b:>6} {gs:>10.4f} {ds:>13.4f} {ds - gs:>+11.4f} {dd - ds:>+14.4f}") gd, gs, ga = en_iyi(gudug_rastgele(200), gudug_olc) print(f"\ngudug butce 200: tek bolme '{ga[0]}', dogrulama {gd:.4f}, sinama {gs:.4f}") print(f"bu derste denenen aday sayisi {len(DENENEN)}")
butce gudug sin dogrusal sin aile farki butce sismesi
1 0.7659 0.7778 +0.0119 +0.0159
10 0.7381 0.7976 +0.0595 +0.0317
50 0.8016 0.7857 -0.0159 +0.0516
200 0.8016 0.7976 -0.0040 +0.0476
gudug butce 200: tek bolme 'ort_tuketim', dogrulama 0.8254, sinama 0.8016
bu derste denenen aday sayisi 352
Aile farkı sütunu bütçe boyunca işaret değiştiriyor: bütçe 1’de +0,0119, bütçe 10’da +0,0595, bütçe 50’de eksiye dönüyor (−0,0159) ve bütçe 200’de eksi kalıyor (−0,0040). Yapıca daha güçlü aile, iki bütçede yapıca daha zayıf aileyi sınama kümesinde geçemedi. Bütçe 10’daki 0,0595 ise güdüğün rastlantıyla kötü bir adaya takılmasından geliyor; orada güdük 0,7381 ile tabanın altında.
Son sütun aynı satırlarda bütçenin şişirdiği farkı taşıyor: +0,0159, +0,0317, +0,0516, +0,0476. Bütçe 200’de aile farkı −0,0040 iken bütçe şişmesi +0,0476 — şişme, aile farkının on iki katına yakın ve ters yönde. Modelin ailesini değiştirmek bu kümede sayıyı oynatmadı; onu oynatan şey kaç aday denendiğiydi ve o oynama gerçek değildi.
Güdüğün bulduğu kural tek bir sütuna dayanıyor: ortalama tüketim üzerinde tek bir bölme, sınama kümesinde 0,8016. Bu dersin dokuz sütunlu, cezalı doğrusal modelleri tek bir eşiği geçemedi.
Denenen aday sayısı 352‘dir ve verilen bütçelerin toplamından küçüktür. Doğrusal ailede 299 ayrı aday var: bir varsayılan aday, üç aramanın 148 adayı ve bütçe süpürmesinin eklediği 150 aday. Güdük ailesinde ise bütçe 200 olmasına karşın 53 ayrı aday var, çünkü o ailenin bütün ayar uzayında yalnız 74 nokta bulunuyor (37 eşik, iki yön). Bütçe 50 ile 200’ün aynı sayıyı vermesinin nedeni budur: uzay doymuştur ve bütçeyi büyütmek yeni aday üretmez. Bir ailenin ayar bütçesi, uzayının büyüklüğü yazılmadan okunamaz.
Rapor edilen sayı, bütçe 200’de seçilen adayın sınama kümesindeki sayısıdır: 0,7976, tabanın 0,0397 üstünde.
Özet
- Aynı 50 adaylık bütçeyle ızgara ancak 48 aday kullanabiliyor (ayrık eksenlerin çarpımı bütçeyi böler); üç aramanın sınama sayıları 0,7937, 0,7857 ve 0,8016.
- Bütçe 1’den 200’e çıkarken doğrulama kümesindeki en iyi sayı 0,7937’den 0,8452’ye tanım gereği tırmanıyor, aynı adayın sınama sayısı 0,7778’den 0,7976’ya gidiyor ve şişme +0,0159’dan +0,0476’ya açılıyor.
- Ayarsız varsayılan aday doğrulama kümesinde zaten 0,8452 veriyor; 200 aday bu sayıyı geçemedi ve arama harcanan bütçe karşılığında sıfır kazanç üretti.
- Bütçe 50 ve 200’de tek bölmeli karar kuralı doğrusal modeli sınama kümesinde geçiyor: aile farkı −0,0159 ve −0,0040 iken bütçe şişmesi +0,0516 ve +0,0476, yani şişme aile farkının on iki katına yakın.
- Bu derste 352 ayrı aday denendi (doğrusal ailede 299, güdük ailesinde 53); güdük ailesinin bütçesi 200’dü ama uzayında yalnız 74 nokta olduğu için arama doydu ve bütçeyi büyütmek yeni aday üretmedi. Rapor edilen sayı bütçe 200’de seçilen adayın sınama sayısıdır (0,7976).
Sonraki Adım
Bu dersin bütün sayıları tek bir orandır: 252 satırın kaçında doğru karar verildiği. O oranın paydasındaki satırların hangi bölgelerden, hangi tarife basamaklarından, hangi hane büyüklüklerinden ve kaç okumadan geldiği hiç sorulmadı. Sonraki ders hatayı bu dilimlere bölerek soruyu sorar ve dilim sayısı arttıkça bulunan kötü dilim sayısının rastlantıyla da büyüdüğünü ölçer.
İlerlemeni kaydetmek ve not almak için Giriş yap
Notlarım
Not almak için giriş yapmalısın.