---
title: 'Veri Analitiği Nedir'
source: 'https://academia.sh/tr/kurslar/veri-analitigine-giris/veri-analitigi-nedir'
course: 'Veri Analitiğine Giriş'
language: tr
updated: '2026-08-17T18:08:46+00:00'
license: 'CC BY-SA 4.0'
---

# Veri Analitiği Nedir

Tek bir abone tablosundan 'etkin abone sayısı' üç savunulabilir tanımla hesaplanıyor ve üç ayrı sayı çıkıyor: sözleşme kaydı etkin olan 3 849, son 30 günde okuma gönderen 3 548, sözleşmesi açık olan 4 211. İlk iki tanımın toplamları yalnız 301 fark ediyor ama 645 abone üzerinde anlaşmıyorlar; tek serbest sayı olan pencere 14 günden 90 güne açıldığında sayı 1 859'dan 3 750'ye çıkıyor. Hiçbir hesap değişmedi, yalnız tanım değişti.

Bir rapordaki sayının nereden geldiği sorulduğunda verilen ilk cevap çoğunlukla hesabı anlatır:
hangi satırlar toplandı, hangi bölme yapıldı. Bu müfredat başka bir yere bakar. Bir sayı çoğu
zaman hesap yüzünden değil, hesap başlamadan önce alınmış bir **tanım kararı** yüzünden o
değerdedir. Hesap doğru yapılmış olabilir ve sayı yine de başka bir sayı olabilirdi.

Veri analitiği, bir soruyu veriyle cevaplanabilir duruma getirme ve çıkan sayıyı bir karara
bağlama işidir. Bu dersin ölçtüğü şey zincirin ilk halkasıdır: bir soru ölçülebilir kılınırken
alınan kararlar sayıyı ne kadar oynatıyor. Ölçü birimi **farktır** — aynı veriden, aynı soruya,
iki savunulabilir kararla kaç farklı sayı çıkıyor.

- **AK1.** Veri kümesi bir **bölgesel ölçüm ağının** abone kayıtlarıdır: su sayaçlarından okuma
  toplayan, okumaları faturaya çeviren ve saha ekibine iş emri açan bir ağ. Ağ da kayıtlar da
  **kurgudur**; aşağıdaki bütün sayılar bir modelin çıktısıdır, ölçülmüş bir kurulumun değil.
- **AK2.** Tablo hazırdır ve bu kursta **veri kümesi** olarak kullanılır. Şema tasarımı,
  normalizasyon ve sorgu yazımı Veritabanı Temelleri kursunda kuruldu; burada tekrarlanmaz.
- **AK3.** Ölçüm günü **0**'dır. Adı `Gun` ile biten her alan o günden geriye sayılan gün
  sayısıdır: `sonOkumaGun` 4 ise sayaç dört gün önce okuma göndermiştir.
- **AK4.** Sayaçların okuma döngüsü modelde aylıktır. Bir sayacın 30 gün boyunca hiç okuma
  göndermemesi olağan değildir; 14 gün göndermemesi olağandır.
- **AK5.** Sözleşme durumu üç değer alır: `etkin`, `askida`, `kapali`. Bu alan **kayıt
  sisteminin** durumudur; sayacın davranışıyla arasında zorunlu bir bağ yoktur.
- **AK6.** Soru şudur: **ağda kaç etkin abone var.** Soru bu haliyle bir hesap değil, bir tanım
  isteğidir.

## Ham Kayıtta Ne Var

Soruyu cevaplamadan önce elde ne olduğuna bakılır. Aşağıdaki blok kümeyi kurar ve tek bir çapraz
tablo basar: sözleşme durumu ile sayacın son okuma zamanı. İkisi arasındaki uyuşmazlık dersin geri
kalanının kaynağıdır.

