---
title: 'Veri ve Model Sürümleme'
source: 'https://academia.sh/tr/kurslar/mlops-temelleri/veri-ve-model-surumleme'
course: 'MLOps Temelleri'
language: tr
updated: '2026-08-17T18:08:52+00:00'
license: 'CC BY-SA 4.0'
---

# Veri ve Model Sürümleme

Aynı ada verilen iki farklı içeriğin ayrılmasının ölçülmesi: dört teslim aynı `olcum-2026` adı altında 2200, 2180, 2160 ve yine 2200 satır getirdiğinde sürümsüz kurulumda tek bir ad dört koşumun tamamını belirsiz bırakıyor ve üç ayrı sınama sayısı 0,8067, 0,8064 ile 0,8078 aynı adın arkasında duruyor, içerik imzasıyla adlandırıldığında üç ad doğuyor ve belirsiz koşum sıfıra iniyor; model tarafında dört koşumun ağırlığı birebir aynı olduğu için yalnız ağırlığa bakan bir model kimliği dört koşumu tek sürümde topluyor ve ancak veri imzası eklendiğinde üç sürüm ayrılıyor; bedel olarak tarih adlı şema 8740 satır saklarken içerik adlı şema 6540 satır saklıyor ve her teslimde imza için 8740 satır okunuyor; çıktı imzası hattın yuttuğu değişikliği görmüyor, altmış kayıt iki kez geldiğinde kaynak imzası değişirken çıktı imzası ve isabet birebir aynı kalıyor.

Önceki dersin defteri her koşumun kaç satır okuduğunu yazdı. On sekiz koşumun hepsi verisini aynı
yerden okudu ve o yerin adı hiç değişmedi. Defter "2200 satır" yazdığında iki koşumun aynı 2200
satırı okuduğunu varsaydık, ama bu varsayım hiçbir yerde sınanmadı.

Bu ders o varsayımı sınar. Veri soyağacı, yani bir sunum değerinden kaynağa giden bağın kaydı, Veri
Mühendisliğine Giriş kursunda ölçüldü ve burada tekrarlanmaz. Buradaki soru daha dar: bir ad
altındaki içerik değiştiğinde ve ad değişmediğinde, kaç koşum birbirinden ayırt edilemez hâle
geliyor.

- **YU19.** Kurgu üretici veriyi **dört teslimde** getirir. Teslimler sırasıyla 2200, 2180, 2160 ve
  yine 2200 satırdır; dördü de aynı `olcum-2026` adıyla yazılır. **Dördüncü teslim birincinin
  içeriğiyle birebir aynıdır.**
- **YU20.** **Veri sürümü** bir adla bir içeriğin eşleşmesidir. Üç şema karşılaştırılır: **sürümsüz**
  (tek ad, üzerine yazılır), **tarih adlı** (her teslime bir ad) ve **içerik adlı** (ad, içerikten
  üretilen imzayı taşır).
- **YU21.** **İmza** içerikten üretilen kısa bir özettir ve ders içinde yazılır; hiçbir dış kitaplık
  çağrılmaz. İmza bir güvenlik aracı değil, bir **kimlik** aracıdır.
- **YU22.** Taban çizgisi **sürümsüz kurulumdur**: tek ad, üzerine yazılan içerik, geriye dönük
  yeniden üretim yok.
- **YU23.** Ölçülen birimler **ad sayısı**, **belirsiz koşum** ve **saklanan satırdır**. Belirsiz
  koşum, aynı adı taşıyıp o ad altında farklı bir sonuç veren koşumdur.
- **YU24.** Öznitelik kodu bu derste **sabittir**; dört koşum da tam geçmişi görür ve dört basamağa
  yuvarlar. Değişen tek şey **verinin içeriğidir**.
- **YU25.** Etiket dağılımı `{0: 1752, 1: 448}`, **taban sınıf oranı 0,7964**'tür ve bu dersteki
  isabet sayıları bir başarım iddiası taşımaz. Çözünürlük **0,0017**'dir.

