İçeriğe geç
academia.sh

Ders 01 / 20

Doğrusal Bağlanım

En küçük karelerin bir açıklama aracı değil bir kestirim yordamı olarak ölçülmesi ve kursun üç sayısının kurulması: sınama kümesinde taban çizgisi 6,5324 m³ kök hata verirken doğrusal model 5,3096 verir, kazanç 1,2228 m³ ve denenen aday sayısı 1'dir. Artıkların ortalaması eğitim kümesinde bölge başına tam sıfırdır, sınama kümesinde -1,0769 ile +1,3685 arasında gezinir; artık değişkenliği kestirim büyüdükçe 3,566'dan 7,137'ye çıkar. Yedi sütunun 127 alt kümesi denendiğinde doğrulamadan seçilen alt küme sınamada 5,3157 ile tam modelin gerisine düşer, sınamadan seçilseydi 5,2931 raporlanırdı ve fark 0,0226 m³'tür.

İçindekiler

Önceki kurs on iki derste özniteliklerin her adımını ölçtü ve kapanışında iki hesabı açık bıraktı. Birincisi: bütün o ölçümler boyunca model hep aynı iki üç aile arasından seçildi — derinlik 6 bir karar ağacı, bir eğim temelli doğrusal model, bir uzaklık temelli yordam — ve ailenin kendisinin ne kattığı hiç sorulmadı. İkincisi: derinliğin niçin altı, komşu sayısının niçin on beş olduğu ve bu sayıların hangi kümeden okunması gerektiği hiç ölçülmedi. Aynı kapanış sınama kümesine en az yirmi dört kez bakıldığını saydı.

Bu kurs iki soruyu birlikte ele alır ve bunun için ölçüyü değiştirir. Öznitelikler sabit tutulur; değişen tek şey modeldir. Her derste üç sayı yan yana durur: taban çizgisi, ailenin ayrılmış kümedeki sayısı ve o sayıyı bulmak için denenen aday sayısı. Üçüncüsü yeni ve kursun kuralıdır: bir modelin sayısı, o sayıyı bulmak için kaç aday denendiği yazılmadan okunamaz. Ayar bütçesi yazılmayan sayı ölçülmemiş sayılır. Bu ders üçlüyü kurar ve en basit aileyle, en küçük karelerle başlar.

  • DM1. Küme M27/K01 ve K02’nin kurgu abone tablosudur; aynı tohumla (20260218) yeniden üretilir. Bölme 756 eğitim, 252 doğrulama, 252 sınama satırıdır ve kurs boyunca değişmez.
  • DM2. Sınıflandırma derslerinde hedef kaçak ya da arıza şüphesi taşıyan abonedir ve taban çizgisi en sık sınıfı söylemektir: sınama kümesinde 0,7579.
  • DM3. Bağlanım derslerinde hedef abonenin üç döneme kadar uzanan okumalarının ortalama tüketimidir (m³) ve taban çizgisi eğitim kümesinin ortalamasıdır: her aboneye aynı sayıyı söylemek.
  • DM4. Bağlanım özniteliği, hedefin hesabına giren hiçbir okumadan türetilmez. Oynaklık, sıfır okuma ve kişi başına tüketim aynı okuma dizisinden çıktığı için kullanılmaz; geriye bölge, hane büyüklüğü, memnuniyet ve dönem sayısı kalır.
  • DM5. Beş bölge göstergesinin toplamı her satırda bire, yani sabit terime eşittir. Biri (kuzey) dışarıda bırakılır ve referans olur.
  • DM6. Ölçü kök ortalama kare hatadır (m³); ortalama mutlak hata yanına basılır. İkisinin ayrıştığı yer model-degerlendirme/05’e bırakılır.
  • DM7. Açıklanan değişim oranı eğitim ortalamasına göre tanımlanır: sıfır, taban çizgisiyle aynı hatayı yapmaktır. Ayrılmış kümede eksi de çıkabilir.
  • DM8. Katsayının nedensel yorumu bu kursun konusu değildir. İşaretin karıştırıcı bir değişkenle dönmesi M26’nın Keşifsel Analiz kursundaki Uygulamalı İstatistik konusunda ölçüldü; burada tekrarlanmaz.
  • DM9. Sınama kümesine her derste yalnız seçim bittikten sonra bakılır ve kaç kez bakıldığı yazılır.

