İçeriğe geç
academia.sh

Ders 11 / 15

Yanlılık Kaynakları

Aynı zararın üç ayrı yerde doğduğunun ayrı ayrı sayılması: on üç alt grupta ölçülen doğrusal model bütünde 0,8194 doğruluk ve 0,3704 duyarlılık verirken az okuması olan abonelerde duyarlılık 0,2222'de kalıyor. Tabloya hiç girmeyen 69 abone yüzünden az okumalıların payı 0,3695 yerine 0,3349 okunuyor; yalnız tam okumalılardan kurulan eğitim kümesi o alt grupta kesinliği 0,5455'ten 0,3774'e indiriyor, kayda geçmeyen 19 şüpheli duyarlılığı 0,0370'e düşürüyor, kırk ziyaretlik kapasite ise aynı alt gruba 0,0359 oranında uygulanıp duyarlılığı 0,1111'de bırakıyor. Üçünde de bütündeki doğruluk en çok 0,0337 oynuyor.

İçindekiler

Önceki konu on derste modelin ürettiği sayıyı açtı: sayının ne olduğu, kimin için olduğu ve modelin onu neye dayanarak ürettiği ölçüldü. Açıklama bir kararı okunabilir kıldı, ama okunabilir bir karar iyi bir karar değildir. Açıklama kararın hangi özniteliğe dayandığını söyler, kararın kime ne yaptığını söylemez; bir alt gruba sistematik zarar veren bir model de aynı berraklıkla açıklanır.

Bu konu o boşluğu doldurur ve ilk soru en somut olanıdır: zarar nereden geliyor. Tabloya kimin girdiği bir yanlılıktır, etiketin kimi kaçırdığı ikincisi, modelin kime uygulandığı üçüncüsüdür. Üçü ayrı yerde doğar, ayrı çözüm ister ve bu derste görüleceği gibi aynı sayıya vurur. Gözlemin seçilmesinden doğan yanlılık M26/K05’in Uygulamalı İstatistik konusunda ölçülmüştü; tekrarlanmaz, girdi olarak alınır.

  • ME1. Küme, etiket, tohum ve bölme M27/K01–K07’den devralınır ve kurgudur: 1.260 abone, 756 satırlık eğitim kümesi. Şüphe etiketi gerçek bir denetim kaydı değildir.
  • ME2. Doğrulama ve sınama kümeleri bu konu boyunca birleştirilip tek bir 504 abonelik ayrılmış küme olarak okunur; alt grup sayıları 252 abonede fazla ince kalıyor. Sınama kümesinin tabanı 0,7579, birleşik kümenin tabanı 0,7857.
  • ME3. Model M27/K03’ün on iki sütunlu doğrusal modelidir, ayarları sabittir ve sınama kümesinde 0,8016 verir; karşılaştırma çizgisi budur.
  • ME4. Alt gruplar bu konuda tanımlanır ve sabit kalır: bölge (beş), tarife basamağı (üç), hane büyüklüğü (üç), okuma sayısı (iki). On üç alt gruba bakılır ve bu sayı her derste yazılır; ayrılmış kümede elli kayıttan küçük alt grup açıklık hesabına girmez.
  • ME5. Tarife basamakları 10 ve 25 m³ eşikleriyle kurulur; 40 m³ üstünde iki abone kaldığı için üst basamak birleştirilir. Okuma sayısı ekseni az (bir ya da iki dönem) ve tam (üç dönem) olarak ikiye ayrılır.
  • ME6. Ölçüler doğruluk, duyarlılık ve kesinliktir; tanımları M27/K03’te kuruldu ve burada tekrarlanmaz. Hiç işaretleme yapılmayan bir alt grupta kesinlik tanımsızdır.
  • ME7. İki ölçüm için devralınan kurgunun üstüne yalnız bu derste geçerli iki katman eklenir: az okuması olan abonelerde şüphelilerin bir bölümünün kayda geçmediği bir kayıt süreci, ve saha ekibinin yalnız en yüksek puanlıları ziyaret ettiği bir kapasite.
  • ME8. Yanlılık burada bir niyet değil bir ölçüdür; üç mekanizma da sıradan kararların yan ürünüdür.

Üç Yanlılık Üç Ayrı Yerde Doğar

Kurulum kümeyi üretir, doğrusal modeli eğitir ve aynı modeli on üç alt grupta ayrı ayrı ölçer.

