Ders 06 / 11
Roller
Aynı kaçak problemi üç iş tanımında üç ayrı çıktıya ve üç ayrı taban çizgisine dönüşür. Veri bilimcinin tabanı sahanın bugünkü yordamıdır ve ilk 40 ziyarette 13 kaçak bulur, teslim ettiği model sırası 30 bulur, fark 17. Makine öğrenmesi mühendisinin tabanı bugün çalışan modeldir ve kayan veride 23 bulur, yeniden kurulan yordam 30 bulur, fark 7. Yapay zekâ mühendisinin tabanı modelsiz sistemdir ve en kötü durumda 21 bulur, sinyalli sistem 30 bulur, fark 9. Aynı model üç rolde 17, 7 ve 9 üretir; sayıyı belirleyen model değil seçilen tabandır. Yedeğe düşen sistem kayan veride 21 verir, hiç düşmeyen 23.
İçindekiler
Önceki ders akışı tek bir masadan yürüttü: bir kişi soruyu yazdı, öznitelikleri seçti, modeli kurdu, eşiği koydu ve sahayı izledi. Gerçekte bu adımlar farklı iş tanımları arasında bölünür ve bölünme yalnız işi paylaştırmakla kalmaz, teslim edilen şeyi de değiştirir.
Veri Analitiğine Giriş kursu üç analist rolünü kabul ölçütleriyle ayırmıştı: ölçen rol sayıyı, kararı bağlayan rol eşiği, genelleyen rol varsayımıyla birlikte bir genellemeyi teslim ediyordu. Bu ders aynı ayrımı makine öğrenmesi tarafında yapar ve ölçtüğü şey teslimin kendisi değil, her rolün seçtiği taban çizgisidir.
- MK32. Rol adları burada bir unvan değil bir iş tanımıdır: ne teslim edildiği ve hangi ölçüyle kabul edildiği. Hiçbir şirket, unvan standardı ya da belge anılmaz.
- MK33. Veri bilimci bir bulgu teslim eder: problem öngörülebilir mi ve ne kadar. Tabanı sahanın bugünkü yordamıdır, çünkü kanıtlaması gereken şey işin bugünkü hâlinden daha iyisinin mümkün olduğudur.
- MK34. Makine öğrenmesi mühendisi her gün çalışan bir yordam teslim eder. Tabanı bugün çalışan modeldir, çünkü işi bir şeyi baştan kanıtlamak değil, ayakta tutmaktır.
- MK35. Yapay zekâ mühendisi uçtan uca bir sistem teslim eder. Tabanı modelsiz kurulan aynı sistemdir ve ölçüsü ortalama değil en kötü durumdur, çünkü bir sistem en kötü gününde ne verdiği kadar güvenilirdir.
- MK36. Üç rol aynı modeli kullanır ve üç ayrı kazanç sayısı üretir. Sayıyı belirleyen model değil, seçilen taban çizgisidir.
- MK37. Bir yedek yol, ölçülmeden iyileştirme sayılmaz. Bu koşumda yedeğe düşen sistem kayan veride hiç düşmeyenden daha az kaçak bulmaktadır.
Kurgu Kümenin Yeniden Kurulması
# kurulum.py — 01. dersin kurgu kumesi ayni tohumla yeniden kurulur: okuma # tablosu, abone ozeti, kurgu etiket, egitim / ayrilmis ayrimi ve agac ogrenici. import math TOHUM, HAM, M32 = 20260218, 1400, 0xFFFFFFFF BOLGE = [("kuzey", 0.28, 21), ("guney", 0.22, 17), ("dogu", 0.18, 26), ("bati", 0.14, 14), ("merkez", 0.18, 23)] OZNITELIK = ["ortalama", "kisi_basi", "dusus", "sifir_okuma", "okuma_sayisi", "memnuniyet", "hane_kisi", "en_yuksek", "en_dusuk"] 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 _ab, _el, _seri = [], [], {} for i in range(HAM): r = uretec(TOHUM + i) b = BOLGE[ayrik(r(), [x[1] for x in BOLGE])] k = {"abone_no": 10001 + i, "bolge": b[0], "taban": b[2], "hane_kisi": ayrik(r(), [0.06, 0.24, 0.30, 0.24, 0.11, 0.05]), "memnuniyet": ayrik(r(), [0.08, 0.14, 0.27, 0.34, 0.17]) + 1} (_el if r() < 0.046 else _ab).append(k) _gecerli = {a["abone_no"] for a in _ab} for k in _ab + _el: r = uretec(TOHUM + 7000 + k["abone_no"]) for d in range(ayrik(r(), [0.05, 0.12, 0.21, 0.62])): t = 0.0 if r() < 0.038 else math.floor(k["taban"] * math.exp( (r() + r() + r() - 1.5) * 0.62) * (1 - d * 0.05) * 100 + 0.5) / 100 if k["abone_no"] in _gecerli: _seri.setdefault(k["abone_no"], []).append(t) r() ABONE = [] for k in _ab: t = _seri.get(k["abone_no"]) if not t: continue ort = sum(t) / len(t) a = {"abone_no": k["abone_no"], "bolge": k["bolge"], "seri": t, "hane_kisi": k["hane_kisi"], "memnuniyet": k["memnuniyet"], "okuma_sayisi": len(t), "ortalama": ort, "en_yuksek": max(t), "en_dusuk": min(t), "sifir_okuma": sum(1 for v in t if v == 0), "kisi_basi": ort / max(1, k["hane_kisi"]), "dusus": (t[0] - t[-1]) / t[0] if len(t) > 1 and t[0] > 0 else 0.0} r = uretec(TOHUM + 31000 + a["abone_no"]) a["suphe"] = 1 if (1.30 * a["sifir_okuma"] + 1.25 * (a["dusus"] > 0.45) + 1.05 * (a["kisi_basi"] > 12.0) + 0.65 * (a["okuma_sayisi"] < 3) + 0.45 * (a["memnuniyet"] <= 2) - 1.55 + (r() + r() - 1.0) * 1.1) > 0 else 0 ABONE.append(a) r = uretec(TOHUM + 90001) EGITIM, AYRILMIS = [], [] for a in ABONE: (EGITIM if r() < 0.70 else AYRILMIS).append(a) poz = lambda k: sum(a["suphe"] for a in k) dogruluk = lambda f, k: sum(1 for a in k if f(a) == a["suphe"]) / len(k) _saf = lambda k: 2 * (poz(k) / len(k)) * (1 - poz(k) / len(k)) if k else 0.0 def ogren(k, derinlik=3, en_az=40): """01. dersin acgozlu karar agaci: bolme olcutu ve durma kurali orada.""" en, secim = _saf(k) * len(k), None if derinlik and len(k) >= en_az: for oz in OZNITELIK: for e in sorted({a[oz] for a in k})[1:]: sol = [a for a in k if a[oz] < e] sag = [a for a in k if a[oz] >= e] m = _saf(sol) * len(sol) + _saf(sag) * len(sag) if m < en - 1e-9: en, secim = m, (oz, e, sol, sag) if secim is None: return 1 if 2 * poz(k) > len(k) else 0 s, g = ogren(secim[2], derinlik - 1, en_az), ogren(secim[3], derinlik - 1, en_az) return s if s == g else (secim[0], secim[1], s, g) def uygula(d, a): while isinstance(d, tuple): d = d[2] if a[d[0]] < d[1] else d[3] return d print(f"kurgu kume (tohum {TOHUM}): {len(ABONE)} abone, {len(EGITIM)} egitim, " f"{len(AYRILMIS)} ayrilmis, {poz(ABONE)} supheli")
kurgu kume (tohum 20260218): 1260 abone, 883 egitim, 377 ayrilmis, 327 supheli
Ortak Ölçü, Beş Sıralayıcı
Üç rolün karşılaştırılabilmesi için ölçü ortak olmalıdır. Ortak ölçü önceki dersten gelir: günlük kapasite 40 ziyarettir ve sayılan şey ilk 40 ziyarette bulunan kaçaktır. Ortak olmayan şey her rolün bu ölçüyü hangi tabana karşı okuduğudur.
Beş sıralayıcı iki veri düzeninde ölçülür. Birinci düzen dersin başındaki tablodur; ikincisi önceki derste kurulan kaymadır — ölçüm politikası değişmiş, sıfır okumalar kestirimle doldurulmuş, eksik dönemler tamamlanmıştır. Etiket iki düzende de aynıdır.
# siralayicilar.py — uc rolun ortak olcusu: gunluk kapasite kadar ziyarette # bulunan kacak. Bes ayri siralayici ve iki ayri veri duzeni yan yana olculur. import statistics from collections import Counter KAPASITE = 40 r = uretec(TOHUM + 7205) CALISAN = [ogren([EGITIM[int(r() * len(EGITIM))] for _ in EGITIM]) for _ in range(9)] r = uretec(TOHUM + 7206) kura = {a["abone_no"]: r() for a in ABONE} ilk = lambda f, s: poz(sorted(s, key=f)[:KAPASITE]) sira = lambda T: (lambda a: (-sum(uygula(d, a) for d in T), a["abone_no"])) saha = lambda a: (-a["ortalama"], a["abone_no"]) elle = lambda a: 1 if (a["sifir_okuma"] >= 1 or a["dusus"] > 0.50 or a["kisi_basi"] > 15.0) else 0 kural = lambda a: (-elle(a), -a["ortalama"], a["abone_no"]) def kayan(a): """05. dersteki olcum politikasi degisikligi: sifir okumalar kestirimle doldurulur, eksik donemler tamamlanir. Etiket degismez.""" dolu = [v for v in a["seri"] if v > 0] tem = round(statistics.fmean(dolu), 2) if dolu else 0.0 t = [v if v > 0 else tem for v in a["seri"]] + [tem] * (3 - len(a["seri"])) ort = sum(t) / len(t) return {**a, "seri": t, "okuma_sayisi": 3, "ortalama": ort, "en_yuksek": max(t), "en_dusuk": min(t), "sifir_okuma": sum(1 for v in t if v == 0), "kisi_basi": ort / max(1, a["hane_kisi"]), "dusus": (t[0] - t[-1]) / t[0] if t[0] > 0 else 0.0} KAYAN_E, KAYAN_A = [kayan(a) for a in EGITIM], [kayan(a) for a in AYRILMIS] r = uretec(TOHUM + 7305) GUNCEL = [ogren([KAYAN_E[int(r() * len(KAYAN_E))] for _ in KAYAN_E]) for _ in range(9)] isaret = lambda s: sum(1 for a in s if a["sifir_okuma"] > 0 or a["okuma_sayisi"] < 3) / len(s) E = [33, 12, 12, 12, 12] y = lambda h: str(h[0]).ljust(E[0]) + "".join(str(v).rjust(E[i + 1]) for i, v in enumerate(h[1:])) SIRALAYICI = [("rastgele sira", lambda a: kura[a["abone_no"]]), ("sahanin yordami: en cok tuketen", saha), ("elle yazilmis kural sirasi", kural), ("calisan model sirasi", sira(CALISAN)), ("kayan veriyle kurulan model", sira(GUNCEL))] print(f"ilk {KAPASITE} ziyarette bulunan kacak") print(y(["siralayici", "eski eg.", "eski ayr.", "kayan eg.", "kayan ayr."])) SAYI = {} for ad, f in SIRALAYICI: SAYI[ad] = [ilk(f, EGITIM), ilk(f, AYRILMIS), ilk(f, KAYAN_E), ilk(f, KAYAN_A)] print(y([ad] + SAYI[ad])) print(f"\nveri kalitesi sinyali (sifir okumasi ya da eksik donemi olan abone payi): " f"eskide {isaret(AYRILMIS):.4f}, kayanda {isaret(KAYAN_A):.4f}") print(f"ayrilmis kumede {poz(AYRILMIS)} supheli var; {KAPASITE} ziyaretin tavani {KAPASITE}")
ilk 40 ziyarette bulunan kacak siralayici eski eg. eski ayr. kayan eg. kayan ayr. rastgele sira 10 14 10 14 sahanin yordami: en cok tuketen 17 13 18 14 elle yazilmis kural sirasi 25 21 26 21 calisan model sirasi 30 30 33 23 kayan veriyle kurulan model 40 30 39 30 veri kalitesi sinyali (sifir okumasi ya da eksik donemi olan abone payi): eskide 0.3740, kayanda 0.0027 ayrilmis kumede 93 supheli var; 40 ziyaretin tavani 40
Tablo beş satırda beş ayrı yordam gösteriyor. Rastgele sıra 14 kaçak buluyor ve iki düzende de sabit; sorunun zorluğu değişmemiştir. Sahanın bugünkü yordamı — en çok tüketenden başlamak — ayrılmış kümede 13 buluyor, yani rastgele sıradan bile bir kaçak geride. Elle yazılmış kural sırası 21 buluyor. Çalışan model 30 buluyor, kayan veride 23’e düşüyor. Kayan veriyle yeniden kurulan model iki düzende de 30 veriyor.
Son satırdaki veri kalitesi sinyali kaymanın nereden geldiğini söylüyor: sıfır okuması ya da eksik dönemi olan abone payı 0,3740’tan 0,0027’ye inmiştir. Modelin dayandığı iki sütun tablodan silinmiştir ve bunu ölçen şey model değil, verinin kendisine bakan bir sayaçtır.
Üç Rol, Üç Taban
# roller.py — ayni model, uc is tanimi, uc ayri taban cizgisi. Her rol kendi # tabanini secer ve teslim ettigi sey o tabanla karsilastirilir. EN_KOTU = lambda s: min(s[1], s[3]) # iki veri duzeninin ayrilmis kume sayilari CALISAN_AD = "calisan model sirasi" GUNCEL_AD = "kayan veriyle kurulan model" YEDEKLI = [SAYI[CALISAN_AD][0], SAYI[CALISAN_AD][1], SAYI["elle yazilmis kural sirasi"][2], SAYI["elle yazilmis kural sirasi"][3]] ROL = [ ("veri bilimci", "sahanin bugunku yordami", SAYI["sahanin yordami: en cok tuketen"][1], "model sirasi", SAYI[CALISAN_AD][1]), ("makine ogrenmesi muh.", "bugun calisan model, kayan veride", SAYI[CALISAN_AD][3], "yeniden kurulan yordam", SAYI[GUNCEL_AD][3]), ("yapay zeka muhendisi", "modelsiz sistem, en kotu durum", EN_KOTU(SAYI["elle yazilmis kural sirasi"]), "sinyalli sistem, en kotu durum", EN_KOTU(SAYI[GUNCEL_AD])), ] D = [24, 34, 10, 32, 10, 8] z = lambda h: str(h[0]).ljust(D[0]) + str(h[1]).ljust(D[1]) + str(h[2]).rjust(D[2]) \ + " " + str(h[3]).ljust(D[3]) + str(h[4]).rjust(D[4]) + str(h[5]).rjust(D[5]) print(z(["rol", "sectigi taban cizgisi", "taban", "teslim ettigi", "teslim", "fark"])) for ad, tb_ad, tb, ts_ad, ts in ROL: print(z([ad, tb_ad, tb, ts_ad, ts, f"{ts - tb:+d}"])) print(f"\nyedege dusen sistem (sinyal dustugunde kural sirasina gecer): " f"eski veride {YEDEKLI[1]}, kayan veride {YEDEKLI[3]}, en kotu {min(YEDEKLI[1], YEDEKLI[3])}") print(f"hic dusmeyen sistem: eski {SAYI[CALISAN_AD][1]}, kayan {SAYI[CALISAN_AD][3]}, " f"en kotu {EN_KOTU(SAYI[CALISAN_AD])}")
rol sectigi taban cizgisi taban teslim ettigi teslim fark veri bilimci sahanin bugunku yordami 13 model sirasi 30 +17 makine ogrenmesi muh. bugun calisan model, kayan veride 23 yeniden kurulan yordam 30 +7 yapay zeka muhendisi modelsiz sistem, en kotu durum 21 sinyalli sistem, en kotu durum 30 +9 yedege dusen sistem (sinyal dustugunde kural sirasina gecer): eski veride 30, kayan veride 21, en kotu 21 hic dusmeyen sistem: eski 30, kayan 23, en kotu 23
Aynı model, aynı veri, aynı ölçü — ve üç ayrı kazanç: 17, 7 ve 9 kaçak. Üç sayı da doğrudur ve hiçbiri diğerinin yerine yazılamaz.
Veri bilimcinin 17’si bir kanıttır: sahanın bugünkü yordamı 40 ziyarette 13 kaçak buluyorsa ve bir model 30 buluyorsa, bu problem öğrenilebilir bir problemdir. Bu sayının ömrü kısadır; bir kez kanıtlandıktan sonra kimse aynı tabanı ikinci kez yazmaz.
Makine öğrenmesi mühendisinin 7’si bir bakım sayısıdır. Sahada zaten bir model çalışmaktadır ve o model kayan veride 23 vermektedir; teslim edilen yordam 30 verir. Yedi kaçak küçük görünür ama tabanı 13 değil 23’tür — mühendisin işi sıfırdan bir kazanç üretmek değil, üretilmiş kazancı kaybetmemektir.
Yapay zekâ mühendisinin 9’u bir dayanıklılık sayısıdır ve tek bir sayı değil iki düzenin en kötüsüdür. Modelsiz sistem her iki düzende de 21 verir; sinyalli sistem en kötü durumda 30 verir. Aradaki 9, ortalama bir kazanç değil, garanti edilen en düşük değerin farkıdır.
Yedek Yolun Ölçülmesi
Son iki satır bir tasarım kararını çürütüyor. Sinyal düştüğünde modeli bırakıp elle yazılmış kural sırasına geçen bir sistem, kayan veride 21 kaçak buluyor. Hiç düşmeyen, yani bozuk öznitelikle çalışmayı sürdüren sistem 23 buluyor. Yedeğe düşmek sayıyı iki kaçak kötüleştiriyor.
Bunun anlamı yedek yolun gereksiz olduğu değildir. Sinyalin değeri yedeğe geçmekte değil, haber vermektedir: 0,3740’tan 0,0027’ye inen bir sayaç, önceki dersteki yedinci adımdan ikinci adıma dönüşü tetikleyen şeydir ve o dönüş sonucunda kurulan model 30 vermektedir. Sinyal olmasaydı saha listesi yedi kaçak eksik üretmeye devam eder, yedeğe düşen sistemde ise dokuz kaçak eksik üretirdi.
Üç rolün ortak yanı burada görünüyor. Üçü de bir sayı teslim ediyor, üçü de o sayının yanına kendi tabanını yazıyor ve üçünün tabanı da bir seçimdir. Taban yazılmadığında üç rol de aynı cümleyi kurabilir: “sistem 40 ziyarette 30 kaçak buluyor.” Bu cümle üç kez doğru, üç kez ölçülmemiştir.
Özet
- Rol adları burada iş tanımıdır: ne teslim edildiği ve hangi ölçüyle kabul edildiği. Ölçü üçünde de aynıdır — ilk 40 ziyarette bulunan kaçak — tabanları farklıdır.
- Veri bilimcinin tabanı sahanın bugünkü yordamıdır ve 13 kaçak bulur; teslim ettiği model sırası 30 bulur, fark 17.
- Makine öğrenmesi mühendisinin tabanı bugün çalışan modeldir ve kayan veride 23 bulur; teslim ettiği yeniden kurulan yordam 30 bulur, fark 7.
- Yapay zekâ mühendisinin tabanı modelsiz sistemdir ve en kötü durumda 21 bulur; sinyalli sistemin en kötü durumu 30’dur, fark 9.
- Yedeğe düşen sistem kayan veride 21, hiç düşmeyen 23 bulur: bir yedek yol ölçülmeden iyileştirme sayılmaz ve sinyalin değeri yedekte değil haber vermektedir.
- Aynı model üç rolde 17, 7 ve 9 üretir; sayıyı belirleyen model değil seçilen tabandır.
Sonraki Adım
Altı ders boyunca her tablonun üç sütunu vardı: taban çizgisi, eğitimde ölçülen ve ayrılmış kümede ölçülen. Üçüncü sütun her seferinde basıldı ve hiçbir derste sorgulanmadı. Ayrımın niçin yapıldığı, hangi oranla yapıldığı, aynı ayrılmış kümeye kaç kez bakılabileceği, iki sayının niçin ayrıştığı bir kez bile sorulmadı. Sayı basıldı, yanından geçildi.
Oysa bu konuda o sütun birkaç kez konuşmaya çalıştı. Elle yazılmış kural eğitimde tabanı geçip ayrılmış kümede altında kaldı. Otuz etiketle kurulan model eğitimde 0,9400, ayrılmış kümede 0,7745 verdi ve etiket arttıkça iki sayı birbirine yaklaştı. Kayan veriyle kurulan model eğitim kümesinde 40 ziyaretin 40’ını da kaçakla doldurdu, ayrılmış kümede 30’da kaldı. Üç durumda da aynı şey oldu: modelin gördüğü veride ölçülen sayı, görmediği veride ölçülenden yüksek çıktı ve aradaki açık hiç açıklanmadı.
Sonraki konu bu açığı ele alır. Ayrımın gerekçesi yazılır, eğitim, doğrulama ve sınama kümeleri birbirinden ayrılır, model karmaşıklığı adım adım artırıldığında iki sayının hangi noktada ayrışmaya başladığı sayılır, aynı yordamın farklı örneklemlerde ne kadar oynadığı ölçülür ve ayrılmış kümede ölçülen sayıyı gerçekte olduğundan büyük gösteren dört ayrı yol tek tek uygulanır.
İlerlemeni kaydetmek ve not almak için Giriş yap
Notlarım
Not almak için giriş yapmalısın.