İçeriğe geç
academia.sh

Ders 04 / 09

Analist Rolleri

Tek cümlelik bir soru üç iş tanımına veriliyor ve aynı tablodan üç ayrı çıktı çıkıyor: ölçen rol 90 günde -228 abone (yüzde -5,14), kararı bağlayan rol ücret ölçütüyle yüzde -3,34 ve yüzde -5 eşiğinin altında kaldığı için eylem yok, genelleyen rol bir yıl sonrası için 2 191 ile 3 286 arasında iki tahmin. Abone başına ücret aynı satırlardan yüzde 1,89 artmıştır; üç doğru sayının ikisi düşüş, biri yükseliş gösterir. Bir cümlelik sorunun arkasında 10 yazılı karar durur.

İçindekiler

Önceki ders akışı tek bir kişinin koşturduğunu varsaydı. Gerçekte akışın adımları çoğu zaman farklı işleri olan kişiler arasında bölünür ve bölünme yeri sonucun ne olacağını değiştirir. Aynı soru bir elde bir sayıya, başka bir elde bir eşiğe, üçüncü bir elde bir tahmin aralığına dönüşür.

Bu ders üç iş tanımını ayırır ve üçüne aynı soruyu verir: ağ genelinde abone sayısı düşüyor mu, ne yapmalı. Ölçülen şey, aynı tablodan çıkan üç çıktının ne kadar farklı olduğudur. Rol adları burada unvan değil, iş tanımı olarak ele alınır: bir rolü belirleyen şey adı değil, işinin ne zaman bittiğini söyleyen kabul ölçütüdür.

  • AK17. Kayıtlar birinci dersin kayıtlarıdır: aynı tohum, aynı 4 800 satır, aynı sayılar. Küme kurgudur.
  • AK18. Rol adları iş tanımıdır. Aynı ad başka bir yerde başka bir işi anlatabilir; ölçülen şey ad değil, kabul ölçütüdür — çıktı ne olduğunda iş bitmiş sayılır.
  • AK19. Soru üçüne de tek cümleyle verilir ve üçü de aynı tabloyu okur. Kimseye ek veri verilmez.
  • AK20. Ücret alanı bir ücret birimidir; ölçek modelin ölçeğidir, herhangi bir para birimi değildir.
  • AK21. Karşılaştırma dönemi 90 gün, eylem eşiği yüzde -5’tir. İkisi de karardır ve ikisi de sayı hesaplanmadan önce yazılmıştır.

Üç İş Tanımı

Ölçen iş tanımı (veri analisti), sorulan sayıyı tanımı ve kararlarıyla birlikte teslim ettiğinde biter. Soruyu değiştirmez. Sorulan şeyin doğru soru olup olmadığı bu tanımın dışındadır; bu rolün ürünü bir sayı ve o sayının nasıl üretildiğidir.

Kararı bağlayan iş tanımı (iş analisti), sayı bir eyleme bağlandığında biter. Bunun için sayının bir eşiği ve eşik aşıldığında yapılacak bir şeyi olmalıdır. Bu tanım sorunun ölçütünü değiştirme yetkisini içerir: sorulan büyüklük bir eyleme bağlanamıyorsa, bağlanabilen bir büyüklükle değiştirilir.

Genelleyen iş tanımı (veri bilimci), bulgu gözlenen dönemden görülmemiş bir döneme ya da görülmemiş satırlara taşındığında biter. Taşıma bir varsayım ister ve varsayım çıktının bir parçası olarak teslim edilir; varsayımsız bir genelleme bu tanımda eksik iştir.

Üç tanım da aynı işi yapmıyor ve hiçbiri diğerinin daha gelişmiş bir sürümü değil. Aralarındaki fark yetkinlik farkı değil, işin nerede bittiği farkıdır.

Üçünün Okuduğu Tek Tablo

// seri.mjs — ilk dersin abone kayitlari, ayni tohum ve ayni sayilar; MODELDIR.
// Olcum gunu 0'dir; "gun" ile biten alanlar o gunden geriye sayilan gun sayisidir.
export const TOHUM = 20260601, ABONE = 4800, BOLGE = ["kuzey", "guney", "dogu", "bati", "merkez"];
const uretec = (t) => { let s = t >>> 0;
  return () => (s = (s * 1664525 + 1013904223) >>> 0) / 4294967296; };