# etik.py — MODELDIR. Ayni KURGU abone tablosu, ayni tohum ve ayni bolme;
# hedef kacak ya da ariza suphesi etiketidir ve o etiket de KURGUDUR.
import math
import statistics

TOHUM, HAM, 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, VERI, YOK = [], [], []
for i in range(HAM):
    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, v = uretec(TOHUM + 7000 + k["no"]), []
    for d in range(ayrik(r(), [0.05, 0.12, 0.21, 0.62])):
        v.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()
    if not v:
        YOK.append(k["bolge"][0])
        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), "il": k["bolge"][0],
         "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, AYR = K[:756], K[756:]
ALAN = ["ort_tuketim", "oynaklik", "hane", "memnuniyet", "donem", "sifir_okuma",
        "kisi_basi", "b_kuzey", "b_guney", "b_dogu", "b_bati", "b_merkez"]
ORT = {a: statistics.fmean(x[a] for x in EGT) for a in ALAN}
SAP = {a: max(1e-9, statistics.pstdev([x[a] for x in EGT])) for a in ALAN}


def olcekli(x):
    return [1.0] + [(x[a] - ORT[a]) / SAP[a] for a in ALAN]


def sikistir(z):
    if z >= 0:
        return 1.0 / (1.0 + math.exp(-z)) if z < 700 else 1.0
    e = math.exp(z) if z > -700 else 0.0
    return e / (1.0 + e)


def egit(kume, etiket):                  # MODELDIR: dogrusal model, egim inisi
    X = [olcekli(x) for x in kume]
    Y = [x[etiket] for x in kume]
    w = [0.0] * len(X[0])
    for _ in range(200):
        g = [0.0] * len(w)
        for i in range(len(X)):
            h = sikistir(sum(w[j] * X[i][j] for j in range(len(w)))) - Y[i]
            for j in range(len(w)):
                g[j] += h * X[i][j]
        for j in range(len(w)):
            w[j] -= 0.3 * g[j] / len(X)
    return w


def olasilik(w, x):
    return sikistir(sum(a * b for a, b in zip(w, olcekli(x))))


def gruplar(x):
    t = 10 if x["ort_tuketim"] <= 10 else 25 if x["ort_tuketim"] <= 25 else 40
    return ["bolge " + x["il"], "tarife %d" % t,
            "hane " + ("1-2" if x["hane"] <= 2 else "3-4" if x["hane"] <= 4 else "5+"),
            "okuma " + ("az" if x["donem"] <= 2 else "tam")]


ALT = sorted({g for x in AYR for g in gruplar(x)})
W = egit(EGT, "supheli")


def olc(w, s):                           # dogruluk, duyarlilik, kesinlik
    sup = sum(x["supheli"] for x in s)
    ip = [x for x in s if olasilik(w, x) > 0.5]
    dp = sum(x["supheli"] for x in ip)
    return (sum((olasilik(w, x) > 0.5) == x["supheli"] for x in s) / len(s),
            dp / sup if sup else float("nan"), dp / len(ip) if ip else float("nan"))


print(f"abone {len(ABONE)}, hic okuma uretmeyen {len(YOK)}, etiketli {len(VERI)}, "
      f"supheli {sum(x['supheli'] for x in VERI)}")
print(f"egitim {len(EGT)}, ayrilmis {len(AYR)}, bakilan alt grup {len(ALT)}")
print(f"taban {sum(x['supheli'] == 0 for x in AYR) / len(AYR):.4f}, butunde"
      + "".join(f"{v:>11.4f}" for v in olc(W, AYR)) + "\n")
print(f"{'alt grup':<14}{'egitim':>7}{'ayrilmis':>9}{'supheli':>8}"
      f"{'dogruluk':>11}{'duyarlilik':>11}{'kesinlik':>11}")
for g in ALT:
    s = [x for x in AYR if g in gruplar(x)]
    print(f"{g:<14}{sum(1 for x in EGT if g in gruplar(x)):>7}{len(s):>9}"
          f"{sum(x['supheli'] for x in s):>8}"
          + "".join(f"{v:>11.4f}" for v in olc(W, s)))
abone 1329, hic okuma uretmeyen 69, etiketli 1260, supheli 276
egitim 756, ayrilmis 504, bakilan alt grup 13
taban 0.7857, butunde     0.8194     0.3704     0.6349

