---
title: 'Anahtar Başarım Göstergeleri'
source: 'https://academia.sh/tr/kurslar/gorsellestirme-ve-raporlama/anahtar-basarim-gostergeleri'
course: 'Görselleştirme, Raporlama ve Ölçekli Analiz'
language: tr
updated: '2026-08-17T18:08:49+00:00'
license: 'CC BY-SA 4.0'
---

# Anahtar Başarım Göstergeleri

Bir ölçütün oynatılabilirliği sayılır: yüzde 60,948 olan okuma kapsama oranı, ölçüm ağında tek bir okuma değişmeden altı yoldan denenir ve beşi oynama eşiğini aşar — payda daraltma 64,286, sıfır okumayı sayma 63,055, pencere genişletme 81,791, yuvarlama 61,000, hedefe oranlama 93,766. Altı maddelik yeniden tanım eşiği aşan yol sayısını 5'ten 0'a indirir; eşiği aşmayan yol kapanmış sayılmaz, çünkü 0,037 puanlık oynaması tanımdan değil bölge boylarından gelir. Ölçüm ağında 106 okuma gerçekten kaybolduğunda sıkı tanım 60,948'den 53,273'e iner, gevşek tanımın altı yolundan ikisi aynı düşüşte sayıyı düşüş öncesi değerin üstünde tutar.

Önceki ders on iki ölçütü verilmiş kabul etti ve yalnız sayfadaki yerlerini ölçtü. Ölçütlerden
biri, eksik okuma oranı, üç kararın ikisini besliyordu. Bir sayı karar üretmeye başladığı andan
itibaren yeni bir özellik kazanır: onu rapor eden kişi, **ölçtüğü şeye hiç dokunmadan** sayıyı
oynatabilir.

Bu dersin ölçüsü **oynatılabilirliktir (gameability)**: bir ölçüt, ölçtüğü şeyi hiç oynatmadan kaç
yoldan ve kaç puan oynatılabiliyor. Ölçüt tasarımının kendisi burada kurulmaz. Hata bütçesi, servis
düzeyi göstergesi ve işletim ölçütlerinin seçimi Sistem Güvenilirliği, Sistem Yönetimi ve DevOps
kurslarında kuruldu; burada tek bir ölçüt alınır ve yalnız tanımının ne kadar gevşek olduğu
sayılır.

- **RP7.** Küme K03'ten devralınır ve **kurgudur**: 3.199 satırlık okuma tablosu, 1.329 abone, üç
  dönem, beş bölge. Tohum koda yazılıdır.
- **RP8.** Ölçüt de **kurgudur**: **okuma kapsama oranı**, dönem 3'te sıfırdan farklı okuması olan
  abonenin dönem başında kayıtlı aboneye oranı.
- **RP9.** Oynatma ölçüm ağına **hiç dokunmaz**: hiçbir okuma eklenmez, silinmez, değiştirilmez.
  Yalnız ölçütün tanımı ya da sunumu değişir.
- **RP10.** Altı yolun her biri tek başına savunulabilir; hiçbiri veri uydurmaz.
- **RP11.** Oynama eşiği **0,05 puandır**. Gerekçesi paydadaki tek bir abonenin 0,075 puan
  etmesidir; eşik bir aboneden küçük her oynamayı eler.
- **RP12.** Ölçüm ağındaki gerçek düşüş de **kurgudur** ve ayrı bir tohumla üretilir.

## Ölçüt

