İçeriğe geç
academia.sh

Ders 02 / 12

Öznitelik Ölçekleme

Standartlaştırma ve normalleştirme kararlarının üç model ailesinde ayrı ayrı ölçülmesi: standartlaştırma eğim temelli doğrusal modele +0,0437 katarken uzaklık temelli yordamda −0,0159 verir ve karar ağacında katkı tam olarak sıfırdır. Ölçek eğitim kümesinden öğrenilen bir nesnedir; sınama kümesine uygulandığında iki değer [0, 1] aralığının dışına çıkar ve standart puanlar 5,11'e kadar yükselir. On bir sütunun hepsi ölçeklendiğinde uzaklık temelli yordam bir abone daha kaybeder.

İçindekiler

Önceki ders ham kayıttaki üç kusuru düzeltti ve uzaklık temelli yordamı 0,7540’tan 0,7857’ye çıkardı. Bu sayı taban çizgisini yalnız 0,0278 geçiyor ve aynı tabloyla eğitilen karar ağacının gerisinde. Sebep temizlenmemiş bir şey değil, hiç sorulmamış bir şey: sütunlar aynı birime çevrildi ama aynı büyüklüğe çevrilmedi. Ortalama tüketim sıfır ile kırk üç arasında değişirken hane büyüklüğü bir ile altı, bölge sütunları sıfır ile bir arasında değişiyor. Farkların karelerini toplayan bir yordam için bu, sütunlara sessizce ağırlık vermektir.

Bu ders iki ölçekleme kararını ölçer. Standartlaştırma her değerden sütunun ortalamasını çıkarıp değişkenliğine böler; sonuç standart puandır ve M26’nın Veri Toplama ve Hazırlama kursunda tanımlanmıştı. Normalleştirme her sütunu en küçük değeri sıfır, en büyüğü bir olacak biçimde aralığa sıkıştırır; M26/K03’ün metin normalleştirmesiyle adı ortaktır ama işi başkadır, biri yazımı tekleştirir, bu sayıyı aralığa oturtur. İkisi de yordam olarak yeni değil; ölçülen şey, her birinin hangi model ailesinde kaç abone ettiğidir.

  • HA9. Bu dersin başlangıç tablosu önceki dersin çıktısıdır: üç kusuru düzeltilmiş 1.260 abonelik kurgu tablo, aynı 756/252/252 bölmesi, sınama kümesinde taban çizgisi 0,7579.
  • HA10. Üç model ailesi karşılaştırılır ve üçü de ders içinde yazılır: en yakın on beş komşuya bakan uzaklık temelli yordam, ağırlıklarını eğim yönünde güncelleyen doğrusal model ve derinlik 6 karar ağacı. Ayarları kurs boyunca sabittir.
  • HA11. Eğim temelli modelin çıktısı S biçimli bir işlevle sıfır ile bir arasına sıkıştırılır; 0,5 eşiği aşan abone şüpheli sayılır. Eşik bir seçimdir ve bu kursta değişmez.
  • HA12. Ölçekleme yalnız beş sayısal sütuna uygulanır: ortalama tüketim, oynaklık, hane büyüklüğü, memnuniyet, dönem sayısı. İkili sütunların ölçeklenmesi dersin sonunda ayrı bir karar olarak ölçülür.
  • HA13. Ölçek eğitilmiş bir nesnedir ve iki yüzü vardır: öğrenme, ölçek sayılarının eğitim kümesinden çıkarılması; uygulama, o sayıların bir kümeye uygulanması. Kursun ikinci kuralı burada ilk kez yordama dönüşür: her hazırlama adımı yalnız eğitim kümesinden öğrenilir ve ayrılmış kümeye uygulanır.
  • HA14. Bütün kümeden öğrenilen ölçek bir sızıntıdır. M27/K01 bunu dört sızıntı türünden biri olarak saymıştı; buradaki iş o sayıları tekrarlamak değil, sızmayan biçimi yordam olarak kurmaktır.
  • HA15. Ölçü doğruluktur ve sınama kümesi 252 abonedir; bir abone 0,0040 eder.
  • HA16. Kayan noktalı karşılaştırma == ile yapılmaz. Aralık dışı sayımında 0.0 <= v <= 1.0 kullanılır; sınır değerinin kendisi aralık içi sayılır.

Üç Model, İki Ölçekleme Kararı

Kurulum tabloyu üretir ve beş sayısal sütunun ham aralıklarını basar.

