---
title: 'Yeniden Üretilebilir Hazırlama'
source: 'https://academia.sh/tr/kurslar/veri-hazirlama/yeniden-uretilebilir-hazirlama'
course: 'Veri Toplama ve Hazırlama'
language: tr
updated: '2026-08-17T18:08:45+00:00'
license: 'CC BY-SA 4.0'
---

# Yeniden Üretilebilir Hazırlama

Kursun on yedi hazırlama adımı veri olarak yazılır: 39 karar, üç konuya 13'er kalem. Adımların ölçtüğü sessiz kayıp toplamı 4.614 kayıttır ve bunun yalnız 69'u benimsenen hatta gerçekleşmiştir; kalan 4.545 kayıt seçilmeyen yaygın kararın ölçülmüş bedelidir. Üç adım parametresini betikten değil koşum ortamından alır ve aynı veriyle iki koşum üçünde de farklı sonuç verir; hattın 17 adımının 14'ü yeniden üretilebilirken değerler betiğe yazılınca 17'si yeniden üretilebilir olur. Kararın geri okunabilirliği hücrelerde 32'de 7 (yüzde 22) iken betikte defter tutulmadan 39'da 36, koşum defteriyle 39'da 39'a çıkar.

On yedi adımda küme hazırlandı ve her adımda giren, çıkan ve kaybolan satır sayıldı — ama bu
sayımlar o dersin içinde kaldı, hiçbiri bir yerde toplu durmuyor. Aynı kümeyi ikinci kez
hazırlayan biri hangi eşiğin seçildiğini, hangi sıralamanın kullanıldığını ya da hangi tohumla örnek
çekildiğini bulamaz.

Elektronik Tablolarla Analiz kursu bu soruyla kapanmıştı: otuz iki kararın yalnız yedisi geri
okunabiliyordu, çünkü kararlar hücrelere gömülüydü. Betik yazmak bunun cevabı gibi görünür ve kısmen
öyledir. Bu ders betiğin **nerede yetmediğini** ölçer: kaç adım aynı veriden aynı sonucu veriyor ve
kaç karar koşumdan sonra okunabiliyor.

- **VD25.** Bir hazırlama hattı, adımların **verisi** yazıldığında belgelenmiş olur: her adımın adı,
  kararları ve satır hesabı. Betiğin kendisi bu kaydın yerine geçmez.
- **VD26.** Bir adım, sonucunu belirleyen bütün değerler betikte yazılıysa **yeniden üretilebilir**.
  Değerlerden biri **koşum ortamından** geliyorsa aynı betik aynı veriden başka bir sonuç çıkarır ve
  fark hiçbir yerde görünmez.

## Hattı Veri Olarak Yazmak

