Ders 05 / 18
Zaman Serisi Görselleştirme
Aynı 36 dönemlik dizi aynı yükseklikte iki eksen ölçeğiyle kodlanıyor: sıfırdan başlayan eksende okuma çözünürlüğü 2,273 m³ ve nokta başına ortalama geri okuma hatası 0,540 m³, kırpılmış eksende 0,909 m³ ve 0,246 m³. Eğim 0,05 m³/dönem duyarlıkla sıfırdan başlayan eksende ancak 24 dönemlik, kırpılmış eksende 14 dönemlik pencereden itibaren geri okunuyor. Mevsimsel bileşenin kendi eğimi vardır ve pencere başlangıcına göre işaret değiştirir: aynı 24 dönemlik uzunluk üç ayrı yerde -0,2239, -0,0487 ve -0,2260 m³/dönem veriyor, kurguya konan eğilim ise -0,140.
İçindekiler
Önceki dört ders bir sayıyı dört kanalla kodladı ve her kanalın geri okuttuğu değeri ölçtü. Dördünde de ortak bir varsayım vardı: gösterilen şey tek bir anlık görüntüydü. Eksenin kendisi bir zaman olduğunda kanalın taşıdığı şey değişir; okuyucu artık bir değeri değil değerin değişimini geri okur ve okuduğu şey uzunluk değil eğimdir.
Bu dersin ölçüsü eğimin geri okunmasıdır ve iki soru sorulur. Aynı dizi aynı yükseklikte iki farklı eksen aralığıyla kodlandığında geri okunan eğim ne oluyor, ve mevsimsel bileşen ayrılmadan eğilim geri okunabiliyor mu. Yeniden örnekleme kararı Python ile Veri Analizi kursunun veri çerçeveleri konusunda ölçüldü ve tekrarlanmaz; burada dizi verili kabul edilir, yalnız gösterimi ölçülür.
- GT26. Zaman ekseninde okunan şey eğimdir. İki nokta arasındaki konum farkı bölü dönem farkı eğimi verir; uzunluk kanalının okuttuğu oran burada okunmaz.
- GT27. Okuma çözünürlüğü bir satırdır. Gösterimin dikey uzamı sonlu sayıda ayrılabilir konuma bölünür ve bir satırdan ince konum ayırt edilemez. Çözünürlük eksen aralığının satır sayısına bölümüdür ve her koşumda sayı olarak basılır.
- GT28. Eğimin geri okuma hatası pencere uzunluğuyla küçülür. İki uçtan okunan eğimin hatası en çok çözünürlük bölü pencere uzunluğudur; kısa pencerede çözünürlük eğimi yutar.
- GT29. Mevsimsel bileşenin kendi eğimi vardır. Bileşen bütün dizide sıfır ortalamalıdır, ama sonlu bir pencerede en küçük kareler eğimi sıfır değildir ve pencerenin nereden başladığına göre işaret değiştirir. Okuyucu tek bir eğim okur ve o eğim iki bileşenin toplamıdır.
- GT30. Dizi kurgudur. Ağın ölçülen üç dönemi 36 döneme uzatılamaz; dizi kuzey bölgesinin ortalaması taban alınarak aynı tohumla türetildi ve içine konan eğilim ile mevsim genliği koda yazılıdır.
Eksen Bir Zaman Olduğunda
# zaman.py — MODELDIR: K03-K05'in kurgu olcum agi ayni tohumla yeniden uretilir # (3.199 satir, 1.329 abone, bes bolge). 36 donemlik dizi de KURGUDUR: agin # olculen uc donemi 36'ya uzatilamaz, dizi kuzey ortalamasi taban alinarak # ayni tohumla turetildi. Icine konan egilim ve mevsim genligi sabittir. 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() kuzey = [o["tuketim_m3"] for o in OKUMA if o["bolge"] == "kuzey"] BASLANGIC = sum(kuzey) / len(kuzey) N, EGILIM, GENLIK, MEVSIM = 36, -0.140, 2.20, 12 _g = uretec(TOHUM + 505) MEVSIMSEL = [GENLIK * math.sin(2 * math.pi * t / MEVSIM) for t in range(N)] SERI = [round(BASLANGIC + EGILIM * t + MEVSIMSEL[t] + (_g() + _g() + _g() - 1.5) * 0.60, 3) for t in range(N)] def egim(v): """En kucuk kareler egimi, birim: m3 / donem.""" n = len(v) ot, ov = (n - 1) / 2, sum(v) / n return (sum((i - ot) * (x - ov) for i, x in enumerate(v)) / sum((i - ot) ** 2 for i in range(n))) def kodla(v, alt, ust, satir): """Kodlayici: deger -> konum. Izgarada tam satir numarasi verir.""" return max(0, min(satir - 1, round((v - alt) / (ust - alt) * (satir - 1)))) def coz(k, alt, ust, satir): """Cozucu: konum -> deger. Okuyucu satirin kendi degerini okur.""" return alt + k / (satir - 1) * (ust - alt) def ciz(v, alt, ust, satir): yer = [kodla(x, alt, ust, satir) for x in v] for s in range(satir - 1, -1, -1): print(f"{coz(s, alt, ust, satir):5.1f} |" + "".join("*" if k == s else " " for k in yer)) print(" +" + "-" * len(v)) return yer print(f"kuzey bolgesi {len(kuzey)} okuma, ortalamasi {BASLANGIC:.3f} m3") print(f"kurgu dizi: {N} donem, icine konan egilim {EGILIM:+.3f} m3/donem, " f"mevsim uzunlugu {MEVSIM} donem, genlik {GENLIK:.2f} m3") print(f"dizinin en kucuk degeri {min(SERI):.2f}, en buyugu {max(SERI):.2f} m3") print(f"dizinin kendi egimi {egim(SERI):+.4f} m3/donem")
kuzey bolgesi 921 okuma, ortalamasi 20.210 m3 kurgu dizi: 36 donem, icine konan egilim -0.140 m3/donem, mevsim uzunlugu 12 donem, genlik 2.20 m3 dizinin en kucuk degeri 13.00, en buyugu 22.02 m3 dizinin kendi egimi -0.1797 m3/donem
Son iki satır dersin gerilimini taşıyor. Kurgunun içine konan eğilim dönem başına -0,140 m³’tür ve koda yazılıdır; dizinin kendi eğimi -0,1797 çıkıyor. Aradaki 0,0397’lik fark gürültüden değil, mevsimsel bileşenin kendi eğiminden gelir ve üçüncü bölümde ayrıca basılır. Bu fark henüz hiçbir gösterim kurulmadan, yalnız sayı düzeyinde ortaya çıkıyor.
Aynı Dizi, İki Eksen Ölçeği
# eksen.py — ayni dizi ayni yukseklikte iki eksen olcegiyle kodlanir. Okuma # cozunurlugu bir satirdir: okuyucu izgarada satirdan ince bir konum ayiramaz. SATIR, DUYARLIK = 12, 0.05 KAYNAK = egim(SERI) sonuc = {} for ad, alt, ust in (("sifirdan", 0.0, 25.0), ("kirpilmis", 13.0, 23.0)): c = (ust - alt) / (SATIR - 1) print(f"eksen {ad}: {alt:.0f}-{ust:.0f} m3, {SATIR} satir, " f"okuma cozunurlugu {c:.3f} m3/satir") yer = ciz(SERI, alt, ust, SATIR) geri = [coz(k, alt, ust, SATIR) for k in yer] hata = sum(abs(geri[i] - SERI[i]) for i in range(N)) / N print(f"{N} noktanin ortalama geri okuma hatasi {hata:.3f} m3; " f"dizi {SATIR} satirin {len(set(yer))} tanesini kullaniyor") sonuc[ad] = geri print("") print(f"egim penceresi sifirdan kirpilmis (pencere sayisi) " f"duyarlik {DUYARLIK:.2f} m3/donem") for w in (4, 6, 9, 12, 15, 18, 24): say = [] for ad in ("sifirdan", "kirpilmis"): g = sonuc[ad] say.append(sum(1 for i in range(N - w + 1) if abs(egim(g[i:i + w]) - egim(SERI[i:i + w])) <= DUYARLIK)) print(f"{w:14d} {say[0]:9d} {say[1]:10d} {N - w + 1:18d}") for ad in ("sifirdan", "kirpilmis"): g = sonuc[ad] en = next(w for w in range(2, N + 1) if all(abs(egim(g[i:i + w]) - egim(SERI[i:i + w])) <= DUYARLIK for i in range(N - w + 1))) print(f"{ad} eksende egim {DUYARLIK:.2f} duyarlikla ancak {en} donemlik " f"pencereden itibaren her yerde geri okunuyor")
eksen sifirdan: 0-25 m3, 12 satir, okuma cozunurlugu 2.273 m3/satir
25.0 |
22.7 | ** *
20.5 |* * * ***
18.2 | ** *** ** ******
15.9 | *** ***** **
13.6 | ****
11.4 |
9.1 |
6.8 |
4.5 |
2.3 |
0.0 |
+------------------------------------
36 noktanin ortalama geri okuma hatasi 0.540 m3; dizi 12 satirin 5 tanesini kullaniyor
eksen kirpilmis: 13-23 m3, 12 satir, okuma cozunurlugu 0.909 m3/satir
23.0 |
22.1 | *
21.2 | * ** *
20.3 |* * * *
19.4 | * * * *
18.5 | * * *
17.5 | * * * **
16.6 | *** * *
15.7 | * ** **
14.8 | *
13.9 | * **
13.0 | *
+------------------------------------
36 noktanin ortalama geri okuma hatasi 0.246 m3; dizi 12 satirin 11 tanesini kullaniyor
egim penceresi sifirdan kirpilmis (pencere sayisi) duyarlik 0.05 m3/donem
4 4 13 33
6 3 19 31
9 13 21 28
12 13 22 25
15 15 20 22
18 14 19 19
24 13 13 13
sifirdan eksende egim 0.05 duyarlikla ancak 24 donemlik pencereden itibaren her yerde geri okunuyor
kirpilmis eksende egim 0.05 duyarlikla ancak 14 donemlik pencereden itibaren her yerde geri okunuyor
İki gösterim aynı 36 sayıyı aynı 12 satırlık yüksekliğe kodluyor; tek fark eksen aralığıdır. Sıfırdan başlayan eksende dizi 12 satırın yalnız 5 tanesini kullanıyor, kırpılmış eksende 11 satıra yayılıyor. Nokta başına ortalama geri okuma hatası bunun sayısal karşılığıdır: 0,540 m³’e karşı 0,246 m³. Hiçbir sayı değişmedi, yalnız aynı sayılar daha ince bir ızgaraya oturdu.
İkinci tablo asıl ölçüdür. Rapora yazılacak eğimin 0,05 m³/dönem duyarlıkla doğru olması isteniyor; bu eşik üç yıllık toplam değişimin onda birine denk geldiği için seçildi. Dört dönemlik pencerede sıfırdan başlayan eksen 33 pencerenin yalnız 4’ünde duyarlığı tutturuyor, kırpılmış eksen 13’ünde; altı dönemlikte fark en keskin yerine geliyor, 3’e karşı 19. Eşiği her pencerede tutturmak için gereken uzunluk sıfırdan başlayan eksende 24 dönem, kırpılmış eksende 14 dönemdir.
Elektronik Tablolarla Analiz kursunun temel grafikler dersi eksen kırpmayı uzunluk kanalı üzerinde ölçmüş ve kırpmanın çubuk oranını veriye ait olmaktan çıkardığını sayıyla göstermişti. Burada aynı işlem ters yönde çalışıyor: uzunluk kanalında okunan şey tabana göre bir orandır ve taban kayınca oran bozulur, konum kanalında okunan şey iki konum arasındaki farktır ve fark tabandan bağımsızdır. Aynı kararın iki kanalda zıt işaret alması, belirleyici olanın karar değil kanal olduğunu gösterir.
Mevsimin Kendi Eğimi
# mevsim.py — mevsimsel bilesenin kendi egimi vardir ve pencerenin nereden # basladigina gore isaret degistirir. adim = [SERI[i + 1] - SERI[i] for i in range(N - 1)] print(f"{len(adim)} komsu adimin {sum(1 for a in adim if a > 0)} tanesinin " f"isareti egilimle ters") print("pencere dizinin egimi mevsimin egimi egilim payi") for bas in (0, 6, 12): p = slice(bas, bas + 24) print(f"{bas:2d}-{bas + 24:<2d} donem {egim(SERI[p]):+14.4f} " f"{egim(MEVSIMSEL[p]):+15.4f} {EGILIM:+12.3f}") def duzlestir(v, p): """Ortalanmis hareketli ortalama; cift uzunlukta uc degerler yarim sayilir.""" y = p // 2 return [(sum(v[i - y + 1:i + y]) + (v[i - y] + v[i + y]) / 2) / p for i in range(y, len(v) - y)] duz = duzlestir(SERI, MEVSIM) dadim = [duz[i + 1] - duz[i] for i in range(len(duz) - 1)] print(f"mevsim ayrildiktan sonra {len(duz)} donem kaliyor; {len(dadim)} adimin " f"{sum(1 for a in dadim if a > 0)} tanesi ters") print(f"duzlestirilmis dizinin egimi {egim(duz):+.4f}, ayni pencerenin ham " f"egimi {egim(SERI[6:30]):+.4f}, kurguya konan egilim {EGILIM:+.3f}")
35 komsu adimin 17 tanesinin isareti egilimle ters pencere dizinin egimi mevsimin egimi egilim payi 0-24 donem -0.2239 -0.0857 -0.140 6-30 donem -0.0487 +0.0857 -0.140 12-36 donem -0.2260 -0.0857 -0.140 mevsim ayrildiktan sonra 24 donem kaliyor; 23 adimin 0 tanesi ters duzlestirilmis dizinin egimi -0.1347, ayni pencerenin ham egimi -0.0487, kurguya konan egilim -0.140
Birinci satır gösterimin en yanıltıcı yanını veriyor: 35 komşu adımın 17’si eğilimin tersi yönde. İki komşu döneme bakıp yön okuyan bir okuyucu yazı tura atmış olur.
Orta tablo nedeni ayırıyor. Üç pencere de 24 dönem uzunluğunda ve üçünde de aynı eğilim var, ama dizinin eğimi -0,2239, -0,0487 ve -0,2260 çıkıyor. Üçüncü sütun farkın kaynağını söylüyor: mevsimsel bileşenin kendi en küçük kareler eğimi 0. dönemden başlayan pencerede -0,0857, 6. dönemden başlayanda +0,0857’dir. Bileşen bütün dizide sıfır ortalamalıdır, sonlu bir pencerede eğime katkı yapar ve katkının işareti pencerenin mevsim içindeki başlangıcına bağlıdır.
Bu, gösterimin değil dizinin özelliğidir ve hiçbir eksen ayarı düzeltemez; ayırma işlemi gösterimden önce yapılmalıdır. Son iki satır ayırmanın sonucudur: mevsim uzunluğunda ortalanmış hareketli ortalamayla 23 adımın hiçbiri ters işaretli kalmıyor ve geri okunan eğim -0,1347 oluyor. Aynı pencerenin ham eğimi -0,0487’ydi; düzleştirme 0,0913’lük bir sapmayı ortadan kaldırdı. Bedeli 12 dönemdir, dizinin başından ve sonundan altışar dönem düşer.
Çözünürlük ve Mevsim Birlikte Bağlar
# ikisi_birden.py — cozunurluk ve mevsim ayri ayri degil birlikte baglar. print("pencere yalniz eksen yalniz mevsim ikisi birlikte") kirp = sonuc["kirpilmis"] kd = duzlestir(kirp, MEVSIM) sd = duzlestir(SERI, MEVSIM) for w in (4, 6, 9, 12, 18): a = sum(1 for i in range(N - w + 1) if abs(egim(kirp[i:i + w]) - EGILIM) <= DUYARLIK) / (N - w + 1) b = sum(1 for i in range(len(sd) - w + 1) if abs(egim(sd[i:i + w]) - EGILIM) <= DUYARLIK) / (len(sd) - w + 1) c = sum(1 for i in range(len(kd) - w + 1) if abs(egim(kd[i:i + w]) - EGILIM) <= DUYARLIK) / (len(kd) - w + 1) print(f"{w:7d} {a * 100:14.1f}% {b * 100:15.1f}% {c * 100:14.1f}%") print(f"kaynaktaki egilim {EGILIM:+.3f} m3/donem; yukaridaki oranlar " f"pencerenin bu sayiyi {DUYARLIK:.2f} duyarlikla verme sikligidir")
pencere yalniz eksen yalniz mevsim ikisi birlikte
4 3.0% 100.0% 85.7%
6 0.0% 100.0% 89.5%
9 7.1% 100.0% 100.0%
12 4.0% 100.0% 100.0%
18 100.0% 100.0% 100.0%
kaynaktaki egilim -0.140 m3/donem; yukaridaki oranlar pencerenin bu sayiyi 0.05 duyarlikla verme sikligidir
Önceki tablo geri okunan eğimi pencerenin kendi eğimiyle karşılaştırıyordu; bu tablo doğrudan kurguya konan eğilimle karşılaştırıyor ve sütunlar üç ayrı düzeltmeye karşılık geliyor.
Birinci sütun tek başına eksen ayarının yetersizliğini gösteriyor: kırpılmış eksen altı dönemlik pencerede eğilimi hiçbir pencerede vermiyor, dokuz dönemlikte 28 pencerenin ikisinde veriyor. Eksen çözünürlüğü noktaların yerini düzeltir, mevsimin eğime kattığı payı düzeltmez. İkinci sütun tersini gösteriyor: mevsim ayrıldığında dört dönemlik pencere bile duyarlığı tutturuyor. Üçüncü sütun ikisinin birlikte bedelini yazıyor — kırpılmış eksende kodlanmış ve sonra düzleştirilmiş dizi yüzde 85,7 ile başlıyor ve dokuz dönemden itibaren yüzde 100 veriyor. Kalan eksik sayısallaştırmadan gelir: her nokta satır ızgarasına yuvarlanmıştır ve kısa pencerede bu yuvarlama düzleştirmeden sonra da eğime yansır.
Karar kuralı buradan çıkar: bir zaman serisi gösterimi eksenin okuma çözünürlüğü ile eğimin okunduğu pencere uzunluğu yanına yazılmadan raporlanamaz. İkisinden biri eksikse okuyucunun gördüğü eğim veride bulunan eğilim değildir.
Özet
- Zaman ekseninde okunan şey uzunluk değil eğimdir; okuma çözünürlüğü bir satırdır ve eksen aralığının satır sayısına bölümüyle yazılır.
- Aynı dizi aynı yükseklikte iki eksen aralığıyla kodlandığında nokta başına ortalama geri okuma hatası 0,540 m³ ile 0,246 m³ oluyor; sıfırdan başlayan eksen 12 satırın 5’ini kullanıyor.
- Eğimin 0,05 m³/dönem duyarlıkla geri okunduğu en kısa pencere sıfırdan başlayan eksende 24, kırpılmış eksende 14 dönemdir.
- Mevsimsel bileşenin kendi eğimi pencere başlangıcına göre -0,0857 ile +0,0857 arasında işaret değiştirir; aynı 24 dönemlik uzunluk üç yerde -0,2239, -0,0487 ve -0,2260 m³/dönem veriyor.
- Mevsim ortalanmış hareketli ortalamayla ayrıldığında 23 adımın hiçbiri ters kalmıyor ve geri okunan eğim -0,1347 oluyor; bedel 12 dönemdir, eksen kırpma bunu tek başına yapamıyor.
Sonraki Adım
Bu 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 iki boyutlu bir alandır. Sonraki ders bölgeleri bir ızgara olarak modeller ve alan boyalı bir gösterimin geri okuttuğu şeyin değer değil alan olduğunu ölçer: büyük bir bölgenin küçük değeri, küçük bir bölgenin büyük değerini bastırır ve hata bölgenin kapladığı hücre sayısıyla orantılı olarak sayılır. Aynı ızgara düzlem üzerine basıldığında esner ve esneme geri okunan sayıyı üçüncü kez oynatır.
İlerlemeni kaydetmek ve not almak için Giriş yap
Notlarım
Not almak için giriş yapmalısın.