Ders 14 / 20
Sınıflandırma Ölçütleri
Karışıklık matrisinden türeyen dört ölçütün beş modeli farklı sıralaması: doğrulukta birinci olan model kesinlikte ikinci, duyarlılıkta ve F1 ölçütünde dördüncü olur, dört ölçütte üç ayrı model başa geçer ve doğruluk ile F1 arasında on model çiftinin yedisi yer değiştirir. Taban çizgisi hiçbir aboneyi işaretlemediği için kesinliği tanımsızdır, duyarlılığı ve F1 ölçütü sıfırdır. Kesinliği 1,0000 duyarlılığı 0,0164 olan bir yordamın sıradan ortalaması 0,5082 iken F1 ölçütü 0,0323'tür ve aradaki fark 0,4759'a çıkar.
İçindekiler
Önceki ders doğruluğu dört hücreye ayırdı ama hücrelerden türeyen ölçütlerin hiçbirini adlandırmadı. Öznitelik mühendisliği kursunun dengesiz sınıflar dersi ise iki adı yazmış — doğru işaretlenen azınlık payına kesinlik, yakalanan azınlık payına duyarlılık — ham sayıları basmış, tanımları ve ikisinin birbirine karşı okunmasını bu kursa bırakmıştı. Bu ders o sözü öder.
Ölçü şudur: beş model dört ölçütte ayrı ayrı sıralanır ve kaç ölçütte sıralamanın başının değiştiği sayılır. Ölçüt değiştiğinde sıralama korunuyorsa hangisinin seçildiği önemsizdir; sıra dönüyorsa ölçüt seçimi model seçiminden önce gelen bir karardır ve o karar veriden okunamaz.
- MD8. Dört ölçütün hepsi tek bir karışıklık matrisinden türer; yeni ölçüm yapılmaz, aynı dört sayı başka biçimde birleştirilir.
- MD9. Beş model önceki dersin kırk dokuz adaylık ızgarasından alınır. Bu derste eğitilen aday sayısı beştir; seçim ölçüt çeşitliliği için yapılmıştır, sınama kümesindeki sayıya göre değil.
- MD10. Kesinliğin paydası modelin işaretlediği abone sayısıdır ve sıfır olabilir. Sıfırken kesinlik tanımsızdır, sıfır değildir; taban çizgisi bu durumdadır.
- MD11. Duyarlılığın paydası sınama kümesindeki 61 şüphelidir ve modelden bağımsızdır.
- MD12. F1 ölçütü kesinlik ile duyarlılığın uyumlu ortalamasıdır; doğru olumlu sayısı sıfırsa sıfır yazılır.
- MD13. Dört ölçüt de karar eşiği 0,5’te okunur. Eşiğin oynattığı sayı sonraki derste ölçülür.
- MD14. Sıralamalar yalnız beş model üzerinde kurulur; taban çizgisi karşılaştırma satırıdır ve sıralamaya girmez.
- MD15. Dengesiz sınıflar dersinin sayıları tekrarlanmaz. Oradaki küme on bir öznitelikliydi, buradaki on iki; sayılar birebir karşılaştırılamaz, ölçüt tanımları karşılaştırılır.
Dört Hücreden Dört Ölçüt
Doğruluk, doğru olumlu ile doğru olumsuz toplamının bütün gözlemlere oranıdır. Kesinlik, şüpheli denen abonelerin kaçının gerçekten şüpheli olduğudur: doğru olumlunun, doğru olumlu ile yanlış olumlu toplamına oranı. Duyarlılık, gerçekten şüpheli abonelerin kaçının yakalandığıdır: doğru olumlunun, doğru olumlu ile yanlış olumsuz toplamına oranı. Kesinlik modelin işaretlediği sütuna bakar, duyarlılık gerçeğin şüpheli satırına. F1 ölçütü ikisini tek sayıda birleştirir ve birleştirme sıradan ortalama değil uyumlu ortalamadır: , burada kesinlik, duyarlılıktır.
# degerlendirme.py — MODELDIR. Kurgu abone tablosu ayni tohumla yeniden uretilir. import math TOHUM, ADAY, M32 = 20260218, 1400, 0xFFFFFFFF BOLGE = [("kuzey", 0.28, 21, 0.00), ("guney", 0.22, 17, -0.10), ("dogu", 0.18, 26, 0.30), ("bati", 0.14, 14, -0.05), ("merkez", 0.18, 23, 0.05)] 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 ABONE, OKUMA = [], {} for i in range(ADAY): r = uretec(TOHUM + i) b = BOLGE[ayrik(r(), [x[1] for x in BOLGE])] hane = 1 + ayrik(r(), [0.06, 0.24, 0.30, 0.24, 0.11, 0.05]) memnun = 1 + ayrik(r(), [0.08, 0.14, 0.27, 0.34, 0.17]) if r() >= 0.046: ABONE.append({"no": 10001 + i, "bolge": b, "hane": hane, "memnuniyet": memnun}) for k in ABONE: r = uretec(TOHUM + 7000 + k["no"]) for d in range(ayrik(r(), [0.05, 0.12, 0.21, 0.62])): OKUMA.setdefault(k["no"], []).append(0.0 if r() < 0.038 else math.floor( k["bolge"][2] * math.exp((r() + r() + r() - 1.5) * 0.62) * (1 - d * 0.05) * 100 + 0.5) / 100) r() VERI = [] for k in ABONE: v = OKUMA.get(k["no"]) if not v: continue ort, oyn, r = sum(v) / len(v), max(v) - min(v), uretec(TOHUM + 51000 + k["no"]) z = (0.052 * (ort - 20) + 0.85 * (min(v) == 0.0) + 0.026 * oyn + 0.24 * (k["hane"] >= 5) - 0.20 * (k["memnuniyet"] >= 4) + k["bolge"][3] + 0.9 * (k["no"] - 10001) / 1399 + (r() + r() + r() - 1.5) * 1.30) x = {"hane": k["hane"], "memnuniyet": k["memnuniyet"], "donem": len(v), "ort_tuketim": round(ort, 2), "oynaklik": round(oyn, 2), "sifir_okuma": int(min(v) == 0.0), "supheli": int(z > 1.35)} x["kisi_basi"] = round(x["ort_tuketim"] / x["hane"], 3) for b in BOLGE: x["b_" + b[0]] = int(k["bolge"][0] == b[0]) VERI.append(x) def karistir(veri, tohum): r, s = uretec(tohum), list(range(len(veri))) for i in range(len(s) - 1, 0, -1): j = int(r() * (i + 1)) s[i], s[j] = s[j], s[i] return [veri[i] for i in s] K = karistir(VERI, TOHUM + 90000) EGT, DOG, SIN = K[:756], K[756:1008], K[1008:] ALAN = ["ort_tuketim", "oynaklik", "hane", "memnuniyet", "donem", "sifir_okuma", "kisi_basi", "b_kuzey", "b_guney", "b_dogu", "b_bati", "b_merkez"] def safsizlik(s): n = sum(x.get("w", 1.0) for x in s) p = sum(x.get("w", 1.0) * x["supheli"] for x in s) / n return 2 * p * (1 - p) def agac(s, derinlik, alan, enaz=2): # MODELDIR: agirlikli karar agaci n = sum(x.get("w", 1.0) for x in s) p = sum(x.get("w", 1.0) * x["supheli"] for x in s) / n en = None if derinlik and len(s) >= 2 * enaz and 0.0 < p < 1.0: for a in alan: d = sorted({x[a] for x in s}) for v in (d[1:] if len(d) < 10 else [d[int(i * len(d) / 10)] for i in range(1, 10)]): sol = [x for x in s if x[a] < v] sag = [x for x in s if x[a] >= v] if min(len(sol), len(sag)) < enaz: continue k = safsizlik(s) - (sum(x.get("w", 1.0) for x in sol) * safsizlik(sol) + sum(x.get("w", 1.0) for x in sag) * safsizlik(sag)) / n if en is None or k > en[0]: en = (k, a, v, sol, sag) if en is None or en[0] <= 1e-9: return {"p": p} return {"alan": en[1], "esik": en[2], "sol": agac(en[3], derinlik - 1, alan, enaz), "sag": agac(en[4], derinlik - 1, alan, enaz)} def olasilik(d, x): while "p" not in d: d = d["sol"] if x[d["alan"]] < d["esik"] else d["sag"] return d["p"] def agirlikla(egt, w): return [dict(x, w=(w if x["supheli"] else 1.0)) for x in egt] def matris(skor, veri, esik=0.5): # do, yo, yn, dn m = [0, 0, 0, 0] for x in veri: i = (0 if x["supheli"] else 1) + (0 if skor(x) >= esik else 2) m[i] += 1 return m def olcek(egt, alan): o = {a: sum(x[a] for x in egt) / len(egt) for a in alan} s = {a: (sum((x[a] - o[a]) ** 2 for x in egt) / len(egt)) ** 0.5 or 1.0 for a in alan} return lambda x: [(x[a] - o[a]) / s[a] for a in alan] def dogrusal(egt, alan, w, tur=300, adim=0.5): # MODELDIR: egim temelli dogrusal model f, k, b = olcek(egt, alan), [0.0] * len(alan), 0.0 X = [f(x) for x in egt] y = [x["supheli"] for x in egt] a = [(w if x["supheli"] else 1.0) for x in egt] n = sum(a) for _ in range(tur): gk, gb = [0.0] * len(alan), 0.0 for i, xi in enumerate(X): z = b + sum(k[j] * xi[j] for j in range(len(k))) e = (1 / (1 + math.exp(-max(-30.0, min(30.0, z)))) - y[i]) * a[i] gb += e for j in range(len(k)): gk[j] += e * xi[j] b -= adim * gb / n for j in range(len(k)): k[j] -= adim * gk[j] / n def skor(x): v = f(x) z = b + sum(k[j] * v[j] for j in range(len(k))) return 1 / (1 + math.exp(-max(-30.0, min(30.0, z)))) return skor NS = sum(x["supheli"] for x in SIN) MODEL = {} for ad, d, w in (("derinlik 5 agac", 5, 1.0), ("derinlik 3 agac", 3, 1.0), ("derinlik 8 agac", 8, 1.0), ("derinlik 6 agac a3", 6, 3.0)): t = agac(agirlikla(EGT, w), d, ALAN) MODEL[ad] = matris(lambda x, t=t: olasilik(t, x), SIN) MODEL["dogrusal a2.5"] = matris(dogrusal(EGT, ALAN, 2.5), SIN) MODEL["taban cizgisi"] = [0, 0, NS, len(SIN) - NS] def olcutler(m): do, yo, yn, dn = m k = do / (do + yo) if do + yo else float("nan") du = do / (do + yn) return (do + dn) / sum(m), k, du, (2 * k * du / (k + du) if do else 0.0) print(f"{'model':<18}{'dogruluk':>9}{'kesinlik':>9}{'duyarlilik':>11}{'F1':>8}" f"{'isaretli':>9}") for ad, m in MODEL.items(): d, k, du, f = olcutler(m) print(f"{ad:<18}{d:>9.4f}{('tanimsiz' if k != k else f'{k:.4f}'):>9}" f"{du:>11.4f}{f:>8.4f}{m[0] + m[1]:>9}")
model dogruluk kesinlik duyarlilik F1 isaretli derinlik 5 agac 0.8016 0.6571 0.3770 0.4792 35 derinlik 3 agac 0.7937 0.6800 0.2787 0.3953 25 derinlik 8 agac 0.7817 0.5517 0.5246 0.5378 58 derinlik 6 agac a3 0.7302 0.4545 0.5738 0.5072 77 dogrusal a2.5 0.7659 0.5135 0.6230 0.5630 74 taban cizgisi 0.7579 tanimsiz 0.0000 0.0000 0
Taban çizgisi satırı üç ölçütü birden bozuyor. Hiçbir aboneyi işaretlemeyen yordamın kesinliği tanımsızdır — bölünecek bir şey yoktur — duyarlılığı ve F1 ölçütü sıfırdır. Doğrulukta 0,7579 okuyan aynı yordam öbür üç ölçütte kullanılamaz bir sonuç verir. Bu, dengesiz sınıflar dersinin ham sayılarla gösterdiği tablonun tanımlanmış halidir.
Beş model satırında iki sütun ters yönde ilerliyor. İşaretlenen abone sayısı 25’ten 77’ye çıkarken kesinlik 0,6800’den 0,4545’e iniyor, duyarlılık 0,2787’den 0,5738’e çıkıyor. Az işaretleyen model işaretlediklerinde daha çok haklıdır ama çoğunu kaçırır; çok işaretleyen model daha azını kaçırır ama işaretlediklerinin yarısından çoğu boştur. Doğruluk sütunu bu takasa neredeyse kayıtsız: en yüksek ile en düşük arasında 0,0714 puan var, kesinlikte 0,2255, duyarlılıkta 0,3443 puan.
Sıralama Ölçütle Birlikte Dönüyor
Aynı beş model dört ölçütte ayrı ayrı sıralanır ve sıralamalar yan yana basılır.
BES = [a for a in MODEL if a != "taban cizgisi"] OLCUT = ("dogruluk", "kesinlik", "duyarlilik", "F1") SIRA = {o: {a: j + 1 for j, a in enumerate( sorted(BES, key=lambda a: -olcutler(MODEL[a])[i]))} for i, o in enumerate(OLCUT)} print(f"{'model':<18}" + "".join(f"{o:>11}" for o in OLCUT)) for a in BES: print(f"{a:<18}" + "".join(f"{SIRA[o][a]:>11}" for o in OLCUT)) bas = [min(SIRA[o], key=SIRA[o].get) for o in OLCUT] print(f"\nolcut basindaki model: {' | '.join(bas)}") print(f"dort olcutte {len(set(bas))} ayri model basa geciyor; dogrulugun sectigi " f"model {sum(1 for b in bas[1:] if b != bas[0])} olcutte basta degil") ters = sum(1 for i in range(len(BES)) for j in range(i + 1, len(BES)) if (SIRA["dogruluk"][BES[i]] - SIRA["dogruluk"][BES[j]]) * (SIRA["F1"][BES[i]] - SIRA["F1"][BES[j]]) < 0) print(f"dogruluk ile F1 arasinda yer degistiren model cifti {ters} / " f"{len(BES) * (len(BES) - 1) // 2}")
model dogruluk kesinlik duyarlilik F1 derinlik 5 agac 1 2 4 4 derinlik 3 agac 2 1 5 5 derinlik 8 agac 3 3 3 2 derinlik 6 agac a3 5 5 2 3 dogrusal a2.5 4 4 1 1 olcut basindaki model: derinlik 5 agac | derinlik 3 agac | dogrusal a2.5 | dogrusal a2.5 dort olcutte 3 ayri model basa geciyor; dogrulugun sectigi model 3 olcutte basta degil dogruluk ile F1 arasinda yer degistiren model cifti 7 / 10
Doğruluk sütunu 1’den 5’e düzgün iniyor çünkü modeller doğruluğa göre listelendi. Öbür üç sütun o düzeni tanımıyor. Doğrulukta birinci olan derinlik 5 ağacı kesinlikte ikinci, duyarlılıkta ve F1 ölçütünde dördüncü. Doğrulukta ikinci olan derinlik 3 ağacı kesinlikte birinci ama duyarlılıkta ve F1 ölçütünde sonuncu. Doğrulukta dördüncü olan doğrusal model duyarlılıkta ve F1 ölçütünde birinci.
Sayılar üç yerde toplanıyor. Dört ölçütte üç ayrı model başa geçiyor; doğruluğun seçtiği model dört ölçütün üçünde başta değil; doğruluk ile F1 arasında on model çiftinin yedisi yer değiştiriyor. Sıralama ölçüde değil, ölçütte kuruluyor. Bir modelin sayısını hangi bütçeyle bulduğunu yazmak yetmez — hangi ölçütle sıralandığını da yazmak gerekir, çünkü beş model dört ölçütte dört ayrı yarışa girmiştir.
Uyumlu Ortalama Niçin Ortalama Değil
F1 ölçütü kesinlik ile duyarlılığı sıradan ortalamayla birleştirseydi, bir tarafı yüksek öbür tarafı sıfıra yakın olan bir yordam orta yerde görünürdü. Uyumlu ortalama küçük olana ağırlık verir. Fark, iki sayı ayrıştıkça büyür ve büyümesi sayılabilir.
print(f"{'kesinlik':>9}{'duyarlilik':>11}{'ortalama':>10}{'F1':>8}{'fark':>8}") for k, du in ((1.00, 1 / 61), (0.90, 0.10), (0.70, 0.30), (0.60, 0.40), (0.50, 0.50)): o, f = (k + du) / 2, 2 * k * du / (k + du) print(f"{k:>9.4f}{du:>11.4f}{o:>10.4f}{f:>8.4f}{o - f:>8.4f}") ORT = {a: sum(olcutler(MODEL[a])[1:3]) / 2 for a in BES} print(f"\n{'model':<18}{'ortalama':>10}{'F1':>8}{'fark':>8}{'ort/F1 sirasi':>15}") for j, a in enumerate(sorted(BES, key=lambda a: -ORT[a])): f = olcutler(MODEL[a])[3] sira = str(j + 1) + " / " + str(SIRA["F1"][a]) print(f"{a:<18}{ORT[a]:>10.4f}{f:>8.4f}{ORT[a] - f:>8.4f}{sira:>15}")
kesinlik duyarlilik ortalama F1 fark 1.0000 0.0164 0.5082 0.0323 0.4759 0.9000 0.1000 0.5000 0.1800 0.3200 0.7000 0.3000 0.5000 0.4200 0.0800 0.6000 0.4000 0.5000 0.4800 0.0200 0.5000 0.5000 0.5000 0.5000 0.0000 model ortalama F1 fark ort/F1 sirasi dogrusal a2.5 0.5682 0.5630 0.0053 1 / 1 derinlik 8 agac 0.5382 0.5378 0.0003 2 / 2 derinlik 5 agac 0.5171 0.4792 0.0379 3 / 4 derinlik 6 agac a3 0.5142 0.5072 0.0069 4 / 3 derinlik 3 agac 0.4793 0.3953 0.0840 5 / 5
İlk tablonun ilk satırı uç durumu gösteriyor: tek bir aboneyi işaretleyen ve o abonede haklı çıkan bir yordamın kesinliği 1,0000, duyarlılığı 0,0164’tür. Sıradan ortalama 0,5082 verir — beş gerçek modelin hepsinden yüksek bir sayı — F1 ölçütü 0,0323 verir. Aradaki fark 0,4759. Ortadaki üç satır aynı sıradan ortalamayı, 0,5000’i, üç ayrı F1 değeriyle karşılıyor: 0,1800, 0,4200 ve 0,4800. İki sayı eşitlendiğinde fark sıfırlanır. Uyumlu ortalamanın yaptığı tek şey, iki ölçütten biri çöktüğünde birleşik sayının da çökmesini sağlamaktır.
İkinci tablo aynı hesabı gerçek modellerde gösteriyor. Kesinlik ile duyarlılığı birbirine yakın olan derinlik 8 ağacında iki ortalama arasındaki fark 0,0003; ikisi en çok ayrışan derinlik 3 ağacında 0,0840. Sıralama da bir yerde bozuluyor: sıradan ortalamaya göre üçüncü olan derinlik 5 ağacı F1 ölçütünde dördüncü, dördüncü olan ağırlıklı ağaç üçüncü sıraya geçiyor. İki modelin kesinlik ve duyarlılık toplamı neredeyse aynıdır (0,5171 ile 0,5142) ama dağılımı farklıdır ve uyumlu ortalama dağılımı görür.
Özet
- Kesinlik modelin işaretlediği sütundan, duyarlılık gerçeğin şüpheli satırından okunur; doğruluk ikisini de kullanmaz, dört hücrenin iki köşegenini toplar.
- Taban çizgisinin kesinliği tanımsızdır çünkü hiçbir abone işaretlenmemiştir; aynı yordam doğrulukta 0,7579 okurken duyarlılıkta ve F1 ölçütünde sıfır verir.
- Beş model doğrulukta 0,7302 ile 0,8016 arasında sıkışırken kesinlikte 0,2255, duyarlılıkta 0,3443 puan yayılır; doğruluk bu takasa neredeyse kayıtsızdır.
- Dört ölçütte üç ayrı model başa geçer, doğruluğun seçtiği model üç ölçütte başta değildir ve doğruluk ile F1 arasında on model çiftinin yedisi yer değiştirir.
- F1 ölçütü uyumlu ortalamadır: kesinliği 1,0000 duyarlılığı 0,0164 olan bir yordamda sıradan ortalama 0,5082, F1 ölçütü 0,0323 verir; iki sayı eşitlendiğinde iki ortalama da eşitlenir.
Sonraki Adım
Bu dersin dört ölçütü de karar eşiği 0,5’te okundu ve o eşik hiç sorgulanmadı. Oysa modellerin ürettiği sayı bir olasılıktır; 0,5 dışarıdan gelen bir seçimdir ve tabloyu baştan sona değiştirir. Sonraki ders eşiği 0’dan 1’e süpürür, her eşikte kesinlik ile duyarlılığı yan yana basar ve işletme noktasını ilk dersin bedel hesabıyla seçer. Aynı süpürme iki eğri üretir — işlem karakteristiği eğrisi ve kesinlik–duyarlılık eğrisi — ve dengesiz bir kümede hangisinin yanıltıcı olduğu, iki eğrinin altındaki alanın aynı modelde ne kadar ayrıştığı sayılarak gösterilir.
İlerlemeni kaydetmek ve not almak için Giriş yap
Notlarım
Not almak için giriş yapmalısın.