---
title: 'Eksik Değer Stratejileri'
source: 'https://academia.sh/tr/kurslar/oznitelik-muhendisligi/eksik-deger-stratejileri'
course: 'Veri Hazırlama ve Öznitelik Mühendisliği'
language: tr
updated: '2026-08-17T18:10:12+00:00'
license: 'CC BY-SA 4.0'
---

# Eksik Değer Stratejileri

Eksik bir sütun için üç stratejinin ayrılmış kümede ayrı ayrı ölçülmesi: ortanca ile doldurma 0,7619, doldurma ile birlikte eksiklik göstergesi eklemek 0,8333, eksik satırı eğitim kümesinden atmak 0,7659 veriyor ve göstergenin katkısı +0,0714, yani on sekiz abonedir. Gösterge, hiç eksik olmayan sütunun verdiği 0,7778 üst sınırını da 0,0555 geçiyor, çünkü eksikliğin kendisi doldurulan değerin taşımadığı bir bilgi taşıyor: anketi yanıtlamayan abonelerde şüpheli oranı 0,5276, yanıtlayanlarda 0,1383.

Önceki üç derste memnuniyet sütunu her abone için dolu kabul edildi. Ham kayıtta öyle değil.
Memnuniyet bir anket yanıtıdır ve anketi yanıtlamayan abone vardır. Boşluğun ne yapılacağı bir
karardır ve şimdiye kadar o karar hiç görünmedi, çünkü sessizce alındı.

Doldurma yordamının kendisi bu derste kurulmuyor. Eksik değerin bulunması, ortanca ile
doldurulması ve satırın atılması M26'nın Veri Toplama ve Hazırlama kursunda ölçüldü; oradaki ölçü
**kaç satırın etkilendiğiydi**. Buradaki soru başkadır: aynı üç seçenek ayrılmış kümedeki sayıyı
ne kadar oynatıyor ve **eksikliğin kendisi** bir öznitelik midir.

- **HA26.** Anketi yanıtlamama **kurgudur** ve etiketten bağımsız değildir: kaçak ya da arıza
  şüphesi taşıyan aboneler anketi daha seyrek yanıtlar. Kurguya bilerek konmuştur ve bu dersin
  ölçtüğü şeydir.
- **HA27.** Eksiklik yalnız memnuniyet sütunundadır. Öteki on sütun ve etiket eksiksizdir.
- **HA28.** Doldurma değeri **eğitilmiş bir nesnedir**: ortanca yalnız eğitim kümesindeki dolu
  satırlardan hesaplanır ve iki kümeye de o değer uygulanır.
- **HA29.** Doldurma istatistiğinin kendisi bir karardır: ortanca seçildi, çünkü memnuniyet
  sıralayıcı bir ölçekte ölçülür ve o ölçekte ortalama meşru bir özet değildir. Seçim değişirse
  dolan değer de değişir.
- **HA30.** **Eksiklik göstergesi**, satırın o sütununun boş olup olmadığını söyleyen bir ikili
  sütundur. Doldurmanın yerine değil, yanına eklenir.
- **HA31.** Ölçüm kümesi, bölme, model ve taban çizgisi önceki derslerle aynıdır: 756/252/252,
  derinlik 6 karar ağacı, sınama kümesinde 0,7579.
- **HA32.** Eksiksiz sütunla ölçülen sayı bir **üst sınır** olarak basılır: eksiklik hiç
  olmasaydı ne okunurdu. Bu satır bir strateji değil, karşılaştırma çizgisidir.
- **HA33.** Sınama kümesi 252 abonedir, bir abone 0,0040 eder.

## Boşluğun Kendisi Ne Kadar Konuşuyor

Kurulum tabloyu üretir, anket eksikliğini koyar ve iki kümede eksikliğin etiketle ilişkisini basar.

