İçeriğe geç
academia.sh

Ders 10 / 18

Uyarı Kuralları

Eşik, oran ve anomali temelli üç kural türünün aynı on günün aynı sekiz bilinen olayı üzerinde koşturulması: her türün parametresi taranarak yakalanan, kaçan, yanlış alarm ve fark etme turu sayılır, üç türün birbirini tamamladığı yer kural kümesi birleşimleriyle ölçülür.

İçindekiler

Düzenlenmiş bir pano yalnız bakıldığında işe yarar. Gecenin üçünde kimse bakmıyorsa panelin sıralaması bir şey değiştirmez; birinin çağrılması gerekir. Çağrıyı doğuran kuralın hangi ölçütten yazılacağı — bileşenin iç ölçütünden mi, üyenin gördüğü ölçütten mi — ayrı bir derste ölçüldü ve burada tekrarlanmaz. Buradaki soru kuralın biçimi: aynı ölçüt üzerinde üç ayrı kural türü yazılabilir ve üçü aynı olayları yakalamaz.

Eşik kuralı değeri sabit bir sınırla karşılaştırır. Oran kuralı değerin bir pencere öncesine göre değişim hızına bakar. Anomali kuralı geçmişten öğrenilmiş bir bandın dışına çıkışı arar. Üçü de bölgesel ölçüm ağının (kurgu) on günlük iki ölçüt serisi ve sekiz bilinen olayı üzerinde koşturulur.

On Gün, Sekiz Olay

// uyari/seri.mjs — on gunluk dakikalik iki olcut serisinin ve sekiz bilinen olayin MODELI.
// IG19: istek sayisi gunluk desen tasir (gece dusuk, ogleden sonra zirve); hata orani desensizdir.
// IG20: her iki seride zararsiz kisa sivrilar vardir (bes bin dakikada bir, 2-4 dk).
// IG21: sekiz olay bilinen olaydir; pencereleri ve hedef degerleri asagida yazilidir.
export const TOHUM = 20260804, GUN = 10, DK = GUN * 1440;
export const SAAT_DESEN = [40, 32, 28, 26, 30, 48, 78, 118, 150, 168, 176, 172,
  165, 170, 178, 174, 160, 138, 120, 104, 92, 78, 62, 50];
// [gun, saat, sure dk, ad, [[seri, hedef deger, bicim]]] — bicim: "ani" ya da "tirmanma"
export const OLAY = [
  [2, 11, 20, "ani hata sicramasi", [["hata", 6.0, "ani"]]],
  [3, 9, 300, "yavas hata tirmanmasi", [["hata", 1.4, "tirmanma"]]],
  [4, 3, 90, "gece trafik kaybi", [["istek", 8, "ani"]]],
  [5, 14, 4, "kisa derin kesinti", [["hata", 9.0, "ani"]]],
  [6, 8, 600, "sabit kayma", [["hata", 0.9, "ani"]]],
  [7, 16, 45, "yayin sonrasi artis", [["hata", 2.6, "ani"]]],
  [8, 1, 300, "gece istek tirmanmasi", [["istek", 110, "tirmanma"]]],
  [9, 6, 360, "kademeli trafik dususu", [["istek", 0.45, "tirmanma"]]],
];
export const pencere = (i) => [OLAY[i][0] * 1440 + OLAY[i][1] * 60, OLAY[i][2]];

export function seri() {
  let s = TOHUM;
  const r = () => ((s = (s * 1664525 + 1013904223) >>> 0) / 2 ** 32);
  const S = { istek: new Float64Array(DK), hata: new Float64Array(DK) };
  const sivri = { istek: 0, hata: 0 };
  for (let t = 0; t < DK; t += 1) {
    const saat = Math.floor(t / 60) % 24, taban = SAAT_DESEN[saat];
    S.istek[t] = taban * (0.94 + r() * 0.12);
    S.hata[t] = 0.2 + (r() * 2 - 1) * 0.08;
    for (const ad of ["istek", "hata"]) {
      if (sivri[ad] > 0) { sivri[ad] -= 1; S[ad][t] *= ad === "hata" ? 4.2 : 1.35; }
      else if (r() < 1 / 5000) sivri[ad] = 2 + Math.floor(r() * 3);
    }
    for (let i = 0; i < OLAY.length; i += 1) {
      const [bas, sr] = pencere(i);
      if (t < bas || t >= bas + sr) continue;
      for (const [ad, hedef, bicim] of OLAY[i][4]) {
        const p = bicim === "tirmanma" ? (t - bas + 1) / sr : Math.min(1, (t - bas + 1) / 3);
        const taban2 = ad === "istek" ? SAAT_DESEN[saat] : 0.2;
        const h = ad === "istek" && hedef < 1 ? taban2 * hedef : hedef;
        S[ad][t] = taban2 + (h - taban2) * p;
      }
    }
  }
  return S;
}