# olcekleme.py — MODELDIR. M27/K01'in kurgu abone tablosu, onceki derste
# temizlenmis haliyle yeniden uretilir.
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)


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)
SAYISAL = ["ort_tuketim", "oynaklik", "hane", "memnuniyet", "donem"]
ALAN = SAYISAL + ["sifir_okuma", "b_kuzey", "b_guney", "b_dogu", "b_bati", "b_merkez"]
print(f"egitim {len(EGT)}, sinama {len(SIN)}, taban cizgisi {TABAN:.4f}")
print(f"{'sutun':<12} {'en kucuk':>9} {'en buyuk':>9} {'ortalama':>9}")
for a in SAYISAL:
    v = [x[a] for x in EGT]
    print(f"{a:<12} {min(v):>9.2f} {max(v):>9.2f} {statistics.fmean(v):>9.2f}")
egitim 756, sinama 252, taban cizgisi 0.7579
sutun         en kucuk  en buyuk  ortalama
ort_tuketim       0.00     42.90     19.77
oynaklik          0.00     40.57      9.62
hane              1.00      6.00      3.22
memnuniyet        1.00      5.00      3.37
donem             1.00      3.00      2.53

Aralıklar arasındaki oran doksan katı buluyor. Şimdi üç model ve iki ölçekleme kararı yazılır. Ölçekleme işlevlerinin öğrenme ve uygulama olarak ikiye ayrılması bir biçim tercihi değil, kursun kuralının koda geçmiş halidir.

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 komsu_tahmin(egt, x, alan, k=15):       # MODELDIR: uzaklik temelli yordam
    u = sorted((sum((x[a] - y[a]) ** 2 for a in alan), y["supheli"]) for y in egt)[:k]
    return int(sum(t[1] for t in u) * 2 > k)


def sikistir(z):                            # S bicimli isleve tasma korumasi
    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 dogrusal_tahmin(m, x, alan):
    return int(sikistir(sum(m[0][i] * x[a] for i, a in enumerate(alan)) + m[1]) > 0.5)


def uc_model(egt, sin, alan=None):
    alan = alan or ALAN
    m1, m3 = agac(egt, 6, alan), dogrusal(egt, alan)
    return (sum(komsu_tahmin(egt, x, alan) == x["supheli"] for x in sin) / len(sin),
            sum(dogrusal_tahmin(m3, x, alan) == x["supheli"] for x in sin) / len(sin),
            sum(agac_tahmin(m1, x) == x["supheli"] for x in sin) / len(sin))


def standart_ogren(egt, sutun):             # OGRENME: ortalama ve degiskenlik
    return {a: (statistics.fmean(x[a] for x in egt),
                statistics.pstdev([x[a] for x in egt])) for a in sutun}


def standart_uygula(p, s):                  # UYGULAMA
    return [dict(x, **{a: (x[a] - p[a][0]) / p[a][1] for a in p}) for x in s]


def normal_ogren(egt, sutun):               # OGRENME: en kucuk ve en buyuk
    return {a: (min(x[a] for x in egt), max(x[a] for x in egt)) for a in sutun}


def normal_uygula(p, s):                    # UYGULAMA
    return [dict(x, **{a: (x[a] - p[a][0]) / (p[a][1] - p[a][0]) for a in p}) for x in s]


PS, PN = standart_ogren(EGT, SAYISAL), normal_ogren(EGT, SAYISAL)
DURUM = [("olceksiz (ham sutun)", EGT, SIN),
         ("standartlastirma", standart_uygula(PS, EGT), standart_uygula(PS, SIN)),
         ("normallestirme", normal_uygula(PN, EGT), normal_uygula(PN, SIN))]
S = {}
print(f"{'karar':<24} {'uzaklik':>8} {'egim temelli':>13} {'agac':>8}")
print(f"{'taban cizgisi':<24} {TABAN:>8.4f} {TABAN:>13.4f} {TABAN:>8.4f}")
for ad, e, s in DURUM:
    S[ad] = uc_model(e, s)
    print(f"{ad:<24} {S[ad][0]:>8.4f} {S[ad][1]:>13.4f} {S[ad][2]:>8.4f}")
h = S["olceksiz (ham sutun)"]
for ad in ("standartlastirma", "normallestirme"):
    k = [S[ad][i] - h[i] for i in range(3)]
    print(f"{ad + ' katkisi':<24} {k[0]:>+8.4f} {k[1]:>+13.4f} {k[2]:>+8.4f}")