```python
# eksik.py — MODELDIR. Kurgu abone tablosu ayni tohumla uretilir; memnuniyet
# sutunu ham kayittaki gibi KURGU bir anket yaniti olarak eksikli hale getirilir.
import math

TOHUM, ADAY, M32 = 20260218, 1400, 0xFFFFFFFF
BOLGE = [("kuzey", 0.28, 21, 0.00), ("guney", 0.22, 17, -0.10),
         ("dogu", 0.18, 26, 0.30), ("bati", 0.14, 14, -0.05),
         ("merkez", 0.18, 23, 0.05)]


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, OKUMA = [], {}
for i in range(ADAY):
    r = uretec(TOHUM + i)
    b = BOLGE[ayrik(r(), [x[1] for x in BOLGE])]
    hane = 1 + ayrik(r(), [0.06, 0.24, 0.30, 0.24, 0.11, 0.05])
    memnun = 1 + ayrik(r(), [0.08, 0.14, 0.27, 0.34, 0.17])
    if r() >= 0.046:
        ABONE.append({"no": 10001 + i, "bolge": b, "hane": hane, "memnuniyet": memnun})
for k in ABONE:
    r = uretec(TOHUM + 7000 + k["no"])
    for d in range(ayrik(r(), [0.05, 0.12, 0.21, 0.62])):
        OKUMA.setdefault(k["no"], []).append(0.0 if r() < 0.038 else math.floor(
            k["bolge"][2] * math.exp((r() + r() + r() - 1.5) * 0.62)
            * (1 - d * 0.05) * 100 + 0.5) / 100)
        r()

VERI = []
for k in ABONE:
    v = OKUMA.get(k["no"])
    if v is None:
        continue
    ort, oyn, r = sum(v) / len(v), max(v) - min(v), uretec(TOHUM + 51000 + k["no"])
    z = (0.052 * (ort - 20) + 0.85 * (min(v) == 0.0) + 0.026 * oyn
         + 0.24 * (k["hane"] >= 5) - 0.20 * (k["memnuniyet"] >= 4) + k["bolge"][3]
         + 0.9 * (k["no"] - 10001) / 1399 + (r() + r() + r() - 1.5) * 1.30)
    x = {"hane": k["hane"], "memnuniyet": k["memnuniyet"], "donem": len(v),
         "ort_tuketim": round(ort, 2), "oynaklik": round(oyn, 2),
         "sifir_okuma": int(min(v) == 0.0), "supheli": int(z > 1.35)}
    for b in BOLGE:
        x["b_" + b[0]] = int(k["bolge"][0] == b[0])
    VERI.append(x)

ar = uretec(TOHUM + 31000)                  # anketi yanitlamama KURGUDUR
for x in VERI:
    x["anket"] = None if ar() < (0.55 if x["supheli"] else 0.15) else x["memnuniyet"]


def karistir(veri, tohum):
    r, s = uretec(tohum), list(range(len(veri)))
    for i in range(len(s) - 1, 0, -1):
        j = int(r() * (i + 1))
        s[i], s[j] = s[j], s[i]
    return [veri[i] for i in s]


K = karistir(VERI, TOHUM + 90000)
EGT, SIN = K[:756], K[1008:]
TABAN = sum(x["supheli"] == 0 for x in SIN) / len(SIN)
ALAN = ["ort_tuketim", "oynaklik", "hane", "memnuniyet", "donem", "sifir_okuma",
        "b_kuzey", "b_guney", "b_dogu", "b_bati", "b_merkez"]
print(f"{'kume':<8} {'satir':>6} {'eksik':>6} {'eksik orani':>12} "
      f"{'eksiklerde supheli':>19} {'tamlarda':>9}")
for ad, s in (("egitim", EGT), ("sinama", SIN)):
    e = [x for x in s if x["anket"] is None]
    t = [x for x in s if x["anket"] is not None]
    print(f"{ad:<8} {len(s):>6} {len(e):>6} {len(e) / len(s):>12.4f} "
          f"{sum(x['supheli'] for x in e) / len(e):>19.4f} "
          f"{sum(x['supheli'] for x in t) / len(t):>9.4f}")
d = sorted(x["anket"] for x in EGT if x["anket"] is not None)
ORTANCA = d[len(d) // 2]                    # OGRENME: yalniz egitim kumesinden
print(f"egitimden ogrenilen ortanca {ORTANCA}, taban cizgisi {TABAN:.4f}")
```

```
kume      satir  eksik  eksik orani  eksiklerde supheli  tamlarda
egitim      756    163       0.2156              0.5276    0.1383
sinama      252     58       0.2302              0.6207    0.1289
egitimden ogrenilen ortanca 4, taban cizgisi 0.7579
```

