İçeriğe geç
academia.sh

Ders 04 / 13

Vekil Ölçütler

Etiket gelmeden önceki iki dönemde elde kalan ölçülerin sayılması: girdi özeti, tahmin payı ve girdi eksiksizliği üç senaryoda yan yana konduğunda kavram kaymalı kurulumun üç vekili sağlam kurulumun üç vekiliyle hane hane aynı çıkar, çünkü kural değişmiştir ve girdi değişmemiştir. Tahmin payı sağlam kurulumda bile 0,0957 sapıyor ve 0,05 bandını aşıyor, veri kaymalı kurulumda 0,1596'ya çıkıyor ama o kurulumda isabet 0,9700'den 0,9800'e gidiyor; girdi özeti gerçekten kayan tek senaryoda 0,0382'de kalıp ateşlemiyor, çünkü kayma 200 abonenin 102'sinde ve ortalama onu seyreltiyor; girdi eksiksizliği üç senaryoda da 0,0000 sapıyor ve tek bir dönemin okuması hiç gelmediğinde iki dönemi birden 0,8000'e düşürerek çalıştığını gösteriyor. Senaryoları ayıran tek ölçü isabettir ve iki dönem sonra gelir.

İçindekiler

Bir önceki ders gecikmeli etiketi saydı: bir dönemin isabeti ancak GECIKME = 2 dönem sonra biliniyor, bozulmanın olduğu an ile görüldüğü an arasında iki dönemlik bir boşluk var ve o boşlukta tahmin üretilmeye devam ediyor. Üç derste bozulmanın iki dönem geç görüldüğü ölçüldü.

Sorulmayan şey o iki dönemde elde ne olduğudur. İsabet yoktur, çünkü etiket gelmemiştir. Elde yalnız etiket gerektirmeyen ölçüler kalır: girdinin kendisinden ve modelin çıktısından okunabilenler. Bunlara vekil ölçüt (proxy metric) denir, çünkü ölçmek istediğimiz şeyin kendisi değil, onunla ilişkili olduğu varsayılan bir şeydir. Bu ders üç vekili üç senaryoda yan yana koyar ve tek soru sorar: hangisi kavram kaymasını görüyor, hangisi görmediği bir şey için ateşliyor.

  • MI41. Kaynak, beş aşamalı hat, kurgu model ve iki kayma türü kurgudur ve ders içinde üretilir. Hiçbir izleme ürünü, gösterge servisi, bulut servisi ya da öğrenme kitaplığı çağrılmaz. Tohum 20260218.
  • MI42. Üç vekil şunlardır: girdi özeti, dönemdeki abone ortalamalarının ortalaması; tahmin payı, modelin 1 dediği satırların oranı; girdi eksiksizliği, dönemde oluşan satırın beklenen 200 satıra oranı. Üçü de etiket okumaz, bu yüzden gecikmesizdir.
  • MI43. Üç senaryo: sağlam; veri kaymalı, 2026-09‘dan sonra işyeri tüketimi dönem başına 0,06 büyür; kavram kaymalı, girdi aynı kalır ve abone_ort + 6 x isyeri > 30 kuralının eşiği 27’ye iner.
  • MI44. Kayma (drift) yordamı — türlerinin ayrımı, ölçümü ve düzeltmesi — Makine Öğrenmesi ve Veri Bilimi müfredatındaki Model Değerlendirme, Yorumlanabilirlik ve Etik kursunda ölçüldü; tekrarlanmaz. Buradaki ek yalnız üretimdeki ömre aittir: etiket yokken vekilin ne gördüğü.
  • MI45. Model, MLOps Temelleri kursunun kusuru düzeltilmiş biçimde devralınır: karar eşiği ayrı bir ayardır ve eğitimde aranır, eğitim ölçütü dengeli isabettir, etiket özniteliklerin gördüğü bir kurala bağlıdır. İzleme dönemlerinde taban sınıf oranı 0,5342.
  • MI46. Taban çizgisi izlemesiz kurulumdur: gösterge yok, uyarı yok, bozulma görülmez. Dönem isabetinin adımı 0,0050 ve bu adımın altındaki fark okunmaz.