karar                     uzaklik  egim temelli     agac
taban cizgisi              0.7579        0.7579   0.7579
olceksiz (ham sutun)       0.7857        0.7579   0.7778
standartlastirma           0.7698        0.8016   0.7778
normallestirme             0.7619        0.7817   0.7778
standartlastirma katkisi  -0.0159       +0.0437  +0.0000
normallestirme katkisi    -0.0238       +0.0238  +0.0000

Ağaç sütunu üç durumda da aynı sayıyı veriyor ve bu, ölçüm gürültüsünün altında kalmış küçük bir fark değil, tam bir sıfırdır. Sebebi gösterilebilir: ağaç her sütunda yalnız değerlerin sırasına bakar, adayları sıralı ayrık değerler arasından seçer ve bir eşikle böler. Standartlaştırma ile normalleştirme artan dönüşümlerdir; sırayı değiştirmezler, dolayısıyla ağacın seçebileceği bölmeler birebir aynı kalır. Ağaç temelli bir yordamın önüne ölçekleme adımı koymak sonucu değiştirmez; katkısı sıfırdır ve bu, adımın alışkanlık olduğunun tanımıdır.

Eğim temelli doğrusal model ters uçtadır. Ölçeksiz tabloda 0,7579 okuyor — yani tam olarak taban çizgisi. Bu sayı iyi bir sayı değil, bir çöküş belirtisidir: model her aboneye aynı yanıtı veriyor. Ortalama tüketim kırk üçe kadar çıkarken hane büyüklüğü altıyı geçmiyor, bu yüzden aynı adım büyüklüğü bir sütun için çok büyük, öteki için çok küçük kalıyor ve ağırlıklar dört yüz turda kullanılabilir bir yere ulaşamıyor. Standartlaştırma bu modele 0,0437, yani on bir abone katıyor.

Uzaklık temelli yordamın satırı ise yaygın bir beklentiyi bozuyor. Standartlaştırma ona 0,0159 kaybettiriyor, normalleştirme 0,0238. Ölçekleme uzaklık temelli yordamlara yardım eden bir adım değildir; sütunlara eşit ağırlık veren bir adımdır. Bu tabloda ham ölçek zaten en geniş aralığı en bilgilendirici iki sütuna, ortalama tüketim ile oynaklığa vermişti. Eşitleme o ağırlığı alıp hane büyüklüğüne ve dönem sayısına dağıtıyor. Kararın işareti, ölçeğin kendisinin kazara taşıdığı bilgiye bağlıdır ve bu ancak ölçülerek bilinir.

Ölçek Eğitilmiş Bir Nesnedir

Ölçekleme adımının öğrendiği şey birkaç sayıdır ve o sayılar yalnız eğitim kümesinden gelir.

print(f"{'sutun':<12} {'ortalama':>9} {'degiskenlik':>12} "
      f"{'en kucuk':>9} {'en buyuk':>9}")
for a in SAYISAL:
    print(f"{a:<12} {PS[a][0]:>9.3f} {PS[a][1]:>12.3f} "
          f"{PN[a][0]:>9.2f} {PN[a][1]:>9.2f}")
sn = normal_uygula(PN, SIN)
print(f"\nsinamada [0, 1] araligi disina cikan deger "
      f"{sum(1 for x in sn for a in SAYISAL if not 0.0 <= x[a] <= 1.0)}, "
      f"abone {sum(1 for x in sn if any(not 0.0 <= x[a] <= 1.0 for a in SAYISAL))}")
ss = standart_uygula(PS, SIN)
print(f"{'sutun':<12} {'sinamada en dusuk':>18} {'en yuksek':>10} (standart puan)")
for a in SAYISAL:
    v = [x[a] for x in ss]
    print(f"{a:<12} {min(v):>18.2f} {max(v):>10.2f}")
PT = standart_ogren(EGT, ALAN)
t = uc_model(standart_uygula(PT, EGT), standart_uygula(PT, SIN))
print(f"\non bir sutunun hepsi standartlastirilinca: uzaklik {t[0]:.4f}, "
      f"egim temelli {t[1]:.4f}, agac {t[2]:.4f}")
sutun         ortalama  degiskenlik  en kucuk  en buyuk
ort_tuketim     19.767        6.200      0.00     42.90
oynaklik         9.622        8.120      0.00     40.57
hane             3.224        1.270      1.00      6.00
memnuniyet       3.372        1.147      1.00      5.00
donem            2.532        0.715      1.00      3.00