```js
// kume.mjs — bolgesel olcum aginin abone kayitlari; MODELDIR, kayitlar kurgudur.
// 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 };
});

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} satir, ${Object.keys(KAYITLAR[0]).length} alan`);
  console.log("alanlar: " + Object.keys(KAYITLAR[0]).join(", ") + "\n");
  const y = gen([12, 9, 11, 11, 11]);
  console.log(y(["sozlesme", "abone", "0-30 gun", "31-90 gun", "90+ gun"]));
  for (const s of ["etkin", "askida", "kapali"]) {
    const l = KAYITLAR.filter((k) => k.sozlesme === s);
    console.log(y([s, l.length, l.filter((k) => k.sonOkumaGun <= 30).length,
      l.filter((k) => k.sonOkumaGun > 30 && k.sonOkumaGun <= 90).length,
      l.filter((k) => k.sonOkumaGun > 90).length]));
  }
  const t = (f) => KAYITLAR.filter(f).length;
  console.log(y(["toplam", ABONE, t((k) => k.sonOkumaGun <= 30),
    t((k) => k.sonOkumaGun > 30 && k.sonOkumaGun <= 90), t((k) => k.sonOkumaGun > 90)]));
}
```

```
tohum 20260601: 4800 satir, 10 alan
alanlar: i, bolge, basamak, baglantiGun, kapanisGun, sozlesme, sonOkumaGun, tuketim, ucret, destek

sozlesme        abone   0-30 gun  31-90 gun    90+ gun
etkin            3849       3376         88        385
askida            362        121         55        186
kapali            589         51         59        479
toplam           4800       3548        202       1050
```

Tablo dört köşesiyle okunur. Sol üst köşe beklenen durumdur: sözleşmesi etkin olan 3 376 abonenin
sayacı son 30 gün içinde okuma göndermiştir. Sağ üst köşe beklenmeyendir: sözleşmesi etkin olan
385 abonenin sayacı 90 günden uzun süredir susmaktadır. Sol alt köşe de beklenmeyendir: sözleşmesi
kapalı olan 51 abonenin sayacı son 30 gün içinde okuma göndermiştir.

Bu iki köşe bir veri hatası değildir; ikisinin de olağan bir açıklaması vardır. Susan sayaç arızalı
olabilir ya da konut boş olabilir. Kapalı sözleşmeden okuma gelmesi, kapanış kaydının işlenmesiyle
sayacın sökülmesi arasında geçen süredir. **Kayıt sistemi ile fiziksel dünya farklı hızlarda
ilerler** ve tablo ikisini ayrı sütunlarda tutar.

Soru bu tabloya sorulduğunda cevap tek değildir, çünkü "etkin abone" sözü hangi sütuna
bakılacağını söylemez.

## Üç Tanım, Üç Sayı

Aşağıdaki blok aynı kümeye üç tanımı ayrı ayrı uygular ve sonuçları yan yana basar. Üçü de
savunulabilir tanımlardır: birincisi kayıt sistemine, ikincisi sayacın davranışına, üçüncüsü
sözleşmenin hukuki durumuna bakar.

```js
// etkin.mjs — ayni ham kumeden "etkin abone sayisi": uc savunulabilir tanim yan yana.
import { KAYITLAR, ABONE, TOHUM } from "./kume.mjs";

const TANIM = [
  { ad: "A: sozlesme kaydi etkin", f: (k) => k.sozlesme === "etkin" },
  { ad: "B: 30 gunde okuma var", f: (k) => k.sonOkumaGun <= 30 },
  { ad: "C: sozlesme acik", f: (k) => k.sozlesme !== "kapali" },
];
const gen = (B) => (h) => h.map((v, j) => (j ? String(v).padStart(B[j])
  : String(v).padEnd(B[0]))).join("");

const S = TANIM.map((t) => new Set(KAYITLAR.filter(t.f).map((k) => k.i)));
const y = gen([26, 8, 10]);
console.log(`tohum ${TOHUM}: ${ABONE} abone kaydi, tek tablo, tek olcum gunu\n`);
console.log(y(["tanim", "abone", "% kayit"]));
TANIM.forEach((t, a) => console.log(y([t.ad, S[a].size,
  ((100 * S[a].size) / ABONE).toFixed(1)])));