```python
# olcut.py — MODELDIR. K03'un kurgu kumesi ayni tohumla uretilir; uzerine tek bir
# anahtar basarim gostergesi (key performance indicator) kurulur.
import math

TOHUM, HAM, M32 = 20260218, 1400, 0xFFFFFFFF
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


ABONE, ELENEN = [], []
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])
    (ELENEN if r() < 0.046 else ABONE).append(
        {"abone_no": 10001 + i, "bolge": b[0], "taban": b[2]})
GECERLI = {k["abone_no"] for k in ABONE}
OKUMA = {}
for k in ABONE + ELENEN:
    r = uretec(TOHUM + 7000 + k["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(
            k["taban"] * math.exp((r() + r() + r() - 1.5) * 0.62) * (1 - d * 0.05) * 100
            + 0.5) / 100
        if k["abone_no"] in GECERLI:
            OKUMA.setdefault(k["abone_no"], {})[d + 1] = t
        r()

HEDEF = 65.0


def kapsama(donem=3, sifir_sayilir=False, payda_daralt=False, genis=False, kume=None):
    kume = kume if kume is not None else OKUMA
    payda = [k for k in ABONE if not payda_daralt or kume.get(k["abone_no"])]
    pay = 0
    for k in payda:
        o = kume.get(k["abone_no"], {})
        dl = (2, 3) if genis else (donem,)
        if any(d in o and (sifir_sayilir or o[d] > 0.0) for d in dl):
            pay += 1
    return pay / len(payda) * 100, pay, len(payda)


taban, pay0, payda0 = kapsama()
print(f"kurgu kume (tohum {TOHUM}): {len(ABONE)} abone, "
      f"{sum(len(v) for v in OKUMA.values())} okuma")
print(f"olcut — okuma kapsama orani (donem 3): {pay0} / {payda0} = {taban:.3f}")
```

```
kurgu kume (tohum 20260218): 1329 abone, 3199 okuma
olcut — okuma kapsama orani (donem 3): 810 / 1329 = 60.948
```

Ölçütün ölçmek istediği şey tek cümleyle söylenebilir: ölçüm ağı dönem içinde abonelerin ne
kadarına ulaşabildi. Bu cümle bir sayıya çevrilirken en az dört karar veriliyor ve hiçbiri
cümlenin içinde yazılı değil. Kim paydadadır, sıfır bir okuma mıdır, dönem ne zaman kapanır,
sayı kaç ondalıkla yazılır.

## Altı Yol

Her yol bu kararlardan birini gevşetir. Hiçbiri veri uydurmaz, hiçbiri ölçüm ağına dokunmaz ve
her biri bir toplantıda tek cümleyle savunulabilir.

```python

# Alti yol. Hicbiri olcum agina dokunmaz: okuma eklenmez, silinmez, degistirilmez.
# Her yol tanimin ya da sunumun bir maddesini gevsetir ve her biri savunulabilir.
ESIK_PUAN = 0.05
SIKI = {"payda", "sifir", "pencere", "sunum", "toplulastirma", "hedef"}


def bolge_orani(kume):
    o = []
    for b, _, _ in BOLGE:
        alt = [k for k in ABONE if k["bolge"] == b]
        o.append(sum(1 for k in alt if kume.get(k["abone_no"], {}).get(3, 0.0) > 0.0)
                 / len(alt) * 100)
    return sum(o) / len(o)


def yollar(kume, sabit=frozenset()):
    t = kapsama(kume=kume)[0]
    y = [("payda daraltma", "payda", kapsama(kume=kume, payda_daralt=True)[0], "%"),
         ("sifir okumayi okuma saymak", "sifir",
          kapsama(kume=kume, sifir_sayilir=True)[0], "%"),
         ("pencere genisletme (donem 2 ya da 3)", "pencere",
          kapsama(kume=kume, genis=True)[0], "%"),
         ("tam sayiya yuvarlama", "sunum", float(round(t)), "%"),
         ("agirliksiz bolge ortalamasi", "toplulastirma", bolge_orani(kume), "%"),
         ("hedefe oranlayarak sunmak", "hedef", t / HEDEF * 100, "hedefin %'i")]
    return [(ad, md, t if md in sabit else v, br) for ad, md, v, br in y]


print(f"taban olcut {taban:.3f}, hedef {HEDEF:.0f}. Paydadaki tek abone "
      f"{100 / payda0:.3f} puan ettigi icin oynama esigi {ESIK_PUAN} puandir.\n")
print(f"{'yol':<38}{'rapora yazilan':>15}{'oynama':>9}  birim")
for ad, md, v, br in yollar(OKUMA):
    print(f"{ad:<38}{v:>15.3f}{v - taban:>9.3f}  {br}")
bir = kapsama(sifir_sayilir=True, payda_daralt=True, genis=True)
print(f"{'ilk uc yol birlikte':<38}{bir[0]:>15.3f}{bir[0] - taban:>9.3f}  "
      f"%   ({bir[1]} / {bir[2]})")
```