Son iki sütun dersin bütün konusudur. Anketi yanıtlamayan abonelerde şüpheli oranı 0,5276,
yanıtlayanlarda 0,1383. Boşluk boş değildir; sütunun **taşıdığı değerden** başka bir şey söyler.
Doldurma kararı bu farkı ya korur ya siler.

Doldurma değerinin kendisi de bir eğitilmiş nesnedir. Eğitim kümesindeki dolu satırların ortancası
4 çıkıyor ve bu tek sayı iki kümeye birden uygulanıyor. Sınama kümesinin kendi ortancasına bakmak
daha "doğru" bir doldurma üretirdi, ama o değeri hesaplamak ayrılmış kümeye bakmak olurdu; ölçekte
kurulan disiplin burada da aynen geçerlidir. Eksiklik oranının iki kümede aynı çıkmaması da
beklenen bir şeydir: eğitimde 0,2156, sınamada 0,2302, ve aradaki fark bölmenin rastgeleliğinden
gelir.

## Üç Strateji, Üç Sayı

Aşağıdaki kod modeli yazar ve beş stratejiyi bir üst sınır satırıyla birlikte ölçer.

```python
def gini(s):
    p = sum(x["supheli"] for x in s) / len(s) if s else 0.0
    return 2 * p * (1 - p)


def agac(s, derinlik, alan, enaz=2):        # MODELDIR: karar agaci, derinlik 6
    p = sum(x["supheli"] for x in s) / len(s)
    en = None
    if derinlik and len(s) >= 2 * enaz and 0.0 < p < 1.0:
        for a in alan:
            d = sorted({x[a] for x in s})
            for v in (d[1:] if len(d) < 10 else
                      [d[int(i * len(d) / 10)] for i in range(1, 10)]):
                sol = [x for x in s if x[a] < v]
                sag = [x for x in s if x[a] >= v]
                if min(len(sol), len(sag)) < enaz:
                    continue
                k = gini(s) - (len(sol) * gini(sol) + len(sag) * gini(sag)) / len(s)
                if en is None or k > en[0]:
                    en = (k, a, v, sol, sag)
    if en is None or en[0] <= 1e-9:
        return {"tahmin": int(p > 0.5)}
    return {"alan": en[1], "esik": en[2], "sol": agac(en[3], derinlik - 1, alan, enaz),
            "sag": agac(en[4], derinlik - 1, alan, enaz)}


def tahmin(d, x):
    while "tahmin" not in d:
        d = d["sol"] if x[d["alan"]] < d["esik"] else d["sag"]
    return d["tahmin"]


def doldur(s, deger):                       # UYGULAMA: bosluga tek bir deger
    return [dict(x, memnuniyet=(deger if x["anket"] is None else x["anket"]))
            for x in s]


def gosterge(s, deger):                     # UYGULAMA: doldurma + eksiklik sutunu
    return [dict(x, memnuniyet=(deger if x["anket"] is None else x["anket"]),
                 anket_eksik=int(x["anket"] is None)) for x in s]


SONUC = {}


def olc(ad, alan, e, s):
    m = agac(e, 6, alan)
    de = sum(tahmin(m, x) == x["supheli"] for x in e) / len(e)
    ds = sum(tahmin(m, x) == x["supheli"] for x in s) / len(s)
    SONUC[ad] = (len(e), len(alan), de, ds)
    print(f"{ad:<32} {len(e):>7} {len(alan):>6} {de:>8.4f} {ds:>8.4f}")


DO, DS = doldur(EGT, ORTANCA), doldur(SIN, ORTANCA)
print(f"{'yordam':<32} {'egitim':>7} {'sutun':>6} {'egitimde':>8} {'sinama':>8}")
olc("sutun tumuyle atildi", [a for a in ALAN if a != "memnuniyet"], EGT, SIN)
olc("ortanca ile dolduruldu", ALAN, DO, DS)
olc("doldurma + eksiklik gostergesi", ALAN + ["anket_eksik"],
    gosterge(EGT, ORTANCA), gosterge(SIN, ORTANCA))
olc("sabit deger -1 ile dolduruldu", ALAN, doldur(EGT, -1), doldur(SIN, -1))
olc("eksik satir egitimden atildi", ALAN,
    [x for x in DO if x["anket"] is not None], DS)
olc("eksiksiz sutun (ust sinir)", ALAN, EGT, SIN)
```