Etiket Gelmeden Önce Elde Ne Var

Aşağıdaki blok ortak tanımı kurar — kaynak, hat, öznitelik, kurgu model, iki kayma türü ve üç ölçü — ve modeli eğitip taban çizgisini basar. Öznitelikler senaryo başına bir kez hesaplanır.

# KURGUDUR. Olcum aginin sayac okumalari , bes asamali hat , kurgu model ve iki kayma
# turu ders icinde uretilir; hicbir izleme urunu , gosterge servisi , bulut servisi ya
# da ogrenme kitapligi cagrilmaz. Tohum 20260218.
TOHUM, M32 = 20260218, 0xFFFFFFFF


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


BOLGE = ["dogu", "bati", "kuzey", "guney", "merkez"]
TIP = ["mesken", "isyeri"]
DONEM = [f"2026-{a:02d}" for a in range(1, 13)]
ABONE = {}
for i in range(200):
    r = uretec(TOHUM + 37 * i)
    ABONE[f"A{i + 1:03d}"] = {"bolge": BOLGE[int(r() * 5)], "tip": TIP[int(r() * 2)],
                              "baslangic": 10000 + int(r() * 60000)}


def kaynak_uret():
    kayit = []
    for i, (ab, a) in enumerate(ABONE.items()):
        e = a["baslangic"]
        for d in DONEM:
            r = uretec(TOHUM + 101 * i + 7 * DONEM.index(d))
            e += 4 + int(r() * 46)
            kayit.append({"abone": ab, "donem": d, "bolge": a["bolge"], "tip": a["tip"],
                          "endeks": e, "birim": "m3"})
    return kayit


def a1_ayikla(kayit):
    ZOR = ("abone", "donem", "bolge", "endeks", "birim")
    tut = [k for k in kayit if all(a in k for a in ZOR)]
    return tut, len(kayit) - len(tut)


def a2_tekille(kayit):
    gor, tut = set(), []
    for k in kayit:
        ad = (k["abone"], k["donem"])
        if ad not in gor:
            gor.add(ad)
            tut.append(k)
    return tut, len(kayit) - len(tut)


def a3_tuketim(kayit):
    tablo = {(k["abone"], k["donem"]): k for k in kayit}
    cikti, dusen = [], 0
    for k in kayit:
        i = DONEM.index(k["donem"])
        onceki = tablo.get((k["abone"], DONEM[i - 1])) if i else None
        if onceki is None:
            dusen += i > 0
            continue
        cikti.append(dict(k, m3=int(k["endeks"]) - int(onceki["endeks"])))
    return cikti, dusen


def satirlar(kaynak=None):
    v, _ = a1_ayikla(kaynak_uret() if kaynak is None else kaynak)
    v, _ = a2_tekille(v)
    v, _ = a3_tuketim(v)
    return v


def oznitelikler(kayitlar, pencere=None, basamak=4):
    sirali = sorted(kayitlar, key=lambda k: DONEM.index(k["donem"]))
    ab, bo = {}, {}
    for k in sirali:
        ab.setdefault(k["abone"], []).append((DONEM.index(k["donem"]), k["m3"]))
        bo.setdefault(k["bolge"], []).append((DONEM.index(k["donem"]), k["m3"]))

    def ortalama(dizi, i):
        secili = [v for d, v in dizi if (d < i and (pencere is None or d >= i - pencere))]
        return round(sum(secili) / len(secili), basamak) if secili else 0.0

    oz = {}
    for k in kayitlar:
        i = DONEM.index(k["donem"])
        oz[(k["abone"], k["donem"])] = {"abone_ort": ortalama(ab[k["abone"]], i),
                                        "bolge_ort": ortalama(bo[k["bolge"]], i),
                                        "isyeri": 1 if k["tip"] == "isyeri" else 0}
    return oz