```js
// hat.mjs — MODELDIR: kursun on yedi hazirlama adimi veri olarak yaziliyor.
// "s" alani o dersin olctugu sessiz kayiptir — uyari uretmeden dusen ya da
// bozulan kayit — ve kendi dersinden okundu. "p" adimin kararlaridir; degeri
// "ortam" olan kararlar betikte yazili degildir, kosum aninda disaridan gelir.
export const HAT = [
  { n: 1, k: "toplama", ad: "dosya bicimleri", s: 142,
    p: { ayrac: ";", tirnak: "korunur", kodlama: "utf-8" } },
  { n: 2, k: "toplama", ad: "veritabanindan cekme", s: 766,
    p: { birim: "abone-donem", birlestirme: "tekil anahtar" } },
  { n: 3, k: "toplama", ad: "arayuzlerden toplama", s: 512,
    p: { sayfalama: "imlec", kapsam: "tum donemler", hiz: "sinira uyan sira" } },
  { n: 4, k: "toplama", ad: "yapisal ayristirma", s: 1877,
    p: { secici: "anlamsal", denetim: "kaynak toplami" } },
  { n: 5, k: "toplama", ad: "ornekleme", s: 0,
    p: { yontem: "tabakali", boy: 200, tohum: "ortam" } },
  { n: 6, k: "temizleme", ad: "eksik degerler", s: 100,
    p: { eksik: "bos + bosluk + yok", karar: "doldur" } },
  { n: 7, k: "temizleme", ad: "yinelenen kayitlar", s: 0,
    p: { anahtar: "kirpilmis sayac kodu", olcut: "kesin eslesme" } },
  { n: 8, k: "temizleme", ad: "tip donusumleri", s: 465,
    p: { sayi: "bicim once taninir", tarih: "bicim once taninir" } },
  { n: 9, k: "temizleme", ad: "aykiri degerler", s: 0,
    p: { yontem: "ceyrekler acikligi", carpan: "ortam", karar: "ayri defter" } },
  { n: 10, k: "temizleme", ad: "kategorik duzeltme", s: 216,
    p: { anahtar: "sadelestirilmis", eslesme: "tarife cetveli" } },
  { n: 11, k: "temizleme", ad: "metin normallestirme", s: 36,
    p: { basamak: "dort basamak", kucultme: "dile duyarli" } },
  { n: 12, k: "donusturme", ad: "birlestirme", s: 69,
    p: { tur: "ic", anahtar: "abone_no + donem" } },
  { n: 13, k: "donusturme", ad: "yeniden sekillendirme", s: 103,
    p: { bicim: "genis", bos: "atlanir" } },
  { n: 14, k: "donusturme", ad: "gruplama", s: 0,
    p: { kirilim: "bolge", ozet: "ortalama + yayilim" } },
  { n: 15, k: "donusturme", ad: "turetilmis degiskenler", s: 328,
    p: { turetme: "kisi basi + degisim", tanimsiz: "sebebiyle sayilir" } },
  { n: 16, k: "donusturme", ad: "kategorik kodlama", s: 0,
    p: { bolge: "sirasiz kodlama", memnuniyet: "sirali", siralama: "ortam" } },
  { n: 17, k: "donusturme", ad: "hazirlama defteri", s: 0,
    p: { defter: "her adim", olcu: "giren + cikan + sessiz" } },
];
export const KARAR = HAT.reduce((a, x) => a + Object.keys(x.p).length, 0);
export const ORTAM = HAT.flatMap((x) => Object.entries(x.p)
  .filter(([, v]) => v === "ortam").map(([k]) => `${x.n}.${k}`));
export const gen = (w) => (h) => h.map((v, j) => (j ? String(v).padStart(w[j])
  : String(v).padEnd(w[0]))).join("");

if (import.meta.url === `file://${process.argv[1]}`) {
  console.log(`hat defteri: ${HAT.length} adim, ${KARAR} karar, ${ORTAM.length} karar ` +
    `kosum ortamindan geliyor (${ORTAM.join(", ")})`);
  const y = gen([14, 9, 15, 16]);
  console.log("\n" + y(["konu", "adim", "karar sayisi", "sessiz kayip"]));
  for (const k of [...new Set(HAT.map((x) => x.k))]) {
    const l = HAT.filter((x) => x.k === k);
    console.log(y([k, l.length, l.reduce((a, x) => a + Object.keys(x.p).length, 0),
      l.reduce((a, x) => a + x.s, 0)]));
  }
  const S = HAT.reduce((a, x) => a + x.s, 0);
  console.log(y(["toplam", HAT.length, KARAR, S]));
  console.log(`\nsessiz kaybin dokumu (adim: kayit)`);
  console.log("  " + HAT.filter((x) => x.s > 0).map((x) => `${x.n}:${x.s}`).join("  "));
  const gercek = HAT[11].s;
  console.log(`toplam ${S} kayit, en buyuk kalem adim 4 (${HAT[3].s}); bunun ${gercek} kaydi ` +
    `benimsenen hatta gercekten dustu, kalan ${S - gercek} kayit secilmeyen yaygin kararin ` +
    `olculmus bedelidir`);
}
```

```
hat defteri: 17 adim, 39 karar, 3 karar kosum ortamindan geliyor (5.tohum, 9.carpan, 16.siralama)

konu               adim   karar sayisi    sessiz kayip
toplama               5             13            3297
temizleme             6             13             817
donusturme            6             13             500
toplam               17             39            4614

sessiz kaybin dokumu (adim: kayit)
  1:142  2:766  3:512  4:1877  6:100  8:465  10:216  11:36  12:69  13:103  15:328