```
taban olcut 60.948, hedef 65. Paydadaki tek abone 0.075 puan ettigi icin oynama esigi 0.05 puandir.

yol                                    rapora yazilan   oynama  birim
payda daraltma                                 64.286    3.338  %
sifir okumayi okuma saymak                     63.055    2.107  %
pencere genisletme (donem 2 ya da 3)           81.791   20.843  %
tam sayiya yuvarlama                           61.000    0.052  %
agirliksiz bolge ortalamasi                    60.985    0.037  %
hedefe oranlayarak sunmak                      93.766   32.818  hedefin %'i
ilk uc yol birlikte                            87.381   26.433  %   (1101 / 1260)
```

Ölçüm ağında tek bir okuma değişmeden aynı ölçüt yüzde 60,948 ile yüzde 93,766 arasında herhangi
bir yerde raporlanabiliyor. Yolların savunulabilirliği de gerçektir. Hiç okuması olmayan 69
aboneyi paydadan çıkarmak, bu abonelerin sayacına hiç ulaşılamadığı için makul görünür. Sıfır
okuma bir okumadır: sayaç okunmuş, tüketim çıkmamıştır. Dönem 2 ya da 3'te okuması olan aboneye
"ulaşıldı" demek de savunulabilir.

En büyük iki oynama en masum görünen iki yoldan geliyor. Pencere genişletme 20,843 puan, hedefe
oranlama 32,818 puan taşıyor. İkincisi sayının **birimini** değiştiriyor: yazılan 93,766 bir
kapsama oranı değil, hedefin yüzde kaçının gerçekleştiğidir. Aynı satırın altında birim yazmazsa
okuyucu bunu kapsamanın kendisi olarak geri okur.

Yollar birbirini dışlamıyor. İlk üçü birlikte uygulandığında rapora yazılan sayı, aynı birimde
kalarak, 87,381 oluyor: 1.101 abone 1.260 abonede. Üç ayrı toplantıda üç ayrı kişinin verdiği üç
savunulabilir karar, kimse bir şey uydurmadan ölçütü 26,433 puan yukarı taşıyor.

Yolların en zor fark edileni ilkidir ve nedeni önceki dersin kavramında yatıyor. Rapor satırında
yalnız "yüzde 64,286" yazıyorsa okuyucunun elinde payı 810, paydası 1.260 olan bir oranla payı
810, paydası 1.329 olan bir oranı ayırt edecek hiçbir şey yoktur. Oranın geri okunabilmesi
dayanağa değil, **payı ile paydasının yanında durmasına** bağlıdır; ikisi yazılmayan bir oran
kendi tanımını gizler.

## Yeniden Tanım

Yeniden tanım altı maddedir ve her maddesi bir yolu bağlar. Sonra aynı altı yol yeniden denenir.

```python

# Yeniden tanim alti maddedir ve her maddesi bir yolu baglar: payda donem basinda
# kayitli abonedir, sifir okuma okuma sayilmaz, pencere donem 3'te kapanir, oran uc
# ondalikla yazilir, toplulastirma abone agirliklidir, hedefe oranlama yasaktir.
def dene(sabit, kume=OKUMA):
    t = kapsama(kume=kume)[0]
    return [(ad, abs(v - t) > ESIK_PUAN, v) for ad, md, v, br in yollar(kume, sabit)]


gevsek, siki = dene(frozenset()), dene(SIKI)
print(f"{'yol':<38}{'gevsek tanim':>16}{'siki tanim':>12}")
for (ad, ga, gv), (_, sa, sv) in zip(gevsek, siki):
    print(f"{ad:<38}{('oynadi ' + format(gv, '.3f')) if ga else 'oynamadi':>16}"
          f"{('oynadi ' + format(sv, '.3f')) if sa else 'oynamadi':>12}")
kapanmayan = [a for a in gevsek if not a[1]]
print(f"\nesigi asan yol: gevsek tanimda {sum(1 for a in gevsek if a[1])}, "
      f"siki tanimda {sum(1 for a in siki if a[1])} ({len(gevsek)} yol denendi)")
for ad, _, v in kapanmayan:
    print(f"kapanmadi, bu kumede islemedi: {ad} — {abs(v - taban):.3f} puan, "
          f"tek abonenin ettigi {100 / payda0:.3f} puandan kucuk")
```

