---
title: 'İstem Yinelemesi'
source: 'https://academia.sh/tr/kurslar/istem-muhendisligi/istem-yinelemesi'
course: 'İstem Mühendisliği'
language: tr
updated: '2026-08-17T18:06:39+00:00'
license: 'CC BY-SA 4.0'
---

# İstem Yinelemesi

Ölçerek iyileştirme döngüsünün kendisi ölçü altına alınıyor. On aday değişiklik 30 kayıtlık bir doğrulama kümesinde sekiz yineleme boyunca aç gözlü aranıyor: doğrulama isabeti 0,4000'den 1,0000'a çıkıyor ve beşinci yinelemede tavana vuruyor, sınama isabeti aynı noktada 0,9333 ile en yükseğine ulaşıp sekizinci yinelemede 0,8111'e iniyor. Doğrulamadaki iki koşum farkının ortalaması 0,1037, adım kazancının ortalaması 0,0625: sekiz yinelemenin yalnızca ikisi kendi ölçüm gürültüsünden büyük. Arama başka bir koşumda tekrarlandığında sekiz adımın yalnız biri aynı yerde aynı değişikliği seçiyor. Bedel 2640 çağrıdır ve seçilen sekiz değişiklikten üçü görevle ilgisizdir.

Önceki dört derste dört tasarım kararı ölçüldü ve her biri tek başına, bir defada denendi. Gerçek
bir istem böyle yazılmaz. Bir istem yazılır, ölçülür, bir yeri değiştirilir, yeniden ölçülür; bu
döngü sayı iyileşmez olana kadar sürer. Döngünün adı **istem yinelemesidir** ve bu ders döngünün
kendisini ölçü altına alır.

Ölçü altına almak, önceki müfredatın Makine Öğrenmesine Giriş kursunda kurulmuş bir ayrımı buraya
taşımak demektir: bir sayıya **bakarak** karar veriyorsan, o sayı artık senin karar verdiğin
kümenin sayısıdır ve genel başarımı temsil etmez. Orada bu ayrım eğitim, doğrulama ve sınama
kümesiyle kuruldu. Burada model eğitilmiyor, **istem aranıyor**; ama ayrım aynı ayrımdır. Her
yinelemede bakılan küme **doğrulama**, hiç bakılmayan küme **sınamadır**.

- **IT61.** Model bir **benzeticidir**, tohumu **20260218**'dir ve gerçek bir uç nokta
  çağrılmaz. Destek talepleri **kurgudur**.
- **IT62.** 120 kurgu talep ikiye ayrılır: **30 kayıt doğrulama**, **90 kayıt sınama**. Arama
  yalnız doğrulamayı görür; sınama hiçbir karara girmez.
- **IT63.** On **aday değişiklik** vardır. Beşi görevle ilgilidir (etiket kümesi, biçim kısıtı,
  iki örnek, iki örnek daha, olumlu bildirim), beşi ilgisizdir (nazik giriş, kısa yaz, teşekkür,
  not satırı, okuyucu notu). İlgisiz olanlar istemin **yalnız metnini** değiştirir.
- **IT64.** Arama **aç gözlüdür**: her yinelemede kalan bütün adaylar doğrulamada denenir, en iyi
  sayıyı veren seçilir ve isteme kalıcı olarak eklenir.
- **IT65.** Bedel **çağrı sayısıyla** yazılır. Denenen her aday, doğrulama kümesi büyüklüğü kadar
  çağrı harcar ve bu çağrılar geri alınamaz.

## Sekiz Yinelemenin İki Sayısı