toplam 4614 kayit, en buyuk kalem adim 4 (1877); bunun 69 kaydi benimsenen hatta gercekten dustu, kalan 4545 kayit secilmeyen yaygin kararin olculmus bedelidir
```

Hattın kendisi burada bir tablo. On yedi adımın her biri bir ad, bir sessiz kayıp kalemi ve bir karar
kümesi taşıyor; kararlar toplam **39** ediyor ve üç konuya 13'er dağılıyor. Biçimin tek amacı var:
adımı çalıştıran kod ile adımın **kararı** ayrı ayrı okunabilsin.

Döküm satırı kursun toplamını veriyor. On yedi adımın ölçtüğü sessiz kayıp **4.614 kayıttır**; en
büyük kalem dördüncü adımdır, çünkü sayfaya bir sütun eklenince hiçbir seçici kırılmaz ve 1.877
kaydın hepsi yanlış alandan okunur. Sayının önemli bir ayrımı var: **4.614'ün yalnız 69'u benimsenen
hatta gerçekten düştü** — iç birleştirmenin hiç göstermediği aboneler. Kalan 4.545 kayıt, o adımda
yaygın olan kararın **ölçülmüş bedelidir** ve o karar seçilmediği için gerçekleşmedi. Biri hattın
gerçek kaybı, öteki kaybın yazılmış olması sayesinde alınmayan riskin büyüklüğüdür.

## Aynı Betik, İki Koşum

```js
// kosum.mjs — hattin ortamdan beslenen uc adimi iki kez kosturulur. Ayni veri,
// ayni kod, iki kosum. Sonra ayni uc adim betige yazilmis degerlerle kosturulur.
import { HAT, KARAR, ORTAM, gen } from "./hat.mjs";

const uretec = (t) => { let s = (Math.imul(t ^ 0x9e3779b9, 2246822507) >>> 0);
  return () => (s = (s * 1664525 + 1013904223) >>> 0) / 4294967296; };
// Kucuk bir model kume; kurgudur ve yalnizca uc adimi kosturmak icin var.
// Her 97. okumada ondalik noktasi kaymis, her 41. okumada yuksek bir deger var.
const r0 = uretec(20260218), KUME = [];
for (let i = 0; i < 600; i++) {
  const t = Math.round((6 + r0() * 46) * 100) / 100;
  KUME.push({ okuma: i % 97 === 0 ? t * 10 : i % 41 === 0 ? t * 2.2 : t,
    bolge: ["kuzey", "guney", "dogu"][Math.floor(r0() * 3)] });
}

const ort = (a) => a.reduce((x, y) => x + y, 0) / a.length;
const ADIM = [
  ["5 ornekleme", (l, o) => { const r = uretec(o.tohum);
    return l.map((x) => ({ x, u: r() })).sort((a, b) => a.u - b.u)
      .slice(0, 200).map((a) => a.x); }],
  ["9 aykiri ayirma", (l, o) => { const v = l.map((x) => x.okuma).sort((a, b) => a - b);
    const q = (t) => v[Math.floor(t * (v.length - 1))], a1 = q(0.25), a3 = q(0.75);
    const ac = a3 - a1;
    return l.filter((x) => x.okuma >= a1 - o.carpan * ac && x.okuma <= a3 + o.carpan * ac); }],
  ["16 kodlama esigi", (l, o) => { const a = [...new Set(l.map((x) => x.bolge))];
    const d = o.siralama === "alfabetik" ? [...a].sort() : a;
    const k = Object.fromEntries(d.map((x, j) => [x, j + 1]));
    return l.filter((x) => k[x.bolge] >= 2); }],
];
const kostur = (o) => ADIM.map(([ad, f]) => { const c = f(KUME, o);
  return { ad, satir: c.length, ort: ort(c.map((x) => x.okuma)) }; });

// Ortam iki kosumda farkli: tohum saatten, carpan bir yapilandirmadan, siralama
// kategori adlarinin geldigi kaynaktan geliyor. Ucu de betikte yazili degil.
const R1 = kostur({ tohum: 4711, carpan: 1.5, siralama: "alfabetik" });
const R2 = kostur({ tohum: 8123, carpan: 3.0, siralama: "ilk gorulme" });
const ESIK = 0.0005; // m3; iki ortalama bu esikten yakinsa ayni sayilir
const ayni = (a, b) => a.satir === b.satir && Math.abs(a.ort - b.ort) < ESIK;

const y = gen([19, 10, 13, 10, 13, 9]);
console.log(`ayni veri (${KUME.length} satir), ayni kod, iki kosum:`);
console.log("\n" + y(["adim", "R1 satir", "R1 ortalama", "R2 satir", "R2 ortalama", "ayni mi"]));
R1.forEach((a, j) => console.log(y([a.ad, a.satir, a.ort.toFixed(3), R2[j].satir,
  R2[j].ort.toFixed(3), ayni(a, R2[j]) ? "evet" : "hayir"])));