```
yol                                       gevsek tanim  siki tanim
payda daraltma                           oynadi 64.286    oynamadi
sifir okumayi okuma saymak               oynadi 63.055    oynamadi
pencere genisletme (donem 2 ya da 3)     oynadi 81.791    oynamadi
tam sayiya yuvarlama                     oynadi 61.000    oynamadi
agirliksiz bolge ortalamasi                   oynamadi    oynamadi
hedefe oranlayarak sunmak                oynadi 93.766    oynamadi

esigi asan yol: gevsek tanimda 5, siki tanimda 0 (6 yol denendi)
kapanmadi, bu kumede islemedi: agirliksiz bolge ortalamasi — 0.037 puan, tek abonenin ettigi 0.075 puandan kucuk
```

Eşiği aşan yol sayısı 5'ten 0'a iniyor. Tablodaki asıl uyarı beşinci satırdadır. Ağırlıksız bölge
ortalaması gevşek tanımda da eşiği aşmadı, çünkü bu kümede beş bölgenin kapsama oranları
birbirine yeterince yakın. Bu yolu "kapandı" saymak, sayıyı koruyan şeyin tanım değil bölgelerin
boy dağılımı olduğunu kabul etmek olur. Bölgelerden biri küçülse ya da kapsaması ayrışsa aynı yol
eşiği aşar ve tanımda karşılığı yoksa hiçbir şey onu durdurmaz.

Bu, oynatılabilirlik sayısının nasıl okunacağını da belirler: **denenmiş ve oynamamış bir yol,
kapatılmış bir yol değildir.** Sayılan şey tanımın kaç yolu bağladığıdır, kaç yolun bu koşumda
işlediği değil.

Altı maddenin hepsinin bir tanıma yazılması ölçütü uzatıyor ve bu bir bedeldir. Bir satırlık
"okuma kapsama oranı" ifadesi altı maddelik bir tanıma dönüştüğünde raporun okuyucusu artık ölçütü
tek bakışta geri okuyamaz. Bedelin ödenme biçimi tanımı rapora değil, raporun dayandığı yere
yazmaktır: rapor satırı yalnız pay, payda ve tanım kimliğini taşır.

## Gerçek Düşüş

Sıkı tanımın bir bedeli olabilir: ölçütü oynatılamaz yapmak, onu ölçtüğü şeye de duyarsız
yapıyorsa kazanç yoktur. Bunu ölçmek için ölçüm ağında gerçek bir kayıp üretilir.

```python

# Gercek dusus: donem 3 okumalarinin bir bolumu olcum aginda gercekten kaybolur.
# Bu bir oynatma degil, olculen seyin kendisinin degismesidir.
DUSUK, kayip = {}, 0
for k in ABONE:
    o = dict(OKUMA.get(k["abone_no"], {}))
    if 3 in o and uretec(TOHUM + 91000 + k["abone_no"])() < 0.14:
        del o[3]
        kayip += 1
    DUSUK[k["abone_no"]] = o
yeni = kapsama(kume=DUSUK)[0]
print(f"olcum aginda kaybolan donem 3 okumasi: {kayip}")
print(f"siki tanimin verdigi sayi: {taban:.3f} -> {yeni:.3f}  ({yeni - taban:+.3f} puan)\n")
print(f"{'ayni dususte gevsek tanimin yollari':<38}{'rapora yazilan':>15}"
      f"{'dususten once':>15}  birim")
orten = 0
for ad, md, v, br in yollar(DUSUK):
    orten += 1 if v >= taban else 0
    print(f"{ad:<38}{v:>15.3f}{('ustunde' if v >= taban else 'altinda'):>15}  {br}")
print(f"\nalti yoldan {orten} tanesi ayni gercek dususte sayiyi dusus oncesi degerin "
      f"ustunde tutuyor;\nbiri bunu birimi degistirerek yapiyor")
```

```
olcum aginda kaybolan donem 3 okumasi: 106
siki tanimin verdigi sayi: 60.948 -> 53.273  (-7.675 puan)

ayni dususte gevsek tanimin yollari    rapora yazilan  dususten once  birim
payda daraltma                                 56.190        altinda  %
sifir okumayi okuma saymak                     55.079        altinda  %
pencere genisletme (donem 2 ya da 3)           81.490        ustunde  %
tam sayiya yuvarlama                           53.000        altinda  %
agirliksiz bolge ortalamasi                    53.470        altinda  %
hedefe oranlayarak sunmak                      81.959        ustunde  hedefin %'i

alti yoldan 2 tanesi ayni gercek dususte sayiyi dusus oncesi degerin ustunde tutuyor;
biri bunu birimi degistirerek yapiyor
```

