İçeriğe geç
academia.sh

Ders 06 / 12

Aykırı Değer Yönetimi

Tek bir kırpma kararının iki model ailesinde ters işaret verdiğinin ölçülmesi: eğitim kümesinden öğrenilen çitle kırpma, eğim temelli doğrusal modele gerçek uçlarda +0,0040, takılı sayaç kaydı da varken +0,0317 katıyor; aynı karar karar ağacında −0,0278 ve −0,0357 veriyor. Çit dışındaki 34 abonenin şüpheli oranı 0,6765 olduğu için kırpma gerçek bilgiyi de siliyor, ve hiçbir satır silinmeden 41 değer kırpılıyor.

İçindekiler

Önceki ders şüpheli abonelerin sayıca azlığını ölçtü. Bu ders birkaç abonenin değerce uzaklığını ölçer. Ortalama tüketim ve oynaklık sütunlarında, eğitim kümesinin çeyrekler açıklığından hesaplanan çitin dışında kalan aboneler var. Bunların bir bölümü gerçek uçtur — kalabalık bir haneden ya da yüksek tarifeli bir bağlantıdan gelir. Bir bölümü ise takılı kalmış sayaçların ürettiği kayıt hatasıdır. Tabloda ikisi birbirinin aynısı görünür: büyük bir sayı.

Çeyrekler açıklığı, çit ve uç değerin bulunması M26’nın Veri Toplama ve Hazırlama kursunda kuruldu; oradaki ölçü kaç satırın çit dışında kaldığıydı. Buradaki soru başkadır: kırpma kararı ayrılmış kümedeki sayıyı hangi modelde ne kadar oynatıyor.

  • HA41. Takılı sayaç arızası kurgudur: küçük bir abone kümesinin ortalama tüketimi otuz katına çıkmış olarak kaydedilir. Etiketten bağımsız seçilir.
  • HA42. Bu arıza 01’deki üç kusurdan farklıdır ve onların düzeltmeleriyle yakalanamaz: değer doğru birimdedir, doğru yazılmıştır ve tek satırdadır. Yalnız yanlıştır.
  • HA43. Çit eğitilmiş bir nesnedir: çeyrekler yalnız eğitim kümesinden hesaplanır, çit çeyrekler açıklığının 1,5 katıyla kurulur ve iki kümeye de aynı çit uygulanır.
  • HA44. Kırpma çit dışındaki değeri çite çeker. Hiçbir satır silinmez; sınama kümesindeki her abone için tahmin üretilir.
  • HA45. İki model ailesi karşılaştırılır: eğim temelli doğrusal model ve derinlik 6 karar ağacı. Doğrusal model önceki derste kurulan disipline göre standartlaştırılmış sütunlarla eğitilir; ağaçta ölçeklemenin katkısı sıfır olduğu için ham sütunlarla eğitilir.

Uçun İki Kaynağı

Kurulum tabloyu üretir, arızayı koyar ve çiti eğitim kümesinden öğrenir.

# aykiri.py — MODELDIR. Kurgu abone tablosu ayni tohumla uretilir; kucuk bir abone
# kumesinin tuketimi KURGU bir takili sayac arizasiyla otuz kat yuksek kaydedilir.
import math
import statistics

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 v is None:
        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)}
    for b in BOLGE:
        x["b_" + b[0]] = int(k["bolge"][0] == b[0])
    VERI.append(x)

sr = uretec(TOHUM + 81000)                  # takili sayac arizasi KURGUDUR
for x in VERI:
    x["ariza"] = round(x["ort_tuketim"] * 30, 2) if sr() < 0.010 else x["ort_tuketim"]


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, SIN = K[:756], K[1008:]
TABAN = sum(x["supheli"] == 0 for x in SIN) / len(SIN)
SAY = ["ort_tuketim", "oynaklik", "hane", "memnuniyet", "donem"]
ALAN = SAY + ["sifir_okuma", "b_kuzey", "b_guney", "b_dogu", "b_bati", "b_merkez"]
UC = ["ort_tuketim", "oynaklik"]


def ceyrek(v, q):
    s = sorted(v)
    i = q * (len(s) - 1)
    a = int(i)
    return s[a] if a + 1 >= len(s) else s[a] + (i - a) * (s[a + 1] - s[a])