```python
# BENZETICI -- KURGUDUR. Gercek bir model uc noktasi cagrilmaz; standart kitaplikla
# yazilmis bir dil modeli benzeticisidir. Talepler de kurgudur.
import math

TOHUM, M32 = 20260218, 0xFFFFFFFF
PENCERE, EN_UZUN = 240, 24


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


def belirtecle(m):                  # KURGU belirtecleyici: parca en cok bes damga
    b = []
    for s in m.lower().replace(",", " , ").split():
        while len(s) > 5:
            b.append(s[:5])
            s = s[5:]
        b.append(s)
    return b


def izno(m):
    h = 2166136261
    for c in m:
        h = ((h ^ ord(c)) * 16777619) & M32
    return h


KONU = ["fatura", "ariza", "sayac", "tarife", "kesinti"]
KALIP = {"fatura": ["bu ayki fatura tutari gecen aya gore cok yuksek geldi",
                    "faturami odedim ama sistemde borc gorunuyor",
                    "fatura ayrintisini nereden gorebilirim"],
         "ariza": ["evde su akmiyor bir ariza var galiba",
                   "baglanti bozuk oldu ve hic calismiyor",
                   "ariza kaydi actim ama ekip gelmedi"],
         "sayac": ["sayac okumasi yanlis girilmis endeks tutmuyor",
                   "sayac degisimi icin randevu istiyorum",
                   "sayac uzerindeki endeks ile fatura ayni degil"],
         "tarife": ["hangi tarife basamagindayim ogrenmek istiyorum",
                    "tarife degisikligi icin ne yapmam gerekiyor",
                    "birim ucret abone tipine gore degisiyor mu"],
         "kesinti": ["mahallede kesinti var ne zaman gelecek",
                     "planli kesinti duyurusu nereden takip edilir",
                     "aksamdan beri kesinti yasiyoruz"]}
EK = ["ayrica gecen ay da ayni sorun olmustu", "bu konuda memnun degilim",
      "acil bilgi almam gerekiyor", "kayit numaram elimde yok"]

TALEP = []
for i in range(120):
    r = uretec(TOHUM + i)
    k = KONU[ayrik(r(), [0.24, 0.22, 0.18, 0.20, 0.16])]
    m = KALIP[k][int(r() * 3)]
    if r() < 0.34:
        m += " " + EK[int(r() * 4)]
    TALEP.append({"no": 4001 + i, "metin": m, "konu": k})

KAVRAM = KONU + ["odeme", "sikayet", "bilgi", "genel"]
IZ = {"fatur": "fatura", "tutar": "fatura", "ayrin": "fatura", "ariza": "ariza",
      "bozuk": "ariza", "calis": "ariza", "akmiy": "ariza", "sayac": "sayac",
      "endek": "sayac", "okuma": "sayac", "tarif": "tarife", "birim": "tarife",
      "abone": "tarife", "basam": "tarife", "kesin": "kesinti", "duyur": "kesinti",
      "mahal": "kesinti", "borc": "odeme", "odedi": "odeme", "ucret": "odeme",
      "memnu": "sikayet", "sorun": "sikayet", "acil": "sikayet", "bilgi": "bilgi",
      "ogren": "bilgi", "nered": "bilgi"}
TUZAK = {"degis": "tarife", "kayit": "ariza", "yukse": "tarife", "gorun": "fatura",
         "ekip": "kesinti", "takip": "tarife", "giril": "fatura"}
SERBEST = ["talebiniz {k} konusuyla ilgili gorunuyor",
           "bu kayit {k} basligina girer , ilgili ekibe yonlendirildi",
           "kaydiniz alindi , konuyu inceleyip donus yapacagiz"]
SAYAC = [0]


def coz(istem):
    ust, _, talep = istem.partition("Talep : ")
    o = []
    for parca in ust.split("Ornek : ")[1:]:
        m, _, e = parca.partition(" => ")
        o.append((m.strip(), e.split(" .")[0].strip()))
    return o, talep


def cagir(istem, tohum=TOHUM, sicaklik=0.6, en_uzun=EN_UZUN):
    SAYAC[0] += 1
    bel = belirtecle(istem)
    bos = {"giris": len(bel), "cikis": 0, "yanit": ""}
    if len(bel) > PENCERE:
        return dict(bos, durum="baglam_asimi")
    if SAYAC[0] % 37 == 0:
        return dict(bos, durum="hiz_siniri")
    r = uretec(tohum ^ izno(istem))
    ornek, talep = coz(istem)
    bt = belirtecle(talep)
    aday = [k for k in KAVRAM if k[:5] in bel]
    if len(aday) < 3:
        aday = KAVRAM
    p = {k: 0.15 for k in aday}
    for t in bt:
        for tablo, w in ((IZ, 1.0), (TUZAK, 1.3)):
            if tablo.get(t) in p:
                p[tablo[t]] += w
    for j, (m, e) in enumerate(ornek):
        if e in p:
            w = 0.5 + (j + 1) / len(ornek)
            for t in set(belirtecle(m)):
                if t in bt:
                    p[e] += 0.30 * w
    e = [math.exp(p[a] / sicaklik) for a in sorted(p)]
    k = sorted(p)[ayrik(r(), [v / sum(e) for v in e])]
    y = (f"etiket : {k}" if "bicim" in bel
         else SERBEST[ayrik(r(), [0.42, 0.26, 0.32])].format(k=k))
    cb = belirtecle(y)
    if len(cb) > en_uzun:
        cb, y = cb[:en_uzun], " ".join(cb[:en_uzun])
    return {"durum": "tamam", "giris": len(bel), "cikis": len(cb), "yanit": y}


def oku(y):
    for s in y.lower().split():
        if s in KONU:
            return s
    return None


DOGRULAMA, SINAMA = TALEP[:30], TALEP[30:]      # 30 dogrulama , 90 sinama
TABAN = "Su destek talebini yanitla . "
DEGISIKLIK = [
    ("etiket kumesi", "Talebi su etiketlerden birine ata : fatura , ariza , sayac , "
                      "tarife , kesinti . "),
    ("bicim kisiti", "Yanitin bicimi : etiket : <deger> . "),
    ("iki ornek", "Ornek : fatura ayrintisini nereden gorebilirim => fatura . "
                  "Ornek : ariza kaydi actim ama ekip gelmedi => ariza . "),
    ("iki ornek daha", "Ornek : sayac okumasi yanlis girilmis endeks tutmuyor => sayac . "
                       "Ornek : hangi tarife basamagindayim ogrenmek istiyorum => tarife . "),
    ("olumlu bildirim", "Yanitinda yalnizca konu etiketi olsun . "),
    ("nazik giris", "Lutfen dikkatli davran . "),
    ("kisa yaz", "Yanitini kisa tut . "),
    ("tesekkur", "Tesekkurler . "),
    ("not satiri", "Not : kayit sistemine islenecek . "),
    ("okuyucu notu", "Yanit destek ekibi tarafindan okunacak . "),
]


def olc(parcalar, kume, tohum=TOHUM):
    SAYAC[0] = 0
    d = 0
    for x in kume:
        s = cagir(TABAN + "".join(parcalar) + "Talep : " + x["metin"], tohum=tohum)
        d += oku(s["yanit"]) == x["konu"]
    return d / len(kume), SAYAC[0]


def ara(tohum, adim=8):
    """Her yinelemede butun adaylari DOGRULAMA uzerinde dener, en iyisini secer."""
    secili, kalan, cagri, iz = [], list(DEGISIKLIK), 0, []
    for _ in range(adim):
        en, ad = None, None
        for a, parca in kalan:
            v, c = olc(secili + [parca], DOGRULAMA, tohum)
            cagri += c
            if en is None or v > en:
                en, ad = v, (a, parca)
        secili.append(ad[1])
        kalan = [x for x in kalan if x[0] != ad[0]]
        dv, c1 = olc(secili, DOGRULAMA, tohum)
        sv, c2 = olc(secili, SINAMA, tohum)
        cagri += c1 + c2
        iz.append((ad[0], dv, sv, cagri))
    return iz


d0, c0 = olc([], DOGRULAMA)
s0, c1 = olc([], SINAMA)
print("yineleme  secilen degisiklik    dogrulama  sinama  ayrisma  toplam cagri")
print(f"{0:>8}  {'-':<20}  {d0:>9.4f}  {s0:.4f}  {d0 - s0:+.4f}  {c0 + c1:>12}")
IZLEK = ara(TOHUM)
for i, (ad, dv, sv, cg) in enumerate(IZLEK, 1):
    print(f"{i:>8}  {ad:<20}  {dv:>9.4f}  {sv:.4f}  {dv - sv:+.4f}  {cg + c0 + c1:>12}")
```