## Aynı Adın Altındaki İçerik

İlk blok önceki iki dersin kurgu kaynağını, hattını ve modelini aynen yeniden kurar.

```python
# KURGUDUR. Sayac okumalari, hat ve model ders icinde tanimlanir; gercek bir
# ogrenme kitapligi ya da model kayit defteri urunu cagrilmaz.
TOHUM, M32 = 20260218, 0xFFFFFFFF


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


BOLGE = ["dogu", "bati", "kuzey", "guney", "merkez"]
TIP = ["mesken", "isyeri"]
DONEM = [f"2026-{a:02d}" for a in range(1, 13)]
ABONE = {}
for i in range(200):
    r = uretec(TOHUM + 37 * i)
    ABONE[f"A{i + 1:03d}"] = {"bolge": BOLGE[int(r() * 5)], "tip": TIP[int(r() * 2)],
                              "baslangic": 10000 + int(r() * 60000)}


def kaynak_uret():
    kayit = []
    for i, (ab, a) in enumerate(ABONE.items()):
        e = a["baslangic"]
        for d in DONEM:
            r = uretec(TOHUM + 101 * i + 7 * DONEM.index(d))
            e += 4 + int(r() * 46)
            kayit.append({"abone": ab, "donem": d, "bolge": a["bolge"], "tip": a["tip"],
                          "endeks": e, "birim": "m3"})
    return kayit


def a1_ayikla(kayit):
    ZOR = ("abone", "donem", "bolge", "endeks", "birim")
    tut = [k for k in kayit if all(a in k for a in ZOR)]
    return tut, len(kayit) - len(tut)


def a2_tekille(kayit):
    gor, tut = set(), []
    for k in kayit:
        ad = (k["abone"], k["donem"])
        if ad in gor:
            continue
        gor.add(ad)
        tut.append(k)
    return tut, len(kayit) - len(tut)


def a3_tuketim(kayit):
    tablo = {(k["abone"], k["donem"]): k for k in kayit}
    cikti, dusen = [], 0
    for k in kayit:
        i = DONEM.index(k["donem"])
        if i == 0:
            continue
        onceki = tablo.get((k["abone"], DONEM[i - 1]))
        if onceki is None:
            dusen += 1
            continue
        try:
            f = int(k["endeks"]) - int(onceki["endeks"])
        except (TypeError, ValueError):
            dusen += 1
            continue
        cikti.append(dict(k, m3=f))
    return cikti, dusen


EGITIM = DONEM[1:9]
SINAMA = DONEM[9:]
ESIK = 40


def satirlar():
    v, _ = a1_ayikla(kaynak_uret())
    v, _ = a2_tekille(v)
    v, _ = a3_tuketim(v)
    return v


def etiket(k):
    return 1 if k["m3"] > ESIK else 0


def oznitelikler(kayitlar, pencere=None, basamak=4):
    """Agirliktan bagimsizdir , bir kez hesaplanir."""
    sirali = sorted(kayitlar, key=lambda k: DONEM.index(k["donem"]))
    ab, bo = {}, {}
    for k in sirali:
        ab.setdefault(k["abone"], []).append((DONEM.index(k["donem"]), k["m3"]))
        bo.setdefault(k["bolge"], []).append((DONEM.index(k["donem"]), k["m3"]))

    def ortalama(dizi, i):
        secili = [v for d, v in dizi if (d < i and (pencere is None or d >= i - pencere))]
        return round(sum(secili) / len(secili), basamak) if secili else 0.0

    oz = {}
    for k in kayitlar:
        i = DONEM.index(k["donem"])
        oz[(k["abone"], k["donem"])] = {
            "abone_ort": ortalama(ab[k["abone"]], i),
            "bolge_ort": ortalama(bo[k["bolge"]], i),
            "isyeri": 1 if k["tip"] == "isyeri" else 0}
    return oz


IZGARA = [(a, b, c) for a in (0.6, 0.8, 1.0) for b in (0.0, 0.2, 0.4) for c in (0, 4, 8)]


def puan(o, w):
    return w[0] * o["abone_ort"] + w[1] * o["bolge_ort"] + w[2] * o["isyeri"]


def egit(kayitlar, oz, izgara=None, esik=ESIK, donemler=None):
    izgara = IZGARA if izgara is None else izgara
    donemler = EGITIM if donemler is None else donemler
    kume = [k for k in kayitlar if k["donem"] in donemler]
    en_iyi, en_iyi_w = -1.0, None
    for w in izgara:
        d = sum(1 for k in kume
                if (1 if puan(oz[(k["abone"], k["donem"])], w) > esik else 0) == etiket(k))
        o = d / len(kume)
        if o > en_iyi:
            en_iyi, en_iyi_w = o, w
    return {"agirlik": en_iyi_w, "egitim_isabeti": round(en_iyi, 4),
            "aday": len(izgara), "egitim_satiri": len(kume)}


def sina(kayitlar, model, oz, esik=ESIK, donemler=None):
    donemler = SINAMA if donemler is None else donemler
    kume = [k for k in kayitlar if k["donem"] in donemler]
    d = sum(1 for k in kume
            if (1 if puan(oz[(k["abone"], k["donem"])], model["agirlik"]) > esik else 0)
            == etiket(k))
    return round(d / len(kume), 4)
```