alt grup       egitim ayrilmis supheli   dogruluk duyarlilik   kesinlik
bolge bati        126       63       1     0.9841     0.0000        nan
bolge dogu        136       83      38     0.7108     0.6842     0.6842
bolge guney       141      117      17     0.8632     0.1176     0.6667
bolge kuzey       219      144      23     0.8264     0.1739     0.4000
bolge merkez      134       97      29     0.7423     0.2759     0.6667
hane 1-2          238      144      31     0.8264     0.3871     0.6667
hane 3-4          398      289      61     0.8201     0.3607     0.6286
hane 5+           120       71      16     0.8028     0.3750     0.6000
okuma az          255      167      27     0.8443     0.2222     0.5455
okuma tam         501      337      81     0.8071     0.4198     0.6538
tarife 10          29       22       6     0.7273     0.0000        nan
tarife 25         590      376      54     0.8511     0.2037     0.4583
tarife 40         137      106      48     0.7264     0.6042     0.7436

Bütünde okunan üç sayı iyi görünüyor: doğruluk 0,8194 ile tabanın 0,0337 üstünde, duyarlılık 0,3704, kesinlik 0,6349. Alt gruplarda aynı model on üç ayrı davranış gösteriyor: doğruluk batıda 0,9841, doğuda 0,7108; duyarlılık doğuda 0,6842, güneyde 0,1176. En keskin iki satır ölçülemeyen satırlardır — batıda ve en alt tarife basamağında hiç işaretleme yapılmadığı için kesinlik tanımsız, ve o basamağın eğitim kümesinde toplam 29 satırı var.

Bu ders okuma sayısı eksenini izler. Az okumalılarda doğruluk 0,8443 ile bütünün üstünde, ama duyarlılık 0,2222 ile tam okumalıların 0,4198’inin altında; açıklık 0,1976. Yüksek doğruluk yanıltıcıdır: şüpheli oranı düşük olduğu için hiç kimseyi işaretlememek zaten yüksek doğruluk verir. İzlenecek sayı 0,2222’dir.

Veri: Tabloya Kim Girdi

Veri yanlılığı, eğitim kümesinin modelin uygulanacağı nüfusa benzememesidir. Kaynağı burada ölçüm ağıdır: bir abone ne kadar az okuma ürettiyse tabloya o kadar zayıf girer, hiç üretmeyen girmez.

AZ = [x for x in AYR if x["donem"] < 3]
TAM = [x for x in AYR if x["donem"] == 3]
az_tablo = sum(1 for x in VERI if x["donem"] < 3)
agda = (az_tablo + len(YOK)) / (len(VERI) + len(YOK))
print(f"tabloda az okumali abone orani {az_tablo / len(VERI):.4f}, agdaki gercek "
      f"oran {agda:.4f}, fark {agda - az_tablo / len(VERI):.4f}")
TEK = [x for x in EGT if x["donem"] == 3]
WT = egit(TEK, "supheli")


def satir(ad, w):
    a, b = olc(w, AZ), olc(w, AYR)
    print(f"{ad:<26}{a[0]:>12.4f}{a[1]:>14.4f}{a[2]:>12.4f}{b[0]:>15.4f}{b[1]:>17.4f}")


print(f"\n{'egitim kumesi':<26}{'az dogruluk':>12}{'az duyarlilik':>14}"
      f"{'az kesinlik':>12}{'butun dogruluk':>15}{'butun duyarlilik':>17}")
satir(f"{len(EGT)} satir, hepsi", W)
satir(f"{len(TEK)} satir, tam okumali", WT)
tabloda az okumali abone orani 0.3349, agdaki gercek oran 0.3695, fark 0.0345

egitim kumesi              az dogruluk az duyarlilik az kesinlik butun dogruluk butun duyarlilik
756 satir, hepsi                0.8443        0.2222      0.5455         0.8194           0.3704
501 satir, tam okumali          0.7605        0.7407      0.3774         0.7857           0.4815

İlk satır eksikliğin büyüklüğünü veriyor: tabloda az okumalı abone oranı 0,3349, ağdaki gerçek oran 0,3695, aradaki 0,0345 tümüyle tabloya hiç girmeyen 69 aboneden geliyor.

İkinci tablo aynı mekanizmanın bir adım ilerisidir: eğitim yalnız tam okumalı 501 satırdan kurulduğunda az okumalı alt grupta duyarlılık 0,7407’ye çıkıyor, ama kesinlik 0,5455’ten 0,3774’e, doğruluk 0,8443’ten 0,7605’e iniyor. Model o alt grubu ayırt edemediği için neredeyse hepsini işaretliyor. Zararın yönü duyarlılıkta yukarı, kesinlikte aşağıdır; tek bir sayıya bakan biri bunu iyileşme sanır. Bütündeki doğruluk yalnız 0,0337 oynuyor.