if (import.meta.filename === process.argv[1]) {
  const S = seri();
  const ort = (a, b, ad) => { let x = 0; for (let t = a; t < b; t += 1) x += S[ad][t]; return x / (b - a); };
  console.log(`tohum ${TOHUM}, ${GUN} gun, ${DK} dakika, 2 olcut, ${OLAY.length} bilinen olay`);
  console.log(`taban: gece hata ${ort(0, 1440, "hata").toFixed(2)}, istek ` +
    `${ort(180, 300, "istek").toFixed(0)}/dk (03-05), ogleden sonra istek ` +
    `${ort(840, 960, "istek").toFixed(0)}/dk (14-16)\n`);
  console.log(`${"olay".padEnd(24)}${"gun".padStart(4)}${"sure".padStart(7)}` +
    `${"olay ici en uc deger".padStart(21)}`);
  OLAY.forEach(([gun, , sr, ad, hedefler], i) => {
    const [b] = pencere(i), a = hedefler[0][0];
    let uc = S[a][b];
    for (let t = b; t < b + sr; t += 1) uc = a === "hata" || hedefler[0][1] > 100
      ? Math.max(uc, S[a][t]) : Math.min(uc, S[a][t]);
    console.log(`${ad.padEnd(24)}${String(gun).padStart(4)}${`${sr} dk`.padStart(7)}` +
      `${`${a} ${uc.toFixed(a === "hata" ? 2 : 0)}`.padStart(21)}`);
  });
}
tohum 20260804, 10 gun, 14400 dakika, 2 olcut, 8 bilinen olay
taban: gece hata 0.20, istek 28/dk (03-05), ogleden sonra istek 176/dk (14-16)

olay                     gun   sure olay ici en uc deger
ani hata sicramasi         2  20 dk            hata 6.00
yavas hata tirmanmasi      3 300 dk            hata 1.40
gece trafik kaybi          4  90 dk              istek 8
kisa derin kesinti         5   4 dk            hata 9.00
sabit kayma                6 600 dk            hata 0.90
yayin sonrasi artis        7  45 dk            hata 2.60
gece istek tirmanmasi      8 300 dk            istek 110
kademeli trafik dususu     9 360 dk             istek 71

Olay kümesi kasıtlı olarak farklı biçimlerden seçildi: yirmi dakikalık ani sıçrama, beş saate yayılan yavaş tırmanma, dört dakikalık derin kesinti, on saat süren sabit kayma, ve iki tanesi mevsimsel ölçüt üzerinde — gece trafiğin düşmesi ve gece isteğin tırmanması. Sonuncusu, kademeli trafik düşüşü, mutlak değer olarak hiçbir zaman düşük görünmüyor: 176’lık öğleden sonra tabanına göre düşüyor ama sayı 71’in altına inmiyor.

Üç Tarama

Her tür tek bir parametreyle taranır. Seçim kuralı kodda yazılı: on günde en çok on iki yanlış alarm bütçesini aşmayan parametreler arasından en çok olay yakalayan seçilir.

// uyari/kural.mjs — uc kural turu ayni on gunun ayni iki serisi uzerinde kosturulur. IG22: bir
// kural kosulu K tur (dakika) ust uste saglandiginda bir uyari uretir ve kosul dusene kadar
// yeniden uretmez; degerlendirme her dakika bir tur koser. IG23: esik medyanin kati olarak
// yazilir; oran kurali W dakika oncesine gore iki kat artis ya da yariya dususe bakar; anomali
// kurali ayni dakika-of-day icin onceki L gunun bandini kullanir (ortalama arti dort sapma, band
// tabani ortalamanin yuzde 15'i). IG24: on gunde en cok 12 yanlis alarm butcesi vardir ve her tur
// icin bu butceyi asmayan parametreler arasindan en cok olay yakalayan secilir.
import { seri, OLAY, pencere, DK } from "./seri.mjs";
const S = seri(), OLCUT = ["hata", "istek"], K = { esik: 5, oran: 3, anomali: 10 }, BUTCE = 12;
const medyan = Object.fromEntries(OLCUT.map((a) =>
  [a, [...S[a]].sort((x, y) => x - y)[Math.floor(DK / 2)]]));