def cit_ogren(egt, sutun, k=1.5):           # OGRENME: ceyrekler acikligi ve cit
    d = {}
    for a in sutun:
        q1, q3 = ceyrek([x[a] for x in egt], 0.25), ceyrek([x[a] for x in egt], 0.75)
        d[a] = (q1 - k * (q3 - q1), q3 + k * (q3 - q1))
    return d


def kirp(c, s):                             # UYGULAMA: hicbir satir silinmez
    return [dict(x, **{a: min(max(x[a], c[a][0]), c[a][1]) for a in c}) for x in s]


ar = [x for x in EGT if x["ariza"] != x["ort_tuketim"]]
print(f"takili sayac: egitimde {len(ar)} abone, sinamada "
      f"{sum(1 for x in SIN if x['ariza'] != x['ort_tuketim'])}; "
      f"bunlarin {sum(x['supheli'] for x in ar)} tanesi supheli")
c = cit_ogren(EGT, UC)
print(f"{'sutun':<12} {'ust cit':>8} {'en buyuk':>9} {'cit disi egitim':>16} "
      f"{'sinama':>7}")
for a in UC:
    print(f"{a:<12} {c[a][1]:>8.2f} {max(x[a] for x in EGT):>9.2f} "
          f"{sum(1 for x in EGT if x[a] > c[a][1]):>16} "
          f"{sum(1 for x in SIN if x[a] > c[a][1]):>7}")
u = [x for x in EGT if any(x[a] > c[a][1] for a in UC)]
print(f"cit disindaki {len(u)} abonenin supheli orani "
      f"{sum(x['supheli'] for x in u) / len(u):.4f}, taban cizgisi {TABAN:.4f}")
takili sayac: egitimde 9 abone, sinamada 1; bunlarin 2 tanesi supheli
sutun         ust cit  en buyuk  cit disi egitim  sinama
ort_tuketim     35.80     42.90               11       4
oynaklik        29.41     40.57               23       7
cit disindaki 34 abonenin supheli orani 0.6765, taban cizgisi 0.7579

Son satır kırpma kararının bedelini önceden söylüyor. Çit dışındaki 34 abonenin şüpheli oranı 0,6765; eğitim kümesinin genelinde bu oran 0,2222. Uçtaki abonelerin üçte ikisi şüpheli, yani uç değerler gürültü değil, kümenin en bilgilendirici bölgesi.

Aynı Kırpma, İki Model

def gini(s):
    p = sum(x["supheli"] for x in s) / len(s) if s else 0.0
    return 2 * p * (1 - p)


def agac(s, derinlik, alan, enaz=2):        # MODELDIR: karar agaci, derinlik 6
    p = sum(x["supheli"] for x in s) / len(s)
    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 = gini(s) - (len(sol) * gini(sol) + len(sag) * gini(sag)) / len(s)
                if en is None or k > en[0]:
                    en = (k, a, v, sol, sag)
    if en is None or en[0] <= 1e-9:
        return {"tahmin": int(p > 0.5)}
    return {"alan": en[1], "esik": en[2], "sol": agac(en[3], derinlik - 1, alan, enaz),
            "sag": agac(en[4], derinlik - 1, alan, enaz)}


def agac_tahmin(d, x):
    while "tahmin" not in d:
        d = d["sol"] if x[d["alan"]] < d["esik"] else d["sag"]
    return d["tahmin"]


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 dogrusal(egt, alan, adim=0.5, tur=400):  # MODELDIR: egim temelli dogrusal model
    w, b, n = [0.0] * len(alan), 0.0, len(egt)
    for _ in range(tur):
        gw, gb = [0.0] * len(alan), 0.0
        for x in egt:
            h = sikistir(sum(w[i] * x[a] for i, a in enumerate(alan)) + b) - x["supheli"]
            for i, a in enumerate(alan):
                gw[i] += h * x[a]
            gb += h
        for i in range(len(alan)):
            w[i] -= adim * gw[i] / n
        b -= adim * gb / n
    return w, b


def standartla(egt, kumeler):               # OGRENME + UYGULAMA (onceki ders)
    p = {a: (statistics.fmean(x[a] for x in egt),
             statistics.pstdev([x[a] for x in egt])) for a in SAY}
    return [[dict(x, **{a: (x[a] - p[a][0]) / p[a][1] for a in SAY}) for x in k]
            for k in kumeler]


def kur(kaynak, kirpma):
    e = [dict(x, ort_tuketim=x[kaynak]) for x in EGT]
    s = [dict(x, ort_tuketim=x[kaynak]) for x in SIN]
    if kirpma:
        c = cit_ogren(e, UC)
        e, s = kirp(c, e), kirp(c, s)
    return e, s