IZGARA = [(a, b, c) for a in (0.6, 0.8, 1.0) for b in (0.0, 0.2, 0.4) for c in (0, 4, 8)]
KARAR_IZGARA = (18, 22, 26, 30, 34)     # karar esigi AYRI bir ayardir , egitimde aranir
IZLEME = DONEM[6:]                      # 2026-07 .. 2026-12 : uretimde izlenen donemler
GECIKME = 2                             # etiket kac donem sonra geliyor
KURAL_ESIK, KURAL_ISYERI = 30, 6        # KAVRAM: abone_ort + 6 x isyeri > 30


def puan(o, w):
    return w[0] * o["abone_ort"] + w[1] * o["bolge_ort"] + w[2] * o["isyeri"]


def etiket(oz_k, esik=KURAL_ESIK, isyeri_kat=KURAL_ISYERI):
    return 1 if oz_k["abone_ort"] + isyeri_kat * oz_k["isyeri"] > esik else 0


def tahmin(oz_k, w, karar):
    return 1 if puan(oz_k, w) > karar else 0


def dengeli_isabet(kume, oz, w, karar):
    dp = dn = yp = yn = 0
    for k in kume:
        o_k = oz[(k["abone"], k["donem"])]
        t, g = tahmin(o_k, w, karar), etiket(o_k)
        dp, yp = dp + (t and g), yp + (t and not g)
        yn, dn = yn + (g and not t), dn + (not t and not g)
    duyarlilik = dp / (dp + yn) if dp + yn else 0.0
    ozgulluk = dn / (dn + yp) if dn + yp else 0.0
    return (duyarlilik + ozgulluk) / 2, round(duyarlilik, 4), round(ozgulluk, 4)


def egit(kayitlar, oz, donemler=None):
    """Egitim olcutu DENGELI ISABETTIR: duyarlilik ile ozgullugun ortalamasi."""
    kume = [k for k in kayitlar if k["donem"] in (donemler or DONEM[1:9])]
    en = (-1.0, None, None, 0.0, 0.0)
    for w in IZGARA:
        for karar in KARAR_IZGARA:
            o, du, oz_ = dengeli_isabet(kume, oz, w, karar)
            if o > en[0]:
                en = (o, w, karar, du, oz_)
    return {"agirlik": en[1], "karar": en[2], "dengeli": round(en[0], 4),
            "duyarlilik": en[3], "ozgulluk": en[4], "egitim_satiri": len(kume)}


def kaydir(kayitlar, baslangic="2026-09", egim=0.06):
    """VERI KAYMASI: baslangictan sonra isyeri tuketimi her donem egim kadar buyuyor."""
    b = DONEM.index(baslangic)
    return [dict(k, m3=round(k["m3"] * (1.0 + egim * (DONEM.index(k["donem"]) - b + 1)), 4))
            if DONEM.index(k["donem"]) >= b and k["tip"] == "isyeri" else dict(k)
            for k in kayitlar]


def kavram_kaydir(kayitlar, oz, baslangic="2026-09", yeni_esik=27):
    """KAVRAM KAYMASI: girdi AYNI , kural degisiyor. Esik 30'dan yeni_esik'e iniyor."""
    b = DONEM.index(baslangic)
    return {(k["abone"], k["donem"]): etiket(
        oz[(k["abone"], k["donem"])],
        yeni_esik if DONEM.index(k["donem"]) >= b else KURAL_ESIK) for k in kayitlar}


def girdi_ozeti(kayitlar, donem, oz):
    d = [oz[(k["abone"], k["donem"])]["abone_ort"] for k in kayitlar if k["donem"] == donem]
    return round(sum(d) / len(d), 4) if d else 0.0


def tahmin_payi(kayitlar, model, oz, donem):
    d = [tahmin(oz[(k["abone"], k["donem"])], model["agirlik"], model["karar"])
         for k in kayitlar if k["donem"] == donem]
    return round(sum(d) / len(d), 4) if d else 0.0