```
yineleme  secilen degisiklik    dogrulama  sinama  ayrisma  toplam cagri
       0  -                        0.4000  0.3778  +0.0222           120
       1  not satiri               0.7000  0.5889  +0.1111           540
       2  bicim kisiti             0.8000  0.5889  +0.2111           930
       3  iki ornek                0.8333  0.8556  -0.0222          1290
       4  etiket kumesi            0.9667  0.8556  +0.1111          1620
       5  olumlu bildirim          1.0000  0.9333  +0.0667          1920
       6  kisa yaz                 0.9667  0.9111  +0.0556          2190
       7  iki ornek daha           0.9667  0.8667  +0.1000          2430
       8  tesekkur                 0.9000  0.8111  +0.0889          2640
```

Doğrulama sütunu bir arama kaydının olağan görüntüsüdür: **0,4000'den 1,0000'a**, kesintisiz
yükseliş. Bu sütuna bakan biri sekiz yinelemede istemi tam isabetli hâle getirdiğini söyler.
Sınama sütunu aynı hikâyeyi anlatmıyor. En yüksek sınama sayısı **0,9333** ve beşinci yinelemede
geliyor; sonraki üç yineleme onu **0,8111**'e indiriyor. Beşinci yinelemeden sonra yapılan her
değişiklik doğrulamayı korumak için seçildi ve sınamada zarar verdi.