Etiket: Kayıt Kimi Kaçırdı

Etiket yanlılığı tabloda kimin bulunduğuyla değil, yanına ne yazıldığıyla ilgilidir. Şüphe etiketi bir kayıt sürecinin çıktısıdır ve o süreç her alt grupta aynı bilgiye sahip değildir.

r = uretec(TOHUM + 62000)
kacan = 0
for x in EGT:                            # KURGU kayit sureci: yalniz bu olcumde
    x["kayitli"] = x["supheli"]
    if x["donem"] < 3 and x["supheli"] and r() < 0.4:
        x["kayitli"], kacan = 0, kacan + 1
poz = sum(1 for x in EGT if x["donem"] < 3 and x["supheli"])
print(f"az okumali egitim satiri {sum(1 for x in EGT if x['donem'] < 3)}, supheli "
      f"{poz}, kayda gecmeyen {kacan}; tam okumalilarda kayda gecmeyen 0")
WK = egit(EGT, "kayitli")
print(f"\n{'egitilen etiket':<26}{'az dogruluk':>12}{'az duyarlilik':>14}"
      f"{'az kesinlik':>12}{'butun dogruluk':>15}{'butun duyarlilik':>17}")
satir("gercek durum", W)
satir("kayitli etiket", WK)
az okumali egitim satiri 255, supheli 44, kayda gecmeyen 19; tam okumalilarda kayda gecmeyen 0

egitilen etiket            az dogruluk az duyarlilik az kesinlik butun dogruluk butun duyarlilik
gercek durum                    0.8443        0.2222      0.5455         0.8194           0.3704
kayitli etiket                  0.8323        0.0370      0.3333         0.8056           0.2778

Eğitim kümesindeki 255 az okumalı satırın 44’ü şüpheli ve bunların 19’u kayda geçmiyor; kaçan kayıt toplam 756 satırın yüzde 2,5’i. Etkisi küçük değil: az okumalı alt grupta duyarlılık 0,0370’e iniyor, yani model oradaki 27 şüpheliden yalnız birini yakalıyor. Kesinlik de 0,3333’e düşüyor; bu mekanizma iki ölçüyü birden bozuyor.

Asıl güçlük ölçünün kendisindedir. Model kayıtlı etiketle eğitilip kayıtlı etiketle ölçülseydi hiçbir şey görünmezdi; kaçan 19 şüpheli ayrılmış kümede de kaçmış olurdu ve sayı yüksek çıkardı. Eksik satır sayılabilir, yanlış etiket sayılamaz.

Dağıtım: Model Kime Uygulandı

Üçüncü yanlılık modelin içinde değil kullanımındadır. Her aboneye bir puan verilir, ama saha ekibi hepsini ziyaret edemez; yalnız en yüksek puanlılara gider. Model o zaman herkese değil bir alt kümeye uygulanmış olur.

SIRA = sorted(AYR, key=lambda x: -olasilik(W, x))
sup_az, sup_tam = sum(x["supheli"] for x in AZ), sum(x["supheli"] for x in TAM)


def kapasite(kap):
    u = SIRA[:kap]
    ua = sum(1 for x in u if x["donem"] < 3)
    return (ua / len(AZ), (kap - ua) / len(TAM),
            sum(1 for x in u if x["donem"] < 3 and x["supheli"]) / sup_az,
            sum(1 for x in u if x["donem"] == 3 and x["supheli"]) / sup_tam,
            sum(x["supheli"] for x in u) / (sup_az + sup_tam))


print(f"{'kapasite':>9}{'az uygulanan':>17}{'tam uygulanan':>17}"
      f"{'az duyarlilik':>17}{'tam duyarlilik':>17}{'butun duyarlilik':>17}")
for kap in (40, 60, 80):
    print(f"{kap:>9}" + "".join(f"{v:>17.4f}" for v in kapasite(kap)))
k40 = kapasite(40)
print(f"\n{'yanlilik':<24}{'az duyarlilik':>15}{'butun duyarlilik':>18}"
      f"{'butun dogruluk':>16}")
for ad, w in (("yok (temel olcum)", W), ("veri", WT), ("etiket", WK)):
    a, b = olc(w, AZ), olc(w, AYR)
    print(f"{ad:<24}{a[1]:>15.4f}{b[1]:>18.4f}{b[0]:>16.4f}")