Dört teslim aşağıdaki blokta koşturulur. Her teslimde aynı kod aynı adla veriyi okur, modeli eğitir
ve sonucu `tuketim-esigi` adıyla yazar. `imza` içerikten kısa bir özet üretir ve şimdilik yalnız
raporlanır; hiçbir karara girmez.

```python
S = satirlar()


def imza(metin):
    """Icerikten uretilen kisa bir ozet. Guvenlik degil , kimlik araci."""
    h = 2166136261
    for c in metin:
        h = ((h ^ ord(c)) * 16777619) & 0xFFFFFFFF
    return f"{h:08x}"


def veri_imzasi(kayitlar):
    return imza("|".join(f"{k['abone']}:{k['donem']}:{k['m3']}" for k in kayitlar))


TESLIM = [2200, 2180, 2160, 2200]
KOSUM = []
for no, n in enumerate(TESLIM, start=1):
    kay = S[:n]
    oz = oznitelikler(kay)
    m = egit(kay, oz)
    KOSUM.append({"kosum": no, "veri_adi": "olcum-2026", "satir": n,
                  "veri_imza": veri_imzasi(kay), "model_adi": "tuketim-esigi",
                  "agirlik": m["agirlik"], "sinama": sina(kay, m, oz)})
print(f"{'teslim':<8}{'veri adi':<13}{'satir':>7}{'veri imzasi':>13}"
      f"{'model adi':>15}{'agirlik':>17}{'sinama':>9}")
for k in KOSUM:
    print(f"{k['kosum']:<8}{k['veri_adi']:<13}{k['satir']:>7}{k['veri_imza']:>13}"
          f"{k['model_adi']:>15}{str(k['agirlik']):>17}{k['sinama']:>9.4f}")
print()
print("ayri sinama sayisi:", len(set(k["sinama"] for k in KOSUM)),
      " ayri agirlik:", len(set(k["agirlik"] for k in KOSUM)),
      " ayri veri icerigi:", len(set(k["veri_imza"] for k in KOSUM)))
```

```
teslim  veri adi       satir  veri imzasi      model adi          agirlik   sinama
1       olcum-2026      2200     bd88a253  tuketim-esigi    (0.6, 0.4, 0)   0.8067
2       olcum-2026      2180     f008c71c  tuketim-esigi    (0.6, 0.4, 0)   0.8064
3       olcum-2026      2160     cebfcc57  tuketim-esigi    (0.6, 0.4, 0)   0.8078
4       olcum-2026      2200     bd88a253  tuketim-esigi    (0.6, 0.4, 0)   0.8067

ayri sinama sayisi: 3  ayri agirlik: 1  ayri veri icerigi: 3
```

