Ders 06 / 18
Coğrafi Görselleştirme
Beş bölge 12x12'lik bir kapsama ızgarasında beş renk basamağıyla kodlanıyor ve okuyucunun geri okuduğu şey basamak değil basamağın kapladığı alan oluyor: okuma sayısıyla ağırlıklı doğru ortalama 19,713 m³ iken alanla ağırlıklı geri okuma 18,484 m³ veriyor ve fark -1,228 m³. Batı, okumaların yüzde 14,9'unu ve alanın yüzde 25'ini taşıdığı için 1,680 ağırlık çarpanı alıyor. İzdüşüm esnemesi eşit alanlı iki bölgeyi 1,237 kat farklı bastırıyor. Alan payı okuma payına eşitlendiğinde hata 0,396 m³'e iniyor, bedeli 93 hücrenin bölge değiştirmesi ve komşu bölge çiftinin 8'den 4'e düşmesidir.
İçindekiler
Önceki ders ekseni zamana çevirdi ve kanalın taşıdığı şeyin değişim olduğunu ölçtü. Ölçüm ağının her okuması bir yerde de alınıyor ve o yer tek boyutlu bir eksen değil, iki boyutlu bir alandır. Alan üzerine kurulan bir gösterimde değer bir renk basamağına çevrilir ve okuyucu basamağı geri okur. Ama okuyucunun gözüne giren şey basamak değil, basamağın kapladığı alandır.
Bu dersin ölçüsü budur: alan boyalı bir gösterimden geri okunan sayı ile veride bulunan sayı arasındaki fark, ve bu farkın bölgelerin alanıyla nasıl orantılı olduğu. Renk basamağı kanalının kaç ayrı düzeyi geri okuttuğu ilişki görselleştirme dersinde ölçüldü; burada basamak sayısı beşte sabit tutulur ve değişken alandır. Hiçbir gerçek yer, harita ürünü ya da izdüşüm adı yazılmaz; kapsama alanı bir ızgara olarak modellenir.
- GT31. Kapsama ızgarası kurgudur. Ağın bölgeleri 12x12’lik bir hücre ızgarasına bölünür; her hücre bir kapsama birimidir ve bölünme koda yazılıdır.
- GT32. Alan boyalı gösterimde kanal renk basamağıdır. Kodlayıcı değeri eşit genişlikli beş dilimden birine, çözücü dilimin ortasına eşler; okuma çözünürlüğü dilim genişliğidir ve okuyucu dilim içindeki yeri ayırt edemediği için bu sayı geri okunamayan payı verir.
- GT33. Geri okuma alanla ağırlıklanır. Bir bakışta okunan ortalama, bölge ortalamalarının hücre sayısıyla ağırlıklı ortalamasıdır. Doğru sayı ise okuma sayısıyla ağırlıklı olandır.
- GT34. Ağırlık çarpanı bölgenin alan payının okuma payına bölümüdür. Çarpan birden büyükse bölge hak ettiğinden fazla, küçükse hak ettiğinden az okunur.
- GT35. İzdüşüm esnemesi eşit alanları eşit basmaz. Eğri bir yüzey dikdörtgen bir ızgaraya basıldığında satırlar eşit genişlikte basılmaz; esneme çarpanı modelde satır numarasının işlevidir ve koda yazılıdır.
- GT36. Alan payı düzeltilebilir, komşuluk düzeltilemez. Hücreler okuma payıyla orantılı dağıtıldığında alan ağırlığı ortadan kalkar, ama ızgaranın hangi bölgenin hangisine komşu olduğu bilgisi bozulur ve bozulma çift sayısıyla ölçülür.
Izgara ve Renk Basamağı
# izgara.py — MODELDIR: K03-K05'in kurgu olcum agi ayni tohumla uretilir. # Agin kapsama alani da KURGUDUR: 12x12'lik bir hucre izgarasidir ve her hucre # bir kapsama birimidir. Hicbir gercek yer, harita ya da izdusum anilmaz. import math TOHUM, HAM, M32 = 20260218, 1400, 0xFFFFFFFF DONEM = ["2026-01", "2026-02", "2026-03"] 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 _k, _e = [], [] for i in range(HAM): r = uretec(TOHUM + i) b = BOLGE[ayrik(r(), [x[1] for x in BOLGE])] ayrik(r(), [0.06, 0.24, 0.30, 0.24, 0.11, 0.05]) ayrik(r(), [0.08, 0.14, 0.27, 0.34, 0.17]) (_e if r() < 0.046 else _k).append( {"abone_no": 10001 + i, "bolge": b[0], "taban": b[2]}) GECERLI = {a["abone_no"] for a in _k} OKUMA = [] for a in _k + _e: r = uretec(TOHUM + 7000 + a["abone_no"]) for d in range(ayrik(r(), [0.05, 0.12, 0.21, 0.62])): t = 0.0 if r() < 0.038 else math.floor( a["taban"] * math.exp((r() + r() + r() - 1.5) * 0.62) * (1 - d * 0.05) * 100 + 0.5) / 100 if a["abone_no"] not in GECERLI: r() continue OKUMA.append({"abone_no": a["abone_no"], "bolge": a["bolge"], "donem": DONEM[d], "tuketim_m3": t}) r() AD = [b[0] for b in BOLGE] SAYIM = {a: sum(1 for o in OKUMA if o["bolge"] == a) for a in AD} DEGER = {a: sum(o["tuketim_m3"] for o in OKUMA if o["bolge"] == a) / SAYIM[a] for a in AD} # Kapsama izgarasi: 12x12, her hucre bir bolgeye ait. Kurgu bir bolunmedir. BOY, BASAMAK = 12, 5 def hucre_bolge(i, j): if i < 3: return "kuzey" if j < 4: return "bati" if i >= 8: return "guney" if j >= 9: return "dogu" return "merkez" IZGARA = [[hucre_bolge(i, j) for j in range(BOY)] for i in range(BOY)] ALAN = {a: sum(r.count(a) for r in IZGARA) for a in AD} ENAZ, ENCOK = min(DEGER.values()), max(DEGER.values()) ADIM = (ENCOK - ENAZ) / BASAMAK def kodla(v): """Kodlayici: deger -> renk basamagi. Esit genislikli BASAMAK dilim.""" return min(BASAMAK - 1, int((v - ENAZ) / ADIM)) def coz(b): """Cozucu: renk basamagi -> deger. Okuyucu dilimin ortasini okur.""" return ENAZ + (b + 0.5) * ADIM print(f"izgara {BOY}x{BOY} = {BOY * BOY} hucre, {BASAMAK} renk basamagi, " f"okuma cozunurlugu {ADIM:.3f} m3/basamak") print("bolge alan(hucre) okuma ortalama basamak geri okunan hata") for a in AD: b = kodla(DEGER[a]) print(f"{a:7s} {ALAN[a]:11d} {SAYIM[a]:6d} {DEGER[a]:9.3f} {b:8d} " f"{coz(b):12.3f} {coz(b) - DEGER[a]:+6.3f}") for i in range(BOY): print(" " + "".join(str(kodla(DEGER[IZGARA[i][j]])) for j in range(BOY)))
izgara 12x12 = 144 hucre, 5 renk basamagi, okuma cozunurlugu 2.179 m3/basamak
bolge alan(hucre) okuma ortalama basamak geri okunan hata
kuzey 36 921 20.210 2 19.226 -0.985
guney 32 645 16.602 1 17.046 +0.445
dogu 15 557 24.674 4 23.584 -1.090
bati 36 476 13.778 0 14.867 +1.090
merkez 25 600 22.396 3 21.405 -0.991
222222222222
222222222222
222222222222
000033333444
000033333444
000033333444
000033333444
000033333444
000011111111
000011111111
000011111111
000011111111
Basamak sütunu kanalın tamamıdır: beş bölge beş ayrı basamağa düştü ve her biri ayırt edilebilir. Bölge başına geri okuma hatası -1,090 ile +1,090 m³ arasında, yani en çok dilim genişliğinin yarısı kadar. Bu, renk basamağı kanalının bilinen ve sınırlı bedelidir.
Alttaki ızgara asıl sorunu gösteriyor. Doğunun basamağı 4’tür, ızgaranın en yüksek değeri, ama sayfada yalnız 15 hücre kaplıyor. Batının basamağı 0’dır ve 36 hücre kaplıyor. Aynı ızgaraya bakan biri “bu ağ düşük tüketiyor” izlenimi alır; sayfada en çok yer kaplayan basamak en düşük olandır. Bölge başına hata bunu hiçbir biçimde bildirmez, çünkü hata bölge bölge ölçülür ve okuyucu bölge bölge bakmaz.
Alan Ağırlığı
# agirlik.py — okuyucunun bir bakista geri okudugu sey basamak degil, basamagin # kapladigi alandir. Iki ortalama yan yana konur. TOPLAM = sum(SAYIM.values()) dogru = sum(DEGER[a] * SAYIM[a] for a in AD) / TOPLAM bakis = sum(coz(kodla(DEGER[a])) * ALAN[a] for a in AD) / (BOY * BOY) duz = sum(coz(kodla(DEGER[a])) for a in AD) / len(AD) print(f"okuma sayisiyla agirlikli ortalama {dogru:.3f} m3 ({TOPLAM} okuma)") print(f"bolge basina duz ortalama {duz:.3f} m3 ({len(AD)} bolge)") print(f"alanla agirlikli geri okuma {bakis:.3f} m3 ({BOY * BOY} hucre)") print(f"alan agirliginin actigi fark {bakis - dogru:+.3f} m3") print("bolge okuma payi alan payi agirlik carpani") for a in AD: op, ap = SAYIM[a] / TOPLAM, ALAN[a] / (BOY * BOY) print(f"{a:7s} {op * 100:9.1f}% {ap * 100:9.1f}% {ap / op:16.3f}")
okuma sayisiyla agirlikli ortalama 19.713 m3 (3199 okuma) bolge basina duz ortalama 19.226 m3 (5 bolge) alanla agirlikli geri okuma 18.484 m3 (144 hucre) alan agirliginin actigi fark -1.228 m3 bolge okuma payi alan payi agirlik carpani kuzey 28.8% 25.0% 0.868 guney 20.2% 22.2% 1.102 dogu 17.4% 10.4% 0.598 bati 14.9% 25.0% 1.680 merkez 18.8% 17.4% 0.926
Üç ortalama, aynı veriden ve hiçbiri hatalı hesaplanmadan. 3.199 okumanın ortalaması 19,713 m³; bölge başına düz ortalama 19,226; alan boyalı gösterimden okunan 18,484. Alan ağırlığının açtığı fark -1,228 m³’tür ve tek bir okuma değişmedi.
Alt tablo farkın nereden geldiğini bölge bölge yazıyor. Batı, okumaların yüzde 14,9’unu taşıyor ama alanın yüzde 25’ini kaplıyor; ağırlık çarpanı 1,680’dir, yani sayfada gerçek payının yaklaşık iki katı kadar konuşuyor. Doğu ise tersine 0,598 çarpanla, payının yarısından biraz fazlası kadar. Batının en düşük, doğunun en yüksek ortalamaya sahip olması bir rastlantıdır, ama iki rastlantı aynı yöne çalışınca geri okunan sayı bir tarafa kayar.
Bu, kanalın seçiminden bağımsız bir kusur değildir; alan kanalının tanımıdır. Renk basamağı alana boyanır ve alan zaten sabittir, veriyle ilgisi yoktur. Gösterim, tasarımcının seçmediği bir ağırlıklandırma uygular ve o ağırlığı hiçbir yere yazmaz.
İzdüşüm Esnemesi
# esneme.py — egri bir yuzey dikdortgen bir izgaraya basildiginda satirlar esit # genislikte basilmaz. Esneme carpani MODELDIR: ust satirlar daha genis basilir. BUKUM, REF = 0.07, BOY - 1 def esneme(i): return 1.0 / math.cos(BUKUM * (REF - i)) BASILAN = {a: sum(esneme(i) for i in range(BOY) for j in range(BOY) if IZGARA[i][j] == a) for a in AD} TOPLAM_ALAN = sum(BASILAN.values()) esnek = sum(coz(kodla(DEGER[a])) * BASILAN[a] for a in AD) / TOPLAM_ALAN print(f"esneme carpani en ust satirda {esneme(0):.3f}, en alt satirda " f"{esneme(BOY - 1):.3f}") print("bolge gercek alan basilan alan buyume") for a in AD: print(f"{a:7s} {ALAN[a]:11d} {BASILAN[a]:13.2f} " f"{BASILAN[a] / ALAN[a] - 1:+7.1%}") print(f"kuzey ile bati esit alanli ({ALAN['kuzey']} hucre) ama basilan alanlari " f"{BASILAN['kuzey'] / BASILAN['bati']:.3f} kat farkli") print(f"esnemeden once alanla agirlikli geri okuma {bakis:.3f} m3, " f"sonra {esnek:.3f} m3") print(f"dogru sayiya uzaklik: {abs(bakis - dogru):.3f} -> " f"{abs(esnek - dogru):.3f} m3")
esneme carpani en ust satirda 1.393, en alt satirda 1.000 bolge gercek alan basilan alan buyume kuzey 36 47.26 +31.3% guney 32 32.28 +0.9% dogu 15 16.54 +10.3% bati 36 38.19 +6.1% merkez 25 27.57 +10.3% kuzey ile bati esit alanli (36 hucre) ama basilan alanlari 1.237 kat farkli esnemeden once alanla agirlikli geri okuma 18.484 m3, sonra 18.579 m3 dogru sayiya uzaklik: 1.228 -> 1.133 m3
Esneme, alan ağırlığının üzerine binen ikinci bir çarpıtmadır ve bu kez tasarımcının kararı bile değildir: eğri bir yüzeyi düz bir ızgaraya basmanın kaçınılmaz bedelidir. Modelde en üst satır en alt satırın 1,393 katı genişlikte basılıyor.
Beşinci satır ölçünün en açık ifadesidir. Kuzey ile batı eşit alanlıdır, ikisi de 36 hücre. Basıldıklarında 47,26 ile 38,19 oluyor, yani aynı büyüklükteki iki bölge 1,237 kat farklı büyüklükte görünüyor. Bir okuyucunun iki bölgenin ağırlığını karşılaştırması için hiçbir dayanağı yok.
Son iki satır dikkatle okunmalı. Esneme bu kurguda toplam hatayı 1,228’den 1,133 m³’e düşürüyor. Bu bir düzeltme değil, bir rastlantıdır: en çok esneyen bölge kuzeydir ve kuzeyin geri okunan değeri doğru sayıya yakın olduğu için ortalamayı yukarı çekmiştir. Esnemenin işareti, bölgelerin ızgarada nerede durduğuna bağlıdır ve tasarımcının denetiminde değildir. Hatayı azaltması da artırması kadar tesadüfidir; ölçülmesi gereken şey toplam değil, bölge başına basılan alan sapmasıdır.
Alan Payını Düzeltmek
# kartogram.py — hucreler okuma payiyla orantili yeniden dagitilir. Alan # agirligi duzelir, izgaranin komsuluk yapisi bozulur. kota = {a: SAYIM[a] * BOY * BOY / TOPLAM for a in AD} pay = {a: int(kota[a]) for a in AD} for a in sorted(AD, key=lambda x: kota[x] - int(kota[x]), reverse=True): if sum(pay.values()) < BOY * BOY: pay[a] += 1 akan = [a for a in AD for _ in range(pay[a])] KART = [akan[i * BOY:(i + 1) * BOY] for i in range(BOY)] YENI = {a: sum(r.count(a) for r in KART) for a in AD} kartbakis = sum(coz(kodla(DEGER[a])) * YENI[a] for a in AD) / (BOY * BOY) tasinan = sum(1 for i in range(BOY) for j in range(BOY) if IZGARA[i][j] != KART[i][j]) def komsuluk(g): c = set() for i in range(BOY): for j in range(BOY): for di, dj in ((0, 1), (1, 0)): x, y = i + di, j + dj if x < BOY and y < BOY and g[i][j] != g[x][y]: c.add(tuple(sorted((g[i][j], g[x][y])))) return c k1, k2 = komsuluk(IZGARA), komsuluk(KART) print("bolge eski alan kartogram alan okuma payi") for a in AD: print(f"{a:7s} {ALAN[a]:9d} {YENI[a]:15d} {SAYIM[a] / TOPLAM * 100:10.1f}%") for i in range(BOY): print(" " + "".join(str(kodla(DEGER[KART[i][j]])) for j in range(BOY))) print(f"alanla agirlikli geri okuma {bakis:.3f} -> {kartbakis:.3f} m3, " f"dogru sayi {dogru:.3f}") print(f"hata {abs(bakis - dogru):.3f} -> {abs(kartbakis - dogru):.3f} m3; " f"{tasinan} hucre bolge degistirdi") print(f"komsu bolge cifti {len(k1)} -> {len(k2)}; kaybolan " f"{len(k1 - k2)}, uydurulan {len(k2 - k1)}")
bolge eski alan kartogram alan okuma payi
kuzey 36 42 28.8%
guney 32 29 20.2%
dogu 15 25 17.4%
bati 36 21 14.9%
merkez 25 27 18.8%
222222222222
222222222222
222222222222
222222111111
111111111111
111111111114
444444444444
444444444444
000000000000
000000000333
333333333333
333333333333
alanla agirlikli geri okuma 18.484 -> 19.317 m3, dogru sayi 19.713
hata 1.228 -> 0.396 m3; 93 hucre bolge degistirdi
komsu bolge cifti 8 -> 4; kaybolan 6, uydurulan 2
Düzeltme basittir: her bölgeye okuma payıyla orantılı sayıda hücre verilir. Doğunun alanı 15’ten 25’e çıkar, batının 36’dan 21’e iner. Geri okuma hatası 1,228’den 0,396 m³’e düşer, yani üçte birine. Kalan 0,396 alan ağırlığından değil, renk basamağının 2,179 m³’lük çözünürlüğünden gelir ve alan düzeltmesiyle kapatılamaz.
Bedel iki sayıyla yazılıdır. Birincisi 144 hücrenin 93’ünün bölge değiştirmesidir; ızgaranın üçte ikisi artık başlangıçtaki yerinde değil. İkincisi daha ağırdır: özgün ızgarada 8 komşu bölge çifti vardı, kartogramda 4 kaldı. Altı komşuluk kayboldu ve iki tane de var olmayan komşuluk uyduruldu. Kartogram doğru sayıyı geri okutur, ama “hangi bölge hangisine bitişik” sorusunun yanıtını bozar; okuyucu ikinci soruyu da bu gösterimden sorabileceğini varsayarsa yeni bir yanlışa düşer.
Karar kuralı buradan çıkar. Alan üzerine kurulan bir gösterim iki sayı olmadan raporlanamaz: bölgenin alan payı ile okuma payının oranı ve renk basamağının çözünürlüğü. Alan payı düzeltilirse komşuluk kaybının kaç çift olduğu da yazılır, çünkü düzeltme başka bir soruyu okunamaz hale getirmiştir.
Özet
- Alan boyalı gösterimde kanal renk basamağıdır; beş basamak 2,179 m³’lük bir okuma çözünürlüğü verir ve bölge başına geri okuma hatası en çok 1,090 m³’tür.
- Okuyucunun bir bakışta geri okuduğu sayı alanla ağırlıklıdır: 3.199 okumanın doğru ortalaması 19,713 m³ iken gösterimden okunan 18,484 m³ çıkıyor, fark -1,228 m³.
- Ağırlık çarpanı alan payının okuma payına bölümüdür; batı 1,680, doğu 0,598 çarpan alıyor ve gösterim bu ağırlığı hiçbir yere yazmıyor.
- İzdüşüm esnemesi eşit alanlı kuzey ile batıyı 1,237 kat farklı bastırıyor; toplam hatayı bu kurguda 0,095 m³ azaltması bir rastlantıdır ve işareti tasarımcının denetiminde değildir.
- Alan payı okuma payına eşitlendiğinde hata 0,396 m³’e iniyor; bedeli 93 hücrenin yer değiştirmesi ve komşu bölge çiftinin 8’den 4’e düşmesidir.
Sonraki Adım
Bu derste ölçülen çarpıtmanın hiçbiri bir tercihten doğmadı: alan ızgarada verilidir, esneme düz bir yüzeye basmanın bedelidir. Yine de geri okunan sayı 1,228 m³ kaydı. Sonraki ders aynı soruyu tersinden sorar ve dört çarpıtmayı bir aile olarak ele alır — eksen kırpma, alan kanalının oranı karesiyle büyütmesi, ikili eksen ve düzensiz aralık aynı veriye sırayla uygulanır ve her birinin geri okuma hatası ayrı ayrı basılır. Dördü de savunulabilir bir varsayılan davranıştan doğar; gösterilecek olan, yanıltmanın kasıt gerektirmediğidir.
İlerlemeni kaydetmek ve not almak için Giriş yap
Notlarım
Not almak için giriş yapmalısın.