print(f"{'dagitim (kapasite 40)':<24}{k40[2]:>15.4f}{k40[4]:>18.4f}{'-':>16}")
 kapasite     az uygulanan    tam uygulanan    az duyarlilik   tam duyarlilik butun duyarlilik
       40           0.0359           0.1009           0.1111           0.3210           0.2685
       60           0.0599           0.1484           0.2222           0.3951           0.3519
       80           0.0958           0.1899           0.3333           0.4568           0.4259

yanlilik                  az duyarlilik  butun duyarlilik  butun dogruluk
yok (temel olcum)                0.2222            0.3704          0.8194
veri                             0.7407            0.4815          0.7857
etiket                           0.0370            0.2778          0.8056
dagitim (kapasite 40)            0.1111            0.2685               -

Kırk ziyaretlik kapasitede model az okumalıların 0,0359’una, tam okumalıların 0,1009’una uygulanıyor; uygulanma oranı arada neredeyse üç kat fark ediyor. Sonuç duyarlılıktan okunur: az okumalılarda 0,1111, tam okumalılarda 0,3210. Model, eşik ve eğitim kümesi değişmedi; yalnız kaç kişiye gidildiği değişti ve açıklık 0,2099’a çıktı. Kapasite 80’de açıklık 0,1235’e iniyor: dağıtım yanlılığı kapasitenin yan ürünüdür.

Son tablo dersin toplamıdır. Aynı alt grubun aynı sayısı üç mekanizmayla 0,7407, 0,0370 ve 0,1111 değerlerine gidiyor — biri yukarı, ikisi aşağı — ve bütündeki doğruluk en çok 0,0337 oynuyor. Üçünün ayrı sayılması zorunludur, çünkü her biri ayrı çözüm ister: eksik satır toplamak, kayıt sürecini denetlemek, kapasiteyi bölüştürmek. On üç alt gruba bakıldığı için bu farkların bir bölümü yalnız bakma sayısından da doğabilir; M26/K05’in çoklu karşılaştırma dersi bunun payını ölçmüştü ve alt grup sayısı her derste bu yüzden yazılır.

Özet

  • Bütünde 0,8194 doğruluk ve 0,3704 duyarlılık veren doğrusal model on üç alt grupta on üç ayrı davranış gösteriyor: doğruluk batıda 0,9841, doğuda 0,7108, ve iki alt grupta hiç işaretleme yapılmadığı için kesinlik tanımsız kalıyor.
  • Veri yanlılığı tabloya kimin girdiğidir: hiç okuma üretmeyen 69 abone yüzünden az okumalıların payı 0,3695 yerine 0,3349 okunuyor, ve eğitim yalnız tam okumalılardan kurulduğunda kesinlik 0,5455’ten 0,3774’e iniyor.
  • Etiket yanlılığı yanına ne yazıldığıdır: kayda geçmeyen 19 şüpheli duyarlılığı 0,0370’e düşürüyor ve etiketin dışında bir ölçüt olmadan görünmüyor.
  • Dağıtım yanlılığı kime uygulandığıdır: kırk ziyaretlik kapasitede model az okumalıların 0,0359’una, tam okumalıların 0,1009’una uygulanıyor ve açıklık 0,2099’a çıkıyor.
  • Üç mekanizma aynı sayıyı üç ayrı yöne taşırken bütündeki doğruluk en çok 0,0337 oynuyor.

Sonraki Adım

Bu derste bir alt grubun sayısı öbüründen düşük çıktığında bunun bir zarar olduğu varsayıldı ve açıklık doğrudan raporlandı. Oysa açıklığın hangi ölçüde ölçüleceği kendi başına bir karardır. Seçilme oranlarını eşitlemek, yakalanan şüpheli oranlarını eşitlemek ve işaretlenenlerin ne kadarının gerçekten şüpheli olduğunu eşitlemek üç ayrı şeydir. Sonraki ders bu üç ölçütü yapı adlarıyla kurar, eşiği her birini düzeltecek biçimde oynatır ve öbürlerinin ne kadar bozulduğunu sayar. Çıkan sonuç bir ayar hatası değildir.

İlerlemeni kaydetmek ve not almak için Giriş yap

Notlarım

Not almak için giriş yapmalısın.

Aramak için yazmaya başlayın.

↑↓ Esc gezin · aç · kapat