Tablo iki sütununda hiç değişmez: veri adı dört satırda da `olcum-2026`, model adı dört satırda da
`tuketim-esigi`. Bir sütununda da hiç değişmez: ağırlık dört koşumda da `(0.6, 0.4, 0)`, yani
üretilen model dosyası **birebir aynıdır**. Değişen iki sütun vardır: içerik imzası üç ayrı değer
alır ve sınama isabeti üç ayrı sayı verir.

## Adın Kaç İçeriği Var

Sayılacak şey artık nettir. Bir adlandırma şeması, aynı adı taşıyıp farklı sonuç veren koşum
bırakıyorsa o koşumlar **belirsizdir**: hangi içerikten geldikleri addan okunamaz.

```python
def olc(kimlik):
    """Kac ad var , kac kosum belirsiz kaliyor , kac satir saklaniyor."""
    grup = {}
    for k in KOSUM:
        grup.setdefault(kimlik(k), []).append(k)
    belirsiz = sum(len(v) for v in grup.values() if len(set(x["sinama"] for x in v)) > 1)
    return len(grup), belirsiz, sum(v[-1]["satir"] for v in grup.values())


print(f"{'sema':<14}{'veri adi':>10}{'belirsiz kosum':>16}{'saklanan satir':>16}")
for ad, kim in (("surumsuz", lambda k: k["veri_adi"]),
                ("tarih adli", lambda k: f"{k['veri_adi']}@t{k['kosum']}"),
                ("icerik adli", lambda k: f"{k['veri_adi']}@{k['veri_imza']}")):
    a, b, s = olc(kim)
    print(f"{ad:<14}{a:>10}{b:>16}{s:>16}")
print()
print(f"{'model kimligi':<26}{'ayri surum':>12}{'belirsiz kosum':>16}")
for ad, kim in (("yalniz agirlik", lambda k: imza(str(k["agirlik"]))),
                ("veri imzasi + agirlik", lambda k: imza(f"{k['veri_imza']}|{k['agirlik']}"))):
    a, b, _ = olc(kim)
    print(f"{ad:<26}{a:>12}{b:>16}")
print()
print("imza icin okunan satir:", sum(TESLIM))
```

```
sema            veri adi  belirsiz kosum  saklanan satir
surumsuz               1               4            2200
tarih adli             4               0            8740
icerik adli            3               0            6540

model kimligi               ayri surum  belirsiz kosum
yalniz agirlik                       1               4
veri imzasi + agirlik                3               0

imza icin okunan satir: 8740
```

Sürümsüz kurulumda tek bir ad vardır ve **dört koşumun dördü de belirsizdir**. Bu satır kursun
kuralının veri tarafındaki hâlidir: 0,8078 sayısı bir rapora girdiğinde onu üreten içerik artık
yoktur, çünkü dördüncü teslim üçüncünün üzerine yazmıştır. Saklanan satır sütunu bunu doğrular:
sürümsüz şema en az yeri tutar, **2200 satır**, ve karşılığında geçmişin tamamını kaybeder.

Tarih adlı şema belirsizliği sıfıra indirir, ama bir kusuru vardır: dört ad üretir, oysa üç içerik
vardır. Birinci ve dördüncü teslim **birebir aynı içeriktir** ve tarih şeması bunu göremediği için
aynı 2200 satırı iki kez saklar. İçerik adlı şema aynı belirsizliği **üç adla** ve **6540 satırla**
karşılar; dördüncü teslim hiç yeni yer tutmaz, çünkü imzası zaten defterdedir.

## İmza Neyi İmzalar

`veri_imzasi` hattın **çıktısını** imzalar, yani abone, dönem ve hesaplanmış tüketim üçlüsünü. Bu
bir seçimdir ve bedeli vardır: hattın yuttuğu bir üretici değişikliği çıktı imzasına hiç yansımaz.
Aşağıdaki blok bunu ölçer. Üretici, temmuz ayında altmış kaydı iki kez göndersin; kaynak değişmiştir
ama tekilleştirme aşaması yinelenen satırları düşürür.