Ayrışma sütunu iki kümenin arasındaki farkı taşıyor. Başlangıçta **+0,0222**, yani iki küme
neredeyse aynı şeyi söylüyor. İkinci yinelemede **+0,2111**'e çıkıyor: doğrulama 0,8000 derken
sınama hâlâ 0,5889. Bu noktada doğrulamaya bakarak verilen her karar, kendisiyle ilgisi olmayan
bir küme hakkında konuşuyor. Ayrışmanın kaynağı kümenin küçüklüğüdür — otuz kayıtta bir kaydın
düzelmesi sayıyı 0,0333 oynatır ve üç kaydın rastgele düzelmesi bir iyileştirme gibi görünür.

Birinci satır bunun en açık örneğidir. Aramanın ilk seçtiği değişiklik **not satırıdır**: göreve
hiçbir bilgi eklemeyen, etiket kümesinden, biçimden ve örnekten söz etmeyen bir cümle.
Doğrulamada **+0,3000** getirdi ve bütün arama boyunca ölçülen en büyük tek adım kazancı oldu.
Sekiz değişiklikten üçü bu türdendir. Aç gözlü arama, sayıyı yükselten şeyi seçer; sayıyı niçin
yükselttiğini sormaz.

## Aramanın Kendi Güvenilirliği