// Duzeltme: uc deger de betige yazilir, ortam artik okunmuyor.
const SABIT = { tohum: 4711, carpan: 1.5, siralama: "alfabetik" };
const D1 = kostur(SABIT), D2 = kostur(SABIT);
const tutan = D1.filter((a, j) => ayni(a, D2[j])).length;
const onceki = R1.filter((a, j) => ayni(a, R2[j])).length;
console.log(`\nortamdan beslenen ${ADIM.length} adimin ${onceki} tanesi iki kosumda ayni; ` +
  `degerler betige yazilinca ${tutan} tanesi ayni. Hattin ${HAT.length} adiminin ` +
  `${HAT.length - ADIM.length + onceki} tanesi duzeltmeden once, ${HAT.length} tanesi ` +
  `duzeltmeden sonra yeniden uretilebiliyor`);

// Geri okunabilirlik: kararin degeri kosumdan sonra bir yerden okunabiliyor mu.
const pay = (a, b) => `${a}/${b} (yuzde ${(100 * a / b).toFixed(0)})`;
console.log(`\ngeri okunabilen karar — yalniz hucrelerde ${pay(7, 32)}, betikte defter ` +
  `tutulmadan ${pay(KARAR - ORTAM.length, KARAR)}, kosum defteriyle ${pay(KARAR, KARAR)}`);
console.log(`okunamayan uc karar ortamdan gelenlerdir; defter tutulmazsa kosumdan sonra ` +
  `hicbir yerden okunamaz`);
```

```
ayni veri (600 satir), ayni kod, iki kosum:

adim                 R1 satir  R1 ortalama  R2 satir  R2 ortalama  ayni mi
5 ornekleme               200       31.886       200       32.361    hayir
9 aykiri ayirma           590       29.468       593       29.806    hayir
16 kodlama esigi          404       31.965       391       32.968    hayir

ortamdan beslenen 3 adimin 0 tanesi iki kosumda ayni; degerler betige yazilinca 3 tanesi ayni. Hattin 17 adiminin 14 tanesi duzeltmeden once, 17 tanesi duzeltmeden sonra yeniden uretilebiliyor