```
yordam                            egitim  sutun egitimde   sinama
sutun tumuyle atildi                 756     10   0.8439   0.7540
ortanca ile dolduruldu               756     11   0.8466   0.7619
doldurma + eksiklik gostergesi       756     12   0.8823   0.8333
sabit deger -1 ile dolduruldu        756     11   0.8823   0.8333
eksik satir egitimden atildi         593     11   0.9191   0.7659
eksiksiz sutun (ust sinir)           756     11   0.8466   0.7778
```

Ortanca ile doldurma 0,7619 veriyor: taban çizgisinin yalnız bir abone üstünde. Sütunu tümüyle
atmak 0,7540 veriyor: tabanın altında. İkisi arasında iki abonelik bir fark var ve bu, ölçüm
çözünürlüğünün altındadır. Yaygın olan iki seçenek de bu tabloda birbirinden ayırt edilemez.

Eğitim sütunu ayrıca okunmalıdır, çünkü stratejileri iki gruba ayırıyor. Doldurma ve sütun atma
eğitimde 0,84 dolayında kalıyor; gösterge ve sabit değer 0,8823'e çıkıyor; satır atma 0,9191'e.
İlk ikisinin eğitimdeki yükselişi ayrılmış kümede de karşılığını buluyor, üçüncüsününki bulmuyor.
Eğitim kümesindeki artışın hangi tür olduğu ancak yanına ayrılmış küme sayısı yazıldığında
anlaşılır; bu, önceki kursun kuralının bu tabloda çalışan halidir.

## Katkı Boşluktan Geliyor

Farkları doldurma satırına göre okumak, hangi kararın gerçekten bir adım olduğunu ayırır.

```python
t = SONUC["ortanca ile dolduruldu"]
print(f"{'yordam':<32} {'katki':>8} {'abone':>6}")
for ad in ("sutun tumuyle atildi", "doldurma + eksiklik gostergesi",
           "sabit deger -1 ile dolduruldu", "eksik satir egitimden atildi",
           "eksiksiz sutun (ust sinir)"):
    k = SONUC[ad][3] - t[3]
    print(f"{ad:<32} {k:>+8.4f} {round(k * 252):>6}")
ae = [x for x in EGT if x["anket"] is None]
print(f"\negitimden atilan {len(ae)} satirin {sum(x['supheli'] for x in ae)} tanesi "
      f"supheli; egitimde kalan supheli sayisi "
      f"{sum(x['supheli'] for x in EGT) - sum(x['supheli'] for x in ae)} / "
      f"{sum(x['supheli'] for x in EGT)}")
print(f"sinamada anketi eksik {sum(1 for x in SIN if x['anket'] is None)} abone icin "
      f"yine de tahmin uretilir; satir atma ayrilmis kumede uygulanamaz")
```

```
yordam                              katki  abone
sutun tumuyle atildi              -0.0079     -2
doldurma + eksiklik gostergesi    +0.0714     18
sabit deger -1 ile dolduruldu     +0.0714     18
eksik satir egitimden atildi      +0.0040      1
eksiksiz sutun (ust sinir)        +0.0159      4

egitimden atilan 163 satirin 86 tanesi supheli; egitimde kalan supheli sayisi 82 / 168
sinamada anketi eksik 58 abone icin yine de tahmin uretilir; satir atma ayrilmis kumede uygulanamaz
```

Tek satır okunmaya değer: eksiklik göstergesi +0,0714, yani on sekiz abone. Bu, kursun şimdiye
kadarki en büyük katkısıdır ve nereden geldiği açıktır. Doldurma boşluğu kapatırken hangi
satırların boş olduğunu da siler; gösterge o bilgiyi geri koyar. Anketi yanıtlamayan abonelerde
şüpheli oranının 0,5276 olduğu bir tabloda, "yanıtlamamış" olmanın kendisi memnuniyet
puanından daha çok şey söyler.

Bunun kanıtı üst sınır satırındadır. Eksiklik hiç olmasaydı model 0,7778 okurdu; gösterge onu
0,0555 **geçiyor**. Bir öznitelik, eksiksiz halinden daha iyi bir sayı veriyorsa katkı sütunun
değerinden değil, sütunun eksik olma biçiminden geliyordur.