const kosullar = {
  esik: (k) => (a, t) => (a === "hata" ? S[a][t] > k * medyan[a]
    : S[a][t] > k * medyan[a] || S[a][t] < medyan[a] / k),
  oran: (w) => (a, t) => { if (t < w) return false;
    const o = S[a][t] / Math.max(1e-9, S[a][t - w]); return o > 2 || o < 0.5; },
  anomali: (l) => (a, t) => { const g = Math.min(l, Math.floor(t / 1440));
    if (g < 1) return false;
    const ge = []; for (let j = 1; j <= g; j += 1) ge.push(S[a][t - j * 1440]);
    const m = ge.reduce((x, y) => x + y, 0) / g;
    const sd = Math.sqrt(ge.reduce((x, y) => x + (y - m) ** 2, 0) / g);
    return Math.abs(S[a][t] - m) > 4 * Math.max(sd, 0.15 * m); },
};

function kosr(tur, p) {
  const uyari = [];
  const kosul = kosullar[tur](p);
  for (const a of OLCUT) {
    let ard = 0, etkin = false;
    for (let t = 0; t < DK; t += 1) {
      if (kosul(a, t)) { ard += 1; if (ard >= K[tur] && !etkin) { etkin = true; uyari.push([t - K[tur] + 1, a]); } }
      else { ard = 0; etkin = false; }
    }
  }
  const ici = (t) => OLAY.findIndex((o, i) => t >= pencere(i)[0] && t < pencere(i)[0] + o[2]);
  const yakalanan = new Map();
  for (const [t] of uyari) { const i = ici(t);
    if (i >= 0 && !yakalanan.has(i)) yakalanan.set(i, t - pencere(i)[0]); }
  const yanlis = uyari.filter(([t]) => ici(t) < 0).length;
  const turlar = [...yakalanan.values()];
  return { p, uyari: uyari.length, yakalanan, kacan: OLAY.length - yakalanan.size, yanlis,
    tur: turlar.length ? turlar.reduce((a, b) => a + b, 0) / turlar.length : null };
}

const TARAMA = { esik: [2, 3, 5, 8], oran: [10, 30, 60, 180], anomali: [1, 3, 7] };
const BASLIK = { esik: "esik (medyan kati)", oran: "oran penceresi (dk)", anomali: "ogrenme penceresi (gun)" };
const secim = {};
for (const tur of Object.keys(TARAMA)) {
  console.log(`${BASLIK[tur].padEnd(24)}${"uyari".padStart(7)}${"yakalanan".padStart(11)}` +
    `${"kacan".padStart(7)}${"yanlis alarm".padStart(14)}${"fark etme turu".padStart(16)}`);
  const satir = TARAMA[tur].map((p) => kosr(tur, p));
  for (const d of satir) console.log(`${String(d.p).padEnd(24)}${String(d.uyari).padStart(7)}` +
    `${`${d.yakalanan.size}/${OLAY.length}`.padStart(11)}${String(d.kacan).padStart(7)}` +
    `${String(d.yanlis).padStart(14)}${(d.tur === null ? "-" : `${d.tur.toFixed(0)} tur`).padStart(16)}`);
  const uygun = satir.filter((d) => d.yanlis <= BUTCE);
  secim[tur] = (uygun.length ? uygun : satir).slice()
    .sort((a, b) => b.yakalanan.size - a.yakalanan.size || a.yanlis - b.yanlis)[0];
  console.log(`secilen: ${secim[tur].p}\n`);
}

const T = Object.keys(TARAMA);
console.log(`${"olay".padEnd(24)}${T.map((t) => t.padStart(12)).join("")}  yalniz`);
const yalniz = [];
OLAY.forEach((o, i) => {
  const h = T.map((t) => secim[t].yakalanan.get(i));
  const kac = h.filter((x) => x !== undefined).length;
  if (kac === 1) yalniz.push([o[3], T[h.findIndex((x) => x !== undefined)]]);
  console.log(`${o[3].padEnd(24)}${h.map((x) => (x === undefined ? "-" : `${x} tur`).padStart(12)).join("")}` +
    `  ${kac === 1 ? T[h.findIndex((x) => x !== undefined)] : kac === 0 ? "hicbiri" : ""}`);
});
const birlesim = new Set(T.flatMap((t) => [...secim[t].yakalanan.keys()]));
console.log(`\nucu birlikte ${birlesim.size}/${OLAY.length} olay, toplam yanlis alarm ` +
  `${T.reduce((a, t) => a + secim[t].yanlis, 0)}, toplam uyari ${T.reduce((a, t) => a + secim[t].uyari, 0)}`);