def isabet(kayitlar, model, oz, donem, etiketler=None):
    kume = [k for k in kayitlar if k["donem"] == donem]
    d = sum(1 for k in kume
            if tahmin(oz[(k["abone"], k["donem"])], model["agirlik"], model["karar"])
            == (etiketler[(k["abone"], k["donem"])] if etiketler
                else etiket(oz[(k["abone"], k["donem"])])))
    return round(d / len(kume), 4) if kume else None


SATIR = satirlar()
OZ = oznitelikler(SATIR)                  # oznitelik BIR KEZ hesaplanir
MODEL = egit(SATIR, OZ)
IZL = [k for k in SATIR if k["donem"] in IZLEME]
buyuk = max(sum(1 for k in IZL if etiket(OZ[(k["abone"], k["donem"])]) == s) for s in (0, 1))
print(f"model {MODEL['agirlik']} karar esigi {MODEL['karar']} , dengeli isabet"
      f" {MODEL['dengeli']} , duyarlilik {MODEL['duyarlilik']} , ozgulluk {MODEL['ozgulluk']}")
print(f"izleme {len(IZLEME)} donem , {len(IZL)} satir , isyeri abone"
      f" {sum(1 for a in ABONE.values() if a['tip'] == 'isyeri')} , taban sinif orani"
      f" {buyuk / len(IZL):.4f} , donem isabetinin adimi {1 / 200:.4f}")
model (0.6, 0.0, 4) karar esigi 18 , dengeli isabet 0.9864 , duyarlilik 1.0 , ozgulluk 0.9728
izleme 6 donem , 1200 satir , isyeri abone 102 , taban sinif orani 0.5342 , donem isabetinin adimi 0.0050

Taban sınıf oranı 0,5342 olduğu için küme dengelidir: hep aynı sınıfı söyleyen bir yordam bu oranı alır ve modelin 0,9864’ü onun çok üstündedir. Model izlenebilir durumdadır. İkinci satırdaki son iki sayı bütün dersi sınırlar: kaymanın dokunduğu abone 102 tanedir, geri kalan 98’i dokunulmamıştır; ve dönem isabetinin adımı 0,0050 olduğu için bundan küçük hiçbir hareket okunmaz.

Üç Vekil, Üç Senaryo

Aşağıdaki blok üç ölçüyü üç senaryonun altı izleme döneminde hesaplar ve dördüncü satır olarak isabeti ekler. Son sütun, 2026-08 tabanına göre sonraki dört dönemde görülen en büyük göreli sapmadır; bir uyarı bandı tam olarak bu sayıyla karşılaştırılır.

# Bu blok ilk bloktaki tanimlari surdurur. Her senaryonun oznitelikleri BIR KEZ hesaplanir.
def eksiksizlik(kayitlar, donem, beklenen=200):
    """UCUNCU VEKIL: donemde kac satir olustu. Deger okumaz , varlik sayar."""
    return round(sum(1 for k in kayitlar if k["donem"] == donem) / beklenen, 4)


KAYAN = kaydir(SATIR)
OZ_K = oznitelikler(KAYAN)
KAVRAM = kavram_kaydir(SATIR, OZ)
SENARYO = (("saglam", SATIR, OZ, None), ("veri kaymali", KAYAN, OZ_K, None),
           ("kavram kaymali", SATIR, OZ, KAVRAM))
OLCU = (("girdi ozeti", lambda kay, oz, et, d: girdi_ozeti(kay, d, oz)),
        ("tahmin payi", lambda kay, oz, et, d: tahmin_payi(kay, MODEL, oz, d)),
        ("eksiksizlik", lambda kay, oz, et, d: eksiksizlik(kay, d)),
        ("isabet", lambda kay, oz, et, d: isabet(kay, MODEL, oz, d, et)))

print("olcu         senaryo        " + "".join(f"{d[-2:]:>8}" for d in IZLEME) + "   sapma")
for ad, f in OLCU:
    for sad, kay, oz, et in SENARYO:
        dizi = [f(kay, oz, et, d) for d in IZLEME]
        sapma = max(abs(v - dizi[1]) / dizi[1] for v in dizi[2:])
        print(f"{ad:<12} {sad:<14}" + "".join(f"{v:8.4f}" for v in dizi) + f"  {sapma:.4f}")