const z = gen([10, 9, 11, 11, 13]);
console.log("\n" + z(["cift", "fark", "yalniz ilk", "yalniz son", "anlasmazlik"]));
for (const [a, b] of [[0, 1], [2, 0], [2, 1]]) {
  const i1 = [...S[a]].filter((i) => !S[b].has(i)).length;
  const i2 = [...S[b]].filter((i) => !S[a].has(i)).length;
  console.log(z([`${"ABC"[a]} - ${"ABC"[b]}`, S[a].size - S[b].size, i1, i2, i1 + i2]));
}

// B tanimindaki tek serbest sayi pencere uzunlugudur; okuma dongusu aylik oldugu icin
// 30 gunden kisa pencere sayacin hic gonderemedigi bir sikligi sorar.
const w = gen([9, 9, 12]);
console.log("\n" + w(["pencere", "abone", "A'ya oran"]));
for (const p of [14, 21, 30, 45, 60, 90]) {
  const n = KAYITLAR.filter((k) => k.sonOkumaGun <= p).length;
  console.log(w([`${p} gun`, n, (n / S[0].size).toFixed(2)]));
}
```

```
tohum 20260601: 4800 abone kaydi, tek tablo, tek olcum gunu

tanim                        abone   % kayit
A: sozlesme kaydi etkin       3849      80.2
B: 30 gunde okuma var         3548      73.9
C: sozlesme acik              4211      87.7

cift           fark yalniz ilk yalniz son  anlasmazlik
A - B           301        473        172          645
C - A           362        362          0          362
C - B           663        714         51          765

pencere      abone   A'ya oran
14 gun        1859        0.48
21 gun        2733        0.71
30 gun        3548        0.92
45 gun        3602        0.94
60 gun        3654        0.95
90 gun        3750        0.97
```

Üç tanım üç sayı verdi: 3 849, 3 548 ve 4 211. Aradaki en büyük fark 663 abonedir, kayıtların
yüzde 13,8'i. Hiçbir hesap değişmedi — üç tanım da tek bir süzme işlemidir ve hiçbiri diğerinden
daha karmaşık değildir. Değişen tek şey hangi sütuna bakıldığıdır.

İkinci tablo daha önemli bir şey yazıyor. A ile B'nin toplamları yalnız **301** fark ediyor, ama
iki tanımın **anlaşmadığı abone sayısı 645**. 473 abone yalnız A'da, 172 abone yalnız B'de. Toplam
fark küçük görünüyor çünkü iki yönlü anlaşmazlığın büyük bölümü birbirini götürüyor. **Toplamların
yakın olması, iki tanımın aynı kişileri saydığı anlamına gelmez.** Bir raporda "iki yöntem de
yaklaşık aynı sonucu veriyor" cümlesi yazılacaksa, ölçülmesi gereken şey toplamların farkı değil,
kayıt düzeyindeki anlaşmazlıktır.

## Pencere de Bir Karardır

B tanımı bir sayı içeriyor: 30 gün. Bu sayı veriden gelmedi, seçildi. Üçüncü tablo seçimin
bedelini yazıyor: pencere 14 güne indirildiğinde etkin abone 1 859'a düşüyor, 90 güne açıldığında
3 750'ye çıkıyor. Aynı tablo, aynı soru, aynı hesap; sonuç iki katından fazla oynuyor.

Pencerenin her değeri savunulabilir değildir. AK4 okuma döngüsünün aylık olduğunu söylüyor; 14
günlük pencere, sayacın göndermesi beklenmeyen bir sıklığı ölçüt yapar ve etkin abonelerin yarısını
susmuş sayar. 90 günlük pencere ise ters yöne düşer: üç ay boyunca hiç okuma göndermemiş bir sayacı
etkin sayar. 30 ile 60 arasındaki değerler sonucu yalnız 106 abone oynatıyor — yani bu aralıkta
tanım sağlamdır. **Bir eşiğin savunulabilirliği, sonucun o eşik etrafında ne kadar oynadığına
bakılarak ölçülür.** Eşiği 14'ten 21'e taşımak sayıyı 874 abone oynatıyor; 45'ten 60'a taşımak 52
abone. İlk bölge kırılgan, ikinci bölge kararlı.

## Sıralama da Oynar

Bir raporda tek bir toplam nadiren durur. Toplamın yanında bir kırılım olur ve birileri o
kırılımın en üstündeki satıra göre iş yapar: önce hangi bölgeye gidilecek, bütçe önce nereye
verilecek. Tanım kararı toplamı oynatıyorsa sıralamayı da oynatır.

```js
// bolge.mjs — tanim karari yalniz toplami degil siralamayi da oynatir: bes bolge, iki tanim.
import { KAYITLAR, BOLGE } from "./kume.mjs";

