Ders 03 / 13
Başarım İzleme
Gerçek etiketin tahminle aynı anda gelmediği bir üretim kurulumunda başarımın ne zaman bilinebildiğinin ölçülmesi: bir dönemin isabeti ancak iki dönem sonra hesaplanabildiği için kavram kaymasının 2026-09'da düşürdüğü isabet ilk kez 2026-11'de görülebiliyor ve bu boşlukta 400 tahmin ölçülmeden üretiliyor. 2026-09'da gerçek isabet 0,8150 iken elde olan en yeni ölçü 2026-07'nin 0,9700'ü oluyor, yani gösterge yanlış değil eski. Gecikme süpürmesi bedeli doğrusal veriyor: 0 dönem gecikmede bozulma aynı dönemde görülüyor ve ölçülmeden üretilen tahmin 0, 1 dönemde 200, 2 dönemde 400, 3 dönemde 600, 4 dönemde bozulma izleme penceresi içinde hiç görülmüyor; etiket hiç toplanmadığında ölçülebilen dönem sayısı 0 ve bozulma hiçbir zaman görülmüyor.
İçindekiler
İki derste ortaya çıkan sonuç şuydu: kavram kaymasını gören tek gösterge isabettir. Girdi özeti kuralın kaydığından habersizdir, tahmin payı zararsız kaymada ateşleyip zararlı kaymada susar, isabet ise 0,9700’den 0,8150’ye düşerek bozulmayı adıyla gösterir.
Bu bulgunun sessizce yaptığı bir varsayım var. İsabet hesaplanabilmesi için satırın gerçekten yüksek olup olmadığının bilinmesi gerekir ve önceki iki derste bu bilgi hep elde varmış gibi davranıldı. Üretimde öyle değildir: tahmin dönem başında üretilir, gerçek etiket ise sayaç okunduktan, itiraz süresi geçtikten ve kayıt kapandıktan sonra gelir. Bu ders o gecikmeyi kurulumun içine koyar ve tek bir soruyu ölçer: hangi dönemin isabeti hangi dönemde bilinebiliyor.
- MI16. Kaynak, hat, model ve kavram kayması kurgudur; gerçek bir öğrenme kitaplığı, izleme ürünü ya da bulut servisi çağrılmaz. Tohum 20260218.
- MI17. Gecikmeli etiket (delayed label) gerçek etiketin tahminden sonra gelmesidir. Burada
gecikme
GECIKME = 2dönemdir: bir dönemin isabeti ancak iki dönem sonra hesaplanabilir. Süre ham birimle değil, dönem olarak yazılır. - MI18. Yakalama gecikmesi (detection delay) bozulmanın olduğu dönem ile ilk kez görülebildiği dönem arasındaki farktır. Bir göstergenin kaç dönem sonra gösterdiği ölçüsü Veri Hatları ve Orkestrasyon kursunda kuruldu; burada tekrarlanmaz, girdi olarak alınır.
- MI19. Bozulma kaynağı önceki dersin kavram kaymasıdır:
2026-09‘dan sonra yüksek sayılma eşiği 30’dan 27’ye iner. Girdi tarafında değişen değer yoktur. - MI20. İzleme dönemleri 2026-07…2026-12, dönem başına 200 satır, toplam 1200. İzleme dönemlerinde taban sınıf oranı 0,5342; küme dengelidir.
- MI21. Uyarı bandı 0,05’tir ve taban
2026-07’nin isabeti olan 0,9700’dür. Bant iki yönlüdür. - MI22. Taban çizgisi izlemesiz kurulumdur: etiket hiç toplanmaz, ölçülebilen dönem 0, bozulma görülmez.
- MI23. Çözünürlük: dönem isabetinin adımı 1/200 = 0,0050; kavram kaymasının düşürdüğü 0,1550, yani otuz bir adım ve bandın çok üstünde. Gecikme dönem olarak sayılır ve bir dönem 200 tahmin demektir.
Etiket İki Dönem Sonra
İlk blok önceki iki dersin kurulumunu kurar ve üstüne tek bir şey ekler: gorulen_donem. Bu
işlev bir dönemin isabetinin verili anda hesaplanabilir olup olmadığını söyler; hesabın kendisi
değişmez, yalnız ne zaman yapılabildiği değişir.
# KURGUDUR. Olcum aginin sayac okumalari, hattin modele bakan ilk uc asamasi, # esik tabanli model, kavram kaymasi ve etiket gecikmesi ders icinde tanimlanir; # gercek bir ogrenme kitapligi, izleme urunu ya da bulut servisi cagrilmaz. 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 in gor: continue gor.add(ad) tut.append(k) return tut, len(kayit) - len(tut) def a3_tuketim(kayit): """Donem farkindan tuketim. Onceki donem yoksa satir hesaplanamaz.""" tablo = {(k["abone"], k["donem"]): k for k in kayit} cikti, dusen = [], 0 for k in kayit: i = DONEM.index(k["donem"]) if i == 0: continue onceki = tablo.get((k["abone"], DONEM[i - 1])) if onceki is None: dusen += 1 continue cikti.append(dict(k, m3=int(k["endeks"]) - int(onceki["endeks"]))) return cikti, dusen def satirlar(): v, _ = a1_ayikla(kaynak_uret()) v, _ = a2_tekille(v) v, _ = a3_tuketim(v) return v def oznitelikler(kayitlar, basamak=4): """Oznitelik agirliktan bagimsizdir; tam gecmisten BIR KEZ hesaplanir.""" 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] return round(sum(secili) / len(secili), basamak) if secili else 0.0 return {(k["abone"], k["donem"]): { "abone_ort": ortalama(ab[k["abone"]], DONEM.index(k["donem"])), "bolge_ort": ortalama(bo[k["bolge"]], DONEM.index(k["donem"])), "isyeri": 1 if k["tip"] == "isyeri" else 0} for k in kayitlar} 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)] def puan(o, w): return w[0] * o["abone_ort"] + w[1] * o["bolge_ort"] + w[2] * o["isyeri"] KURAL_ESIK = 30 KURAL_ISYERI = 6 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 IZLEME = DONEM[6:] # 2026-07 .. 2026-12 : uretimde izlenen donemler KARAR_IZGARA = (18, 22, 26, 30, 34) # karar esigi ETIKET esiginden AYRI bir ayardir def tahmin(oz_k, w, karar): return 1 if puan(oz_k, w) > karar else 0 def dengeli_isabet(kume, oz, w, karar, kural=None): c = {(0, 0): 0, (0, 1): 0, (1, 0): 0, (1, 1): 0} for k in kume: o_k = oz[(k["abone"], k["donem"])] c[(tahmin(o_k, w, karar), kural(k, o_k) if kural else etiket(o_k))] += 1 du = c[(1, 1)] / max(c[(1, 1)] + c[(0, 1)], 1) # duyarlilik oz_ = c[(0, 0)] / max(c[(0, 0)] + c[(1, 0)], 1) # ozgulluk return {"isabet": (c[(1, 1)] + c[(0, 0)]) / len(kume), "duyarlilik": du, "ozgulluk": oz_, "dengeli": (du + oz_) / 2, "agirlik": w, "karar": karar} def egit(kayitlar, oz, donemler=None, kural=None): """Egitim = agirlik ucLUsu ILE karar esigini birlikte aramak: 27 x 5 = 135 aday.""" kume = [k for k in kayitlar if k["donem"] in (donemler or DONEM[1:9])] return max((dengeli_isabet(kume, oz, w, karar, kural) for w in IZGARA for karar in KARAR_IZGARA), key=lambda o: o["dengeli"]) def isabet(kayitlar, model, oz, donem, etiketler=None): """etiketler=None -> kural degismemis demektir.""" kume = [k for k in kayitlar if k["donem"] == donem] d = 0 for k in kume: o_k = oz[(k["abone"], k["donem"])] g = etiketler[(k["abone"], k["donem"])] if etiketler else etiket(o_k) d += tahmin(o_k, model["agirlik"], model["karar"]) == g return round(d / len(kume), 4) # ---- KURGU kavram kaymasi (onceki ders): GIRDI AYNI KALIR , kural degisir. def kavram_kaydir(kayitlar, oz, baslangic="2026-09", yeni_esik=27): 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} GECIKME = 2 # bir donemin etiketi kac donem sonra eline geciyor def gorulen_donem(donem, simdi, gecikme=GECIKME): """Bir donemin isabeti ancak `gecikme` donem sonra hesaplanabilir.""" return DONEM.index(donem) + gecikme <= DONEM.index(simdi) S = satirlar() OZ = oznitelikler(S) MODEL = egit(S, OZ) YENI = kavram_kaydir(S, OZ) IZL = [k for k in S if k["donem"] in IZLEME] dag = {0: 0, 1: 0} for k in IZL: dag[etiket(OZ[(k["abone"], k["donem"])])] += 1 GERCEK = {d: isabet(S, MODEL, OZ, d, YENI) for d in IZLEME} print("izleme satiri:", len(IZL), " donem basina:", len(IZL) // len(IZLEME), " taban sinif orani:", round(dag[0] / len(IZL), 4), " gecikme:", GECIKME, "donem") print("gercek isabet:", [f"{GERCEK[d]:.4f}" for d in IZLEME])
izleme satiri: 1200 donem basina: 200 taban sinif orani: 0.5342 gecikme: 2 donem gercek isabet: ['0.9700', '0.9700', '0.8150', '0.8700', '0.8650', '0.8500']
GERCEK sözlüğü, sonradan bakan birinin görebileceği isabet dizisidir. Üretimde duran biri bu
dizinin tamamını hiçbir zaman elinde tutmaz; her dönemde onun yalnız bir önekini görür.
Hangi Dönemin İsabeti Hangi Dönemde Bilinir
İkinci blok her dönem için üretimdeki tabloyu kurar: o anda ölçülebilen en yeni dönem, o dönemin isabeti, o andaki gerçek isabet ve elde olup henüz ölçülmemiş tahmin sayısı. Üçüncü sütun bir gözlemcinin değil, sonradan bakanın bilgisidir; üretimde duran kişi ikinci sütuna bakar.
BANT, TABAN = 0.05, GERCEK[IZLEME[0]] print(f"{'simdi':<10}{'olculebilen son donem':>22}{'o donemin isabeti':>19}" f"{'simdiki gercek isabet':>23}{'olculmemis tahmin':>19}") for simdi in IZLEME: olculen = [d for d in IZLEME if gorulen_donem(d, simdi)] uretilen = IZLEME[: IZLEME.index(simdi) + 1] son = olculen[-1] if olculen else None print(f"{simdi:<10}{(son or '-'):>22}" f"{(f'{GERCEK[son]:.4f}' if son else '-'):>19}{GERCEK[simdi]:>23.4f}" f"{(len(uretilen) - len(olculen)) * 200:>19}") BOZULAN = next(d for d in IZLEME if abs(GERCEK[d] - TABAN) / TABAN > BANT) GORULEN = next(s for s in IZLEME if any(gorulen_donem(d, s) and abs(GERCEK[d] - TABAN) / TABAN > BANT for d in IZLEME)) print("\nbozulmanin oldugu donem:", BOZULAN, " uyarinin atesleyebildigi donem:", GORULEN, " gorulme gecikmesi:", DONEM.index(GORULEN) - DONEM.index(BOZULAN), "donem") BOSLUK = IZLEME[IZLEME.index(BOZULAN):IZLEME.index(GORULEN)] print("bu boslukta olculmeden uretilen tahmin:", len(BOSLUK) * 200, " bosluktaki donemler:", BOSLUK) print("bunlarin sonradan yanlis oldugu anlasilan sayisi:", sum(round((1 - GERCEK[d]) * 200) for d in BOSLUK), " kural degismeseydi olacak sayi:", sum(round((1 - isabet(S, MODEL, OZ, d)) * 200) for d in BOSLUK))
simdi olculebilen son donem o donemin isabeti simdiki gercek isabet olculmemis tahmin 2026-07 - - 0.9700 200 2026-08 - - 0.9700 400 2026-09 2026-07 0.9700 0.8150 400 2026-10 2026-08 0.9700 0.8700 400 2026-11 2026-09 0.8150 0.8650 400 2026-12 2026-10 0.8700 0.8500 400 bozulmanin oldugu donem: 2026-09 uyarinin atesleyebildigi donem: 2026-11 gorulme gecikmesi: 2 donem bu boslukta olculmeden uretilen tahmin: 400 bosluktaki donemler: ['2026-09', '2026-10'] bunlarin sonradan yanlis oldugu anlasilan sayisi: 63 kural degismeseydi olacak sayi: 7
Bozulmanın olduğu dönem 2026-09‘dur ve o dönemde ekranda duran sayı 0,9700‘dür. Bu sayı
yanlış değildir; 2026-07‘nin isabeti gerçekten 0,9700’dü. Sayı yalnızca eskidir ve eskiliği
hiçbir yerde yazmıyorsa yanlıştan ayırt edilemez. Bir sonraki dönemde de aynı şey olur: gerçek
isabet 0,8700’e inmişken elde olan en yeni ölçü hâlâ 0,9700’dür.
Uyarının ateşleyebildiği ilk dönem 2026-11’dir, çünkü 2026-09‘un etiketleri ancak o zaman
tamamlanır. Yakalama gecikmesi iki dönemdir ve bu boşlukta 400 tahmin ölçülmeden
üretilmiştir. Bu 400 tahminin **63’ünün** yanlış olduğu sonradan anlaşılır; kural değişmeseydi
aynı iki dönemde yanlış sayısı 7 olacaktı. Aradaki 56 tahmin, bozulmanın görülmediği süre
boyunca üretilip kullanılmış olanlardır ve geriye dönüp düzeltilemezler, çünkü karar zaten
verilmiştir.
Dikkat edilecek ikinci şey son sütundur: boşluk kapandıktan sonra da her dönemde 400 tahmin ölçülmemiş durumda kalır. Gecikme geçici bir başlangıç sorunu değil, sürekli taşınan bir borçtur; üretimdeki gösterge hiçbir zaman şimdiyi göstermez, her zaman iki dönem öncesini gösterir.
Gecikmenin Bedeli
Üçüncü blok gecikmeyi süpürür. Kurulumun geri kalanı sabittir; değişen tek şey etiketin kaç dönem sonra geldiğidir. Son satır izlemesiz taban çizgisidir: etiket hiç toplanmaz.
SON = len(IZLEME) - IZLEME.index(BOZULAN) # bozulmadan sonraki donem sayisi print(f"{'gecikme':<12}{'bozulma gorulur':>18}{'gorulme gecikmesi':>19}" f"{'olculebilen donem':>19}{'olculmeden uretilen':>21}") for g in (0, 1, 2, 3, 4): gor = next((s for s in IZLEME if any(gorulen_donem(d, s, g) and abs(GERCEK[d] - TABAN) / TABAN > BANT for d in IZLEME)), None) gec = DONEM.index(gor) - DONEM.index(BOZULAN) if gor else SON print(f"{g:<12}{(gor or 'gorulmedi'):>18}{(gec if gor else '-'):>19}" f"{sum(1 for d in IZLEME if gorulen_donem(d, IZLEME[-1], g)):>19}{gec * 200:>21}") print(f"{'etiket yok':<12}{'gorulmedi':>18}{'-':>19}{0:>19}{SON * 200:>21}")
gecikme bozulma gorulur gorulme gecikmesi olculebilen donem olculmeden uretilen 0 2026-09 0 6 0 1 2026-10 1 5 200 2 2026-11 2 4 400 3 2026-12 3 3 600 4 gorulmedi - 2 800 etiket yok gorulmedi - 0 800
Bedel doğrusaldır ve birimi bellidir: her dönemlik gecikme 200 ölçülmemiş tahmin demektir.
Dördüncü satırda gecikme, izleme penceresinin sonuna dayanır; bozulma 2026-09’da olmuştur ama
etiketi 2027-01’de geleceği için pencere içinde hiç görülmez. Bu satır önemlidir, çünkü
gecikme yeterince büyüdüğünde ölçü var olmayı sürdürür ama işe yaramaz.
Son satır izlemesiz taban çizgisidir ve gecikme 4 ile aynı sonucu verir: bozulma görülmez, 800 tahmin ölçülmeden üretilir. Aradaki tek fark ölçülebilen dönem sayısındadır, 2’ye karşı 0. Kursun kuralı burada da geçerlidir: bir gösterge ancak ateşleyebildiği zaman ölçülmüş sayılır ve ateşlemesi pencere dışına düşen bir gösterge ölçülmemiş bir güvence verir.
Özet
- İsabet, girdi özeti ile tahmin payından farklı olarak gerçek etiket ister; etiket üretimde tahminle aynı anda gelmez ve bu kurulumda iki dönem sonra gelir.
- Bozulma
2026-09’da olur, ama uyarının ateşleyebildiği ilk dönem 2026-11‘dir: görülme gecikmesi iki dönem ve bu boşlukta 400 tahmin ölçülmeden üretilmiştir; bunların **63’ünün** yanlış olduğu sonradan anlaşılır, kural değişmeseydi sayı 7 olacaktı. 2026-09‘da ekrandaki sayı 0,9700’dür ve yanlış değildir, yalnızca iki dönem eskidir; eskiliği yazılmayan bir gösterge yanlış bir göstergeden ayırt edilemez.- Boşluk kapandıktan sonra da her dönemde 400 tahmin ölçülmemiş kalır: gecikme geçici değil, sürekli taşınan bir borçtur.
- Süpürme bedeli doğrusal verir: gecikme 0’da 0, 1’de 200, 2’de 400, 3’te 600 ölçülmemiş tahmin; 4’te bozulma izleme penceresi içinde hiç görülmez ve izlemesiz taban çizgisinde ölçülebilen dönem sayısı 0’dır.
Sonraki Adım
Üç derste bozulmanın görülmesi ölçüldü ve son ölçü bir boşluk bıraktı: bozulma olduktan sonra iki dönem boyunca tek gören ölçü suskundur ve o boşlukta 400 tahmin ölçülmeden üretilir. Bu boşlukta elde ne olduğu ise hiç sorulmadı. Girdi özeti ve tahmin payı oradadır, etiket beklemeden hesaplanırlar ve önceki derste ikisinin de yanıltabildiği görüldü. Sonraki ders bunları vekil ölçüt olarak ele alır ve tek tek ne gördüklerini sayar: hangi vekil kavram kaymasını görebiliyor, hangisi zararsız kaymada ateşliyor ve girdi eksiksizliği gibi üçüncü bir vekil eklendiğinde tablo değişiyor mu.
İlerlemeni kaydetmek ve not almak için Giriş yap
Notlarım
Not almak için giriş yapmalısın.