console.log(`yalniz tek turle yakalanan ${yalniz.length} olay: ` +
  `${yalniz.map(([a, t]) => `${a} (${t})`).join(", ")}`);
const KUME = [["esik"], ["oran"], ["anomali"], ["esik", "anomali"], ["esik", "oran"],
  ["oran", "anomali"], ["esik", "oran", "anomali"]];
console.log(`\n${"kural kumesi".padEnd(24)}${"kapsanan olay".padStart(14)}${"yanlis alarm".padStart(14)}` +
  `${"uyari".padStart(7)}`);
for (const k of KUME) {
  const kaps = new Set(k.flatMap((t) => [...secim[t].yakalanan.keys()]));
  console.log(`${k.join("+").padEnd(24)}${`${kaps.size}/${OLAY.length}`.padStart(14)}` +
    `${String(k.reduce((a, t) => a + secim[t].yanlis, 0)).padStart(14)}` +
    `${String(k.reduce((a, t) => a + secim[t].uyari, 0)).padStart(7)}`);
}
esik (medyan kati)        uyari  yakalanan  kacan  yanlis alarm  fark etme turu
2                            15        4/8      4            11          13 tur
3                            14        5/8      3             9          21 tur
5                             4        4/8      4             0          52 tur
8                             3        3/8      5             0           1 tur
secilen: 3

oran penceresi (dk)       uyari  yakalanan  kacan  yanlis alarm  fark etme turu
10                           18        5/8      3            13           1 tur
30                           18        5/8      3            13           0 tur
60                           19        6/8      2            12           8 tur
180                          74        8/8      0            57          29 tur
secilen: 60

ogrenme penceresi (gun)   uyari  yakalanan  kacan  yanlis alarm  fark etme turu
1                            12        6/8      2             6          21 tur
3                             8        6/8      2             0          22 tur
7                             9        6/8      2             0          22 tur
secilen: 3

olay                            esik        oran     anomali  yalniz
ani hata sicramasi             0 tur       0 tur       0 tur  
yavas hata tirmanmasi        104 tur      48 tur      58 tur  
gece trafik kaybi                  -       1 tur       2 tur  
kisa derin kesinti                 -       0 tur           -  oran
sabit kayma                    1 tur       1 tur       0 tur  
yayin sonrasi artis            0 tur       0 tur       2 tur  
gece istek tirmanmasi          0 tur           -      68 tur  
kademeli trafik dususu             -           -           -  hicbiri

ucu birlikte 7/8 olay, toplam yanlis alarm 21, toplam uyari 41
yalniz tek turle yakalanan 1 olay: kisa derin kesinti (oran)

kural kumesi             kapsanan olay  yanlis alarm  uyari
esik                               5/8             9     14
oran                               6/8            12     19
anomali                            6/8             0      8
esik+anomali                       6/8             9     22
esik+oran                          7/8            21     33
oran+anomali                       7/8            12     27
esik+oran+anomali                  7/8            21     41

Taramaların her biri kendi ödünleşimini gösteriyor. Eşik sıkılaştıkça yanlış alarm sıfıra iniyor (medyanın beş katında 0 yanlış alarm) ama yakalanan olay da düşüyor ve fark etme turu 52’ye çıkıyor. Sekiz katlık eşiğin ortalama fark etme turu 1’dir; bu sayı kuralın hızlı olmasından değil, yalnız hızlı olayları yakalamasından gelir — ortalama yalnız yakalanan olaylar üzerinden alınıyor.

Oran kuralında pencere büyüdükçe kapsam artıyor: 180 dakikalık pencere sekiz olayın sekizini yakalıyor. Bedeli 57 yanlış alarm, çünkü mevsimsel ölçütte sabah yükselişi de üç saat öncesine göre iki katı aşıyor. Pencere seçimi burada olay biçimi ile günlük desen arasındaki bir uzlaşmadır.