const r = uretec(TOHUM);
const sec = (u, d) => { let t = 0; for (const [a, p] of d) { t += p; if (u < t) return a; }
  return d.at(-1)[0]; };

export const KAYITLAR = Array.from({ length: ABONE }, (_, i) => {
  const bolge = BOLGE[Math.floor(r() * 5)];
  const basamak = sec(r(), [[1, 0.46], [2, 0.34], [3, 0.20]]);
  const baglantiGun = 30 + Math.floor(r() * 2900);
  // Kapanis olasiligi en dusuk tarife basamaginda yuksektir ve kapanislar son aylara yigilir.
  const kapanmaP = [0.16, 0.09, 0.05][basamak - 1];
  const kapanisGun = r() < kapanmaP
    ? Math.min(baglantiGun - 1, Math.floor(r() * r() * 420)) : null;
  const askida = kapanisGun === null && r() < 0.085;
  const sozlesme = kapanisGun !== null ? "kapali" : askida ? "askida" : "etkin";
  // Sayacin son okumasindan bu yana gecen gun. Kapali ve askidaki abonelerin bir bolumu
  // hala okuma gonderir; etkin abonelerin bir bolumu (arizali sayac, bos konut) gondermez.
  const g = sozlesme === "etkin" ? (r() < 0.13 ? 31 + Math.floor(r() * 300) : Math.floor(r() * 29))
    : sozlesme === "askida" ? (r() < 0.34 ? Math.floor(r() * 29) : 31 + Math.floor(r() * 250))
    : (r() < 0.11 ? Math.floor(r() * 29) : 31 + Math.floor(r() * 500));
  const tuketim = Math.round((2 + basamak * 4 + r() * 9) * 10) / 10;
  const ucret = Math.round((6 + basamak * basamak * 7) * (0.85 + r() * 0.3));
  return { i, bolge, basamak, baglantiGun, kapanisGun, sozlesme, sonOkumaGun: g,
    tuketim, ucret, destek: r() < 0.22 ? 1 + Math.floor(r() * 3) : 0 };
});

// d gun once sozlesmesi acik olan abone: o tarihte baglanmis ve henuz kapanmamis.
export const acik = (d) => KAYITLAR.filter((k) =>
  k.baglantiGun >= d && (k.kapanisGun === null || k.kapanisGun < d));
export const nokta = (d) => {
  const l = acik(d), u = l.reduce((s, k) => s + k.ucret, 0);
  return { d, n: l.length, u, basina: u / l.length };
};

const gen = (B) => (h) => h.map((v, j) => (j ? String(v).padStart(B[j])
  : String(v).padEnd(B[0]))).join("");

if (import.meta.url === `file://${process.argv[1]}`) {
  console.log(`tohum ${TOHUM}: ${ABONE} abone kaydi; asagidaki seri tek tablodan okunuyor\n`);
  const y = gen([11, 9, 15, 15]);
  console.log(y(["gun once", "abone", "toplam ucret", "abone basina"]));
  for (const d of [90, 60, 30, 0]) {
    const p = nokta(d);
    console.log(y([d, p.n, p.u, p.basina.toFixed(2)]));
  }
}
tohum 20260601: 4800 abone kaydi; asagidaki seri tek tablodan okunuyor

gun once       abone   toplam ucret   abone basina
90              4439         139508          31.43
60              4426         139657          31.55
30              4377         138739          31.70
0               4211         134843          32.02

Dört satır, üç sütun. Sözleşmesi açık abone sayısı 90 günde 4 439’dan 4 211’e iniyor ve düşüş hızlanıyor: ilk 30 günde 13, son 30 günde 166. Toplam ücret aynı yönde ama daha yavaş iniyor. Üçüncü sütun ters yöne gidiyor: abone başına ücret her adımda yükseliyor.

Üç sütun da aynı satırlardan çıktı ve üçü de doğru. Hangisinin “abone sayısı düşüyor mu” sorusunun cevabı olduğu tabloda yazmıyor.

Aynı Sorudan Üç Çıktı

// roller.mjs — ayni soru, ayni tablo, uc is tanimi: uc ayri cikti yan yana.
// Soru: "ag genelinde abone sayisi dusuyor mu, ne yapmali."
import { nokta } from "./seri.mjs";

const P0 = nokta(0), P30 = nokta(30), P90 = nokta(90);
const yuzde = (yeni, eski) => ((100 * (yeni - eski)) / eski).toFixed(2);
const ESIK = -5.0, UFUK = 365;