```python
def kaynak_imzasi(kayitlar):
    return imza("|".join(f"{k['abone']}:{k['donem']}:{k['endeks']}" for k in kayitlar))


def hatta_ver(kaynak):
    v, _ = a1_ayikla(kaynak)
    v, _ = a2_tekille(v)
    v, _ = a3_tuketim(v)
    return v


ham = kaynak_uret()
# Uretici 60 kaydi iki kez gonderdi: kaynak degisti , hat onu yutuyor.
yinelenen = ham + [dict(k) for k in ham if k["abone"] <= "A060" and k["donem"] == "2026-07"]
print(f"{'teslim':<12}{'kaynak satiri':>15}{'kaynak imzasi':>15}"
      f"{'cikti satiri':>14}{'cikti imzasi':>14}{'sinama':>9}")
for ad, kaynak in (("saglam", ham), ("yinelenen", yinelenen)):
    c = hatta_ver(kaynak)
    oz2 = oznitelikler(c)
    m2 = egit(c, oz2)
    print(f"{ad:<12}{len(kaynak):>15}{kaynak_imzasi(kaynak):>15}{len(c):>14}"
          f"{veri_imzasi(c):>14}{sina(c, m2, oz2):>9.4f}")
print()
print(f"{'teslim':<8}{'satir':>7}{'sinama satiri':>15}{'cozunurluk':>12}")
for n in TESLIM[:3]:
    sk = [k for k in S[:n] if k["donem"] in SINAMA]
    print(f"{n:<8}{n:>7}{len(sk):>15}{1 / len(sk):>12.4f}")
```

```
teslim        kaynak satiri  kaynak imzasi  cikti satiri  cikti imzasi   sinama
saglam                 2400       d501f04f          2200      bd88a253   0.8067
yinelenen              2460       93576832          2200      bd88a253   0.8067

teslim    satir  sinama satiri  cozunurluk
2200       2200            600      0.0017
2180       2180            594      0.0017
2160       2160            588      0.0017
```

Kaynak imzası değişti, çıktı imzası **birebir aynı** kaldı ve isabet de aynı. İki teslimin sürüm
kaydı aynı satırı gösterir, oysa üreticiden gelen içerik farklıdır. Bu, hattın **doğru** davranışıdır
ve sürümlemenin bir sınırıdır: çıktı imzası hattın yuttuğu değişikliği görmez. Ters yönde de eksiktir;
kaynağı imzalayan bir şema burada bir sürüm farkı işaretler, oysa modele giden veri hiç değişmemiştir.
İki imza iki ayrı soruyu yanıtlar ve **hangisinin tutulduğu yazılmadan** bir veri sürümü eksik
kalır.

Alt tablo bir başka ayrıntıyı kapatır. Teslim küçüldükçe sınama kümesi de küçülür: 600, 594 ve 588
satır. Üç teslimde çözünürlük 0,0017'de kalır, ama karşılaştırılan sayılar **aynı kümede** ölçülmüş
değildir. 0,8067 ile 0,8064 arasındaki fark bu yüzden bir başarım farkı olarak okunamaz.

## Modelin Kimliği Ağırlığından İbaret Değildir

Alt tablo dersin en sessiz bulgusunu taşır. Model dosyası dört koşumda da aynıdır, dolayısıyla
modeli **kendi içeriğine göre** adlandıran bir şema dört koşumu **tek bir sürümde** toplar ve
dördünü de belirsiz bırakır. Bu, veri tarafındaki hatanın aynadaki görüntüsüdür: orada bir ad üç
içeriği örtüyordu, burada bir içerik üç sayıyı örtüyor.

