İçeriğe geç
academia.sh

Ders 02 / 20

Polinom Bağlanım

Doğrusal olmayan bir ilişkinin sütun ekleyerek doğrusal modelle kurulması ve derecenin iki sayıyı ayrıştırması: derece 1'den 8'e süpürüldüğünde sütun sayısı 7'den 168'e çıkar, eğitim kök hatası 5,0757'den 4,8437 m³'e iner, doğrulama kök hatası 5,2569'da dibe vurup 5,6877'ye tırmanır. Doğrulamadan okunan derece 4'tür ve sınamada 5,3775 verir; sınamadan okunsaydı derece 5 seçilir ve 5,2009 raporlanırdı, fark 0,1766 m³'tür. Doğrulamadan seçilen derece sınamada derece 1'in 0,0679 m³ gerisindedir. Dört öznitelik yalnız 450 ayrık birleşim üretir; her hücreye eğitim ortalamasını söyleyen tavan model eğitimde 3,8418, sınamada 6,3887 verir ve sınamadaki 33 abone eğitimde hiç görülmemiş bir hücreye düşer.

İçindekiler

Önceki ders modeli bir düzlem olarak kurdu ve sütunları verildiği gibi kullandı: hane büyüklüğü bir sütun, memnuniyet bir sütun, dönem sayısı bir sütun. O modelin söylediği şey, hane büyüklüğü bir arttığında tüketimin her yerde aynı miktarda arttığıdır. Bunun doğru olması için bir neden yok. İki kişilik haneden dört kişiliğe geçerken artan tüketim, dört kişilikten altıya geçerken aynı oranda artmayabilir; bölgenin etkisi hane büyüklüğüne göre değişebilir.

Bu ilişkiyi kurmak için model ailesini değiştirmek gerekmez. Doğrusal model, katsayılarında doğrusaldır; sütunlarında değil. Hane büyüklüğünün karesi bir sütun olarak eklendiğinde model hâlâ en küçük karelerle çözülür, ama artık eğrilik taşır. Polinom öznitelikleri bu genişletmenin adıdır ve tek bir ayar değişkeni vardır: derece. Bu ders dereceyi 1’den 8’e süpürür, her derecenin eğitim ve ayrılmış küme sayılarını yan yana basar ve seçimin hangi kümeden okunduğunu iki ayrı sayı olarak gösterir.

  • DM10. Küme, bölme ve hedef önceki dersteki gibidir: aynı kurgu abone tablosu, tohum 20260218, 756/252/252, hedef ortalama tüketim (m³), taban çizgisi eğitim ortalaması ve sınama kümesinde 6,5324 m³ kök hata.
  • DM11. Polinom yalnız üç sayısal sütun üzerinde açılır: hane büyüklüğü, memnuniyet, dönem sayısı. Derece dd için 1i+j+kd1 \le i+j+k \le d koşulunu sağlayan bütün tek terimliler eklenir.
  • DM12. Dört bölge göstergesi her derecede olduğu gibi kalır; polinomun içine girmez. Kuzey önceki derste olduğu gibi referanstır.
  • DM13. Sütunlar eğitim kümesinden öğrenilen ortalama ve değişkenlikle ölçeklenir. Hane büyüklüğünün sekizinci kuvveti bir milyonu aşar; ölçekleme olmadan eleme sayısal olarak çöker.
  • DM14. Yüksek derecelerde sütunlar birbirinin doğrusal birleşimine dönüşür, çünkü hane büyüklüğü yalnız altı, memnuniyet beş, dönem sayısı üç ayrık değer alır. Denklem takımını çözülebilir kılmak için köşegene 10610^{-6} eklenir. Bu bir düzenlileştirme kararı değil, tekil takıma karşı konan sayısal bir eşiktir; ceza kararı sonraki dersin konusudur.
  • DM15. Denenen aday sayısı 8’dir: sekiz derece, başka hiçbir ayar yok.
  • DM16. Seçim doğrulama kümesinden okunur. Sınama kümesindeki sayılar tabloda yer alır ama seçime girmez; yer almalarının nedeni iki seçimin farkının ölçülmesidir.
  • DM17. Tavan model, aynı dört özniteliğin her ayrık birleşimine eğitim kümesindeki ortalamayı söyleyen yordamdır. Bu özniteliklerle kurulabilecek hiçbir model eğitim kümesinde ondan iyi olamaz.

