---
title: 'Ayar Değişkeni Araması'
source: 'https://academia.sh/tr/kurslar/denetimli-ogrenme/hiperparametre-arama'
course: 'Denetimli Öğrenme'
language: tr
updated: '2026-08-17T18:10:20+00:00'
license: 'CC BY-SA 4.0'
---

# 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.

Ö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ı ($10^{-3}$–$10^{3}$, 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

```python
# 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.

```python
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.

```python
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.