Dört model dosyası birbirinin yerine konabilir görünür, çünkü aynı ağırlıkları taşırlar. Yerlerine
konamazlar: her biri farklı bir veri kümesinde ölçülmüştür ve bildirdikleri sayı 0,8067, 0,8064 ve
0,8078'dir. Aradaki 0,0014 ile 0,0011 fark çözünürlüğün altında değildir, çünkü sınama kümesinin
boyu da teslimle birlikte değişmiştir. Ağırlığa veri imzası eklendiğinde kimlik **üç sürüme** ayrılır
ve belirsiz koşum **0**'a iner. Bir model sürümü, model dosyasının değil, **model dosyasıyla onu
üreten veri sürümünün** birlikte imzasıdır.

## Sürümlemenin Bedeli ve Söylemediği

Bedel üç kalemdir. Birincisi **saklanan satırdır**: içerik adlı şema 6540 satır tutar, sürümsüz
şemanın **2,97 katı**. İkincisi **okunan satırdır**: imza içerikten hesaplandığı için her teslimde
bütün satırlar bir kez daha okunur, dört teslimde **8740 satır**. Üçüncüsü **eklenen adımdır**:
yazma işlemi artık imza hesaplamak ve defter satırı eklemek zorundadır.

Bunun karşılığında alınan şey dar ve kesindir: sürümleme **hangi içeriğin hangi sayıyı ürettiğini**
söyler. Söylemediği şeyse hangi içeriğin **doğru** olduğudur. Üç teslimden hangisinin eksik geldiğini,
hangisinin tam olduğunu ve 0,8078 sayısının güvenilir olup olmadığını üç imza da söylemez; onu
söyleyen şey Veri Mühendisliğine Giriş kursunda ölçülen denetimlerdir. Sürümleme bir kalite aracı
değil, bir **kimlik aracıdır** ve katkısı yalnız belirsiz koşum sayısıyla ölçülür.

## Özet

- Dört teslim aynı `olcum-2026` adıyla 2200, 2180, 2160 ve yine 2200 satır getirdi; ad hiç
  değişmedi, içerik **üç ayrı imza** aldı ve sınama isabeti **0,8067**, **0,8064** ile **0,8078**
  oldu.
- Sürümsüz şemada tek ad vardır ve **dört koşumun dördü de belirsizdir**; içerik adlı şemada **üç
  ad** vardır ve belirsiz koşum **0**'dır.
- Tarih adlı şema belirsizliği aynı şekilde kapatır ama **dört ad** üretip **8740 satır** saklar;
  içerik adlı şema aynı işi **üç ad** ve **6540 satırla**, yani sürümsüz şemanın **2,97 katıyla**
  yapar, çünkü dördüncü teslimin birinciyle aynı olduğunu görür.
- Çıktı imzası hattın yuttuğu değişikliği görmez: altmış kayıt iki kez geldiğinde kaynak imzası
  değişir, **çıktı imzası ve isabet birebir aynı kalır**. Hangi imzanın tutulduğu yazılmadan bir
  veri sürümü eksik kalır.
- Model dosyası dört koşumda da birebir aynıdır. Yalnız ağırlığa bakan bir model kimliği dört koşumu
  **tek sürümde** toplar; veri imzası eklendiğinde **üç sürüm** ayrılır ve belirsiz koşum **0** olur.
- Sürümleme hangi içeriğin hangi sayıyı ürettiğini söyler, hangisinin **doğru** olduğunu söylemez;
  o soru denetimlerin işidir.

## Sonraki Adım

Üç derste koşumun kendisi kayda geçti ve sürümlendi: hangi kalemlerle koşulduğu yazıldı, hangi
içeriği okuduğu bir imzaya bağlandı ve aynı adın arkasındaki üç içerik birbirinden ayrıldı. Bütün
bu iş **eğitim tarafında** yapıldı. Modele giren özniteliğin eğitim sırasında bir kodla, üretimde
çağrıldığında **başka bir kodla** hesaplanıyor olabileceği hiç sorulmadı. Sonraki ders o iki yolu
yan yana koyar ve tek bir soruyu ölçer: ağırlıklar birebir aynıyken isabet neden düşüyor.