Derece Arttıkça İki Sayı Ayrışıyor

Kurulum önceki dersin kurulumudur; üzerine polinom öznitelikleri ve derece süpürmesi eklenir.

# polinom.py — MODELDIR. Ayni KURGU abone tablosu, ayni tohum ve ayni bolme.
import math

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 = [], []
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:
        continue
    x = {"bolge_ad": k["bolge"][0], "hane": k["hane"], "memnuniyet": k["memnuniyet"],
         "donem": len(v), "hedef": round(sum(v) / len(v), 2)}
    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:]
ORT = sum(x["hedef"] for x in EGT) / len(EGT)


def kok(kestirim, s):
    return math.sqrt(sum((kestirim(x) - x["hedef"]) ** 2 for x in s) / len(s))


print(f"egitim {len(EGT)}, dogrulama {len(DOG)}, sinama {len(SIN)}, "
      f"taban cizgisi sinamada {kok(lambda x: ORT, SIN):.4f} m3")
egitim 756, dogrulama 252, sinama 252, taban cizgisi sinamada 6.5324 m3

Polinom öznitelikleri, ölçekleme ve çözüm bir arada durur. Ölçekleme adımı önceki kursun kuralına uyar ve iki yüzlüdür: öğrenme yalnız eğitim kümesinden, uygulama her kümeye.

import itertools

SAYISAL = ["hane", "memnuniyet", "donem"]
GOSTERGE = ["b_guney", "b_dogu", "b_bati", "b_merkez"]


def usler(derece):                          # 1 <= i+j+k <= derece olan butun tek terimliler
    return [u for u in itertools.product(range(derece + 1), repeat=len(SAYISAL))
            if 1 <= sum(u) <= derece]


def ham(x, us):
    return ([float(x[a]) for a in GOSTERGE]
            + [math.prod(x[a] ** k for a, k in zip(SAYISAL, u)) for u in us])


def olcek_ogren(egt, us):                   # OGRENME: yalniz egitim kumesinden
    H = [ham(x, us) for x in egt]
    p = len(H[0])
    o = [sum(r[j] for r in H) / len(H) for j in range(p)]
    s = [max(1e-9, math.sqrt(sum((r[j] - o[j]) ** 2 for r in H) / len(H)))
         for j in range(p)]
    return o, s


def uygula(x, us, o, s):                    # UYGULAMA
    h = ham(x, us)
    return [1.0] + [(h[j] - o[j]) / s[j] for j in range(len(h))]


def coz(A, b):
    n = len(b)
    for i in range(n):
        p = max(range(i, n), key=lambda k: abs(A[k][i]))
        A[i], A[p], b[i], b[p] = A[p], A[i], b[p], b[i]
        for k in range(i + 1, n):
            f = A[k][i] / A[i][i]
            for j in range(i, n):
                A[k][j] -= f * A[i][j]
            b[k] -= f * b[i]
    w = [0.0] * n
    for i in range(n - 1, -1, -1):
        w[i] = (b[i] - sum(A[i][j] * w[j] for j in range(i + 1, n))) / A[i][i]
    return w


DENGE = 1e-6                                # tekil takimi cozulebilir kilan sayisal esik


def polinom(egt, us, o, s):                 # MODELDIR: polinom baglanim
    X = [uygula(x, us, o, s) for x in egt]
    y = [x["hedef"] for x in egt]
    p = len(X[0])
    A = [[sum(X[i][a] * X[i][b] for i in range(len(X)))
          + (DENGE if a == b and a else 0.0) for b in range(p)] for a in range(p)]
    return coz(A, [sum(X[i][a] * y[i] for i in range(len(X))) for a in range(p)])