Üç Sayı

Kurulum kümeyi üretir, böler ve iki taban çizgisini basar.

# baglanim.py — MODELDIR. M27/K01'in KURGU abone tablosu ayni tohumla yeniden
# uretilir; hedef abonenin uc donemlik ortalama tuketimidir (m3).
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
    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 = {"no": k["no"], "bolge_ad": k["bolge"][0], "hane": k["hane"],
         "memnuniyet": k["memnuniyet"], "donem": len(v), "hedef": round(ort, 2),
         "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, 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))


def mutlak(kestirim, s):
    return sum(abs(kestirim(x) - x["hedef"]) for x in s) / len(s)


print(f"abone {len(VERI)}, egitim {len(EGT)}, dogrulama {len(DOG)}, sinama {len(SIN)}")
print(f"siniflandirma taban cizgisi (en sik sinif, sinamada) "
      f"{sum(x['supheli'] == 0 for x in SIN) / len(SIN):.4f}")
print(f"baglanim taban cizgisi (egitim ortalamasi) {ORT:.4f} m3\n")
print(f"{'kume':<12} {'kok hata':>9} {'mutlak hata':>12}")
for ad, s in (("egitim", EGT), ("dogrulama", DOG), ("sinama", SIN)):
    print(f"{ad:<12} {kok(lambda x: ORT, s):>9.4f} {mutlak(lambda x: ORT, s):>12.4f}")
abone 1260, egitim 756, dogrulama 252, sinama 252
siniflandirma taban cizgisi (en sik sinif, sinamada) 0.7579
baglanim taban cizgisi (egitim ortalamasi) 19.7665 m3

kume          kok hata  mutlak hata
egitim          6.1995       4.9017
dogrulama       6.4193       5.1148
sinama          6.5324       5.0806

İki taban çizgisi de öğrenmeyen yordamlardır ve ikisi de bu kurs boyunca sabit kalır. Sınıflandırmada 0,7579 sayısı önceki iki kurstan olduğu gibi devralınır. Bağlanımda taban çizgisi her aboneye 19,7665 m³ söyler ve sınama kümesinde 6,5324 m³ kök hata verir: kalan bütün sayıların ölçüleceği sıfır noktası.

En Küçük Kareler Bir Kestirim Yordamıdır

En küçük kareler, kare hata toplamını en küçük yapan katsayıları çözer. Çözüm kapalı biçimdedir: sütunların birbiriyle çarpımlarından kurulan bir denklem takımı eleme ile çözülür.

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


def coz(A, b):                              # kismi pivotlamali eleme
    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


def satir(x, alan):
    return [1.0] + [float(x[a]) for a in alan]


def en_kucuk_kare(s, alan):                 # MODELDIR: dogrusal baglanim
    X = [satir(x, alan) for x in s]
    y = [x["hedef"] for x in s]
    p = len(X[0])
    A = [[sum(X[i][a] * X[i][b] for i in range(len(X))) 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, alan):
    return lambda x: sum(a * b for a, b in zip(w, satir(x, alan)))


def oran(kestirim, s):                      # aciklanan degisim orani
    return 1 - (sum((kestirim(x) - x["hedef"]) ** 2 for x in s)
                / sum((ORT - x["hedef"]) ** 2 for x in s))


W = en_kucuk_kare(EGT, ALAN)
f = kestirici(W, ALAN)
print(f"sabit terim {W[0]:>8.3f}   (kuzey referans)")
for i, a in enumerate(ALAN):
    print(f"{a:<12} {W[i + 1]:>8.3f}")
print(f"\n{'kume':<12} {'taban kok':>10} {'model kok':>10} {'fark':>8} "
      f"{'mutlak':>8} {'oran':>7}")
for ad, s in (("egitim", EGT), ("dogrulama", DOG), ("sinama", SIN)):
    t = kok(lambda x: ORT, s)
    print(f"{ad:<12} {t:>10.4f} {kok(f, s):>10.4f} {t - kok(f, s):>+8.4f} "
          f"{mutlak(f, s):>8.4f} {oran(f, s):>7.4f}")
print(f"\ndenenen aday sayisi 1")
sabit terim   21.820   (kuzey referans)
b_guney        -3.383
b_dogu          4.598
b_bati         -5.851
b_merkez        2.340
hane            0.062
memnuniyet     -0.148
donem          -0.550

kume          taban kok  model kok     fark   mutlak    oran
egitim           6.1995     5.0757  +1.1238   3.7461  0.3297
dogrulama        6.4193     5.3225  +1.0969   4.0005  0.3125
sinama           6.5324     5.3096  +1.2228   4.0020  0.3393

denenen aday sayisi 1

Üçlü tamamlandı: taban çizgisi 6,5324, ailenin sayısı 5,3096, denenen aday sayısı 1. Kazanç 1,2228 m³, yani tabanın yüzde 18,7’si. Aday sayısının bir olması bu dersin ayrıcalığıdır — sütun kümesi baştan yazıldı, hiçbir ayar değişkeni yok, çözüm kapalı biçimde tek seferde geldi. Kursun kalan derslerinde bu sayı bir daha bir olmayacak.

Aynı katsayı listesi iki ayrı işe koşulabilir ve ikisi aynı şey değildir. Bölge katsayıları kurgudaki taban tüketim düzeylerinin sırasını doğru veriyor: doğu en yüksek, batı en düşük. Ama bu dersin ölçüsü katsayının doğruluğu değil, görülmemiş bir abonede yapılan hatadır. Sınama kümesindeki açıklanan değişim oranı 0,3393’tür ve tabana göre tanımlıdır: sıfır, her aboneye eğitim ortalamasını söylemekle aynı hatayı yapmak demektir.

Varsayımlar Sayıyla Denetlenir

Doğrusal bağlanımın varsayımları vardır: artıkların ortalaması sıfırdır, değişkenlikleri kestirimden bağımsızdır, uçlar simetriktir. Bunlar kuram olarak değil, sayı olarak denetlenir.

def artiklar(kestirim, s):
    return [kestirim(x) - x["hedef"] for x in s]


def orta(v):                                # makine hassasiyetindeki artik sifirdir
    m = sum(v) / len(v)
    return m if abs(m) > 5e-5 else 0.0


print(f"{'bolge':<9} {'egitimde ort':>13} {'sinamada n':>11} {'sinamada ort':>13}")
for b in BOLGE:
    e = [x for x in EGT if x["bolge_ad"] == b[0]]
    v = [x for x in SIN if x["bolge_ad"] == b[0]]
    print(f"{b[0]:<9} {orta(artiklar(f, e)):>+13.4f} {len(v):>11} "
          f"{orta(artiklar(f, v)):>+13.4f}")
sirali = sorted(SIN, key=f)
n = len(sirali) // 4
print(f"\n{'dilim':<7} {'kestirim ort':>13} {'artik ort':>10} {'artik degiskenlik':>19}")
for k in range(4):
    d = sirali[k * n:(k + 1) * n] if k < 3 else sirali[3 * n:]
    v = artiklar(f, d)
    m = sum(v) / len(v)
    s2 = math.sqrt(sum((q - m) ** 2 for q in v) / len(v))
    print(f"dilim {k + 1:<1} {sum(f(x) for x in d) / len(d):>13.2f} {m:>+10.3f} "
          f"{s2:>19.3f}")
v = artiklar(f, SIN)
m = sum(v) / len(v)
s2 = math.sqrt(sum((q - m) ** 2 for q in v) / len(v))
print(f"\nsinamada iki degiskenlik disina dusen artik "
      f"{sum(1 for q in v if abs(q - m) > 2 * s2)}, "
      f"eksi yonde {sum(1 for q in v if q - m < -2 * s2)}, "
      f"arti yonde {sum(1 for q in v if q - m > 2 * s2)}")
bolge      egitimde ort  sinamada n  sinamada ort
kuzey           +0.0000          68       -1.0370
guney           +0.0000          58       -0.0391
dogu            +0.0000          36       -1.0769
bati            +0.0000          32       +1.3685
merkez          +0.0000          58       +0.5708

dilim    kestirim ort  artik ort   artik degiskenlik
dilim 1         15.33     +1.192               3.566
dilim 2         18.67     -1.007               4.746
dilim 3         21.29     -0.237               4.883
dilim 4         23.85     -0.498               7.137

sinamada iki degiskenlik disina dusen artik 17, eksi yonde 11, arti yonde 6

İlk sütun bir denetim değil, bir kimliktir. Eğitim kümesinde her bölgenin artık ortalaması tam sıfırdır ve bunun nedeni modelin iyi olması değildir: bölge göstergeleri sütun olarak modelin içindedir ve en küçük kareler çözümü her sütunu artıklara dik yapar. Bu sayı hiçbir zaman sıfırdan farklı çıkamaz, dolayısıyla hiçbir şey söylemez. Söyleyen sütun üçüncüsüdür: aynı ortalamalar sınama kümesinde -1,0769 ile +1,3685 arasında geziniyor. Batı bölgesindeki otuz iki abonede model ortalama 1,37 m³ fazla söylüyor.

İkinci tablo daha keskin bir bozulma gösteriyor. Artıkların değişkenliği kestirim büyüdükçe 3,566’dan 7,137’ye, yani iki katına çıkıyor. Model, az tüketen abonelerde çok daha isabetli, çok tüketenlerde çok daha kaba. Eşit değişkenlik varsayımının tutmamasının sebebi kurgunun kendisinde: tüketim çarpımsal bir dağılımdan üretiliyor, dolayısıyla büyük değerlerin saçılması da büyük. Son satır aynı asimetriyi öteki yönden veriyor — iki değişkenlik uzağındaki on yedi artığın on biri bir yönde, altısı öteki yönde.

Bozulan varsayımlar bir açıklama çalışmasında katsayıların oynama payını geçersiz kılardı; M26’nın Uygulamalı İstatistik konusu bu hesabı yaptı. Kestirim hedefinde ise ölçü tektir ve zaten alınmıştır: 5,3096. Varsayım denetimi burada sayıyı geçersiz kılmaz, sayının nerede kötü olduğunu söyler.

Ayar Bütçesi Yazılmayan Sayı Ölçülmemiş Sayılır

Bu derste tek bir aday denendi. Yedi sütunun boş olmayan bütün alt kümeleri denenirse ne olur.

import itertools

en_dogrulama, en_sinama, aday = None, None, 0
for r in range(1, len(ALAN) + 1):
    for c in itertools.combinations(ALAN, r):
        aday += 1
        g = kestirici(en_kucuk_kare(EGT, list(c)), list(c))
        d, s = kok(g, DOG), kok(g, SIN)
        if en_dogrulama is None or d < en_dogrulama[0]:
            en_dogrulama = (d, s, c)
        if en_sinama is None or s < en_sinama[1]:
            en_sinama = (d, s, c)
print(f"denenen aday sayisi {aday}")
print(f"tam model            dogrulama {kok(f, DOG):.4f}  sinama {kok(f, SIN):.4f}")
print(f"dogrulamadan secilen dogrulama {en_dogrulama[0]:.4f}  "
      f"sinama {en_dogrulama[1]:.4f}  {len(en_dogrulama[2])} sutun")
print(f"sinamadan secilen    dogrulama {en_sinama[0]:.4f}  "
      f"sinama {en_sinama[1]:.4f}  {len(en_sinama[2])} sutun")
print(f"secim sinamada yapilsaydi rapor edilecek sayi {en_sinama[1]:.4f}, "
      f"durustu {en_dogrulama[1]:.4f}, fark {en_dogrulama[1] - en_sinama[1]:.4f} m3")
print(f"disarida birakilan sutun: "
      f"{[a for a in ALAN if a not in en_dogrulama[2]]}")
denenen aday sayisi 127
tam model            dogrulama 5.3225  sinama 5.3096
dogrulamadan secilen dogrulama 5.3073  sinama 5.3157  6 sutun
sinamadan secilen    dogrulama 5.4150  sinama 5.2931  6 sutun
secim sinamada yapilsaydi rapor edilecek sayi 5.2931, durustu 5.3157, fark 0.0226 m3
disarida birakilan sutun: ['memnuniyet']

Üç satır üç ayrı sayı veriyor ve üçü de aynı model ailesinden, aynı özniteliklerden, aynı bölmeden çıkıyor. Aralarındaki tek fark kaç aday denendiği ve seçimin hangi kümeden okunduğudur.

Doğrulama kümesinden okunan seçim memnuniyet sütununu atıyor ve doğrulamada 5,3073 ile tam modelin 5,3225’ini geçiyor. Aynı seçim sınamada 5,3157 veriyor — yani tam modelin gerisinde. Yüz yirmi yedi aday arasından doğrulamaya bakarak seçmek, hiç seçmemekten kötü bir sonuç üretti; 252 satırlık bir küme üzerinde 127 kez en küçüğü aramak, o kümenin kendi saçılmasını da seçer.

Son iki satır kursun kuralını sayıya çeviriyor. Seçim sınama kümesinden yapılsaydı raporlanacak sayı 5,2931 olurdu; dürüst sayı 5,3157’dir ve fark 0,0226 m³’tür. Farkın işareti sabittir — seçimin yapıldığı kümedeki sayı hiçbir zaman daha kötü çıkamaz. Bu yüzden 5,3096 ile 5,2931 arasındaki karşılaştırma ancak yanlarına 1 ve 127 yazıldığında anlam taşır.

Özet

  • Kursun üç sayısı kuruldu: taban çizgisi, ailenin ayrılmış kümedeki sayısı ve denenen aday sayısı. Sınıflandırmada taban 0,7579, bağlanımda 6,5324 m³’tür.
  • En küçük kareler yedi sütunla sınama kümesinde 5,3096 m³ veriyor; kazanç 1,2228 m³ ve denenen aday sayısı 1’dir. Bu, kursun aday sayısı bir olan tek dersidir.
  • Artık ortalaması eğitim kümesinde bölge başına tam sıfırdır ve bu bir denetim değil, en küçük kareler çözümünün kimliğidir; aynı ortalama sınama kümesinde -1,0769 ile +1,3685 arasında gezinir.
  • Eşit değişkenlik varsayımı tutmuyor: artık değişkenliği kestirim büyüdükçe 3,566’dan 7,137’ye çıkıyor. Kestirim hedefinde bu, sayıyı geçersiz kılmaz; sayının nerede kötü olduğunu söyler.
  • Yedi sütunun 127 alt kümesi denendiğinde doğrulamadan seçilen alt küme sınamada 5,3157 ile tam modelin gerisine düşüyor; sınamadan seçilseydi 5,2931 raporlanırdı ve fark 0,0226 m³’tür.

Sonraki Adım

Bu derste model bir düzlemdi ve sütunları verildiği gibi kullanıldı. Oysa hane büyüklüğü ile tüketim arasındaki ilişkinin bir doğru olması gerekmez; iki kişilik haneden dört kişiliğe geçerken artan tüketim, dört kişilikten altıya geçerken aynı oranda artmayabilir. Doğrusal olmayan bir ilişkiyi doğrusal bir modelle kurmanın yolu vardır ve sütun eklemekten ibarettir: karesi, küpü, ikili çarpımları. Sonraki ders bu genişletmeyi dereceyle ölçer — derece 1’den 8’e süpürülür, her derecenin eğitim ve ayrılmış küme sayıları yan yana basılır, seçim doğrulama kümesinden okunur ve sınama kümesinden okunsaydı hangi derecenin seçileceği aynı tabloda gösterilir.

İ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