Ders 05 / 13
Uyarı ve Eşikler
Uyarı bandının daraldıkça ne kazandırıp ne kaybettirdiğinin sayılması: 0,05 bandında üç ölçü ve üç senaryo boyunca 13 dönem ateşliyor, bunların 6'sı yanlış alarm; 0,10'da 6 ateşleme ve 2 yanlış alarm; 0,20'de hiç yanlış alarm yok ama gerçek bozulmanın dördü de kaçıyor, çünkü 0,20'lik göreli bant 0,9700 tabanında isabetin 0,7760'ın altına inmesini ister ve en dip değer 0,8150'dir. Tahmin payı 0,05 bandında hem sağlam kurulumda hem kavram kaymalı kurulumda tam üç dönem ateşliyor; aynı ateşleme bir yerde saf yanlış alarm, öbür yerde yakalama sayılıyor, bu yüzden ölçülmemiş sayılır. Yalnız isabet iki zararsız senaryoda hiç ateşlemeyip zararlı senaryoda dört dönem ateşliyor ve yakalama gecikmesi iki dönem.
İçindekiler
Bir önceki ders üç vekilin sapmasını saydı ve son sütunda tek bir sayı bıraktı: 2026-08 tabanına
göre en büyük göreli sapma. O sayı tek başına bir karar vermez. Karar, sapmanın bir bantla
karşılaştırılmasıyla doğar; bandın adı uyarı eşiğidir (alert threshold) ve bir ölçünün değil,
bir seçimin parçasıdır.
Seçim ucuz görünür ve değildir. Bant daraldıkça daha çok dönem ateşler; ateşleyen dönemlerin kaçının gerçekten bozulmuş olduğu ise bandın bilmediği bir şeydir. Bu ders bandı 0,05, 0,10 ve 0,20’de sabitler, üç ölçüyü üç senaryoda koşturur ve iki sayıyı ayrı ayrı yazar: ateşleyen dönem ile bunların kaçının gerçek bozulmaya karşılık geldiği.
- MI47. Kaynak, 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.
- MI48. Uyarı eşiği, bir ölçünün
2026-08tabanından göreli sapmasının aşmaması gereken paydır. Üç bant sınanır: 0,05, 0,10 ve 0,20. Taban dönemi kaymaların hiçbirinin başlamadığı son dönemdir. - MI49. Gerçek bozulma banttan bağımsız tanımlanır: bir dönemin gerçek isabetinin
2026-08tabanından 0,0500’den fazla düşmesi, yani on çözünürlük adımı. Bu ölçü değerlendirme içindir; üretimde iki dönem gecikmeyle bilinir. - MI50. Yanlış alarm (false positive), ateşleyen ama gerçek bozulma listesinde olmayan dönemdir.
Gösterge gecikmesinin ölçümü Veri Hatları ve Orkestrasyon kursunun hat gözlemlenebilirliği
dersinde yapıldı ve tekrarlanmaz. Buradaki tek ek gecikmeli etikettir: isabet üzerinden
ateşleyen bir uyarının gecikmesine
GECIKMEeklenir. - MI51. Model MLOps Temelleri kursundan düzeltilmiş biçimde devralınır: karar eşiği ayrı bir ayardır, eğitim ölçütü dengeli isabettir. İzleme dönemlerinde taban sınıf oranı 0,5342.
- MI52. Taban çizgisi izlemesiz kurulumdur: bant yok, ateşleyen dönem 0, yakalama gecikmesi tanımsız. Dönem isabetinin adımı 0,0050.
Uyarı Eşiği Bir Karşılaştırmadır
Aşağıdaki blok ortak tanımı kurar ve üzerine iki şey ekler: bir ölçü dizisini tabanla karşılaştıran
uyari, ve bir dönemin isabetinin hangi dönemde bilinebildiğini söyleyen gorulen_donem.
# 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 def uyari(dizi, taban, pay): """Bir olcu tabandan `pay` kadar saparsa o donem ates eder.""" return [d for d, v in dizi if abs(v - taban) / max(abs(taban), 1e-9) > pay] def gorulen_donem(donem, simdi): """Gecikmeli etiket: bir donemin isabeti ancak GECIKME donem sonra bilinir.""" return DONEM.index(donem) + GECIKME <= DONEM.index(simdi) 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']} , {len(IZL)} satir , taban sinif orani {buyuk / len(IZL):.4f} ," f" adim {1 / 200:.4f} , 2026-09'un isabeti" f" {[d for d in DONEM if gorulen_donem('2026-09', d)][0]} doneminde bilinir")
model (0.6, 0.0, 4) karar esigi 18 , dengeli isabet 0.9864 , 1200 satir , taban sinif orani 0.5342 , adim 0.0050 , 2026-09'un isabeti 2026-11 doneminde bilinir
Son alan bandın ölçemediği şeyi baştan söyler: 2026-09’da bir şey bozulsa bile o dönemin isabeti
2026-11’de bilinir. İsabet üzerine kurulan bir uyarı, bandı ne kadar dar olursa olsun iki dönem
sonra konuşur. Bandın oynatabildiği tek şey, gecikmesiz vekillerin kaç kez konuşacağıdır.
Bant Daraldıkça
Aşağıdaki blok üç ölçüyü üç senaryoda üç bantla karşılaştırır. Her hücre iki sayı taşır: ateşleyen
dönem ve bunların kaçının yanlış alarm olduğu. bozulan sütunu banttan bağımsızdır; o
senaryoda gerçekten bozulmuş dönem sayısını verir.
# Bu blok ilk bloktaki tanimlari surdurur. Her senaryonun oznitelikleri BIR KEZ hesaplanir. BANT = (0.05, 0.10, 0.20) DUSUS = 0.0500 # GERCEK BOZULMA: isabetin tabandan bu kadardan fazla dusmesi 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)), ("isabet", lambda kay, oz, et, d: isabet(kay, MODEL, oz, d, et))) ATES, GERCEK = {}, {} for sad, kay, oz, et in SENARYO: isb = [(d, isabet(kay, MODEL, oz, d, et)) for d in IZLEME] GERCEK[sad] = set(d for d, v in isb[2:] if dict(isb)["2026-08"] - v > DUSUS) for ad, f in OLCU: dizi = [(d, f(kay, oz, et, d)) for d in IZLEME] for b in BANT: ATES[(sad, ad, b)] = set(uyari(dizi[2:], dict(dizi)["2026-08"], b)) print(f"gercek bozulma: isabetin 2026-08 tabanindan {DUSUS:.4f} uzerinde dusmesi") print("hucre: atesleyen donem / yanlis alarm\n") print("olcu senaryo bozulan " + "".join(f"{b:>12.2f}" for b in BANT)) for ad, _ in OLCU: for sad, *_ in SENARYO: h = [f"{len(ATES[(sad, ad, b)])} / {len(ATES[(sad, ad, b)] - GERCEK[sad])}" for b in BANT] print(f"{ad:<12} {sad:<14} {len(GERCEK[sad]):>7} " + "".join(f"{x:>12}" for x in h)) print("\nbant toplam ates yanlis alarm yakalanan gecikme: tahmin payi isabet") for b in BANT: t = [sum(len(ATES[(s, a, b)]) for s, *_ in SENARYO for a, _ in OLCU), sum(len(ATES[(s, a, b)] - GERCEK[s]) for s, *_ in SENARYO for a, _ in OLCU), sum(len(ATES[(s, a, b)] & GERCEK[s]) for s, *_ in SENARYO for a, _ in OLCU)] g = [] for ad, ek in (("tahmin payi", 0), ("isabet", GECIKME)): a = sorted(ATES[("kavram kaymali", ad, b)]) g.append(str(DONEM.index(a[0]) - DONEM.index("2026-09") + ek) if a else "tanimsiz") print(f"{b:<5.2f} {t[0]:>11} {t[1]:>13} {t[2]:>10} {g[0]:>21} {g[1]:>7}")
gercek bozulma: isabetin 2026-08 tabanindan 0.0500 uzerinde dusmesi hucre: atesleyen donem / yanlis alarm olcu senaryo bozulan 0.05 0.10 0.20 girdi ozeti saglam 0 0 / 0 0 / 0 0 / 0 girdi ozeti veri kaymali 0 0 / 0 0 / 0 0 / 0 girdi ozeti kavram kaymali 4 0 / 0 0 / 0 0 / 0 tahmin payi saglam 0 3 / 3 0 / 0 0 / 0 tahmin payi veri kaymali 0 3 / 3 2 / 2 0 / 0 tahmin payi kavram kaymali 4 3 / 0 0 / 0 0 / 0 isabet saglam 0 0 / 0 0 / 0 0 / 0 isabet veri kaymali 0 0 / 0 0 / 0 0 / 0 isabet kavram kaymali 4 4 / 0 4 / 0 0 / 0 bant toplam ates yanlis alarm yakalanan gecikme: tahmin payi isabet 0.05 13 6 7 1 2 0.10 6 2 4 tanimsiz 2 0.20 0 0 0 tanimsiz tanimsiz
Yakalama Sayısının Geçersiz Olduğu Yer
Alt tablonun ilk satırı bandı savunuyor görünür: 0,05’te 13 ateşleme, 7’si gerçek bozulmaya
denk geliyor. Bu sayı geçersizdir ve gerekçesi üst tablodadır. tahmin payi satırlarına bakın:
sağlam kurulumda 3 dönem ateşliyor, kavram kaymalı kurulumda yine tam 3 dönem. Aynı ölçü,
aynı bant, aynı ateşleme sayısı; tek fark, ikinci durumda o dönemlerin bozulmuş olması. Ateşleme
bozulmadan gelmiyor, bozulmayla aynı zamana denk düşüyor. Sağlam satır bunu kanıtlar: hiçbir şey
bozuk değilken de aynı üç dönem konuşuyor.
Bu kursun kuralının tam tanımıdır: ateşlemesi ile bozulması ayrı ayrı gösterilmeyen bir gösterge ölçülmemiş sayılır. Sağlam satır olmasaydı 0,05 bandındaki tahmin payı kusursuz bir gösterge gibi okunurdu — 3 ateşleme, 0 yanlış alarm. Sağlam satırla birlikte 7 yakalamanın 3’ü düşer ve geriye 4 kalır. O dördünü tek bir ölçü verir: isabet, iki zararsız senaryoda 0,05 ve 0,10 bantlarında hiç ateşlemeyip zararlı senaryoda dört dönemin dördünde ateşleyen tek satır. Bedeli son sütundadır: yakalama gecikmesi 2 dönem, ve bant seçilerek küçültülemez.
Yanlış Alarm ile Körlüğün Takası
Bandı genişletmek sayıyı düzeltmez, sıfırlar. 0,05’ten 0,10’a çıkıldığında yanlış alarm 6’dan 2’ye iner ve yakalanan 7’den 4’e — ama düşen üç yakalama zaten geçersiz olan tahmin payı yakalamalarıdır, yani 0,10 bandı hiçbir gerçek bilgi kaybetmeden yanlış alarmın üçte ikisini atar. Bu, bandı genişletmenin bedava olduğu tek adımdır.
0,20 satırı ise üç sıfırdır: yanlış alarm yok, ateşleme yok, yakalama yok. Bandın isabet üzerindeki karşılığı hesaplanabilir: 0,9700 tabanının 0,80 katı 0,7760‘tır, yani 0,20’lik bir bant isabetin bu değerin altına inmesini bekler. Kavram kaymasının en dip değeri 0,8150‘dir ve 0,7760’ın 0,0390 üstünde, yaklaşık sekiz çözünürlük adımı yukarıda kalır. Bant, ölçünün ulaşamayacağı bir yere konmuştur; sessizliği bir sağlık işareti değil, tanım gereği ölü bir göstergedir.
Üç bandı birlikte okumak kursun ikinci iddiasını verir: izleme de bozar. Dar bant hiçbir şeyin bozulmadığı bir üretimde altı kez uyandırır; geniş bant isabetin 0,9700’den 0,8150’ye düştüğü bir üretimde hiç konuşmaz. Aradaki bant yalnız bu kurguda iyi bir seçimdir, çünkü hangi ateşlemenin gerçek olduğunu gerçek isabete bakarak biliyoruz — üretimde o bilgi iki dönem sonra gelir ve bant onsuz seçilir.
Özet
- Uyarı eşiği bir ölçü değil bir seçimdir:
2026-08tabanından göreli sapmanın aşmaması gereken paydır ve ateşleyen dönem sayısını doğrudan belirler. - 0,05 bandında üç ölçü ve üç senaryo boyunca 13 dönem ateşler, 6’sı yanlış alarmdır; 0,10’da 6 ateşleme ve 2 yanlış alarm; 0,20’de üçü de sıfırdır.
- 0,05’teki 7 yakalamanın 3’ü geçersizdir: tahmin payı sağlam kurulumda da tam 3 dönem ateşler. Ateşlemesi ile bozulması ayrı ayrı gösterilmeyen gösterge ölçülmemiş sayılır; geçerli yakalama 4’tür ve hepsi isabetten gelir.
- İsabet, iki zararsız senaryoda hiç ateşlemeyip zararlı senaryoda dört dönemin dördünde ateşleyen tek ölçüdür; bedeli 2 dönemlik yakalama gecikmesidir ve bant seçimiyle küçültülemez.
- 0,20 bandı isabetin 0,7760’ın altına inmesini ister; en dip değer 0,8150’dir, yani bant ölçünün ulaşamayacağı yerdedir ve sessizliği bir sağlık işareti değildir.
Sonraki Adım
Bu dersin geçerli tek göstergesi isabetti ve isabet etiket ister. Şimdiye kadar etiket kurgunun bir armağanıydı: her satırın gerçek sınıfı biliniyordu, yalnız iki dönem geç geliyordu. Üretimde öyle değildir — etiket toplanır ve toplanan şey bütün tahminler için gelmez. Sonraki ders etiketin nereden geldiğini sorar: toplama yordamı tahminlerin ancak bir kısmını kapsadığında ölçülen isabetin gerçek isabetten ne kadar saptığını ve hangi toplama biçiminin kapsamı büyütürken yanlılığı da büyüttüğünü sayar.
İlerlemeni kaydetmek ve not almak için Giriş yap
Notlarım
Not almak için giriş yapmalısın.