HAM = [k for k in kaynak_uret() if not (k["abone"] <= "A040" and k["donem"] == "2026-10")]
GEC = satirlar(HAM)
print("\nkontrol , 40 abonenin 2026-10 okumasi hic gelmedi:")
print("eksiksizlik " + "".join(f"{eksiksizlik(GEC, d):8.4f}" for d in IZLEME))
olcu         senaryo              07      08      09      10      11      12   sapma
girdi ozeti  saglam         25.9220 26.0517 25.9800 26.3525 26.3261 26.5325  0.0185
girdi ozeti  veri kaymali   25.9220 26.0517 25.9800 26.4685 26.6053 27.0472  0.0382
girdi ozeti  kavram kaymali 25.9220 26.0517 25.9800 26.3525 26.3261 26.5325  0.0185
tahmin payi  saglam          0.4550  0.4700  0.4550  0.5100  0.5100  0.5150  0.0957
tahmin payi  veri kaymali    0.4550  0.4700  0.4550  0.5150  0.5200  0.5450  0.1596
tahmin payi  kavram kaymali  0.4550  0.4700  0.4550  0.5100  0.5100  0.5150  0.0957
eksiksizlik  saglam          1.0000  1.0000  1.0000  1.0000  1.0000  1.0000  0.0000
eksiksizlik  veri kaymali    1.0000  1.0000  1.0000  1.0000  1.0000  1.0000  0.0000
eksiksizlik  kavram kaymali  1.0000  1.0000  1.0000  1.0000  1.0000  1.0000  0.0000
isabet       saglam          0.9700  0.9700  0.9900  0.9750  0.9850  0.9900  0.0206
isabet       veri kaymali    0.9700  0.9700  0.9900  0.9750  0.9800  0.9800  0.0206
isabet       kavram kaymali  0.9700  0.9700  0.8150  0.8700  0.8650  0.8500  0.1598

kontrol , 40 abonenin 2026-10 okumasi hic gelmedi:
eksiksizlik   1.0000  1.0000  1.0000  0.8000  0.8000  1.0000

Tablonun en sert yeri sağlam ile kavram kaymalı satırlarının karşılaştırılmasıdır. Üç vekilin üçü de bu iki senaryoda hane hane aynı sayıyı veriyor: 26,5325 ile 26,5325, 0,5150 ile 0,5150, 1,0000 ile 1,0000. Bu bir yaklaşıklık değil, kimliktir. Kavram kayması tanımı gereği girdiye dokunmaz, yalnız kuralı değiştirir; girdiden okunan hiçbir ölçü de o değişimi taşıyamaz. Aynı dönemlerde isabet 0,9900’den 0,8500’e iniyor ve son sütunda sapma 0,0206’dan 0,1598’e çıkıyor. Üç vekilden hiçbiri kavram kaymasını görmüyor.

Ateşleyen Vekil ve Susan Vekil

Tahmin payı satırı ikinci okumayı verir. Sapması sağlam kurulumda bile 0,0957’dir; yani hiçbir şeyin bozulmadığı bir üretimde 0,05’lik bir bant ateşler. Veri kaymalı kurulumda 0,1596’ya çıkıp 0,10’luk bandı da aşar — ve tam o kurulumda isabet 0,9700’den 0,9800’e çıkar. Vekil, başarımın düzeldiği senaryoda en yüksek alarmı verir. Bu, kursun kuralının en çıplak biçimidir: bir göstergenin ateşlemesi bozulmanın kanıtı değildir. Nedeni de görünür: kural değişmedikçe doğru bir model kaymış girdide de doğru kalır, yalnız daha çok satıra 1 der.

Girdi özeti ters yönde şaşırtır. Girdinin gerçekten kaydığı tek senaryoda sapması 0,0382’de kalır ve 0,05’i aşmaz. Sayı yanlış değildir: kayma 200 abonenin 102’sine dokunur, ortalama bunu kalan 98 aboneyle böler ve 25,9220’den 27,0472’ye giden hareket bandın altında kalır. Bir vekilin neye baktığı kadar hangi kırılımda baktığı da ölçünün parçasıdır; kırılımsız ortalama, dokunduğu kesim küçüldükçe kaymayı seyreltir.