console.log("rol 1 olcen — soruyu degistirmez; sayiyi ve kararlarini teslim eder");
console.log(`  90 gunde abone ${P90.n} -> ${P0.n}: ${P0.n - P90.n} abone, %${yuzde(P0.n, P90.n)}`);
console.log("  karar: acik sozlesme tanimi, karsilastirma donemi 90 gun, kirilim yok (3)");

console.log("\nrol 2 karari baglayan — olcutu ucrete cevirir ve bir esige baglar");
console.log(`  90 gunde ucret ${P90.u} -> ${P0.u}: ${P0.u - P90.u}, %${yuzde(P0.u, P90.u)}`);
const d = Number(yuzde(P0.u, P90.u));
console.log(`  esik %${ESIK.toFixed(2)}: ${d <= ESIK ? "asildi, eylem gerekir" : "asilmadi, eylem yok"}`);
console.log(`  abone basina ucret ${P90.basina.toFixed(2)} -> ${P0.basina.toFixed(2)}: ` +
  `%${yuzde(P0.basina, P90.basina)}`);
console.log("  karar: olcut ucret, esik yuzde -5, donem 90 gun, kirilim yok (4)");

console.log("\nrol 3 genelleyen — soruyu gelecege tasir; tek sayi teslim etmez");
const surdur = (p) => Math.round(P0.n + ((P0.n - p.n) / p.d) * UFUK);
const a = surdur(P30), b = surdur(P90);
console.log(`  son 30 gunun hiziyla ${UFUK} gun sonra: ${a} abone`);
console.log(`  son 90 gunun hiziyla ${UFUK} gun sonra: ${b} abone`);
console.log(`  iki savunulabilir pencere arasi fark: ${Math.abs(a - b)} abone`);
console.log("  karar: tahmin penceresi, dogrusal surme varsayimi, mevsim verisi yok (3)");

console.log(`\nayni tablodan uc dogru sayi: abone %${yuzde(P0.n, P90.n)}, ` +
  `ucret %${yuzde(P0.u, P90.u)}, abone basina ucret %${yuzde(P0.basina, P90.basina)}`);
console.log("ucu de ayni satirlardan cikiyor; ikisi dususu, biri yukselisi gosteriyor");
rol 1 olcen — soruyu degistirmez; sayiyi ve kararlarini teslim eder
  90 gunde abone 4439 -> 4211: -228 abone, %-5.14
  karar: acik sozlesme tanimi, karsilastirma donemi 90 gun, kirilim yok (3)

rol 2 karari baglayan — olcutu ucrete cevirir ve bir esige baglar
  90 gunde ucret 139508 -> 134843: -4665, %-3.34
  esik %-5.00: asilmadi, eylem yok
  abone basina ucret 31.43 -> 32.02: %1.89
  karar: olcut ucret, esik yuzde -5, donem 90 gun, kirilim yok (4)

rol 3 genelleyen — soruyu gelecege tasir; tek sayi teslim etmez
  son 30 gunun hiziyla 365 gun sonra: 2191 abone
  son 90 gunun hiziyla 365 gun sonra: 3286 abone
  iki savunulabilir pencere arasi fark: 1095 abone
  karar: tahmin penceresi, dogrusal surme varsayimi, mevsim verisi yok (3)

ayni tablodan uc dogru sayi: abone %-5.14, ucret %-3.34, abone basina ucret %1.89
ucu de ayni satirlardan cikiyor; ikisi dususu, biri yukselisi gosteriyor

Birinci rol soruyu olduğu gibi cevaplıyor: 90 günde 228 abone eksildi, yüzde 5,14. Yanında üç karar var. Bu çıktının içinde bir yargı yok — yüzde 5,14’ün kötü olup olmadığını söylemiyor, çünkü söylemek için yazılı bir eşik gerekir ve eşik bu iş tanımının dışındadır.

İkinci rol ölçütü değiştiriyor ve gerekçesini yazıyor: abone sayısı bir eyleme bağlanamaz, çünkü kaybedilen abonelerin ne taşıdığı sayıda görünmez. Ücret ölçütüyle düşüş yüzde 3,34 ve yüzde -5 eşiğinin altında kalıyor; karar “eylem yok”. Üçüncü satır aynı hareketi ters işaretle yazıyor: abone başına ücret yüzde 1,89 yükselmiş. Üç sayının aynı satırlardan çıkıp ayrı yöne gitmesinin nedeni bir sonraki bölümde basılacak.