const oran = (l, f) => l.filter(f).length / l.length;
const sat = BOLGE.map((b) => {
  const l = KAYITLAR.filter((k) => k.bolge === b);
  return { b, n: l.length, a: oran(l, (k) => k.sozlesme === "etkin"),
    c: oran(l, (k) => k.sonOkumaGun <= 30) };
});
// Sira 1 = en dusuk oran, yani raporda "once bakilacak" bolge.
const sira = (alan) => new Map([...sat].sort((x, y) => x[alan] - y[alan])
  .map((s, i) => [s.b, i + 1]));
const sA = sira("a"), sB = sira("c");

const gen = (B) => (h) => h.map((v, j) => (j ? String(v).padStart(B[j])
  : String(v).padEnd(B[0]))).join("");
const y = gen([9, 8, 10, 8, 10, 8, 8]);
console.log(y(["bolge", "abone", "A orani", "A sira", "B orani", "B sira", "kayma"]));
for (const s of sat) {
  console.log(y([s.b, s.n, s.a.toFixed(4), sA.get(s.b), s.c.toFixed(4), sB.get(s.b),
    sB.get(s.b) - sA.get(s.b)]));
}
const ilk = (alan) => [...sat].sort((x, y2) => x[alan] - y2[alan]);
const yay = (alan) => Math.max(...sat.map((s) => s[alan])) - Math.min(...sat.map((s) => s[alan]));
console.log(`\nA tanimiyla ilk bakilacak bolge ${ilk("a")[0].b}, B tanimiyla ${ilk("c")[0].b}`);
console.log(`B'de ilk iki bolgeyi ayiran fark ${(ilk("c")[1].c - ilk("c")[0].c).toFixed(4)}, ` +
  `bes bolgenin tum yayilimi ${yay("c").toFixed(4)}`);
```

```
bolge       abone   A orani  A sira   B orani  B sira   kayma
kuzey         929    0.7976       3    0.7277       3       0
guney         913    0.7985       4    0.7240       1      -3
dogu          999    0.8248       5    0.7648       5       0
bati          969    0.7905       1    0.7245       2       1
merkez        990    0.7970       2    0.7525       4       2