Girdi eksiksizliği üç senaryoda da 0,0000 sapar. Bu, ölçünün bozuk olduğu anlamına gelmez; kontrol koşumu bunu ayırır. Kaynakta 40 abonenin 2026-10 okuması hiç gelmediğinde eksiksizlik iki dönemi birden 0,8000’e düşürür — Veri Mühendisliğine Giriş kursunun gec_gelen sınıfı budur ve iki dönem çıkmasının nedeni tüketimin bir önceki dönemin endeksine bağlı olmasıdır. Ölçü çalışıyor; yalnız başka bir bozulma sınıfını görüyor. Kaymanın hiçbir türü satır düşürmez, bu yüzden eksiksizlik kayma izlemesinde toplanma bedelini öder ve karşılığında sıfır bilgi verir.

Dört satırı birlikte okumak dersin cevabıdır. Senaryoları ayıran tek ölçü isabettir: 0,0206 karşısında 0,1598, yani otuz bir çözünürlük adımı. Ama isabet etiket ister ve etiket iki dönem sonra gelir. Elde gecikmesiz olan üç ölçü vardır ve üçü de ayırt etmez; ayırt eden tek ölçü gecikmelidir. Vekil ölçüt, gecikmenin bedelini ödemekten kurtarmaz.

Özet

  • Üç vekil — girdi özeti, tahmin payı, girdi eksiksizliği — etiket okumaz ve gecikmesizdir; bu yüzden gecikmeli etiketin bıraktığı iki dönemlik boşlukta elde kalan tek ölçü sınıfıdır.
  • Kavram kaymalı senaryoda üç vekilin üçü de sağlam senaryoyla hane hane aynı sayıyı verir (26,5325 / 0,5150 / 1,0000), çünkü kural değişir ve girdi değişmez. Sapmalar 0,0185, 0,0957 ve 0,0000’dır; hiçbiri kavram kaymasını görmez.
  • Tahmin payı sağlam kurulumda 0,0957 sapar ve 0,05 bandını aşar; veri kaymalı kurulumda 0,1596’ya çıkar, o kurulumda isabet 0,9700’den 0,9800’e gider. Zararsız kaymada ateşleyen vekil budur.
  • Girdi özeti, girdinin gerçekten kaydığı tek senaryoda 0,0382’de kalıp ateşlemez: kayma 200 abonenin 102’sine dokunur ve kırılımsız ortalama onu seyreltir.
  • Girdi eksiksizliği üç senaryoda da 0,0000 sapar ama bozuk değildir: 40 abonenin bir dönem okuması gelmediğinde iki dönemi birden 0,8000’e düşürür. Kayma satır düşürmez, bu yüzden vekil burada ölçülebilir katkı vermez.
  • Senaryoları ayıran tek ölçü isabettir (0,1598’e karşı 0,0206, otuz bir çözünürlük adımı) ve o da iki dönem sonra gelir.

Sonraki Adım

Bu dersin son sütunu bir sapma sayısıydı ve o sayı tek başına hiçbir şey yapmaz; bir bantla karşılaştırıldığında karara dönüşür. 0,05 dendiğinde tahmin payı üç senaryoda da konuşur, 0,20 dendiğinde hiçbirinde konuşmaz. Sonraki ders bandı değişken yapar: 0,05, 0,10 ve 0,20’de üç ölçünün kaç dönem ateşlediğini, bu ateşlemelerin kaçının gerçek bozulmaya karşılık geldiğini ve kaçının yanlış alarm olduğunu sayar; sonunda hiç yanlış alarm vermeyen bandın tek gerçek bozulmayı da kaçırdığı görülür.

İlerlemeni kaydetmek ve not almak için Giriş yap

Notlarım

Not almak için giriş yapmalısın.

Aramak için yazmaya başlayın.

↑↓ Esc gezin · aç · kapat