SONUC = {}
print(f"{'durum':<38} {'egim temelli':>13} {'agac':>8}")
print(f"{'taban cizgisi':<38} {TABAN:>13.4f} {TABAN:>8.4f}")
for ad, kaynak, kirpma in (("yalniz gercek uc, kirpma yok", "ort_tuketim", False),
                           ("yalniz gercek uc, cit ile kirpildi", "ort_tuketim", True),
                           ("takili sayac da var, kirpma yok", "ariza", False),
                           ("takili sayac da var, cit ile kirpildi", "ariza", True)):
    e, s = kur(kaynak, kirpma)
    es, ss = standartla(e, [e, s])
    m = dogrusal(es, ALAN)
    d = sum(int(sikistir(sum(m[0][i] * x[a] for i, a in enumerate(ALAN)) + m[1]) > 0.5)
            == x["supheli"] for x in ss) / len(ss)
    t = agac(e, 6, ALAN)
    g = sum(agac_tahmin(t, x) == x["supheli"] for x in s) / len(s)
    SONUC[ad] = (d, g)
    print(f"{ad:<38} {d:>13.4f} {g:>8.4f}")
durum                                   egim temelli     agac
taban cizgisi                                 0.7579   0.7579
yalniz gercek uc, kirpma yok                  0.8016   0.7778
yalniz gercek uc, cit ile kirpildi            0.8056   0.7500
takili sayac da var, kirpma yok               0.7698   0.7857
takili sayac da var, cit ile kirpildi         0.8016   0.7500

Ağaç sütunu dört durumda üç ayrı sayı veriyor ve ilginç olan, kırpılmış iki satırın aynı sayıyı okumasıdır. Kırpma her iki tabloyu da aynı yere getiriyor: çit üstündeki bütün değerler tek bir noktaya toplandığında arızalı kayıtla gerçek uç birbirinden ayırt edilemez duruma geliyor.

Katkı Kaç Abone Eder

print(f"{'kirpma karari':<34} {'egim temelli':>13} {'abone':>6} "
      f"{'agac':>8} {'abone':>6}")
for ad, a, b in (("yalniz gercek uc", "yalniz gercek uc, kirpma yok",
                  "yalniz gercek uc, cit ile kirpildi"),
                 ("takili sayac da var", "takili sayac da var, kirpma yok",
                  "takili sayac da var, cit ile kirpildi")):
    kd, kg = SONUC[b][0] - SONUC[a][0], SONUC[b][1] - SONUC[a][1]
    print(f"{ad:<34} {kd:>+13.4f} {round(kd * 252):>6} "
          f"{kg:>+8.4f} {round(kg * 252):>6}")
e, s = kur("ariza", False)
c = cit_ogren(e, UC)
print(f"\narizali tabloda ogrenilen ust cit: ort_tuketim {c['ort_tuketim'][1]:.2f}, "
      f"oynaklik {c['oynaklik'][1]:.2f}")
print(f"kirpilan deger: egitim {sum(1 for x in e for a in UC if x[a] > c[a][1])}, "
      f"sinama {sum(1 for x in s for a in UC if x[a] > c[a][1])}; "
      f"silinen satir 0")
print(f"arizanin egim temelli modele maliyeti "
      f"{SONUC['takili sayac da var, kirpma yok'][0] - SONUC['yalniz gercek uc, kirpma yok'][0]:+.4f}, "
      f"agaca {SONUC['takili sayac da var, kirpma yok'][1] - SONUC['yalniz gercek uc, kirpma yok'][1]:+.4f}")
print(f"alti derste kullanilan oznitelik sayisi {len(ALAN)}, uretilen yeni buyukluk 0")
kirpma karari                       egim temelli  abone     agac  abone
yalniz gercek uc                         +0.0040      1  -0.0278     -7
takili sayac da var                      +0.0317      8  -0.0357     -9

arizali tabloda ogrenilen ust cit: ort_tuketim 36.20, oynaklik 29.41
kirpilan deger: egitim 41, sinama 12; silinen satir 0
arizanin egim temelli modele maliyeti -0.0317, agaca +0.0079
alti derste kullanilan oznitelik sayisi 11, uretilen yeni buyukluk 0