A tanimiyla ilk bakilacak bolge bati, B tanimiyla guney
B'de ilk iki bolgeyi ayiran fark 0.0005, bes bolgenin tum yayilimi 0.0408
```

Listenin başı değişti: A tanımıyla ilk bakılacak bölge batı, B tanımıyla güney. Merkez iki sıra
yukarı kaydı, güney üç sıra aşağı. Doğu her iki tanımda da en iyi bölge kaldı — kayma her satırda
olmuyor, ama karar verilen satırda oluyor.

Nedeni son satırda yazılı. Beş bölgenin oranı B tanımında yalnız 0,0408 aralığa yayılıyor. İki
tanım arasındaki fark ise ağ genelinde 6,3 puandır — ikinci tablodaki yüzde 80,2 ile yüzde 73,9
arasındaki fark. **Gruplar arası fark, tanım değişikliğinin ürettiği kaymadan küçükse sıralama
bölgelerin değil tanımın bir özelliğidir.** B tanımında ilk iki bölgeyi ayıran fark 0,0005;
güneyde tek bir sayacın okuma göndermesi (661 yerine 662) sıralamayı ters çevirir. Saha ekibini bu
listenin başına göre yönlendirmek, bir yuvarlama farkına göre yönlendirmektir.

## Kararı Yazılmayan Sayı

Bu dersin ürettiği sayı 3 548'dir: son 30 gün içinde okuma göndermiş abone sayısı. Yanında üç
karar durur ve üçü de yazılmadan sayı raporlanamaz:

- **Hangi sütun ölçüt.** Sayacın davranışı ölçüt alındı, sözleşme kaydı değil. Gerekçe: soru "kaç
  aboneye fatura kesilebilir" sorusuna hizmet ediyorsa okuma olmadan fatura da olmaz.
- **Pencere 30 gün.** Gerekçe: okuma döngüsü aylıktır ve sonuç 30 ile 60 arasında 106 abone
  oynuyor, yani seçim bu aralıkta sonucu belirlemiyor.
- **Sözleşme durumu süzülmedi.** Sözleşmesi kapalı 51 abone, okuma gönderdiği için sayının içinde
  kaldı. Gerekçe: fatura kesilebilirlik sorusunda bunlar da sayılır; kapanışın işlenmemiş olması
  ayrı bir sorundur.

Bu üç satır yazılmadığında geriye 3 548 sayısı kalır ve o sayı bir bulgu değil, bir seçimdir.
**Kararı yazılmayan sayı ölçülmemiş sayılır.** Bu kural müfredat boyunca sürecek ve her derste
aynı biçimde uygulanacak: rapor edilen sayı, onu üretirken alınan kararlar, kararı değiştirince
ortaya çıkan fark.

Buradan çıkan ikinci sonuç daha rahatsız edicidir. "Veri konuşur" diye bir şey yoktur. Bu tabloda
üç doğru sayı vardır ve hiçbiri diğerini yanlışlamaz; hangisinin raporlanacağını belirleyen şey
veri değil, sorunun ne için sorulduğudur. Aynı tablodan bir sayaç değiştirme listesi çıkarılacaksa
A ile B'nin anlaşmadığı 645 abone hedeftir; bir fatura kesimi yapılacaksa B'dir; bir sözleşme
sayımı raporlanacaksa C. Analitiğin işi bu üç sayıdan birini seçmek değil, hangisinin hangi soruya
karşılık geldiğini yazmaktır.

## Özet

- Veri analitiği bir soruyu ölçülebilir duruma getirme işidir; sayı çoğu zaman hesap sırasında
  değil, tanım sırasında belirlenir.
- Tek bir abone tablosundan "etkin abone" üç savunulabilir tanımla üç ayrı sayı verir: 3 849
  (sözleşme kaydı etkin), 3 548 (son 30 günde okuma var), 4 211 (sözleşme açık).
- Toplamların yakınlığı anlaşmayı göstermez: A ile B'nin toplam farkı 301, ama kayıt düzeyinde
  anlaşmadıkları abone sayısı 645.
- Tanımın içindeki eşik de bir karardır; pencere 14 günden 90 güne açıldığında sayı 1 859'dan
  3 750'ye çıkar. Eşiğin savunulabilirliği sonucun o eşik etrafındaki oynaklığıyla ölçülür.
- Tanım kararı sıralamayı da oynatır: ilk bakılacak bölge A tanımıyla batı, B tanımıyla güneydir
  ve B'de ilk iki bölgeyi tek bir sayacın okuması ayırır.
- Bir sayının yanında hangi kararla üretildiği yazılmıyorsa o sayı bir bulgu değil bir seçimdir;
  kararı yazılmayan sayı ölçülmemiş sayılır.

## Sonraki Adım

Bu ders tek bir soruyu ölçülebilir duruma getirdi: **kaç etkin abone var.** Sorunun kendisi
sorgulanmadı. Oysa aynı tabloya sorulabilecek sorular tek bir çeşit değildir. "Kaç abone var"
sorusu geçmişi anlatır; "abone sayısı neden düştü" sorusu bir neden ister; "gelecek çeyrekte kaç
abone olacak" sorusu bir tahmin ister; "hangi aboneye önce gidilmeli" sorusu bir eylem önerir.
Dördü de aynı tabloya sorulabilir, ama dördü aynı veriyle cevaplanamaz. Sonraki ders bu dört soru
çeşidini ayırır ve bir soru kümesinde kaçının eldeki kümeyle cevaplanabildiğini sayar.