```python
IKINCI = ara(TOHUM + 1)
print("ayni arama , baska kosum")
for i, ((a1, *_), (a2, d2, s2, _)) in enumerate(zip(IZLEK, IKINCI), 1):
    print(f"{i:>2}  {a1:<18} -> {a2:<18} dogrulama {d2:.4f}  sinama {s2:.4f}")
print(f"iki aramanin ayni sirada sectigi degisiklik: "
      f"{sum(a == b for (a, *_), (b, *_) in zip(IZLEK, IKINCI))}/8")

sec, fd, fs = [], [], []
for ad, *_ in [(None,)] + IZLEK:
    if ad:
        sec.append(dict(DEGISIKLIK)[ad])
    fd.append(abs(olc(sec, DOGRULAMA)[0] - olc(sec, DOGRULAMA, TOHUM + 1)[0]))
    fs.append(abs(olc(sec, SINAMA)[0] - olc(sec, SINAMA, TOHUM + 1)[0]))
gd = sum(fd) / len(fd)
print(f"\niki kosum farki -- dogrulama (30 kayit) ortalama {gd:.4f} , en buyuk {max(fd):.4f}")
print(f"iki kosum farki -- sinama (90 kayit) ortalama {sum(fs) / len(fs):.4f} ,"
      f" en buyuk {max(fs):.4f}")

dv, sv = [d0] + [x[1] for x in IZLEK], [s0] + [x[2] for x in IZLEK]
adim = [dv[i] - dv[i - 1] for i in range(1, 9)]
print(f"adim kazanci iki kosum farkindan buyuk olan yineleme: "
      f"{sum(x > gd for x in adim)}/8 , adim kazanci ortalamasi {sum(adim) / 8:+.4f}")
print(f"\ndogrulama en yuksek {max(dv):.4f} ({dv.index(max(dv))}. yineleme) ,"
      f" sinama en yuksek {max(sv):.4f} ({sv.index(max(sv))}. yineleme)")
print(f"5 -> 8 : dogrulama {dv[5]:.4f} -> {dv[8]:.4f} , sinama {sv[5]:.4f} -> {sv[8]:.4f}")
print(f"ayrisma en buyuk {max(d - s for d, s in zip(dv, sv)):+.4f} , 8. yinelemede "
      f"{dv[8] - sv[8]:+.4f}")
ilgisiz = ("nazik giris", "kisa yaz", "tesekkur", "not satiri", "okuyucu notu")
print(f"arama bedeli {IZLEK[-1][3] + c0 + c1} cagri , secilen sekiz degisiklikten "
      f"{sum(a in ilgisiz for a, *_ in IZLEK)} tanesi gorevle ilgisiz")
```

```
ayni arama , baska kosum
 1  not satiri         -> kisa yaz           dogrulama 0.7000  sinama 0.5667
 2  bicim kisiti       -> etiket kumesi      dogrulama 0.6333  sinama 0.4444
 3  iki ornek          -> bicim kisiti       dogrulama 0.7667  sinama 0.7333
 4  etiket kumesi      -> iki ornek          dogrulama 0.9667  sinama 0.8778
 5  olumlu bildirim    -> nazik giris        dogrulama 0.9667  sinama 0.9111
 6  kisa yaz           -> not satiri         dogrulama 0.8667  sinama 0.7111
 7  iki ornek daha     -> iki ornek daha     dogrulama 0.9000  sinama 0.8889
 8  tesekkur           -> okuyucu notu       dogrulama 0.9333  sinama 0.8333
iki aramanin ayni sirada sectigi degisiklik: 1/8

iki kosum farki -- dogrulama (30 kayit) ortalama 0.1037 , en buyuk 0.1667
iki kosum farki -- sinama (90 kayit) ortalama 0.0728 , en buyuk 0.1778
adim kazanci iki kosum farkindan buyuk olan yineleme: 2/8 , adim kazanci ortalamasi +0.0625

dogrulama en yuksek 1.0000 (5. yineleme) , sinama en yuksek 0.9333 (5. yineleme)
5 -> 8 : dogrulama 1.0000 -> 0.9000 , sinama 0.9333 -> 0.8111
ayrisma en buyuk +0.2111 , 8. yinelemede +0.0889
arama bedeli 2640 cagri , secilen sekiz degisiklikten 3 tanesi gorevle ilgisiz
```

Üstteki çizelge aramayı **aynı düzenekte, yalnız tohumu değiştirerek** yeniden koşturuyor. Sekiz
adımın **yalnız biri** aynı yerde aynı değişikliği seçiyor. İkinci koşum ilk adımda "kısa yaz"ı,
ikinci adımda etiket kümesini seçiyor ve beşinci adımda "nazik giriş"e ulaşıyor. İki arama iki
ayrı istem üretti; ikisi de kendi doğrulama kümesinde iyi görünüyor ve ikisi de aynı düzeneğin
ürünü. **Arama, aradığı şeyi değil, koşumu buluyor.**