Burada bir tehlike var ve adı konmalı. Ölçütü değiştirip eşiğin altında kalmak, sayıyı beğenmeyip başka bir sayı aramaktan ancak tek bir şeyle ayrılır: eşik sayıdan önce yazılmışsa bir karardır, sonra yazılmışsa bir gerekçedir. AK21 eşiği hesaptan önce yazdı; bu yüzden ikinci rolün çıktısı savunulabilir. Aynı eşik sonuç görüldükten sonra yüzde -3’e çekilseydi hesap aynı kalır, çıktı bir karar olmaktan çıkardı.

Üçüncü rol tek bir sayı teslim etmiyor ve bu eksiklik değil, iş tanımının gereğidir. Aynı seriden iki savunulabilir tahmin çıkıyor: son 30 günün hızıyla 2 191 abone, son 90 günün hızıyla 3 286. Aradaki fark 1 095 abone — bugünkü sayının dörtte biri. İkisi arasında seçim yapmak için düşüşün mevsimsel mi yoksa süregiden mi olduğunu bilmek gerekir ve elde bunu ayıracak geçmiş yok. İkinci dersin derinlik şartı burada bir soru olarak geri geliyor: dört dönemlik geçmiş bir yıllık dalgayı göstermez. Üçüncü rolün asıl çıktısı bu yüzden bir sayı değil, bir veri isteğidir.

Üç Rolün de Yazmadığı Kırılım

Üç rolün karar listesinde ortak bir satır var: kırılım yok. Üçü de ağ toplamı üzerinden çalıştı, çünkü üçünün de kabul ölçütü toplamla karşılanıyordu. Oysa üç sayının birbirinden neden ayrıldığı tek bir kırılımda yazılı.

// kirilim.mjs — uc rolun de "kirilim yok" yazdigi yer: kaybin tarife basamagina dagilimi.
import { acik } from "./seri.mjs";

const T0 = acik(0), T90 = acik(90);
const say = (l, b) => l.filter((k) => k.basamak === b).length;
const ucr = (l, b) => l.filter((k) => k.basamak === b).reduce((s, k) => s + k.ucret, 0);
const gen = (B) => (h) => h.map((v, j) => (j ? String(v).padStart(B[j])
  : String(v).padEnd(B[0]))).join("");

const y = gen([10, 10, 10, 9, 12, 12, 10]);
console.log(y(["basamak", "90 gun", "bugun", "fark", "ucret 90", "ucret bugun", "ucret f."]));
for (const b of [1, 2, 3]) {
  console.log(y([b, say(T90, b), say(T0, b), say(T0, b) - say(T90, b),
    ucr(T90, b), ucr(T0, b), ucr(T0, b) - ucr(T90, b)]));
}
const dn = T0.length - T90.length;
const d1 = say(T0, 1) - say(T90, 1);
console.log(`\n${dn} abonelik kaybin ${d1} tanesi birinci basamakta: ` +
  `%${((100 * d1) / dn).toFixed(1)}`);
console.log(`birinci basamak abone basina ${(ucr(T90, 1) / say(T90, 1)).toFixed(2)} ucret tasiyor, ` +
  `ucuncu basamak ${(ucr(T90, 3) / say(T90, 3)).toFixed(2)}`);
basamak       90 gun     bugun     fark    ucret 90 ucret bugun  ucret f.
1               2058      1899     -159       26758       24706     -2052
2               1482      1420      -62       50512       48430     -2082
3                899       892       -7       62238       61707      -531

-228 abonelik kaybin -159 tanesi birinci basamakta: %69.7
birinci basamak abone basina 13.00 ucret tasiyor, ucuncu basamak 69.23

Kaybın yüzde 69,7’si birinci tarife basamağında. Birinci basamaktaki bir abone 13,00 ücret birimi taşıyor, üçüncü basamaktaki 69,23 — beş katından fazla. Bu iki sayı üçünü birden açıklıyor: abone sayısı sert düşüyor çünkü kayıp en kalabalık basamakta, toplam ücret daha yavaş düşüyor çünkü o basamak en az ücret taşıyor, abone başına ücret yükseliyor çünkü ortalamadan aşağı çeken satırlar gidiyor.

