Ders 04 / 11
Risk Kaydı
Belirsizliğin bir kayıt üzerinden izlenmesi: riskler olasılık ve etkiyle modellenir, bir dönem tohumu görünür bir üreteçle koşturulur, kayıttaki olasılık tahmini ile ölçülen gerçekleşme oranı bantlar halinde karşılaştırılır, hiç kaydedilmediği halde gerçekleşen riskler sayılır ve gözden geçirme sıklığının gerçekleşmeden önce yakalanan risk sayısına etkisi kişi-dakika karşılığıyla birlikte ölçülür.
İçindekiler
Önceki üç ders verilmiş bir kararın kaydını, verilme sürecini ve dayandığı tabloyu ölçtü. Üçünde de karar bir noktada kesinleşir ve kayıt kapanır. Kapanmayan bir şey kalır: kararın dayandığı varsayımın tutmama ihtimali. Ödünleşim çözümlemesinde bir ölçüte 0,50 ağırlık verilmesi, o niteliğin kritik olduğu varsayımına dayanır; varsayım yanlışsa karar da yanlıştır ve bunu ancak zaman gösterir.
Bu, kayda geçirilecek bir karar değil, izlenecek bir belirsizliktir ve kendi kaydını gerektirir. Riskin test bütçesini nasıl böldüğü test planlama konusunda ölçüldü; burada tekrarlanmaz. Buradaki soru kaydın kendisiyle ilgilidir: kayıt tutulduğunda ne yakalanıyor, ne kaçıyor ve kaydın ne sıklıkta gözden geçirildiği bunu nasıl değiştiriyor.
Risk Kaydı ve Bir Dönem
Risk kaydı iki alanla modellenir: olasılık ve etki. Olasılık kayda yazılan bir tahmindir; etki gerçekleştiğinde ne kadar iş çıkaracağının ölçeğidir. Modeldeki on dört riskin sekizi kayıtta, altısı kayıt dışıdır — kayıt dışı olanlar sistemde vardır, kimse yazmamıştır.
Her riskin iki olasılığı ayrılır: kayda yazılan tahmin ve dönem boyunca gözlenen davranışı belirleyen gerçek olasılık. İkincisi modelin girdisidir (KK12); kayıt tutan kişi onu görmez, yalnızca dönemler geçtikçe ölçer. Beş yüz dönem koşturulur ve üreteç kendi yazılır, tohum görünürdür.
// risk/kayit.mjs — risk kaydi olasilik ve etkiyle modellenir, bir donem kosturulur // [ad, kayittaki tahmin (null ise kayitta yok), gercek olasilik, etki]; hepsi modelin girdisi (KK12) export const RISK = [ ["katalog-surum-kirilmasi", 0.60, 0.55, 4], ["sube-agi-kopmasi", 0.70, 0.75, 3], ["onbellek-tazelik-asimi", 0.50, 0.15, 3], ["kimlik-servisi-kesintisi", 0.40, 0.35, 5], ["yedekleme-penceresi-tasmasi", 0.30, 0.45, 2], ["uye-verisi-uyumsuzlugu", 0.20, 0.20, 5], ["kart-basim-gecikmesi", 0.15, 0.10, 2], ["kural-motoru-buyumesi", 0.10, 0.50, 3], ["arama-dizini-tutarsizligi", null, 0.40, 3], ["rapor-sunucusu-yetersizligi", null, 0.35, 4], ["bildirim-kuyrugu-birikmesi", null, 0.30, 2], ["lisans-yenileme-gecikmesi", null, 0.25, 4], ["sube-personeli-egitim-eksigi", null, 0.20, 2], ["odunc-limiti-istisnasi", null, 0.15, 1], ].map(([ad, tahmin, gercek, etki]) => ({ ad, tahmin, gercek, etki, kayitli: tahmin !== null })); export const AY = 12; // bir donem export const rastgele = (tohum) => () => { // uretec burada yazilir, tohum gorunurdur tohum = (tohum + 0x6d2b79f5) | 0; let t = Math.imul(tohum ^ (tohum >>> 15), 1 | tohum); t = (t + Math.imul(t ^ (t >>> 7), 61 | t)) ^ t; return ((t ^ (t >>> 14)) >>> 0) / 4294967296; }; // Bir donem: her risk gercek olasiligiyla gerceklesir, gerceklesirse ayi duzgun dagilir. export function donem(rnd) { return RISK.map((r) => { const oldu = rnd() < r.gercek; return { risk: r, oldu, ay: oldu ? 1 + Math.floor(rnd() * AY) : null }; }); } export const BANT = (p) => (p >= 0.5 ? "yuksek" : p >= 0.2 ? "orta" : "dusuk"); if (import.meta.url.endsWith(process.argv[1].split("/").pop())) { const TEKRAR = 500, TOHUM = 20240517, rnd = rastgele(TOHUM); const kez = RISK.map(() => 0); for (let i = 0; i < TEKRAR; i++) donem(rnd).forEach((s, j) => { if (s.oldu) kez[j] += 1; }); const olculen = kez.map((k) => k / TEKRAR); const kayitli = RISK.filter((r) => r.kayitli); const toplam = kez.reduce((t, k) => t + k, 0); const disi = RISK.reduce((t, r, j) => t + (r.kayitli ? 0 : kez[j]), 0); console.log(`${RISK.length} risk: ${kayitli.length} kayitli, ${RISK.length - kayitli.length} ` + `kayit disi; ${TEKRAR} donem, tohum ${TOHUM}`); console.log(`gerceklesen risk ${toplam}, bunlarin ${disi} tanesi kayit disi ` + `(%${(100 * disi / toplam).toFixed(1)})\n`); console.log("kayittaki tahmin bandi ile olculen gerceklesme orani:"); for (const bant of ["yuksek", "orta", "dusuk"]) { const g = RISK.map((r, j) => ({ r, o: olculen[j] })).filter((x) => x.r.kayitli && BANT(x.r.tahmin) === bant); console.log(` ${bant.padEnd(7)} ${g.length} risk, ortalama tahmin ` + `${(g.reduce((t, x) => t + x.r.tahmin, 0) / g.length).toFixed(2)}, olculen oran ` + `${(g.reduce((t, x) => t + x.o, 0) / g.length).toFixed(2)}`); } console.log("\ntahmini olculen orandan en cok sapan kayitli riskler:"); for (const x of RISK.map((r, j) => ({ r, o: olculen[j] })).filter((x) => x.r.kayitli) .sort((a, b) => Math.abs(b.o - b.r.tahmin) - Math.abs(a.o - a.r.tahmin)).slice(0, 3)) console.log(` ${x.r.ad.padEnd(28)} tahmin ${x.r.tahmin.toFixed(2)} olculen ${x.o.toFixed(2)} ` + `sapma ${(x.o - x.r.tahmin > 0 ? "+" : "") + (x.o - x.r.tahmin).toFixed(2)} etki ${x.r.etki}`); console.log("\nkayit disi kalip gerceklesen riskler (olculen oran x etki):"); for (const x of RISK.map((r, j) => ({ r, o: olculen[j] })).filter((x) => !x.r.kayitli) .sort((a, b) => b.o * b.r.etki - a.o * a.r.etki)) console.log(` ${x.r.ad.padEnd(28)} olculen ${x.o.toFixed(2)} etki ${x.r.etki} ` + `carpim ${(x.o * x.r.etki).toFixed(2)}`); }
14 risk: 8 kayitli, 6 kayit disi; 500 donem, tohum 20240517 gerceklesen risk 2348, bunlarin 808 tanesi kayit disi (%34.4) kayittaki tahmin bandi ile olculen gerceklesme orani: yuksek 3 risk, ortalama tahmin 0.60, olculen oran 0.49 orta 3 risk, ortalama tahmin 0.30, olculen oran 0.34 dusuk 2 risk, ortalama tahmin 0.13, olculen oran 0.30 tahmini olculen orandan en cok sapan kayitli riskler: kural-motoru-buyumesi tahmin 0.10 olculen 0.50 sapma +0.40 etki 3 onbellek-tazelik-asimi tahmin 0.50 olculen 0.15 sapma -0.35 etki 3 yedekleme-penceresi-tasmasi tahmin 0.30 olculen 0.45 sapma +0.15 etki 2 kayit disi kalip gerceklesen riskler (olculen oran x etki): rapor-sunucusu-yetersizligi olculen 0.35 etki 4 carpim 1.41 arama-dizini-tutarsizligi olculen 0.39 etki 3 carpim 1.18 lisans-yenileme-gecikmesi olculen 0.24 etki 4 carpim 0.98 bildirim-kuyrugu-birikmesi olculen 0.29 etki 2 carpim 0.59 sube-personeli-egitim-eksigi olculen 0.18 etki 2 carpim 0.36 odunc-limiti-istisnasi olculen 0.15 etki 1 carpim 0.15
İlk sayı kaydın kapsama alanını veriyor: gerçekleşen 2348 riskin 808’i, yani yüzde 34,4’ü kayıtta hiç yoktu. Risk kaydının ölçülebilir ilk niteliği içindekilerin ne kadar doğru tahmin edildiği değil, dışında ne kaldığıdır. Sekiz maddelik bir kayda bakan biri, gerçekleşen olayların üçte birini hiç görmemiş olur.
Bant tablosu ikinci sayıyı veriyor ve kaydın kendi içindeki doğruluğunu gösteriyor. Yüksek bandın ortalama tahmini 0,60, ölçülen oranı 0,49; düşük bandın tahmini 0,13, ölçülen oranı 0,30. Bantlar sıralamayı bile korumuyor: düşük diye işaretlenmiş riskler orta banda yakın bir sıklıkla gerçekleşiyor. Bir risk kaydının olasılık sütunu, ölçülen oranla karşılaştırılmadığı sürece bir sıralama değil, bir izlenim listesidir.
Sapma tablosu bu bozulmanın nereden geldiğini gösteriyor. kural-motoru-buyumesi 0,10 tahmin
edilmişti, 0,50 ölçüldü; onbellek-tazelik-asimi 0,50 tahmin edilmişti, 0,15 ölçüldü. İki sapma
zıt yönde ve ikisi de büyük. Kayda bakan biri ikinci riske hazırlanır, birinciyle karşılaşır. Bu,
kaydın gözden geçirilmesinin neden bir formalite olmadığını gösteren sayıdır: tahmin bir kez
yazılıp bırakıldığında yanlışlığı kendini göstermez.
Son tablo kayıt dışı kalanları etkiyle birlikte sıralıyor. En üstteki iki madde,
rapor-sunucusu-yetersizligi ve arama-dizini-tutarsizligi, çarpım olarak kayıttaki pek çok
maddenin üzerinde. Kayıt dışı kalmalarının nedeni önemsiz olmaları değil, kimsenin akla
getirmemesidir.
Gözden Geçirme Sıklığı
Kayıt dışı bir risk kendiliğinden kayda girmez; birinin onu fark etmesi gerekir. Fark etme, kaydın gözden geçirildiği anlarda olur. Aşağıdaki koşum dört sıklığı aynı dönemler üzerinde karşılaştırır: hiç gözden geçirmemek, yılda bir, üç ayda bir ve ayda bir. Bir gözden geçirmede kayıt dışı bir riskin fark edilme olasılığı ile gözden geçirmenin kişi-dakikası modelin girdisidir (KK13).
Ölçülen şey fark edilen risk sayısı değil, gerçekleşmeden önce fark edilen risk sayısıdır. Bir riski gerçekleştikten sonra kayda geçirmek kaydı düzeltir, olayı önlemez.
// risk/gozden.mjs — gozden gecirme sikligi kac riski gerceklesmeden once yakaliyor import { RISK, AY, rastgele, donem } from "./kayit.mjs"; const FARK = 0.20; // bir gozden gecirmede kayit disi bir riskin fark edilme olasiligi (KK13) const KISI_DK = 45; // bir gozden gecirmenin kisi-dakikasi (KK13) const SIKLIK = { hic: [], yillik: [12], "uc-aylik": [3, 6, 9, 12], aylik: [...Array(AY)].map((_, i) => i + 1), }; const TEKRAR = 500, TOHUM = 20240518; console.log(`${TEKRAR} donem, tohum ${TOHUM}; fark etme olasiligi ${FARK}, ` + `gozden gecirme basina ${KISI_DK} kisi-dk`); console.log("siklik gecirme fark edilen onceden yakalanan kayit disi gerceklesen kisi-dk"); const sonuc = {}; for (const [ad, aylar] of Object.entries(SIKLIK)) { const rnd = rastgele(TOHUM); // her siklik ayni tohumla, ayni donemler uzerinde kosar let farkEdilen = 0, once = 0, kacan = 0; for (let i = 0; i < TEKRAR; i++) for (const s of donem(rnd)) { if (s.risk.kayitli) continue; let bulunduAy = null; for (const m of aylar) if (rnd() < FARK) { bulunduAy = m; break; } if (bulunduAy !== null) farkEdilen += 1; if (s.oldu && (bulunduAy === null || bulunduAy >= s.ay)) kacan += 1; else if (s.oldu) once += 1; } const kisiDk = aylar.length * KISI_DK; sonuc[ad] = { once: once / TEKRAR, kacan: kacan / TEKRAR, kisiDk, fark: farkEdilen / TEKRAR }; console.log(` ${ad.padEnd(10)} ${String(aylar.length).padStart(4)} ` + `${(farkEdilen / TEKRAR).toFixed(2).padStart(11)} ${(once / TEKRAR).toFixed(2).padStart(17)} ` + `${(kacan / TEKRAR).toFixed(2).padStart(22)} ${String(kisiDk).padStart(9)}`); } console.log("\nsikligi artirmanin karsiligi (donem basina):"); const ad = Object.keys(SIKLIK); for (let i = 1; i < ad.length; i++) { const a = sonuc[ad[i - 1]], b = sonuc[ad[i]]; const ek = b.once - a.once; console.log(` ${ad[i - 1]} -> ${ad[i]}: +${(b.kisiDk - a.kisiDk)} kisi-dk, ` + `+${ek.toFixed(2)} onceden yakalanan risk -> risk basina ` + `${ek > 0 ? `${((b.kisiDk - a.kisiDk) / ek).toFixed(0)} kisi-dk` : "karsiligi yok"}`); } // Soru kumesi: 14 risk x 3 soru; donem sonunda kayitta olan risk sayisina gore beklenen deger const KAYITLI = RISK.filter((r) => r.kayitli).length, N = RISK.length; console.log(`\nsoru kumesi (${N} risk x 3 soru = ${3 * N} yanit; R1 bu risk dusunuldu mu, ` + `R2 olasiligi ne kabul edilmisti, R3 tahmin tuttu mu):`); for (const [ad, aylar] of Object.entries(SIKLIK)) { const kayitta = KAYITLI + sonuc[ad].fark, disi = N - kayitta; const dogru = kayitta * (aylar.length ? 3 : 2); const eksik = disi * 2 + (aylar.length ? 0 : kayitta); console.log(` ${ad.padEnd(10)} kayitta ${kayitta.toFixed(2)}/${N} risk -> dogru ` + `${dogru.toFixed(1)}, eksik ${eksik.toFixed(1)}, yanlis ${disi.toFixed(1)}`); }
500 donem, tohum 20240518; fark etme olasiligi 0.2, gozden gecirme basina 45 kisi-dk siklik gecirme fark edilen onceden yakalanan kayit disi gerceklesen kisi-dk hic 0 0.00 0.00 1.67 0 yillik 1 1.26 0.00 1.63 45 uc-aylik 4 3.54 0.44 1.22 180 aylik 12 5.62 1.03 0.59 540 sikligi artirmanin karsiligi (donem basina): hic -> yillik: +45 kisi-dk, +0.00 onceden yakalanan risk -> risk basina karsiligi yok yillik -> uc-aylik: +135 kisi-dk, +0.44 onceden yakalanan risk -> risk basina 310 kisi-dk uc-aylik -> aylik: +360 kisi-dk, +0.60 onceden yakalanan risk -> risk basina 602 kisi-dk soru kumesi (14 risk x 3 soru = 42 yanit; R1 bu risk dusunuldu mu, R2 olasiligi ne kabul edilmisti, R3 tahmin tuttu mu): hic kayitta 8.00/14 risk -> dogru 16.0, eksik 20.0, yanlis 6.0 yillik kayitta 9.26/14 risk -> dogru 27.8, eksik 9.5, yanlis 4.7 uc-aylik kayitta 11.54/14 risk -> dogru 34.6, eksik 4.9, yanlis 2.5 aylik kayitta 13.62/14 risk -> dogru 40.9, eksik 0.8, yanlis 0.4
Yıllık gözden geçirme dönem başına 1,26 risk fark ediyor ve bunların hiçbirini gerçekleşmeden önce yakalamıyor. Sayı sıfır olduğu için tesadüf değildir: gözden geçirme on ikinci ayda, gerçekleşme ise on iki aya yayılmış durumda, dolayısıyla fark etme neredeyse her zaman olaydan sonra geliyor. Yılda bir gözden geçirilen bir risk kaydı, sonraki dönem için doğru bir kayıt üretir ve içinde bulunulan dönem için hiçbir şey yapmaz.
Üç aylık sıklık 0,44, aylık sıklık 1,03 riski gerçekleşmeden önce yakalıyor; kayıt dışı kalıp gerçekleşen risk 1,67’den 0,59’a iniyor. Karşılığı ise artan bir eğridir: üç aylığa geçmek önceden yakalanan risk başına 310 kişi-dakika, aylığa geçmek 602 kişi-dakika. İkinci geçişin birim maliyeti birincinin iki katına yakın, çünkü kolay fark edilen riskler daha seyrek gözden geçirmede zaten yakalanmıştır. Sıklığı artırmanın getirisi azalır; nerede durulacağı, riskin etkisiyle kişi-dakikanın karşılaştırılabildiği bir soruya dönüşür.
Soru kümesi tablosu aynı eğriyi kaydın okunabilirliği tarafında gösteriyor. Kırk iki yanıttan gözden geçirilmeyen kayıtta 16’sı doğru, 20’si eksik, 6’sı yanlıştır. Yanlış olanlar “bu risk düşünüldü mü” sorusuna verilen yanıtlardır: kayıt dışı bir risk için verilecek yanıt “hayır” olur ve bu yanıt doğru görünür, çünkü kayıt gerçekten sessizdir. Aylık gözden geçirmede doğru yanıt 40,9’a çıkıyor. Kaydın değeri, içine bir kez yazılanla değil, ne sıklıkta yeniden okunduğuyla belirleniyor.
Özet
- Gerçekleşen 2348 riskin 808’i, yani yüzde 34,4’ü kayıtta hiç yoktu; bir risk kaydının ilk ölçüsü içindekilerin doğruluğu değil, dışında kalanın büyüklüğüdür.
- Kayıttaki bantlar sıralamayı korumadı: yüksek bandın tahmini 0,60 iken ölçülen oranı 0,49, düşük bandın tahmini 0,13 iken ölçülen oranı 0,30 çıktı.
- İki büyük sapma zıt yönlüdür —
kural-motoru-buyumesi0,10 tahminle 0,50 ölçüldü,onbellek-tazelik-asimi0,50 tahminle 0,15; bir kez yazılıp bırakılan tahmin yanlışlığını göstermez. - Yıllık gözden geçirme dönem başına 1,26 risk fark etti ve hiçbirini gerçekleşmeden önce yakalamadı; üç aylık 0,44, aylık 1,03 risk yakaladı ve kaçan risk 1,67’den 0,59’a indi.
- Sıklığı artırmanın birim bedeli yükseliyor: önceden yakalanan risk başına 310 ve 602 kişi-dakika; soru kümesinde doğru yanıt 16’dan 40,9’a çıkarken yanlış yanıt 6’dan 0,4’e indi.
Sonraki Adım
Risk kaydı gerçekleşmemiş bir şeyi izler: olasılığı olan, henüz olmamış bir olay. Yanında bir kayıt daha durur ve o, çoktan gerçekleşmiş bir şeyi izler. Bir karar verildiğinde bazen bilerek eksik bir çözüm seçilir — hızlı çıkmak için, ya da doğru çözümün ne olduğu henüz bilinmediği için. O eksiklik sistemde kalır ve her değişiklikte biraz fazladan iş çıkarır. Bazen de eksiklik bilerek seçilmez, sonradan fark edilir. Sonraki ders bu iki durumu ayırır, aradaki farkın ölçülebilir olup olmadığını sınar ve eksikliğin değişiklik başına çıkardığı fazladan işi sayar.
İlerlemeni kaydetmek ve not almak için Giriş yap
Notlarım
Not almak için giriş yapmalısın.