Sıkı tanım kaybı olduğu gibi geçiriyor: 106 okuma kaybolduğunda sayı 60,948'den 53,273'e, yani
7,675 puan iniyor. Oynatılamaz olmak duyarsız olmak değil.

Gevşek tanımın altı yolundan ikisi aynı gerçek düşüşte sayıyı düşüş öncesi değerin üstünde
tutuyor. Pencere genişletme 81,490 yazıyor, çünkü dönem 3'te kaybolan okumaların sahiplerinin
çoğunun dönem 2 okuması duruyor. Hedefe oranlama 81,959 yazıyor. İki rapor da aynı kümeden
çıkıyor, ikisi de doğru hesaplanmış ve biri kapsamanın düştüğünü, öteki yükseldiğini söylüyor.

Ölçütün oynatılabilirliği burada tam anlamını buluyor. Oynatma yalnız iyi bir sayıyı daha iyi
göstermez; **kötü haberi görünmez yapar.** Yedi puanlık gerçek bir kayıp, tanımı gevşek bir
ölçütte hiç raporlanmadan geçebilir.

Dikkat edilmesi gereken bir ayrım daha var. Pencere genişletmenin düşüşü örtmesi bir kötü niyet
belirtisi değildir: dönem 2 okuması duran bir aboneye gerçekten ulaşılmıştır ve o yolu seçen kişi
bunu bilerek yapmak zorunda değildir. Tanım yazılmadığında yol, kimse tercih etmeden de
seçilebilir; ölçütün geçen dönem hangi pencereyle hesaplandığı yazılı olmadığı için bu dönem
başka bir pencere kullanılması fark edilmez. Oynatılabilirlik bir kişilik özelliği değil, tanımın
bir özelliğidir.

## Özet

- Oynatılabilirlik sayılabilir bir niceliktir: ölçüt, ölçtüğü şeye hiç dokunulmadan kaç yoldan ve
  kaç puan oynatılabiliyor.
- Yüzde 60,948 olan kapsama oranı altı yoldan denendiğinde beşi 0,05 puanlık eşiği aşar ve
  rapora yazılan sayı 60,948 ile 93,766 arasında herhangi bir yerde durabilir.
- En büyük iki oynama pencere genişletme (20,843 puan) ile hedefe oranlamadır (32,818 puan);
  ikincisi sayının birimini değiştirir ve birim yazılmazsa okuyucu onu kapsama diye geri okur.
- Altı maddelik yeniden tanım eşiği aşan yolu 5'ten 0'a indirir; eşiği aşmayan yol kapanmış
  sayılmaz, çünkü 0,037 puanlık oynaması tanımdan değil bölgelerin boy dağılımından gelir.
- Yollar birbirini dışlamaz: ilk üçü birlikte uygulandığında sayı aynı birimde kalarak 87,381
  olur (1.101 abone, 1.260 abonede) ve 26,433 puan yukarı taşınır.
- Ölçüm ağında 106 okuma gerçekten kaybolduğunda sıkı tanım 7,675 puan düşer; gevşek tanımın altı
  yolundan ikisi aynı düşüşte sayıyı düşüş öncesi değerin üstünde tutar.

## Sonraki Adım

Bu ders ölçütün tanımını sabitledi, ama tanımın sabitlenmesi sayının sabitlenmesi değildir. Sıkı
tanım "pencere dönem 3'te kapanır" diyor; kapanan pencereye ait bir okuma rapor üretildikten sonra
sisteme girdiğinde aynı tanım aynı kümeye uygulanıp başka bir sayı verir. Rapor bir kaynağın
üstünde durur ve o kaynak rapora ya anlık sorguyla, ya dönemsel bir çekmeyle, ya da önceden
toplanmış bir modelle bağlanır. Sonraki ders üç bağlanma düzenini aynı ölçütle koşturur, aralarındaki
farkı sayar ve rapor veri modelinin hangi soruları sonsuza dek kapattığını gösterir.