def kestirici(w, us, o, s):
    return lambda x: sum(a * b for a, b in zip(w, uygula(x, us, o, s)))


SONUC = []
print(f"{'derece':>7} {'sutun':>6} {'egitimde':>9} {'dogrulama':>10} {'sinama':>8} "
      f"{'agirlik':>10}")
for derece in range(1, 9):
    us = usler(derece)
    o, s = olcek_ogren(EGT, us)
    w = polinom(EGT, us, o, s)
    g = kestirici(w, us, o, s)
    SONUC.append((derece, len(us) + len(GOSTERGE), kok(g, EGT), kok(g, DOG), kok(g, SIN)))
    print(f"{derece:>7} {SONUC[-1][1]:>6} {SONUC[-1][2]:>9.4f} {SONUC[-1][3]:>10.4f} "
          f"{SONUC[-1][4]:>8.4f} {math.sqrt(sum(v * v for v in w[1:])):>10.2f}")
print(f"\ntaban cizgisi sinamada {kok(lambda x: ORT, SIN):.4f} m3, denenen aday sayisi 8")
 derece  sutun  egitimde  dogrulama   sinama    agirlik
      1      7    5.0757     5.3225   5.3096       3.26
      2     13    5.0531     5.3219   5.2648       5.12
      3     23    5.0355     5.3184   5.3183      17.22
      4     38    5.0013     5.2569   5.3775     212.08
      5     59    4.9228     5.2635   5.2009    1520.80
      6     87    4.8933     5.3610   5.3224    3487.91
      7    123    4.8733     5.4923   5.5168    6959.24
      8    168    4.8437     5.6877   5.9085    9344.45

taban cizgisi sinamada 6.5324 m3, denenen aday sayisi 8

Eğitim sütunu tek yönlüdür ve kesintisiz iyileşir: 5,0757’den 4,8437’ye. Bu bir bulgu değil, bir kimliktir. Derece dd’nin sütunları derece d1d-1’in sütunlarını kapsar, dolayısıyla küçük derecenin çözümü büyük derecede de erişilebilir; en küçük kareler onu ancak iyileştirebilir. Eğitim sayısının artan bir sütun kümesi boyunca kötüleşmesi olanaksızdır ve bu yüzden eğitim sayısı derece seçiminde hiçbir zaman kullanılamaz.

Doğrulama sütunu iki yönlüdür: 5,3225’ten 5,2569’a iner, sonra 5,6877’ye tırmanır. Ağırlık sütunu tırmanışın mekanizmasını gösteriyor. Katsayı büyüklüğü 3,26’dan 9.344,45’e, yani üç bin katına çıkıyor. Yüksek dereceli tek terimliler birbirinin neredeyse doğrusal birleşimidir — altı ayrık değer alan bir sütunun altıncı kuvveti daha düşük kuvvetlerinin bir birleşimidir — ve model bu neredeyse aynı sütunlara devasa, birbirini götüren katsayılar veriyor. Eğitim kümesinde bu bedava; ayrılmış kümede o katsayılar tam olarak götürülmüyor ve fark hataya dönüşüyor.

Seçim Hangi Kümeden Okundu

Sekiz satırlık tablodan bir derece seçmek gerekiyor ve bu seçim iki farklı kümeden yapılabilir.

en_dogrulama = min(SONUC, key=lambda t: t[3])
en_sinama = min(SONUC, key=lambda t: t[4])
birinci = SONUC[0]
print(f"dogrulamadan okunan derece {en_dogrulama[0]}: dogrulama "
      f"{en_dogrulama[3]:.4f}, sinama {en_dogrulama[4]:.4f}")