sinamada [0, 1] araligi disina cikan deger 2, abone 2
sutun         sinamada en dusuk  en yuksek (standart puan)
ort_tuketim               -2.63       3.83
oynaklik                  -1.19       5.11
hane                      -1.75       2.19
memnuniyet                -2.07       1.42
donem                     -2.14       0.66

on bir sutunun hepsi standartlastirilinca: uzaklik 0.7659, egim temelli 0.8016, agac 0.7778

Öğrenilen nesne on sayıdır ve hepsi 756 abonelik eğitim kümesinden çıkmıştır. Uygulanan yerde bunun görünür bir sonucu var: normalleştirme “her değeri sıfır ile bir arasına oturtur” diye tanımlanır, ama sınama kümesinde iki değer o aralığın dışına çıkıyor. Bu bir hata değildir ve düzeltilmez. Düzeltmenin tek yolu en küçüğü ve en büyüğü sınama kümesine de bakarak seçmek olurdu; o da ölçeği ayrılmış kümeden öğrenmek, yani sızdırmak olurdu. M27/K01 ayrımdan önce ölçeklemeyi dört sızıntı türünden biri olarak saymıştı; buradaki iş o sayıları tekrarlamak değil, sızmayan biçimi bir nesne olarak kurmaktır. Standart puan tablosu aynı şeyi öteki yönden gösterir: oynaklık sütununda sınama kümesindeki en yüksek değer 5,11 standart puandır ve eğitim kümesinden öğrenilmiş ölçek onu kırpmadan geçirir.

Son satır üçüncü bir kararı ölçüyor: hangi sütunlar ölçeklenir. Beş sayısal sütun yerine ikili sütunlar da dahil on bir sütunun hepsi standartlaştırıldığında eğim temelli model 0,8016’da kalıyor, ağaç 0,7778’de kalıyor, uzaklık temelli yordam ise 0,7698’den 0,7659’a düşüyor. Bir abonelik bu fark tek başına okunmaz, ama yönü açıklanabilir: bir ikili sütun standartlaştırıldığında seyrek olan kategori büyük bir standart puana taşınır ve bölge farkı uzaklık toplamında olduğundan ağır basar. Ölçekleme kararı tek bir düğme değildir; hangi sütuna uygulandığı da karardır ve o da ayrılmış kümede ölçülür.

Özet

  • Standartlaştırma eğim temelli doğrusal modele 0,0437, yani on bir abone katıyor; aynı karar uzaklık temelli yordamda −0,0159, karar ağacında tam olarak 0,0000 veriyor.
  • Ağaçtaki sıfır ölçüm gürültüsü değil kanıtlanabilir bir sonuçtur: standartlaştırma ve normalleştirme artan dönüşümlerdir, sütun içindeki sırayı değiştirmezler ve ağaç yalnız sıraya bakar.
  • Eğim temelli model ölçeksiz tabloda tam olarak taban çizgisini, 0,7579’u okuyor; bu iyi bir sayı değil, tek adım büyüklüğünün doksan kat farklı aralıklara yetmediğinin belirtisidir.
  • Ölçek eğitim kümesinden öğrenilen on sayıdır; sınama kümesine uygulandığında iki değer [0, 1] aralığının dışına çıkar ve bu düzeltilmez, çünkü düzeltmenin tek yolu ölçeği ayrılmış kümeden öğrenmektir.
  • Ölçeklenecek sütunların seçimi ayrı bir karardır: ikili sütunlar da ölçeklendiğinde uzaklık temelli yordam 0,7698’den 0,7659’a iniyor, öteki iki model değişmiyor.

Sonraki Adım

Bu derste bölge bilgisi hazır beş ikili sütun olarak kullanıldı ve o beş sütunun nereden geldiği sorulmadı. Oysa bölge bir metin alanıdır ve sayıya çevrilmesi bir karardır: her kategori için bir sütun açılabilir, kategorilere sıra numarası verilebilir ya da her kategori kendi eğitim kümesindeki şüpheli oranıyla değiştirilebilir. Üçünün maliyeti farklıdır; birincisi sütun sayısını kategori sayısı kadar büyütür, üçüncüsü tek sütunla yetinir ama etiketi kodlamanın içine sokar. Sonraki ders bu üç kodlamayı iki yüz kırk kodluk bir okuma rotası alanında ölçer, ayrılmış kümede görülmemiş kategorileri sayar ve hedef temelli kodlamanın eğitim kümesinde ürettiği şişmenin kat içinde hesaplandığında ne kadar geri çekildiğini basar.

İ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