geri okunabilen karar — yalniz hucrelerde 7/32 (yuzde 22), betikte defter tutulmadan 36/39 (yuzde 92), kosum defteriyle 39/39 (yuzde 100)
okunamayan uc karar ortamdan gelenlerdir; defter tutulmazsa kosumdan sonra hicbir yerden okunamaz
```

Üst tablo betiğin tek başına neden yetmediğini gösteriyor. Üç adımın parametresi betikte yazılı
değil: örneklemenin tohumu saatten, aykırı ayırmanın çarpanı bir yapılandırmadan, kodlamanın
sıralaması kategori adlarının geldiği kaynaktan geliyor. Kod iki koşumda aynı, veri de aynı 600
satır; sonuç üçünde de farklı.

Farkların biçimi ayrı. Örnekleme iki koşumda da 200 satır çeker ve ortalamayı 31,886 ile 32,361 m³
arasında oynatır: **satır sayısı hiç değişmez**, bu yüzden satır sayısına bakan bir denetim hiçbir
şey görmez. Aykırı ayırma 590 ile 593 satır bırakır. Kodlama eşiği 404 ile 391 satır seçer — bu, bir
önceki dersin bulgusunun hattaki karşılığıdır ve sıralama kararı ortamdan geldiği için artık
**seçildiği bile görünmez**.

Hattın on yedi adımının **14'ü** düzeltmeden önce, **17'si** üç değer betiğe yazılınca yeniden
üretilebiliyor. Düzeltme bir yeniden yazma değil, üç sayının koddan okunur hale getirilmesidir.

Son satır kursun açılışındaki soruyu kapatıyor. Kararlar hücrelerin içindeyken 32 karardan 7'si geri
okunabiliyordu, yüzde 22. Betiğe yazıldığında 39 kararın 36'sı okunabilir olur, yüzde 92. Koşum
defteri tutulduğunda, yani her adım kendi kararlarını ve satır hesabını çıktıya yazdığında oran
**39'da 39** olur. Aradaki fark yeniden üretilebilirliğin durduğu yerdir: **betik ne yapabileceğini
gösterir, defter ne yapıldığını gösterir.**

## Özet

- Bir hazırlama hattı, adımların verisi yazıldığında belgelenir: 17 adım, 39 karar, adım başına bir
  satır hesabı.
- On yedi adımın ölçtüğü sessiz kayıp 4.614 kayıttır; 69'u benimsenen hatta gerçekleşti, 4.545'i
  seçilmeyen yaygın kararın ölçülmüş bedelidir.
- Parametresi koşum ortamından gelen üç adım aynı veriyle iki koşumda farklı sonuç verir;
  örneklemede satır sayısı değişmediği için fark satır denetiminden kaçar.
- Değerler betiğe yazılınca yeniden üretilebilen adım sayısı 14'ten 17'ye çıkar.
- Kararın geri okunabilirliği hücrelerde 32'de 7 (yüzde 22), betikte defter tutulmadan 39'da 36
  (yüzde 92), koşum defteriyle 39'da 39'dur.

## Kurs Kapanışı

On yedi dersin hesabı tek bir tabloda duruyor ve her sayı kendi dersinden okundu.

| Ders | Giren satır | Çıkan satır | Nereye gitti |
|---|---|---|---|
| Toplama 01 dosya biçimleri | 2.076 fiziksel | 2.037 kayıt | naif bölmede 142 sessiz |
| Toplama 02 veritabanından çekme | 1.877 | 1.877 | yanlış birleştirmede 766 sessiz |
| Toplama 03 arayüzlerden toplama | 1.877 | 1.877 | dar kapsamda 477, sayfalamada 35 |
| Toplama 04 yapısal ayrıştırma | 1.877 | 1.877 | 1.877 kayıt yanlış alandan |
| Toplama 05 örnekleme | 1.877 | 200 | 1.677 karar gereği dışarıda, 0 sessiz |
| Temizleme 01 eksik değerler | 2.086 | 2.068 | 18 elendi, 204 dolduruldu |
| Temizleme 02 yinelenen kayıtlar | 2.068 | 1.880 | 188 birleşti, 23 yanlış bağ |
| Temizleme 03 tip dönüşümleri | 1.880 | 1.880 | 0 elendi, yaygında 465 sessiz |
| Temizleme 04 aykırı değerler | 1.880 | 1.816 | 64 ayrı deftere |
| Temizleme 05 kategorik düzeltme | 1.816 | 1.816 | 15 yazım 5 sınıfta |
| Temizleme 06 metin normalleştirme | 1.816 | 1.816 | 1.491 eşleşme kurtarıldı |
| Dönüştürme 01 birleştirme | 3.471 okuma | 3.199 | 169 eşleşmeyen, 103 çift geçen, 69 abone sessiz |
| Dönüştürme 02 yeniden şekillendirme | 3.199 | 1.260 geniş | 581 boş hücre, 103 üzerine yazıldı |
| Dönüştürme 03 gruplama | 3.199 | 5 özet | 3.194 eridi, 7 göz görünmedi |
| Dönüştürme 04 türetilmiş değişkenler | 3.199 | 3.199 | 328 tanımsız, süzgeçte düşer |
| Dönüştürme 05 kategorik kodlama | 3.199 | 3.199 | eşik 2.166 / 1.678 / 1.633 |
| Dönüştürme 06 hazırlama defteri | 3.199 | 3.199 | 39 karar deftere yazıldı |

Bir konunun çıkan satırı sonraki konunun giren satırına eşit değil, çünkü üç konu aynı kurgu ağın
**üç ayrı çekimiyle** çalışır: toplama 1.877 okumayı, temizleme 2.086 satırlık ham çekimi,
dönüştürme üç dönemlik 3.471 okumayı ölçer. Uçtan uca taşınan tek bir sayı değil, **hesabın
kendisidir**.

Kursun kuralı bu tablonun okunma biçimidir: **hazırlama adımlarının toplamı bir hesaptır; giren ile
çıkan arasındaki fark kalem kalem yazılamıyorsa veri hazırlanmamış, yalnız değiştirilmiştir. Kaybını
yazamadığın temizlik bir temizlik değildir.** On yedi dersin ölçtüğü **sessiz kayıp toplamı 4.614
kayıttır** ve bu sayının varlığı bir kusur değil kursun çıktısıdır: yazılmayan bir sessiz kayıp sıfır
görünür.

On yedi derste küme hazırlandı ve her adımın hesabı yazıldı. Ama bütün bu adımlar tek tek, elle
yazılmış küçük kodlarla yapıldı; aynı işi binlerce satırda, tekrarlanabilir ve okunabilir biçimde
yapan bir araç takımı hiç kullanılmadı. Sonraki kurs, Python ile Veri Analizi, elle yazılan her
adımın bir veri çerçevesi arayüzündeki karşılığını ele alır.