İki satırda da işaretler ters. Kırpma eğim temelli modelde artı, ağaçta eksi katkı veriyor ve takılı sayaç bulunduğunda iki yön de okunacak büyüklüğe çıkıyor: sekiz abone ve dokuz abone. Mekanizma iki modelin uç değeri işleme biçiminde. Eğim temelli model her turda bütün satırların hatasını toplayıp ağırlıkları o toplama göre kaydırır; ortalamadan otuz kat uzak bir satır o toplamı tek başına belirler ve on bir ağırlığın hepsini birden çeker. Ağaç ise uç satırı tek bir bölmeyle kenara ayırabilir ve kalan kümeye dokunmaz — ama kırpma o bölmeyi ortadan kaldırır, çünkü çit üstündeki sıralama silinir ve orada kalan 34 abonenin 0,6765’lik şüpheli oranı bir eşiğe dönüştürülemez duruma gelir.

Arıza satırı bunu ikinci yönden doğruluyor. Dokuz satırlık bir kayıt hatası eğim temelli modele 0,0317 kaybettiriyor, ağaca ise 0,0079 kazandırıyor — yani ağaç için ölçülmemiş bir fark. Kırpma uygulandığında eğim temelli model tam olarak 0,8016’ya, arıza hiç olmasaydı okuyacağı sayıya dönüyor. Aynı adım aynı veride bir modelin zararını tamamen geri alırken ötekini tabanın 0,0079 üstüne kadar indiriyor.

Kırpmanın yordamsal yüzü de kayda değer. Çit yalnız eğitim kümesinden öğrenildi, arızalı tabloda üst çit 36,20’ye kaydı, 41 değer kırpıldı ve silinen satır sıfır. Kaynağı bilinmeyen bir uç için tek bir doğru yanıt yoktur; ölçülebilen tek şey, o yanıtın hangi modelde kaç abone ettiğidir.

Özet

  • Çit dışındaki 34 abonenin şüpheli oranı 0,6765, kümenin genelinde 0,2222; uç değerler bu tabloda gürültü değil, en bilgilendirici bölgedir.
  • Aynı kırpma kararı eğim temelli doğrusal modelde artı, karar ağacında eksi katkı veriyor: gerçek uçlarda +0,0040 ve −0,0278, takılı sayaç kaydı da varken +0,0317 ve −0,0357.
  • Eğim temelli model bütün satırların hatasını toplayarak ağırlık günceller ve ortalamadan otuz kat uzak bir satır o toplamı tek başına belirler; ağaç uç satırı tek bir bölmeyle ayırabilirken kırpma o bölmeyi ortadan kaldırır.
  • Dokuz satırlık kayıt hatası eğim temelli modele 0,0317 kaybettiriyor, ağaçta 0,0079’luk ölçülmemiş bir fark bırakıyor; kırpma eğim temelli modeli tam olarak arızasız haldeki 0,8016’ya geri getiriyor.
  • Çit yalnız eğitim kümesinden öğrenildi, 41 değer kırpıldı ve hiçbir satır silinmedi; sınama kümesindeki her abone için tahmin üretildi.

Sonraki Adım

Son çıktının son satırı altı dersin ortak sınırını söylüyor: kullanılan öznitelik sayısı on bir ve üretilen yeni büyüklük sıfır. Altı derste yapılan her şey var olan bir alanın okunma biçimini değiştirmekti — birimi düzeltmek, ölçeği eğitimden öğrenmek, kategoriyi sayıya çevirmek, boşluğun kendisini bir sütuna yazmak, satırların ağırlığını değiştirmek, ucu çite çekmek. Hiçbir derste iki sütunun oranı, farkı ya da çarpımı alınmadı; bir tarihten dönemsel gösterge, bir metinden uzunluk çıkarılmadı. Ve ters yönde de bir şey yapılmadı: hiçbir sütun “katkısı ölçülmedi” gerekçesiyle tablodan çıkarılmadı, on bir öznitelik altı ders boyunca olduğu gibi kaldı. Sonraki konu bu iki işi üstlenir. Önce alan bilgisinden yeni sütunlar türetilir ve her birinin katkısı tek tek ölçülür — katkısı sıfır çıkanlar da yazılır. Sonra ters soru sorulur: hangi sütunlar tablodan çıkarılmalı, üç seçim yöntemi aynı kümede kaç öznitelik seçiyor ve seçimin kendisi ayrılmış kümedeki sayıyı ne kadar şişiriyor.

İ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