Ders 15 / 20
Eşik Seçimi ve Eğriler
Eşiğin oynattığı iki sayının ve eğri altındaki alanın ayrılması: eşik 0,10'dan 0,90'a çıkarken kesinlik 0,3608'den 1,0000'e yükselir, duyarlılık 0,9344'ten 0,0328'e iner ve bedel 182'den 356'ya çıkar. Doksan dokuz eşik adayı arasından doğrulama kümesiyle seçilen 0,16 sınama kümesinde 181 bedel verir, varsayılan 0,50 eşiğinden 86 birim ucuzdur ve sınamadan okunsaydı 7 birim daha iyi görünürdü. Şüpheli oranı 0,2421'den 0,0354'e indirilince işlem karakteristiği eğrisinin altındaki alan 0,8058'den 0,8624'e çıkarken kesinlik–duyarlılık eğrisininki 0,6212'den 0,4124'e iner.
İçindekiler
Önceki dersin dört ölçütü de karar eşiği 0,5’te okundu. O eşik modelden gelmez: model bir olasılık üretir, eşik o olasılığı bir karara çevirir ve dışarıdan verilir. Sıfır virgül beşin tek gerekçesi iki sınıfın ortasında durmasıdır; şüpheli oranı 0,2421 olan bir kümede bu ortanın niçin doğru yer olduğunu söyleyen bir şey yoktur.
Bu ders eşiği süpürür: aynı model, aynı sınama kümesi, tek değişen eşik. Kesinlik ile duyarlılık her eşikte yeniden hesaplanır, işletme noktası bir bedel hesabıyla seçilir, süpürmenin ürettiği iki eğri sayı olarak basılır.
- MD16. Model bir olasılık üretir; eşik bu olasılığı karara çevirir ve modelden bağımsızdır. Doksan dokuz eşik denenir, 0,01’den 0,99’a; bu dersin ayar bütçesi budur.
- MD17. Bedel ilk dersinkidir: işaretlenen her abone için 1 birim saha ziyareti, kaçırılan her şüpheli için 6 birim. İşletme noktası doğrulama kümesinden seçilir; sınama kümesindeki sayı yalnız raporlanır.
- MD18. Süpürme boyunca eğitim kümesi, öznitelikler ve model sabit kalır.
- MD19. İşlem karakteristiği eğrisinin yatay ekseni yanlış olumlu oranı, dikey ekseni duyarlılıktır; kesinlik–duyarlılık eğrisinin yatay ekseni duyarlılık, dikey ekseni kesinliktir. Eğriler çizilmez, nokta olarak basılır.
- MD20. Eğri altındaki alan yamuk kuralıyla hesaplanır ve eşit skorlu gözlemler tek nokta sayılır.
- MD21. Seyreltilmiş küme sınama kümesindeki şüphelilerin onda birini tutarak kurulur; eğitim ve model değişmez. Kalan yedi şüpheliyle yapılan kestirim oynaktır ve tabanıyla okunur.
- MD22. Eşik seçimi olasılığın doğru olmasını değil, yalnız sıralamanın doğru olmasını gerektirir.
Eşiği Süpürmek
Eşik yükseldikçe model daha az abone işaretler. İşaretlediklerinde daha çok haklı çıkar, ama kaçırdığı şüpheli sayısı büyü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): p = sum(x["supheli"] for x in s) / len(s) return 2 * p * (1 - p) def agac(s, derinlik, alan, enaz=2): # MODELDIR: karar agaci n = len(s) p = sum(x["supheli"] for x in s) / n en = None if derinlik and n >= 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) - (len(sol) * safsizlik(sol) + len(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 matris(skor, veri, esik=0.5): # do, yo, yn, dn m = [0, 0, 0, 0] for x in veri: m[(0 if x["supheli"] else 1) + (0 if skor(x) >= esik else 2)] += 1 return m def dogrusal(egt, alan, w, tur=300, adim=0.5): # MODELDIR: egim temelli dogrusal model 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} f = lambda x: [(x[a] - o[a]) / s[a] for a in alan] k, b = [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) S = dogrusal(EGT, ALAN, 1.0) # MODELDIR: olasilik ureten egim temelli dogrusal model ZIYARET, KACAK = 1.0, 6.0 def nokta(skor, veri, e): do, yo, yn, dn = matris(skor, veri, e) return {"isaretli": do + yo, "do": do, "yoo": yo / (yo + dn), "du": do / (do + yn), "k": do / (do + yo) if do + yo else float("nan"), "bedel": ZIYARET * (do + yo) + KACAK * yn} print(f"{'esik':>5}{'isaretli':>9}{'yakalanan':>10}{'yo orani':>9}" f"{'duyarlilik':>11}{'kesinlik':>9}{'bedel':>7}") for e in (0.10, 0.20, 0.30, 0.40, 0.50, 0.60, 0.70, 0.80, 0.90): n = nokta(S, SIN, e) print(f"{e:>5.2f}{n['isaretli']:>9}{n['do']:>10}{n['yoo']:>9.4f}" f"{n['du']:>11.4f}{n['k']:>9.4f}{n['bedel']:>7.0f}")
esik isaretli yakalanan yo orani duyarlilik kesinlik bedel 0.10 158 57 0.5288 0.9344 0.3608 182 0.20 100 45 0.2880 0.7377 0.4500 196 0.30 66 34 0.1675 0.5574 0.5152 228 0.40 47 29 0.0942 0.4754 0.6170 239 0.50 33 22 0.0576 0.3607 0.6667 267 0.60 24 18 0.0314 0.2951 0.7500 282 0.70 17 12 0.0262 0.1967 0.7059 311 0.80 8 8 0.0000 0.1311 1.0000 326 0.90 2 2 0.0000 0.0328 1.0000 356
İki sütun ters yönde ilerliyor. Eşik 0,10’da model 158 abone işaretliyor, 61 şüphelinin 57’sini yakalıyor, kesinliği 0,3608. Eşik 0,90’da yalnız 2 abone işaretliyor, ikisinde de haklı, ama duyarlılık 0,0328. Kesinlik düzgün artmıyor: 0,60’ta 0,7500 iken 0,70’te 0,7059’a iniyor, çünkü paydası da modelle birlikte küçülüyor. Duyarlılık ise eşikte azalmayan bir işlevdir, paydası sabittir.
Son sütun kararı veren sütun: bedel 0,10 eşiğinde 182, 0,90 eşiğinde 356. Aradaki 174 birim tamamen eşiğin ürünüdür; model, öznitelikler ve eğitim kümesi hiç değişmedi.
İşletme Noktası Bir Bedel Hesabıyla Seçilir
Eşik bir ayar değişkenidir ve kursun kuralı burada da geçerlidir: hangi kümeden okunduğu yazılmadan seçilmiş sayılmaz.
ESIKLER = [i / 100 for i in range(1, 100)] bd = min(ESIKLER, key=lambda e: nokta(S, DOG, e)["bedel"]) bs = min(ESIKLER, key=lambda e: nokta(S, SIN, e)["bedel"]) print(f"denenen esik adayi {len(ESIKLER)}, dogrulama kumesi {len(DOG)} abone") print(f"{'isletme noktasi':<22}{'esik':>6}{'isaretli':>9}{'yakalanan':>10}" f"{'dogrulama':>11}{'sinama':>8}") for ad, e in (("varsayilan", 0.50), ("dogrulamadan secilen", bd), ("sinamadan secilen", bs)): n = nokta(S, SIN, e) print(f"{ad:<22}{e:>6.2f}{n['isaretli']:>9}{n['do']:>10}" f"{nokta(S, DOG, e)['bedel']:>11.0f}{n['bedel']:>8.0f}")
denenen esik adayi 99, dogrulama kumesi 252 abone isletme noktasi esik isaretli yakalanan dogrulama sinama varsayilan 0.50 33 22 205 267 dogrulamadan secilen 0.16 121 51 160 181 sinamadan secilen 0.13 138 55 173 174
Doğrulama kümesindeki doksan dokuz adayın en ucuzu 0,16 eşiğidir ve o kümede 160 birim tutar; aynı eşik sınama kümesinde 181 birim veriyor. Varsayılan 0,50 eşiği ise 267 birim: eşiği seçmek 86 birim, üçte bire yakın bir kazanç sağlıyor ve bu kazanç modelden değil, çıktısının nasıl okunduğundan geliyor.
Üçüncü satır seçimin kaynağını ölçüyor. Sınama kümesindeki en küçük bedel 0,13 eşiğinde, 174 birim. Aradaki 7 birim, seçimi sınama kümesinden okuyan birinin fazladan iyi görünen payıdır — küçük bir sayıdır çünkü bedel eğrisi eşiğe göre yayvandır, ama işareti hep aynı yöndedir.
İki Eğri ve Dengesizlik
Süpürme iki eğri üretir. İşlem karakteristiği eğrisi (ROC) yanlış olumlu oranına karşı duyarlılığı gösterir; kesinlik–duyarlılık eğrisi duyarlılığa karşı kesinliği. Farkları şüpheli oranı değiştiğinde ortaya çıkar.
def egri(skor, veri): # ROC ve kesinlik-duyarlilik noktalari p = sorted(((skor(x), x["supheli"]) for x in veri), key=lambda t: -t[0]) P = sum(y for _, y in p) N = len(p) - P do = yo = i = 0 n = [(0.0, 0.0, 1.0)] while i < len(p): j = i while j < len(p) and p[j][0] == p[i][0]: j += 1 d = sum(y for _, y in p[i:j]) do, yo, i = do + d, yo + (j - i) - d, j n.append((yo / N, do / P, do / (do + yo))) return n def alan_roc(n, sinir=1.0): # yamuk kurali; sinir yanlis olumlu oranini kirpar return sum((min(b[0], sinir) - a[0]) * (a[1] + b[1]) / 2 for a, b in zip(n, n[1:]) if a[0] < sinir) / sinir def alan_kd(n): # duyarlilik ekseninde basamak toplami return sum((b[1] - a[1]) * b[2] for a, b in zip(n, n[1:])) SEY = [x for i, x in enumerate(SIN) if not x["supheli"] or i % 10 == 0] sabit = lambda x: 0.5 print(f"{'sinama kumesi':<15}{'satir':>6}{'supheli':>8}{'oran':>7}{'ROC':>8}{'KD':>8}" f"{'sabit ROC':>10}{'sabit KD':>9}") for ad, v in (("gercek dagilim", SIN), ("seyreltilmis", SEY)): n, s, ns = egri(S, v), egri(sabit, v), sum(x["supheli"] for x in v) print(f"{ad:<15}{len(v):>6}{ns:>8}{ns / len(v):>7.4f}{alan_roc(n):>8.4f}" f"{alan_kd(n):>8.4f}{alan_roc(s):>10.4f}{alan_kd(s):>9.4f}") for h in (0.50, 0.70): r = [nokta(S, v, max(e for e in ESIKLER if nokta(S, v, e)["du"] >= h))["k"] for v in (SIN, SEY)] print(f"duyarlilik {h:.2f} ustunde kesinlik: gercek dagilim {r[0]:.4f}, " f"seyreltilmis {r[1]:.4f}")
sinama kumesi satir supheli oran ROC KD sabit ROC sabit KD gercek dagilim 252 61 0.2421 0.8058 0.6212 0.5000 0.2421 seyreltilmis 198 7 0.0354 0.8624 0.4124 0.5000 0.0354 duyarlilik 0.50 ustunde kesinlik: gercek dagilim 0.5161, seyreltilmis 0.2500 duyarlilik 0.70 ustunde kesinlik: gercek dagilim 0.4624, seyreltilmis 0.1667
İki eğri ters yönde hareket ediyor. Şüpheli oranı 0,2421’den 0,0354’e inince işlem karakteristiği eğrisinin altındaki alan 0,8058’den 0,8624’e çıkıyor, kesinlik–duyarlılık eğrisininki 0,6212’den 0,4124’e iniyor. Yükselişin bir bölümü yedi şüpheliyle yapılan kestirimin oynaklığıdır; asıl mesele son iki sütunda. Sabit skorlu yordamın işlem karakteristiği eğrisi her iki kümede de 0,5000 verir; bu eğrinin tabanı şüpheli oranına bakmaz. Öteki eğrinin tabanı ise doğrudan şüpheli oranıdır.
Son iki satır bunun işletmedeki karşılığı. Duyarlılık 0,50’nin üstünde tutulduğunda kesinlik gerçek dağılımda 0,5161, seyreltilmiş kümede 0,2500; 0,70’in üstünde tutulduğunda 0,4624’e karşı 0,1667. Alan 0,86 okurken, şüphelilerin yarısını yakalamak için işaretlenen her dört aboneden üçü boşa gidiyor. Dengesiz kümede yanıltıcı olan eğri, tabanı dengesizlikle birlikte hareket etmeyen eğridir.
Tek Sayının Sakladığı
Eğri altındaki alan bütün eşikleri tek sayıda toplar ve toplarken iki şeyi düşürür: hangi eşikte çalışıldığını ve eğrinin hangi bölgesinin işe yaradığını.
T3 = agac(EGT, 3, ALAN) # MODELDIR: derinlik 3 karar agaci S1 = dogrusal(EGT, ["ort_tuketim"], 1.0) # MODELDIR: tek oznitelikli dogrusal model print(f"{'model':<22}{'ROC':>8}{'yo<0.10':>9}{'KD':>8}{'en iyi bedel':>14}" f"{'farkli skor':>12}") for ad, s in (("dogrusal, 12 alan", S), ("agac d3, 12 alan", lambda x: olasilik(T3, x)), ("dogrusal, ort_tuketim", S1)): n = egri(s, SIN) print(f"{ad:<22}{alan_roc(n):>8.4f}{alan_roc(n, 0.10):>9.4f}{alan_kd(n):>8.4f}" f"{min(nokta(s, SIN, e)['bedel'] for e in ESIKLER):>14.0f}" f"{len({round(s(x), 12) for x in SIN}):>12}")
model ROC yo<0.10 KD en iyi bedel farkli skor dogrusal, 12 alan 0.8058 0.3364 0.6212 174 252 agac d3, 12 alan 0.7222 0.2553 0.4485 197 8 dogrusal, ort_tuketim 0.7138 0.3008 0.5589 213 241
Asıl okuma son iki satırda. İki modelin işlem karakteristiği alanı 0,7222 ile 0,7138, arada 0,0084 var — bu ölçüye göre neredeyse eşitler. Öbür üç sütun aynı fikirde değil: kesinlik–duyarlılık alanında tek öznitelikli model 0,1104 puan önde, yanlış olumlu oranının 0,10 altında kaldığı bölgede 0,0455 puan önde, en iyi bedelde 16 birim geride. Üç okuma, üç ayrı kazanan.
Sekiz ayrı skor üreten derinlik 3 ağacı ile 241 ayrı skor üreten tek öznitelikli model eğri üzerinde bambaşka ilerler: biri sekiz büyük basamak, öteki yüzlerce küçük adım. Alan ikisini de aynı sayıya sıkıştırır. Kursun kuralına burada bir madde eklenir: hangi eşikte çalışılacağı yazılmadan eğri altındaki alan bir işletme kararına çevrilemez.
Özet
- Eşik yükseldikçe duyarlılık azalmayan biçimde düşer ama kesinlik düzgün artmaz: 0,60 eşiğinde 0,7500 olan kesinlik 0,70 eşiğinde 0,7059’a iner. Doksan dokuz eşik adayı bedeli 182 ile 356 arasında oynatır; model ve eğitim kümesi hiç değişmez.
- Doğrulamadan seçilen 0,16 eşiği sınamada 181 birim verir, varsayılan 0,50 eşiğinden 86 birim ucuzdur; aynı seçim sınamadan okunsaydı 7 birim daha iyi görünürdü.
- Şüpheli oranı 0,2421’den 0,0354’e inince işlem karakteristiği alanı 0,8058’den 0,8624’e çıkar, kesinlik–duyarlılık alanı 0,6212’den 0,4124’e iner; birinci eğrinin tabanı her iki kümede 0,5000, ikincisininki şüpheli oranının kendisidir.
- İşlem karakteristiği alanı 0,0084 farkla eşit sayılan iki model, kesinlik–duyarlılık alanında 0,1104 ve en iyi bedelde 16 birim ayrışır.
Sonraki Adım
Bu dersin tamamı sıralamaya dayandı. Eşik süpürüldü, eğriler basıldı, işletme noktası seçildi; hiçbirinde modelin söylediği sayının kendisinin doğru olması gerekmedi. Bütün skorlar artan bir işlevden geçirilse sıralama değişmez, iki eğri aynı kalır, işletme noktası aynı aboneleri işaretler. Oysa model bir abone için 0,80 dediğinde bu sayının bir karşılığı olmalıdır: 0,80 denen abonelerin yaklaşık yüzde sekseni şüpheli çıkmalıdır. Sonraki ders söylenen olasılık ile gerçekleşen oranı aralık aralık yan yana basar, sıralaması iyi kalibrasyonu kötü bir modelin varlığını gösterir ve düzeltmeyi yalnız doğrulama kümesinden öğrenilen tek değişkenli bir eşleme olarak yazar.
İlerlemeni kaydetmek ve not almak için Giriş yap
Notlarım
Not almak için giriş yapmalısın.