Ders 04 / 19
Sıfırdan ve Mevcuttan Kurma
Aynı envanter üzerinde ilkeden kurma ile mevcuttan türetme stratejilerinin geçiş maliyeti ve ölçek kalitesi bakımından karşılaştırılması, karma yolun istisna kaydıyla kurulması ve dondurmaya dayalı aşamalı geçiş.
İçindekiler
Görsel denetim envanteri verdi: dört üründe 52 ayrı değer, bunların 17’si karşılıksız çeşitlilik. Envanter neyin kullanıldığını söylüyor; neyin kullanılması gerektiğini söylemiyor. Bu ders aradaki geçişi kurar ve geçişin iki farklı yoldan yapılabileceğini gösterir.
İlkeden kurma, ölçeği envanterden bağımsız olarak, Aralık Ölçeği ve Tipografik Ölçek derslerindeki ölçütlerden türetir; sonra mevcut değerleri bu ölçeğe oturtur. Mevcuttan türetme, en çok kullanılan değerleri ölçek ilan eder; ölçek envanterin özetidir. İki yol farklı geçiş maliyeti ve farklı ölçek kalitesi üretir, ve bu iki büyüklük birbirinden bağımsızdır.
İki Strateji, Tek Envanter
Karşılaştırma üç sayısal özellik sınıfında yapılır: aralık, yazı boyutu ve köşe yarıçapı. Renk ayrı ele alınır, çünkü rengin ölçeği bir sayı dizisi değil rol tablosudur ve geçişi kayma değil eşleşme denetimiyle ölçülür.
Her strateji iki ölçüt kümesiyle değerlendirilir. Ölçek kalitesi: adım sayısı, ayırt edilebilirlik eşiğinin altında kalan komşu çift sayısı ve gruplama için gereken oranı 2 ve üzeri olan komşu çift sayısı. Geçiş maliyeti: kaç kullanımın değeri kayar, bu kaymaların kaçı ayırt edilebilirlik eşiğini aşar ve en büyük kayma nedir.
// strateji.mjs — ayni envanter uzerinde iki baslangic stratejisinin karsilastirilmasi // Gorsel Denetim dersinde cikarilan envanter: deger -> kullanim sayisi. const ENVANTER = { aralik: { 2: 1, 4: 1, 6: 4, 8: 9, 10: 4, 12: 6, 14: 3, 16: 5, 18: 2, 20: 3, 24: 5, 28: 1, 32: 1 }, "yazi boyutu": { 12: 4, 13: 7, 14: 4, 15: 2, 16: 1, 18: 1, 20: 1, 22: 1, 24: 1 }, "kose yaricapi": { 3: 3, 4: 5, 6: 2, 8: 3, 12: 1 }, }; const ESIK = { aralik: 2, "yazi boyutu": 1, "kose yaricapi": 2 }; // A stratejisi: olcek ilkelerden kurulur. Aralik olcegi karma olcektir (Aralik Olcegi dersi), // yazi boyutu 16 tabanli 1.25 oranli olcektir (Tipografik Olcek dersi). const ILKEDEN = { aralik: [4, 8, 12, 16, 24, 32, 48, 64, 96], "yazi boyutu": [-1, 0, 1, 2, 3].map((n) => Math.round(16 * Math.pow(1.25, n))), "kose yaricapi": [4, 8], }; // B stratejisi: olcek mevcuttan turetilir. En cok kullanilan degerler, kullanimin // belirli bir oranini kapsayana kadar secilir. const KAPSAMA_HEDEFI = 0.8; function mevcuttan(dagilim, hedef) { const toplam = Object.values(dagilim).reduce((t, v) => t + v, 0); const sirali = Object.entries(dagilim) .map(([d, n]) => [Number(d), n]) .sort((a, b) => b[1] - a[1] || a[0] - b[0]); const secilen = []; let birikim = 0; for (const [d, n] of sirali) { if (birikim / toplam >= hedef) break; secilen.push(d); birikim += n; } return secilen.sort((a, b) => a - b); } const MEVCUTTAN = Object.fromEntries( Object.entries(ENVANTER).map(([s, d]) => [s, mevcuttan(d, KAPSAMA_HEDEFI)]) ); // --- olcut hesaplari ---------------------------------------------------------- const enYakin = (d, olcek) => olcek.reduce((a, b) => (Math.abs(b - d) < Math.abs(a - d) ? b : a)); function olcekKalitesi(olcek, esik) { let ayirtEdilemeyen = 0; let gruplayan = 0; for (let i = 1; i < olcek.length; i++) { if (olcek[i] - olcek[i - 1] <= esik) ayirtEdilemeyen++; if (olcek[i] / olcek[i - 1] >= 2) gruplayan++; } return { adim: olcek.length, ayirtEdilemeyen, gruplayan }; } function gecisMaliyeti(dagilim, olcek, esik) { let kullanim = 0; let kayan = 0; let gorunur = 0; let enBuyuk = 0; let toplamKayma = 0; for (const [d, n] of Object.entries(dagilim)) { const deger = Number(d); const hedef = enYakin(deger, olcek); const kayma = Math.abs(hedef - deger); kullanim += n; if (kayma > 0) kayan += n; if (kayma > esik) gorunur += n; toplamKayma += kayma * n; enBuyuk = Math.max(enBuyuk, kayma); } return { kullanim, kayan, gorunur, enBuyuk, ortKayma: toplamKayma / kullanim }; } for (const [ad, olcekler] of [["A ilkeden", ILKEDEN], ["B mevcuttan", MEVCUTTAN]]) { console.log(`--- ${ad} ---`); console.log("ozellik olcek adim ayirt-edilemeyen gruplayan"); for (const sinif of Object.keys(ENVANTER)) { const k = olcekKalitesi(olcekler[sinif], ESIK[sinif]); console.log( `${sinif.padEnd(15)} ${olcekler[sinif].join(",").padEnd(30)} ${String(k.adim).padStart(4)} ` + `${String(k.ayirtEdilemeyen).padStart(17)} ${String(k.gruplayan).padStart(10)}` ); } console.log("ozellik kullanim kayan gozle gorulur en buyuk kayma ort kayma"); let tk = 0; let tkayan = 0; let tgorunur = 0; for (const sinif of Object.keys(ENVANTER)) { const g = gecisMaliyeti(ENVANTER[sinif], olcekler[sinif], ESIK[sinif]); tk += g.kullanim; tkayan += g.kayan; tgorunur += g.gorunur; console.log( `${sinif.padEnd(15)} ${String(g.kullanim).padStart(9)} ${String(g.kayan).padStart(6)} ` + `${String(g.gorunur).padStart(14)} ${String(g.enBuyuk).padStart(15)} ${g.ortKayma.toFixed(2).padStart(10)}` ); } console.log( `${"toplam".padEnd(15)} ${String(tk).padStart(9)} ${String(tkayan).padStart(6)} ${String(tgorunur).padStart(14)}` + ` kayan oran ${((100 * tkayan) / tk).toFixed(1)}% gorunur oran ${((100 * tgorunur) / tk).toFixed(1)}%\n` ); } // --- karma yol: ilkeden olcek + kayda gecirilmis istisna ----------------------- // Bir ham deger olcege gorunur bicimde kaymiyorsa oturur; kayiyorsa ya olcege bir adim // eklenir ya da deger degistirilir. Adim eklemenin olcutu kullanim sayisidir. const ISTISNA_ESIGI = 3; console.log("--- karma yol: ilkeden olcek, gorunur kayanlar icin karar ---"); console.log("ozellik ham deger kullanim hedef kayma karar"); const eklenen = {}; for (const sinif of Object.keys(ENVANTER)) { eklenen[sinif] = []; for (const [d, n] of Object.entries(ENVANTER[sinif])) { const deger = Number(d); const hedef = enYakin(deger, ILKEDEN[sinif]); const kayma = Math.abs(hedef - deger); if (kayma <= ESIK[sinif]) continue; const karar = n >= ISTISNA_ESIGI ? "olcege adim ekle" : "degeri oturt"; if (n >= ISTISNA_ESIGI) eklenen[sinif].push(deger); console.log( `${sinif.padEnd(15)} ${String(deger).padStart(10)} ${String(n).padStart(9)} ${String(hedef).padStart(6)} ` + `${String(kayma).padStart(6)} ${karar}` ); } } console.log("\nozellik genisletilmis olcek adim ayirt-edilemeyen gorunur kalan"); for (const sinif of Object.keys(ENVANTER)) { const olcek = [...new Set([...ILKEDEN[sinif], ...eklenen[sinif]])].sort((a, b) => a - b); const k = olcekKalitesi(olcek, ESIK[sinif]); const g = gecisMaliyeti(ENVANTER[sinif], olcek, ESIK[sinif]); console.log( `${sinif.padEnd(15)} ${olcek.join(",").padEnd(30)} ${String(k.adim).padStart(4)} ` + `${String(k.ayirtEdilemeyen).padStart(17)} ${String(g.gorunur).padStart(14)}` ); } // --- asamali gecis: dondurma sonrasi kapsama ---------------------------------- // Dondurma: yeni bildirimler yalniz olcekten gelir. Eski bildirimler ancak o dosyaya // baska bir is icin dokunuldugunda gecer. r, bir donemde dokunulan eski bildirim orani. console.log("\ndonem r=0.10 r=0.20 r=0.35 (olcege uyan bildirim orani)"); const baslangic = 0.6; // dondurma aninda zaten olcege uyan bildirim orani for (const donem of [0, 1, 2, 3, 4, 6, 8]) { const satir = [0.1, 0.2, 0.35].map((r) => (1 - (1 - baslangic) * Math.pow(1 - r, donem)).toFixed(3)); console.log(`${String(donem).padStart(5)} ${satir[0].padStart(7)} ${satir[1].padStart(7)} ${satir[2].padStart(7)}`); }
--- A ilkeden ---
ozellik olcek adim ayirt-edilemeyen gruplayan
aralik 4,8,12,16,24,32,48,64,96 9 0 1
yazi boyutu 13,16,20,25,31 5 0 0
kose yaricapi 4,8 2 0 1
ozellik kullanim kayan gozle gorulur en buyuk kayma ort kayma
aralik 45 18 4 4 0.98
yazi boyutu 22 13 2 2 0.68
kose yaricapi 14 6 1 4 0.79
toplam 81 37 7 kayan oran 45.7% gorunur oran 8.6%
--- B mevcuttan ---
ozellik olcek adim ayirt-edilemeyen gruplayan
aralik 6,8,10,12,14,16,24 7 5 0
yazi boyutu 12,13,14,15,16 5 4 0
kose yaricapi 3,4,6,8 4 3 0
ozellik kullanim kayan gozle gorulur en buyuk kayma ort kayma
aralik 45 9 6 8 0.76
yazi boyutu 22 4 4 8 0.91
kose yaricapi 14 1 1 4 0.29
toplam 81 14 11 kayan oran 17.3% gorunur oran 13.6%
--- karma yol: ilkeden olcek, gorunur kayanlar icin karar ---
ozellik ham deger kullanim hedef kayma karar
aralik 20 3 16 4 olcege adim ekle
aralik 28 1 24 4 degeri oturt
yazi boyutu 18 1 16 2 degeri oturt
yazi boyutu 22 1 20 2 degeri oturt
kose yaricapi 12 1 8 4 degeri oturt
ozellik genisletilmis olcek adim ayirt-edilemeyen gorunur kalan
aralik 4,8,12,16,20,24,32,48,64,96 10 0 1
yazi boyutu 13,16,20,25,31 5 0 2
kose yaricapi 4,8 2 0 1
donem r=0.10 r=0.20 r=0.35 (olcege uyan bildirim orani)
0 0.600 0.600 0.600
1 0.640 0.680 0.740
2 0.676 0.744 0.831
3 0.708 0.795 0.890
4 0.738 0.836 0.929
6 0.787 0.895 0.970
8 0.828 0.933 0.987
Kayan Değer Sayısı Yanlış Ölçüttür
İki stratejinin toplam satırları ilk bakışta beklenen yönde: ilkeden kurmada kullanımların yüzde 45.7’si kayıyor, mevcuttan türetmede yalnız yüzde 17.3’ü. Envanterin özeti olan bir ölçeğin envantere daha yakın olması şaşırtıcı değildir.
Bir sonraki sütun bu okumayı tersine çeviriyor. Gözle görülür biçimde değişen kullanım oranı ilkeden kurmada yüzde 8.6, mevcuttan türetmede yüzde 13.6. Yani envanterden türetilen ölçek, daha az değeri kaydırıyor ama daha çok değeri gözle görülür biçimde kaydırıyor.
Nedeni dağılımın kuyruğundadır. Mevcuttan türetme en çok kullanılan değerleri seçer; kullanımın yüzde 80’i küçük değerlerde toplandığı için ölçek 6 ile 24 arasına sıkışır. Büyük değerler — 28 ve 32 piksellik bölüm boşlukları — ölçeğin dışında kalır ve 24’e çekilir; 20 piksel de 16’ya iner. Küçük değerlerde neredeyse hiç kayma olmadığı için toplam kayan sayısı düşük görünür, ama kayanların hepsi büyük kaymadır: en büyük kayma 8 piksel.
İlkeden kurulan ölçekte durum terstir. Çok sayıda değer 1–2 piksel kayar — bunlar ayırt edilebilirlik eşiğinin altındadır ve karşılıksız kapanır. Gerçekten değişen yalnız yedi kullanımdır.
Buradan çıkan ölçüt şudur: geçiş maliyeti kayan değer sayısıyla değil, eşiği aşan kayma sayısıyla ölçülür. Bu ayrım Yinelenme ve Tutarlılık dersindeki bulgunun bir sonucudur: tutarsızlığın büyük bölümü görünmez ve görünmeyen tutarsızlık bedelsiz düzeltilir.
Envanterin Özeti Bir Ölçek Değildir
Ölçek kalitesi tabloları ikinci farkı gösteriyor ve bu fark tartışmaya kapalıdır.
İlkeden kurulan üç ölçekte ayırt edilebilirlik eşiğinin altında kalan komşu çift sayısı sıfır. Mevcuttan türetilen ölçeklerde aynı sayı sırasıyla 5, 4 ve 3; toplam 12. Yazı boyutu ölçeği 12, 13, 14, 15, 16 biçiminde ilerliyor — beş basamağın hiçbiri diğerinden ayırt edilemiyor. Böyle bir ölçek karar sayısını düşürmez, yalnız var olan kararsızlığı belgelendirir.
Gruplama sütunu aynı sonucu ikinci kez veriyor. İlkeden kurulan aralık ölçeğinde oranı 2 ve üzeri olan bir komşu çift var; mevcuttan türetilende hiç yok. Yakınlık ve Gruplama dersindeki kural bir grup sınırının grup içi boşluğun en az iki katı olmasını istiyordu; mevcuttan türetilen ölçekle bu kural komşu adımlarla ifade edilemez.
Sonuç şudur: envanterin en sık kullanılan değerleri bir ölçek oluşturmaz. Ölçeğin işi seçenek kısmaktır; en sık kullanılanları seçmek, en sık verilen kararsız kararları meşru kılmaktır.
Karma Yol Ölçeği Korur, İstisnayı Kayda Geçirir
Üçüncü blok iki stratejinin arasındaki yolu kuruyor. Ölçek ilkeden kurulur; ardından gözle görülür biçimde kayan her ham değer tek tek ele alınır ve iki karardan biri verilir.
Ölçüt kullanım sayısıdır. Sistem İhtiyacının Gerekçelendirilmesi dersinde bir kararın sisteme girmesi için gereken en az kullanım sayısı üç olarak hesaplanmıştı; aynı eşik burada ölçeğe adım ekleme ölçütü olarak kullanılır. Üç ve üzeri kullanımı olan bir ham değer, ölçeğin eksik olduğunu gösterir; bir ya da iki kullanımı olan değer ölçeğe oturtulur.
Tabloda tek bir değer eşiği geçiyor: 20 piksellik aralık, üç kullanımla. Ölçeğe eklenir ve aralık ölçeği 4, 8, 12, 16, 20, 24, 32, 48, 64, 96 hâline gelir. Genişletilmiş ölçekte ayırt edilemeyen komşu çift sayısı hâlâ sıfır — ekleme ölçeği bozmadı — ve gözle görülür kalan kullanım aralıkta 4’ten 1’e indi.
Diğer dört değer — 28 ve 12 piksellik aralık ile 18 ve 22 piksellik yazı boyutu — birer kullanımla ölçeğe oturtulur. Bu kararlar Yinelenme ve Tutarlılık dersindeki istisna kaydına girer: hangi değerin neye oturtulduğu ve hangi ekranın etkilendiği yazılır. Kayıt tutulmazsa aynı değer altı ay sonra geri gelir ve kimse neden kaldırıldığını bilmez.
Dondurma Geçişi Zamana Yayar
Son tablo geçişin nasıl uygulanacağını ölçüyor. Bütün bildirimleri tek seferde değiştirmek en hızlı yoldur ve en riskli yoldur: değişikliğin tamamı aynı anda yayına girer, bir hata her ekranı birden etkiler.
Alternatif, dondurmadır: belirli bir andan sonra yazılan her yeni bildirim ölçekten gelmek zorundadır; eski bildirimler ancak o dosyaya başka bir iş için dokunulduğunda geçer. Dondurma anında bildirimlerin yüzde 60’ı zaten ölçeğe uyuyorsa, kapsama oranı dönem başına dokunulan eski bildirim oranına bağlı olarak artar.
Tablo üç hızı karşılaştırıyor. Dönem başına eski bildirimlerin yüzde 10’una dokunuluyorsa sekiz dönem sonunda kapsama 0.828’de kalıyor; yüzde 35’ine dokunuluyorsa aynı sürede 0.987’ye çıkıyor. Yüzde 20’lik orta hızda sekiz dönem sonunda 0.933.
İki sonuç okunur. Birincisi, dondurma yalnız başına yeterlidir ancak yavaş çalışan bir üründe çok yavaştır; dokunma oranı düşük olan ürünler için ayrıca planlı bir geçiş gerekir. İkincisi, kapsama hiçbir zaman tam 1’e ulaşmaz — üstel yaklaşma son yüzde birkaçı hep bırakır. Bu son artık, geçişin bir noktada elle bitirilmesi gerektiği anlamına gelir.
Hangi Strateji Ne Zaman
Karar üç girdiye bakar. Ürün yeniyse ya da yerleşik taban küçükse ilkeden kurma tek makul yoldur; geçiş maliyeti zaten yoktur ve ölçek kalitesi tam alınır. Yerleşik taban büyükse ve görünür değişikliğe tolerans düşükse — sözleşmeye bağlı bir görünüm, sık kullanılan bir iç araç — karma yol seçilir: ölçek ilkeden kurulur, kullanımı eşiği geçen ham değerler için adım eklenir.
Mevcuttan türetme ise ölçek kurma stratejisi olarak değil, envanterin okunması olarak kalır. En sık kullanılan değerler ölçeği vermez; ölçeğin hangi bölgesinde yoğunlaşma olduğunu verir. İlkeden kurulan bir ölçeğin alt bölgesi neden ince, üst bölgesi neden kaba olmalıdır sorusunun yanıtı bu dağılımdadır.
Özet
- Aynı envanter üzerinde ilkeden kurma kullanımların yüzde 45.7’sini kaydırır ama yalnız yüzde 8.6’sını gözle görülür biçimde değiştirir; mevcuttan türetme yüzde 17.3’ünü kaydırır ve yüzde 13.6’sını görünür biçimde değiştirir.
- Geçiş maliyeti kayan değer sayısıyla değil eşiği aşan kayma sayısıyla ölçülür; envanterden türetilen ölçek küçük değerleri korur, büyük değerleri keser.
- Envanterin en sık kullanılan değerleri bir ölçek oluşturmaz: mevcuttan türetilen üç ölçekte ayırt edilemeyen komşu çift sayısı 12, gruplama oranını sağlayan çift sayısı sıfırdır.
- Karma yol ölçeği ilkeden kurar ve gözle görülür kayan ham değerleri kullanım sayısına göre ayırır; üç ve üzeri kullanımı olan değer ölçeğe adım ekletir, azı ölçeğe oturur ve istisna kaydına girer.
- Dondurma geçişi zamana yayar; kapsama üstel olarak yaklaşır ve tam 1’e ulaşmaz, dolayısıyla son artık planlı biçimde kapatılır.
- Yeni ya da küçük tabanlı üründe ilkeden kurma, büyük ve değişikliğe kapalı tabanda karma yol seçilir; mevcuttan türetme bir ölçek stratejisi değil bir okuma aracıdır.
Sonraki Adım
Ölçekler kurulduğunda sistemin sayısal iskeleti hazır olur, ama iskelet neyin doğru görüneceğini söylemez. Aynı ölçekle iki ayrı arayüz kurulabilir ve ikisi de kurumun sesini taşımayabilir. Bir kararı sayıya bağlanamayan durumlarda neyin belirlediği ayrı bir sorudur: düğmenin dolgulu mu çerçeveli mi olacağı, bir hata iletisinin özür mü yönerge mi olduğu, arayüzün sessiz mi teşvik edici mi konuştuğu. Sonraki ders bu kararların dayanağını kurar; ilkelerin hangi koşulda karar verdirdiğini, hangi ilkenin boşta kaldığını ve ses tonu sözleşmesinin nasıl denetleneceğini bir matris üzerinde hesaplar.
İlerlemeni kaydetmek ve not almak için Giriş yap
Notlarım
Not almak için giriş yapmalısın.