Kırılımın kendisi de bir karardır ve tarife basamağıyla kırmak tek seçenek değildi; bölgeyle, abone yaşıyla ya da tüketim düzeyiyle kırılsaydı başka bir tablo çıkardı. Ama üç rolün hiçbiri herhangi bir kırılım yazmadı. Bir kabul ölçütü neyi teslim etmeyi zorunlu kılıyorsa o üretilir; zorunlu kılmadığı şey, gerekli olsa bile üretilmez. Üç doğru sayıyı birlikte okunabilir kılan satır, hiçbirinin iş tanımının içinde değildi.

Çıktı Yanlış Rolde Okununca

Üç çıktı da doğru, ama biri diğerinin yerine okunduğunda ortaya yanlış bir cümle çıkar.

Birinci rolün “-228 abone” çıktısı bir karar gibi okunursa, okuyan taraf eksik olan eşiği kendi kafasından tamamlar ve kimsenin yazmadığı bir sınır rapora girmiş olur. İkinci rolün “eşik aşılmadı” çıktısı bir ölçüm gibi okunursa, 228 abonenin gittiği bilgisi kaybolur — o cümle ölçmüyor, bir eşikle karşılaştırıyor. Üçüncü rolün “3 286” sayısı bir ölçüm gibi okunursa, doğrusal sürme varsayımı bir olgu olarak yolculuk etmeye başlar; oysa aynı seri başka bir pencereyle 2 191 verir.

Toplam sayı da bir şey söylüyor. Tek cümlelik bir sorunun arkasında üç rolün yazdığı 10 karar duruyor. Hiçbiri veriyi değiştirmiyor, hepsi sonucu değiştiriyor. Bir raporda üç çıktıdan biri duruyorsa, yanında hangi iş tanımının ürettiği ve hangi kararların yazıldığı da durmalıdır. Aksi halde kursun kuralı işler: kararı yazılmayan sayı ölçülmemiş sayılır.

Özet

  • Üç iş tanımı kabul ölçütleriyle ayrılır: ölçen rol sayıyı ve kararlarını, kararı bağlayan rol sayının bağlandığı eşiği, genelleyen rol varsayımıyla birlikte bir genellemeyi teslim eder.
  • Aynı tablodan üç doğru sayı çıkar: abone yüzde -5,14, toplam ücret yüzde -3,34, abone başına ücret yüzde 1,89. İkisi düşüş, biri yükseliş gösterir.
  • Ölçütü değiştirmek eşik hesaptan önce yazıldıysa bir karardır, sonra yazıldıysa bir gerekçedir; ayrımı yapan tek şey sıradır.
  • Genelleyen rolün iki savunulabilir tahmini 2 191 ile 3 286 arasında, 1 095 abone açıktır; seçimi yapacak geçmiş elde olmadığı için çıktı bir sayı değil bir veri isteğidir.
  • Üç sayının ayrı yöne gitmesinin nedeni tek bir kırılımda yazılıdır: kaybın yüzde 69,7’si en düşük tarife basamağındadır ve üç rolün hiçbirinin kabul ölçütü kırılımı zorunlu kılmaz.
  • Tek cümlelik sorunun arkasında 10 yazılı karar durur; bir çıktı hangi iş tanımından geldiği yazılmadan raporlanamaz.

Sonraki Adım

Bu konu boyunca dört ders aynı şeyi yaptı: soruyu ölçülebilir duruma getirdi, tanımı değiştirip sayının ne kadar oynadığını yazdı. Tablonun kendisi hep verilmiş kabul edildi. Alınan bütün kararlar sorunun tarafındaydı — hangi sütun ölçüt, hangi pencere, hangi eşik, hangi dönem.

Bu dersin son bloğunda bir işlem yapıldı ve hiç sorgulanmadı: ücret alanının ortalaması alındı ve “abone başına ücret” diye raporlandı. Aynı hesap tarife basamağı alanına da uygulanabilirdi ve bir sayı verirdi — basamakların ortalaması. O sayı da hesaplanabilir, yazılabilir, tabloya konabilir ve hiçbir anlamı olmaz. İkisi arasındaki farkı belirleyen şey hesap değil, alanın ne tür bir şey olduğudur. Sözleşme durumu bir sınıf adıdır, tarife basamağı sıralı bir kademedir, ücret ölçülmüş bir niceliktir, abone kimliği sayı gibi görünen bir etikettir. Sonraki konu bu ayrımı kurar ve bir alanın türü yanlış atandığında ortaya çıkan sayıyı gösterir.

İ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