Anomali kuralında öğrenme penceresi bir gün olduğunda band tek bir güne dayanıyor, dolayısıyla dar kalıyor ve altı yanlış alarm üretiyor. Üç güne çıkınca yanlış alarm sıfırlanıyor ve kapsam düşmüyor. Yedi gün üç günden daha iyi değil; öğrenme penceresini uzatmanın getirisi üçüncü günden sonra tükeniyor.

Tamamlayıcılık

Olay tablosu üç türün aynı olaylarda farklı davrandığını gösteriyor. Ani sıçramayı üçü de sıfırıncı turda yakalıyor. Yavaş tırmanmada eşik 104. turda, oran 48. turda, anomali 58. turda çalıyor — eşik kuralı olayın sonuna doğru geliyor, çünkü değer eşiği ancak o zaman aşıyor. Dört dakikalık derin kesintiyi yalnız oran kuralı yakalıyor: olay eşiğin üstüne çıkıyor ama beş dakikalık ardışıklık koşulunu doldurmadan bitiyor, oran kuralının üç turluk koşulu ise doluyor.

Kural kümesi tablosu asıl kararı taşıyor. Anomali tek başına sekiz olayın altısını sıfır yanlış alarmla yakalıyor. Eşik kuralı bu kümeye eklendiğinde kapsam değişmiyor — eşiğin yakaladığı beş olayın hepsi zaten anomali tarafından yakalanıyor — ama dokuz yanlış alarm ekliyor. Oran kuralı eklendiğinde kapsam altıdan yediye çıkıyor: kazanılan tek olay dört dakikalık derin kesinti, bedeli on iki yanlış alarm. Bir olay daha yakalamak on iki yanlış alarm ediyor ve bu, bir sonraki dersin konusudur.

Sekizinci olay üç türün hiçbiriyle yakalanmıyor. Kademeli trafik düşüşü mutlak eşiğin altına hiç inmiyor, saatlik değişimi iki katı bulmuyor, ve öğrenilmiş bandın alt sınırını aşacak kadar sapmıyor. Yanıtsız kalan sorunun bedeli burada altı saatlik bir düşüşün fark edilmemesidir; bu olayın görülmesi kural türü değiştirmekle değil, ölçütü değiştirmekle olur — mutlak istek sayısı yerine günlük desene göre normalleştirilmiş bir oran.

Özet

  • Üç kural türü aynı ölçüt üzerinde farklı olayları yakalar: eşik değere, oran değişim hızına, anomali öğrenilmiş banda bakar.
  • Parametre taraması her türde bir ödünleşim gösterdi: eşik sıkılaştıkça yanlış alarm sıfırlanıyor ama fark etme turu 52’ye çıkıyor; oran penceresi 180 dakikaya çıkınca kapsam 8/8 oluyor ama yanlış alarm 57’ye fırlıyor.
  • Anomali kuralının öğrenme penceresini bir günden üç güne çıkarmak yanlış alarmı 6’dan 0’a indirdi; yedi güne çıkarmanın ek getirisi olmadı.
  • Dört dakikalık derin kesintiyi yalnız oran kuralı yakaladı; ardışıklık koşulu olay süresinden uzun olduğu için eşik ve anomali kaçırdı.
  • Anomali tek başına 6/8 olayı sıfır yanlış alarmla yakalıyor; eşik eklemek kapsamı değiştirmeden dokuz yanlış alarm, oran eklemek bir olay karşılığında on iki yanlış alarm getiriyor.
  • Sekizinci olay hiçbir türle yakalanmadı: eksik olan kural türü değil, ölçütün kendisi.

Sonraki Adım

Bu dersin üç kuralı birlikte koşturulduğunda on günde 41 uyarı üretti ve bunların 21’i hiçbir olaya denk gelmedi. Sayılar kâğıt üzerinde küçük görünür; ama bu uyarılar bir listeye değil, bir kişiye gider. Aynı olay birden çok kuralı birden çaldırdığında o kişi aynı şey için üç kez uyarılır, gece yarısı gelen dördüncü uyarıda okumadan kapatır, ve okunmadan kapatılan uyarıların içinde gerçek bir olay olduğunda kimse fark etmez. Sonraki ders bir dönem boyunca üretilen uyarılara gruplama, susturma ve bağımlılık bastırma uygulayıp kişi başına uyarı sayısını, eyleme dönen uyarı oranını ve bastırmanın kaçırdığı gerçek olayı sayar.

İ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