Sabit değerle doldurma aynı sayıyı, 0,8333'ü veriyor. Sebebi ağacın çalışma biçimidir: eksik
satırlara verilen −1, ölçeğin dışında tek bir değer olduğu için ağaç onu tek bir eşikle ayırabilir
ve sütunu örtük bir göstergeye çevirir. Bu eşitlik burada **ağaç için** ölçülmüştür; sütunları
toplayarak uzaklık hesaplayan ya da ağırlıkla çarpan bir yordam için −1 sıradan bir sayıdır ve
sonucu ayrıca ölçülmelidir.

Satır atma satırı iki ayrı sorun taşıyor. Eğitim kümesinde 0,9191 okuyor ama sınamada 0,7659'da
kalıyor; 593 satıra inen bir kümede ağaç daha çok ezberliyor. Asıl sorun ikinci çıktıdadır: atılan
163 satırın 86'sı şüpheli, yani azınlık sınıfının yarısından çoğu atılıyor ve eğitim kümesinde 168
şüpheliden yalnız 82'si kalıyor. Üçüncü ve kesin engel şudur: sınama kümesinde anketi eksik 58
abone var ve onlar için de bir tahmin üretilmesi gerekir. Satır atmak eğitimde bir seçenektir,
ayrılmış kümede seçenek değildir; bu yüzden hiçbir zaman tek başına bir strateji olamaz.

Katkının kaynağı da sorulmalı. Anketi yanıtlamamak tahmin anında bilinen bir olgudur ve bu haliyle
gerçek bir özniteliktir; katkı öğrenmeden gelir. Ama eksiklik denetim **sonucunda** oluşuyorsa —
şüpheli bulunan abone anketi yanıtlamayı bırakıyorsa — aynı sütun geleceği gören bir özniteliğe
dönüşür ve katkı sızıntıdan gelir. İki durum tabloda birbirinin aynısıdır. Ayrım yalnız eksikliğin
**ne zaman** oluştuğu bilinerek yapılır ve bu bilgi veride yoktur.

## Özet

- Anketi yanıtlamayan abonelerde şüpheli oranı 0,5276, yanıtlayanlarda 0,1383; eksiklik etiketle
  ilişkilidir ve doldurma bu ilişkiyi siler.
- Ortanca ile doldurma 0,7619, sütunu tümüyle atmak 0,7540 veriyor; aradaki iki abonelik fark
  ölçüm çözünürlüğünün altındadır ve iki seçenek ayırt edilemez.
- Doldurmanın yanına eksiklik göstergesi eklemek 0,8333 veriyor, katkı +0,0714, yani on sekiz
  abone; bu sayı eksiklik hiç olmasaydı okunacak 0,7778 üst sınırını da 0,0555 geçiyor.
- Sabit değerle doldurma ağaçta göstergeyle aynı sayıyı veriyor, çünkü ölçeğin dışındaki tek bir
  değer ağaç için örtük bir göstergedir; bu eşitlik başka model aileleri için ölçülmemiştir.
- Eksik satırı eğitimden atmak azınlık sınıfının yarısından çoğunu atıyor (168 şüpheliden 82'si
  kalıyor) ve sınamadaki 58 abone için tahmin gerektiği için ayrılmış kümede hiç uygulanamaz.

## Sonraki Adım

Bu derste azınlık sınıfının yarısının atılması bir yan etki olarak görüldü, ama sınıfların
büyüklük farkının kendisi hiç ölçülmedi. Eğitim kümesinde 756 abonenin 168'i şüpheli, sınama
kümesinde 252 abonenin 61'i. Bu oranda doğruluk yanıltıcı bir ölçüdür: hiç kimseyi şüpheli
işaretlemeyen taban çizgisi 0,7579 okur ve yakaladığı şüpheli sayısı sıfırdır. Sonraki ders bu
iki sayıyı yan yana basar ve dengesizliğe verilen üç yanıtı — azınlığı çoğaltma, çoğunluğu
seyreltme ve sınıf ağırlığı — hem doğrulukta hem yakalanan şüpheli sayısında ölçer. Ölçüt
kuramı, kesinlik ve duyarlılık tanımları bu kursun konusu değildir ve Denetimli Öğrenme kursuna
bırakılır.