Alt bölüm bunun sayısını veriyor. Doğrulama kümesinde aynı istemin iki koşumu arasındaki fark
ortalama **0,1037**, en büyüğü 0,1667. Aramanın adım başına ortalama kazancı **+0,0625**. Sekiz
yinelemenin **yalnız ikisinde** adım kazancı kendi ölçüm gürültüsünden büyük; kalan altı adım,
kursun kuralına göre **ölçülmemiş** sayılır ve buna rağmen isteme kalıcı olarak eklendiler.
Sınama kümesinde aynı fark ortalama **0,0728**, yani üç kat büyük bir kümede ölçü gözle görülür
biçimde daha durgun. Küçük doğrulama kümesi hem daha ucuzdur hem de aramanın kovalayacağı
gürültüyü kendisi üretir.

Doyma noktası **beşinci yinelemedir**: doğrulama orada 1,0000'a vurur ve daha yükselemez, sınama
da orada en yüksek değerini alır. Sonraki üç yineleme **720 ek çağrı** harcayıp sınamayı
0,9333'ten 0,8111'e indiriyor. Aramanın toplam bedeli **2640 çağrıdır** ve bu çağrıların büyük
bölümü seçilmeyen adaylara gitti. Bir istem araması, bir ayar aramasıyla aynı yasaya tabidir:
bütçe büyüdükçe doğrulamadaki kazanç sınamaya taşınmaz. **Ölçülmeden değiştirilen istem bir
iyileştirme değil bir tahmindir**; ölçülen küme yanlışsa, ölçmek de tahmin etmektir.

## Özet

- Aç gözlü arama sekiz yinelemede doğrulama isabetini **0,4000'den 1,0000'a** çıkardı; sınama
  isabeti aynı sürede **0,3778'den** en yüksek **0,9333**'e çıkıp **0,8111**'e indi.
- Kazanç **beşinci yinelemede doydu**. Sonraki üç yineleme 720 ek çağrı harcayıp sınamayı 0,1222
  düşürdü; iki küme arasındaki ayrışma en büyük değerini ikinci yinelemede **+0,2111** olarak aldı.
- Aramanın ilk ve en büyük adımı (**+0,3000**) görevle ilgisiz bir cümleden geldi; seçilen sekiz
  değişiklikten **üçü** göreve hiçbir bilgi eklemiyor.
- Doğrulamada iki koşum farkı ortalama **0,1037**, adım kazancı ortalama **+0,0625**: sekiz
  yinelemenin yalnız **ikisi** kendi ölçüm gürültüsünden büyük. Sınamada aynı fark **0,0728**.
- Aynı arama başka bir tohumla koşturulduğunda sekiz adımın **yalnız biri** aynı yerde aynı
  değişikliği seçiyor; toplam bedel **2640 çağrıdır**.

## Sonraki Adım

Sekiz derste istem bir tasarım nesnesine dönüştü. Bileşenlerine ayrıldı, kalıcı bir yönerge
kazandı, rol ve talep düzeyinde açıldı, biçimi ve uzunluğu belirlendi, örnek aldı, kuralları
olumlu yazıldı ve ölçülerek yinelendi. Her adımda değişen tek şey **metin** oldu ve her adımın
bedeli belirteçle, çağrıyla ya da ihlalle yazıldı. Ortak yanları da açıktır: hepsi modele **ne
söyleneceğini** düzenledi.

Hiçbiri modele **nasıl düşüneceğini** sormadı. Bu sekiz derste model her talebe tek bir hamlede
yanıt verdi: istemi aldı, bir etiket seçti, bir cümle yazdı. Arada bir adım yoktu. Oysa iki
fatura döneminin farkını hesaplayıp hangi tarifeye göre fazla ödendiğini bulmak gibi bir talep
tek hamlede çözülecek bir şey değildir; birkaç ara adım ister ve o adımların modelin kendisi
tarafından üretilmesi gerekir. Sonraki konu bunu ele alır ve ilk dersinde kursun ikinci iddiasını
kurar: ara adım istemek **belirteci katlar** ve her görevde kazandırmaz. Aynı teknik çok adımlı
bir hesapta kazandırırken tek adımlı bir sınıflandırmada bedeli artırıp sayıyı yerinde bırakır,
ve ikisi de basılır.
