Ders 07 / 11
Temel Bileşen Çözümlemesi
On iki sütunlu bir abone tablosu daha az sayıya indirildiğinde neyin korunup neyin kaybolduğunun ölçülmesi: sütun ortalamalarıyla geri kurma 3,3411 verirken iki bileşenle geri kurma 2,7762 veriyor ve fark tabanın yalnız 0,169'u kadar; aynı iki bileşen bileşen payının 0,341'ini taşıdığı hâlde ikili uzaklıkların ortalaması özgününün 0,4965 katına iniyor ve 31.626 çiftin yalnız 0,0057'si yüzde on yanılma payıyla ayakta kalıyor. Ölçeklenmemiş kümede birinci bileşenin yükü tek bir sütuna +0,96 ile bağlanıyor ve ilk iki bileşenin payı 0,863'e çıkıyor, ama ortak birimde ölçülen geri kurma hatası 2,8473 ile ölçeklenmiş izdüşümün gerisinde kalıyor.
İçindekiler
Altı derste noktalar gruplandı. Küme sayısı seçildi, bağlantı ölçütü değiştirildi, yoğunluk eşikleri süpürüldü, sonuçlar rastgele bölmelemeye karşı okundu. Bütün bu işlemlerin altında tek bir işlem vardı: iki abone arasındaki uzaklığı hesaplamak. Uzaklık her seferinde sütunların hepsine birden bakılarak bulundu ve sütunların kaç tane olduğu hiç sorgulanmadı.
Bu bölümün sorusu şudur: bir noktayı tarif etmek için gerçekten kaç sayı gerekiyor. On iki sütunlu bir tabloda her abone on iki sayıyla duruyor, ama sütunlar birbirinden bağımsız değil — kişi başı tüketim ortalama tüketimden ve hane büyüklüğünden türetilmiş, bölge göstergeleri birbirini dışlıyor. Sütunları atmak yerine karıştırıp daha az sayıya indirmek bir seçenektir ve bu dersin ölçtüğü şey o indirmenin bedelidir: nokta az sayıdan geri kurulmaya çalışılınca özgün yerinden ne kadar uzağa düşüyor.
- BA1. Kurgu abone tablosu M27/K01–K03 ile aynıdır ve kurgudur: tohum 20260218, 1.260 satır, bölme 756/252/252. Etiket sütunu bu kursta hiç üretilmez.
- BA2. On iki sütun kullanılır: altı sayısal ölçüm, sıfır okuma göstergesi ve beş bölge göstergesi.
- BA3. Ölçek ve bileşen yönleri yalnız eğitim kümesinden öğrenilir, sınama kümesine aynı sayılarla uygulanır. Bütün kümeden öğrenilseydi ölçüm şişerdi.
- BA4. Bileşen payı hesabı burada tekrarlanmaz. M26/K05’in keşifsel analiz kursu payı bir keşif aracı olarak, M27/K02’nin öznitelik seçimi konusu ise bir öznitelik ölçüsü olarak kurmuştu; bu derste pay yalnız girdidir ve okunmak için kullanılır.
- BA5. Geri kurma hatası, ölçeklenmiş uzayda noktanın özgün yeri ile az sayıdan kurulmuş yeri arasındaki uzaklığın nokta başına ortalamasıdır. Birimi standart sapmadır.
- BA6. Taban çizgisi sütun ortalamalarıyla geri kurmadır: hiçbir bileşen kullanılmaz, her nokta eğitim kümesinin ortalama noktasına eşitlenir. Öğrenmeyen en yalın geri kurma budur.
- BA7. İkinci bir taban çizgisi daha okunur: k tane rastgele dik yön. Bileşenlerin farkının yön sayısından mı seçiminden mi geldiğini yalnız bu ayırır. Üç çekiliş ortalanır.
- BA8. Yönler ders içinde yinelemeyle bulunur ve modeldir: eşdeğişim dizeyi kurulur, en büyük yön 200 yinelemede aranır, her yeni yön öncekilere diklenir. Kitaplık çağrılmaz.
Geri Kurma Hatası ve Tabanı
Yordam üç adımdır. Sütunlar ortak bir ölçeğe getirilir, eğitim kümesinin eşdeğişim dizeyi kurulur, ve bu dizeyin en büyük değişkenliği taşıyan yönü yinelemeyle bulunup listeye eklenir. Her yeni yön kendinden öncekilere dik olmaya zorlanır. Bir nokta k yöne izdüşürülüp geri kurulduğunda kalan uzaklık, o k yönün taşımadığı her şeydir.
# ORTAK — MODELDIR. M27/K01'in KURGU abone tablosu ayni tohumla yeniden uretilir. # Etiket sutunu bu kursta hic uretilmez. import math TOHUM, HAM, M32 = 20260218, 1400, 0xFFFFFFFF BOLGE = [("kuzey", 0.28, 21), ("guney", 0.22, 17), ("dogu", 0.18, 26), ("bati", 0.14, 14), ("merkez", 0.18, 23)] 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 = sum(v) / len(v) x = {"no": k["no"], "hane": k["hane"], "memnuniyet": k["memnuniyet"], "donem": len(v), "ort_tuketim": round(ort, 2), "oynaklik": round(max(v) - min(v), 2), "sifir_okuma": int(min(v) == 0.0), "kisi_basi": round(ort / k["hane"], 3)} for b in BOLGE: x["b_" + b[0]] = int(k["bolge"][0] == b[0]) VERI.append(x) ALAN = ["ort_tuketim", "oynaklik", "kisi_basi", "hane", "memnuniyet", "donem", "sifir_okuma", "b_kuzey", "b_guney", "b_dogu", "b_bati", "b_merkez"] 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:]
n = len(ALAN) ORT = {a: sum(x[a] for x in EGT) / len(EGT) for a in ALAN} SAC = {a: max(1e-9, (sum((x[a] - ORT[a]) ** 2 for x in EGT) / len(EGT)) ** 0.5) for a in ALAN} def carp(m, v): return [sum(m[i][j] * v[j] for j in range(len(v))) for i in range(len(m))] def diklestir(v, B): for u in B: c = sum(v[i] * u[i] for i in range(len(v))) v = [v[i] - c * u[i] for i in range(len(v))] return v def yonleri_bul(Z): C = [[sum(z[i] * z[j] for z in Z) / len(Z) for j in range(n)] for i in range(n)] B, pay = [], [] for _ in range(n): v, lam = [1.0 / (i + 1) for i in range(n)], 0.0 for _ in range(200): w = diklestir(carp(C, v), B) u = sum(q * q for q in w) ** 0.5 if u < 1e-9: break v, lam = [q / u for q in w], u if lam < 1e-9: break B.append(v) pay.append(lam) return B, pay def geri_kur(z, B): c = [sum(z[j] * b[j] for j in range(n)) for b in B] return [sum(c[i] * B[i][j] for i in range(len(B))) for j in range(n)] def hata(Z, B): return sum(sum((z[j] - geri_kur(z, B)[j]) ** 2 for j in range(n)) ** 0.5 for z in Z) / len(Z) def rastgele_yonler(k, tohum): r, B = uretec(tohum), [] while len(B) < k: v = diklestir([r() + r() + r() - 1.5 for _ in range(n)], B) u = sum(q * q for q in v) ** 0.5 if u > 1e-6: B.append([q / u for q in v]) return B ZE = [[(x[a] - ORT[a]) / SAC[a] for a in ALAN] for x in EGT] ZS = [[(x[a] - ORT[a]) / SAC[a] for a in ALAN] for x in SIN] BILESEN, PAY = yonleri_bul(ZE) TOP, TABAN = sum(PAY), hata(ZS, []) print(f"sutun {n}, bulunan yon {len(BILESEN)}, taban cizgisi {TABAN:.4f}") print(f"{'k':>3} {'pay':>7} {'egitim':>8} {'ayrilmis':>9} {'rastgele':>9} {'fark':>8}") for k in (1, 2, 3, 4, 6, 8, 10, 11): B, s = BILESEN[:k], 0.0 for t in range(3): s += hata(ZS, rastgele_yonler(k, TOHUM + 900 * (t + 1))) print(f"{k:>3} {sum(PAY[:k]) / TOP:>7.3f} {hata(ZE, B):>8.4f} {hata(ZS, B):>9.4f} " f"{s / 3:>9.4f} {hata(ZS, B) - TABAN:>+8.4f}")
sutun 12, bulunan yon 11, taban cizgisi 3.3411 k pay egitim ayrilmis rastgele fark 1 0.190 3.0359 3.0295 3.1971 -0.3116 2 0.341 2.7663 2.7762 3.0531 -0.5650 3 0.458 2.5071 2.5419 2.8281 -0.7993 4 0.571 2.1700 2.2211 2.6875 -1.1200 6 0.771 1.5551 1.5474 2.2723 -1.7937 8 0.935 0.7878 0.8316 1.8246 -2.5096 10 0.989 0.2625 0.2668 1.1637 -3.0743 11 1.000 0.0000 0.0000 0.8436 -3.3411
Üç sayı tablodadır. Taban çizgisi 3,3411: hiçbir bileşen kullanılmadığında bir nokta ortalama noktadan bu kadar uzaktır. İki bileşenle geri kurma 2,7762 verir; fark 0,5650, yani tabanın 0,169’u. Aynı k’da üç rastgele dik yönün ortalaması 3,0531’dir — bileşenlerin rastgele yönlerden farkı 0,2769. Düşüşün geri kalanı, yani 0,2880, yalnız iki yön kullanılmasından gelir; hangi iki yön olduğu bilinmese bile taban o kadar aşağı iner. Bileşenlerin katkısı ancak bu payın üstünde kalan kısımdır ve tabanla arasındaki farkın yarısına yakınıdır.
Tablonun ikinci okuması, pay sütunuyla hata sütununun aynı hızda gitmemesidir. İki bileşende pay 0,341 — kulağa üçte birden fazla gibi gelir — ama hata yalnız 0,169 düşmüştür. Pay kareli büyüklükler üzerinden, geri kurma hatası ise uzaklık üzerinden okunur; payın yarısı uzaklığın yarısı değildir. Bu iki sütunun birbirinin yerine okunması boyut azaltmada en sık yapılan yanlıştır.
Üçüncü okuma son satırdadır. On iki sütun var ama yordam yalnız on bir yön bulabildi ve on birinci yönde hata tam olarak sıfıra indi. Beş bölge göstergesinin toplamı her satırda bire eşit olduğu için biri diğerlerinden okunabiliyor; on ikinci yön diye bir şey yok. Tablo on iki sayı tutuyor, ama on bir sayıdan fazlasını taşımıyor.
Uzaklıkların Ne Kadarı Ayakta Kalıyor
Geri kurma hatası noktanın yerini ölçer. Kümeleme ise noktanın yerini değil, noktalar arasındaki uzaklığı kullanır. İzdüşüm bu ikisini aynı ölçüde korumak zorunda değildir, çünkü bir izdüşüm uzaklıkları yalnız kısaltabilir — hiçbir zaman uzatamaz.
def uzaklik_korunumu(Z, B): P = [[sum(z[j] * b[j] for j in range(n)) for b in B] for z in Z] toplam, sayi, korunan = 0.0, 0, 0 for a in range(len(Z)): for b in range(a + 1, len(Z)): d = sum((Z[a][j] - Z[b][j]) ** 2 for j in range(n)) ** 0.5 if d < 1e-9: continue dk = sum((P[a][i] - P[b][i]) ** 2 for i in range(len(B))) ** 0.5 toplam, sayi = toplam + dk / d, sayi + 1 korunan += dk / d >= 0.9 return toplam / sayi, korunan / sayi, sayi print(f"{'k':>3} {'pay':>7} {'ort oran':>9} {'korunan':>9} {'rastgele oran':>14}") for k in (1, 2, 4, 6, 8, 10): o, g, c = uzaklik_korunumu(ZS, BILESEN[:k]) r = uzaklik_korunumu(ZS, rastgele_yonler(k, TOHUM + 900))[0] print(f"{k:>3} {sum(PAY[:k]) / TOP:>7.3f} {o:>9.4f} {g:>9.4f} {r:>14.4f}") print(f"olculen cift sayisi {c}")
k pay ort oran korunan rastgele oran 1 0.190 0.3398 0.0004 0.2341 2 0.341 0.4965 0.0057 0.3747 4 0.571 0.7029 0.0542 0.5358 6 0.771 0.8535 0.4299 0.6945 8 0.935 0.9540 0.8910 0.7924 10 0.989 0.9943 0.9994 0.9049 olculen cift sayisi 31626
İkinci tablo birincisinden serttir. İki bileşende ikili uzaklıklar ortalama olarak özgününün 0,4965 katına iner — uzaklıkların yarısı kaybolmuştur — ve 31.626 çiftin yalnız 0,0057’si yüzde on yanılma payı içinde ayakta kalır. Altı bileşende ortalama oran 0,8535’e çıkar ve çiftlerin 0,4299’u korunur. Uzaklıkların çoğunun ayakta kaldığı ilk satır sekiz bileşendir: 0,9540 ve 0,8910.
Buradan çıkan karar açıktır. İki bileşenli bir izdüşüm üzerinde kümeleme yapmak, uzaklıkların yarısını attıktan sonra uzaklığa dayalı bir yordam çalıştırmaktır. Rastgele yönlerin aynı k’da 0,3747 vermesi bileşenlerin bir şey kazandırdığını gösterir, ama kazanç 0,4965 ile 0,3747 arasındadır ve iki sayı da tam korunmadan uzaktır. Bileşen payı bu satırların hiçbirini haber vermez: pay 0,341 iken korunan çift oranı 0,0057’dir ve iki sayı aynı büyüklük sırasında bile değildir.
Ölçekleme Kararı İzdüşümü Değiştirir
Bileşenler en çok değişkenliği taşıyan yönleri arar. Değişkenlik sütunun biriminden okunduğu için, sütunlar farklı birimlerdeyse en büyük birimli sütun en büyük yönü kendine çeker. Bu bir kusur değil, yordamın tanımıdır — ama ölçekleme kararının izdüşümü nereye çevirdiği ölçülmeden verilirse bir karar değil bir kazadır.
for olcekli in (True, False): bol = (lambda a: SAC[a]) if olcekli else (lambda a: 1.0) HE = [[(x[a] - ORT[a]) / bol(a) for a in ALAN] for x in EGT] HS = [[(x[a] - ORT[a]) / bol(a) for a in ALAN] for x in SIN] B, P = yonleri_bul(HE) y = sorted((-abs(B[0][j]), ALAN[j], B[0][j]) for j in range(n)) print(f"{'olcekli' if olcekli else 'ham':<8} ilk iki pay " f"{(P[0] + P[1]) / sum(P):.3f} c0 yukleri: " + ", ".join(f"{a} {w:+.2f}" for _, a, w in y[:4])) kalan, toplam = [0.0] * n, 0.0 for z in HS: g = geri_kur(z, B[:2]) d = [(z[j] - g[j]) / (1.0 if olcekli else SAC[ALAN[j]]) for j in range(n)] toplam += sum(q * q for q in d) ** 0.5 for j in range(n): kalan[j] += d[j] * d[j] / len(HS) print(f"{'':8} k=2 ortak birimde hata {toplam / len(HS):.4f} sutun kalanlari: " + ", ".join(f"{ALAN[j]} {kalan[j]:.2f}" for j in (0, 1, 4, 11)))
olcekli ilk iki pay 0.341 c0 yukleri: kisi_basi +0.55, ort_tuketim +0.54, b_bati -0.34, hane -0.31
k=2 ortak birimde hata 2.7762 sutun kalanlari: ort_tuketim 0.36, oynaklik 0.19, memnuniyet 1.00, b_merkez 1.07
ham ilk iki pay 0.863 c0 yukleri: oynaklik +0.96, ort_tuketim +0.24, kisi_basi +0.12, donem +0.04
k=2 ortak birimde hata 2.8473 sutun kalanlari: ort_tuketim 0.10, oynaklik 0.00, memnuniyet 1.00, b_merkez 1.21
İki satır aynı veriyi iki ayrı yere götürüyor. Ölçeklenmemiş kümede birinci bileşen neredeyse
tümüyle tek bir sütundur: oynaklik yükü +0,96 ve geri kalan on bir sütunun hiçbiri o bileşende
0,25’i geçmiyor. İlk iki bileşenin payı 0,863’e çıkıyor. Ölçeklenmiş kümede aynı bileşen
kisi_basi +0,55 ve ort_tuketim +0,54 taşıyor, oynaklik ilk dörde bile girmiyor ve ilk iki
bileşenin payı 0,341’de kalıyor.
Yalnız pay sütununa bakan biri ölçeklenmemiş izdüşümü seçerdi: 0,863, 0,341’in iki buçuk katı.
Ortak birimde ölçülen geri kurma hatası bunun tersini söylüyor — ölçeklenmemişte 2,8473,
ölçeklenmişte 2,7762. Ölçeklenmemiş izdüşüm payın 0,863’ünü topluyor çünkü tek bir sütunun ham
birimi bütün payı yutuyor; o sütunu kusursuz geri kuruyor (oynaklik kalanı 0,00) ve karşılığında
memnuniyet sütununu 1,00 kalanla, yani tabandan hiç iyi olmayan bir yerde bırakıyor. b_merkez
sütununda kalan 1,21 — izdüşüm o sütunu sütun ortalamasından daha kötü kuruyor, çünkü seçtiği
yön o sütunu yanlış yöne itiyor.
Ölçeklenmiş izdüşüm de kusursuz değildir: memnuniyet orada da 1,00 kalanla duruyor ve
b_merkez 1,07. Fark, kaybın nereye dağıtıldığındadır. Ölçekleme kararı hangi sütunun
kurtarılacağını seçmektir ve bu seçim, bileşenler hesaplanmadan çok önce, ölçekleme adımında
verilmiştir.
Özet
- Geri kurma hatasının tabanı sütun ortalamalarıyla geri kurmadır ve 3,3411’dir; iki bileşenle geri kurma 2,7762 verir, fark tabanın 0,169’u kadardır.
- İkinci taban rastgele dik yönlerdir: aynı k’da 3,0531. Bileşenlerin katkısı 0,2769’dur, düşüşün kalan 0,2880’i yalnız iki yön kullanılmasından gelir.
- Bileşen payı ile geri kurma hatası aynı hızda gitmez: pay 0,341 iken hata yalnız 0,169 düşer, çünkü pay kareli büyüklükler, hata ise uzaklık üzerinden okunur.
- Korunan geometri paydan daha azdır: iki bileşende ikili uzaklıklar özgününün 0,4965 katına iner ve 31.626 çiftin yalnız 0,0057’si yüzde on yanılma payıyla ayakta kalır.
- Ölçekleme izdüşümü değiştirir: ölçeklenmemiş kümede ilk iki bileşenin payı 0,863’e çıkar ama ortak birimde hata 2,8473 ile ölçeklenmişin gerisinde kalır ve bazı sütunlar tabandan kötü geri kurulur.
Sonraki Adım
Bu derste bileşenler eşdeğişim dizeyi üzerinden yineleyerek bulundu ve her nokta bulunan yönlere izdüşürülüp geri kuruldu. Yordam işledi, ama bir soruyu hiç sormadı: geri kurulan tabloyu saklamak için kaç sayı gerekiyor. On iki sütunlu 252 satırlık bir tablo 3.024 sayıdır; iki bileşenli gösterim aynı tabloyu kaç sayıyla tutar, ve o adet düştükçe hata hangi eğriyle artar. Sonraki ders izdüşümü bir dizey ayrışımı olarak yazar, rank kavramını ölçünün içine sokar ve saklanan sayı adedi ile geri kurma hatası arasındaki takası aynı taban çizgisiyle birlikte basar.
İlerlemeni kaydetmek ve not almak için Giriş yap
Notlarım
Not almak için giriş yapmalısın.