print(f"sinamadan okunsaydi derece {en_sinama[0]}: dogrulama "
      f"{en_sinama[3]:.4f}, sinama {en_sinama[4]:.4f}")
print(f"iki secim arasindaki fark {en_dogrulama[4] - en_sinama[4]:.4f} m3")
print(f"derece 1 sinamada {birinci[4]:.4f}; dogrulamadan secilen derece "
      f"{en_dogrulama[4] - birinci[4]:+.4f} m3 ile onun gerisinde\n")
print(f"{'derece':>7} {'ayrisma (dogrulama - egitim)':>30}")
for d, sutun, e, dg, sn in SONUC:
    print(f"{d:>7} {dg - e:>30.4f}")
dogrulamadan okunan derece 4: dogrulama 5.2569, sinama 5.3775
sinamadan okunsaydi derece 5: dogrulama 5.2635, sinama 5.2009
iki secim arasindaki fark 0.1766 m3
derece 1 sinamada 5.3096; dogrulamadan secilen derece +0.0679 m3 ile onun gerisinde

 derece   ayrisma (dogrulama - egitim)
      1                         0.2467
      2                         0.2687
      3                         0.2828
      4                         0.2556
      5                         0.3407
      6                         0.4677
      7                         0.6189
      8                         0.8440

İlk üç satır kursun kuralının niçin gerekli olduğunu tek bir örnekte gösteriyor. Doğrulama kümesi derece 4’ü seçiyor; o derece sınamada 5,3775 veriyor. Sınama kümesinden seçilseydi derece 5 gelirdi ve 5,2009 raporlanırdı. İki sayı arasındaki 0,1766 m³, dersin sekiz adaylık bütçesinin bedelidir ve modelin öğrendiği hiçbir şeyden gelmiyor.

Dördüncü satır daha rahatsız edicidir. Doğrulamadan seçilen derece 4, sınamada derece 1’in 0,0679 m³ gerisinde. Yani sekiz aday deneyip doğrulama kümesine bakarak seçmek, hiç denemeyip en basit modelde kalmaktan kötü bir sonuç üretti. Bu bir hesap hatası değil, doğrulama kümesinin de 252 satır olmasının sonucudur; o kümedeki en küçük sayı, o kümenin kendi saçılmasını da içerir. Kursun ikinci iddiası bu satırda ilk kez ölçülüyor: daha güçlü bir aile daha zayıf olanı geçmedi.

Ayrışma sütunu tabloyu tek bir sayıya indiriyor. Doğrulama ile eğitim arasındaki fark derece 4’e kadar 0,25 ile 0,28 arasında duruyor, derece 5’te 0,3407’ye çıkıyor ve derece 8’de 0,8440 oluyor. Ayrışmanın başladığı yer derece 5’tir; doğrulama sayısının dibe vurduğu yerden bir sonraki adım.

Bu Özniteliklerin Tavanı

Derece 8’de 168 sütun var. Bu sütunların hepsi dört özniteliğin işlevleridir ve o dört öznitelik yalnız sonlu sayıda birleşim üretir.

hucre = {}
for x in EGT:
    hucre.setdefault((x["bolge_ad"], x["hane"], x["memnuniyet"], x["donem"]),
                     []).append(x["hedef"])
ORTALAMA = {k: sum(v) / len(v) for k, v in hucre.items()}


def hucre_kestirimi(x):                     # her hucreye egitim ortalamasi: tavan model
    return ORTALAMA.get((x["bolge_ad"], x["hane"], x["memnuniyet"], x["donem"]), ORT)


print(f"ayrik oznitelik birlesimi 5*6*5*3 = {5 * 6 * 5 * 3}, "
      f"egitimde dolu hucre {len(hucre)}")
print(f"hucre ortalamasi modeli: egitim {kok(hucre_kestirimi, EGT):.4f}, "
      f"sinama {kok(hucre_kestirimi, SIN):.4f}")
print(f"sinamada gorulen ama egitimde bulunmayan hucre "
      f"{sum(1 for x in SIN if (x['bolge_ad'], x['hane'], x['memnuniyet'], x['donem']) not in ORTALAMA)}")
ayrik oznitelik birlesimi 5*6*5*3 = 450, egitimde dolu hucre 268
hucre ortalamasi modeli: egitim 3.8418, sinama 6.3887
sinamada gorulen ama egitimde bulunmayan hucre 33

Hücre ortalaması modeli, bu dört öznitelikle kurulabilecek en esnek yordamdır: her birleşime kendi eğitim ortalamasını söyler ve hiçbir biçim varsayımı taşımaz. Eğitim kümesinde 3,8418 veriyor, yani derece 8 polinomunun 4,8437’sini rahatça geçiyor. Sınama kümesinde ise 6,3887 veriyor ve taban çizgisinin 6,5324’üne yalnızca 0,1437 m³ yaklaşıyor.

İki sayı arasındaki bu uçurum derece süpürmesinin nereye doğru gittiğini söylüyor. 268 dolu hücreye 756 satır düşüyor, yani hücre başına ortalama üç abone; üç abonenin ortalaması bir kestirim değil, o üç abonenin kendisidir. Polinom derecesi büyüdükçe model bu yordama yaklaşıyor ve sınama sayısı da onun sayısına doğru gidiyor. Son satır aynı sınırı öteki yönden gösteriyor: sınama kümesindeki 252 abonenin 33’ü eğitim kümesinde hiç görülmemiş bir hücreye düşüyor ve onlara söylenecek tek şey taban çizgisidir.

Özet

  • Polinom öznitelikleri model ailesini değiştirmez; doğrusal model katsayılarında doğrusaldır, sütunlarında değil. Derece 1’den 8’e giderken sütun sayısı 7’den 168’e çıkıyor.
  • Eğitim kök hatası 5,0757’den 4,8437 m³’e kesintisiz iniyor ve bu bir kimliktir: büyük derecenin sütunları küçüğünü kapsar. Eğitim sayısı derece seçiminde kullanılamaz.
  • Doğrulama kök hatası 5,2569’da dibe vurup 5,6877’ye tırmanıyor; ağırlık büyüklüğü aynı aralıkta 3,26’dan 9.344,45’e çıkıyor. Tırmanışın mekanizması, neredeyse aynı sütunlara verilen birbirini götüren devasa katsayılardır.
  • Doğrulamadan okunan derece 4 sınamada 5,3775 veriyor; sınamadan okunsaydı derece 5 ile 5,2009 raporlanırdı ve fark 0,1766 m³’tür. Aynı seçim sınamada derece 1’in 0,0679 m³ gerisinde kalıyor.
  • Dört öznitelik 450 ayrık birleşim üretir ve eğitimde 268’i doludur; her hücreye kendi ortalamasını söyleyen tavan model eğitimde 3,8418, sınamada 6,3887 verir. Sınamadaki 33 abone eğitimde hiç görülmemiş bir hücreye düşer.

Sonraki Adım

Derece süpürmesi bir düğmeyi tam sayı adımlarla çevirdi: derece 4 ile 5 arasında ara durak yok ve derece 5’e geçmek yirmi bir sütunu birden ekliyor. Sütunları eklemekle silmek arasında üçüncü bir yol vardır — hepsini bırakıp katsayılarını cezalandırmak. M27/K01 bu sezgiyi tek bir ceza türüyle kurmuştu ve ceza katsayısı büyüdükçe iki sayının ters yönde gittiğini ölçmüştü. Sonraki ders cezanın biçimini değiştirir: karesel, mutlak ve karma ceza aynı sütun kümesine ayrı ayrı uygulanır ve ölçü artık hata değil seyrekliktir — hangi ceza kaç katsayıyı tam sıfırlıyor, hangisi hepsini küçültüp bırakıyor, ve sıfırlanan sütunların ayrılmış kümedeki karşılığı ne.

İ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