---
title: 'Aykırı Değer Yönetimi'
source: 'https://academia.sh/tr/kurslar/oznitelik-muhendisligi/aykiri-deger-yonetimi'
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'
---

# Aykırı Değer Yönetimi

Tek bir kırpma kararının iki model ailesinde ters işaret verdiğinin ölçülmesi: eğitim kümesinden öğrenilen çitle kırpma, eğim temelli doğrusal modele gerçek uçlarda +0,0040, takılı sayaç kaydı da varken +0,0317 katıyor; aynı karar karar ağacında −0,0278 ve −0,0357 veriyor. Çit dışındaki 34 abonenin şüpheli oranı 0,6765 olduğu için kırpma gerçek bilgiyi de siliyor, ve hiçbir satır silinmeden 41 değer kırpılıyor.

Önceki ders şüpheli abonelerin **sayıca** azlığını ölçtü. Bu ders birkaç abonenin **değerce**
uzaklığını ölçer. Ortalama tüketim ve oynaklık sütunlarında, eğitim kümesinin çeyrekler
açıklığından hesaplanan çitin dışında kalan aboneler var. Bunların bir bölümü gerçek uçtur —
kalabalık bir haneden ya da yüksek tarifeli bir bağlantıdan gelir. Bir bölümü ise takılı kalmış
sayaçların ürettiği kayıt hatasıdır. Tabloda ikisi birbirinin aynısı görünür: büyük bir sayı.

Çeyrekler açıklığı, çit ve uç değerin bulunması M26'nın Veri Toplama ve Hazırlama kursunda
kuruldu; oradaki ölçü kaç satırın çit dışında kaldığıydı. Buradaki soru başkadır: **kırpma
kararı** ayrılmış kümedeki sayıyı hangi modelde ne kadar oynatıyor.

- **HA41.** Takılı sayaç arızası **kurgudur**: küçük bir abone kümesinin ortalama tüketimi otuz
  katına çıkmış olarak kaydedilir. Etiketten bağımsız seçilir.
- **HA42.** Bu arıza `01`'deki üç kusurdan farklıdır ve onların düzeltmeleriyle yakalanamaz:
  değer doğru birimdedir, doğru yazılmıştır ve tek satırdadır. Yalnız yanlıştır.
- **HA43.** **Çit eğitilmiş bir nesnedir**: çeyrekler yalnız eğitim kümesinden hesaplanır, çit
  çeyrekler açıklığının 1,5 katıyla kurulur ve iki kümeye de aynı çit uygulanır.
- **HA44.** Kırpma çit dışındaki değeri çite çeker. **Hiçbir satır silinmez**; sınama kümesindeki
  her abone için tahmin üretilir.
- **HA45.** İki model ailesi karşılaştırılır: eğim temelli doğrusal model ve derinlik 6 karar
  ağacı. Doğrusal model önceki derste kurulan disipline göre standartlaştırılmış sütunlarla
  eğitilir; ağaçta ölçeklemenin katkısı sıfır olduğu için ham sütunlarla eğitilir.

## Uçun İki Kaynağı

Kurulum tabloyu üretir, arızayı koyar ve çiti eğitim kümesinden öğrenir.

```python
# aykiri.py — MODELDIR. Kurgu abone tablosu ayni tohumla uretilir; kucuk bir abone
# kumesinin tuketimi KURGU bir takili sayac arizasiyla otuz kat yuksek kaydedilir.
import math
import statistics

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)

sr = uretec(TOHUM + 81000)                  # takili sayac arizasi KURGUDUR
for x in VERI:
    x["ariza"] = round(x["ort_tuketim"] * 30, 2) if sr() < 0.010 else x["ort_tuketim"]


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)
SAY = ["ort_tuketim", "oynaklik", "hane", "memnuniyet", "donem"]
ALAN = SAY + ["sifir_okuma", "b_kuzey", "b_guney", "b_dogu", "b_bati", "b_merkez"]
UC = ["ort_tuketim", "oynaklik"]


def ceyrek(v, q):
    s = sorted(v)
    i = q * (len(s) - 1)
    a = int(i)
    return s[a] if a + 1 >= len(s) else s[a] + (i - a) * (s[a + 1] - s[a])


def cit_ogren(egt, sutun, k=1.5):           # OGRENME: ceyrekler acikligi ve cit
    d = {}
    for a in sutun:
        q1, q3 = ceyrek([x[a] for x in egt], 0.25), ceyrek([x[a] for x in egt], 0.75)
        d[a] = (q1 - k * (q3 - q1), q3 + k * (q3 - q1))
    return d


def kirp(c, s):                             # UYGULAMA: hicbir satir silinmez
    return [dict(x, **{a: min(max(x[a], c[a][0]), c[a][1]) for a in c}) for x in s]


ar = [x for x in EGT if x["ariza"] != x["ort_tuketim"]]
print(f"takili sayac: egitimde {len(ar)} abone, sinamada "
      f"{sum(1 for x in SIN if x['ariza'] != x['ort_tuketim'])}; "
      f"bunlarin {sum(x['supheli'] for x in ar)} tanesi supheli")
c = cit_ogren(EGT, UC)
print(f"{'sutun':<12} {'ust cit':>8} {'en buyuk':>9} {'cit disi egitim':>16} "
      f"{'sinama':>7}")
for a in UC:
    print(f"{a:<12} {c[a][1]:>8.2f} {max(x[a] for x in EGT):>9.2f} "
          f"{sum(1 for x in EGT if x[a] > c[a][1]):>16} "
          f"{sum(1 for x in SIN if x[a] > c[a][1]):>7}")
u = [x for x in EGT if any(x[a] > c[a][1] for a in UC)]
print(f"cit disindaki {len(u)} abonenin supheli orani "
      f"{sum(x['supheli'] for x in u) / len(u):.4f}, taban cizgisi {TABAN:.4f}")
```

```
takili sayac: egitimde 9 abone, sinamada 1; bunlarin 2 tanesi supheli
sutun         ust cit  en buyuk  cit disi egitim  sinama
ort_tuketim     35.80     42.90               11       4
oynaklik        29.41     40.57               23       7
cit disindaki 34 abonenin supheli orani 0.6765, taban cizgisi 0.7579
```

Son satır kırpma kararının bedelini önceden söylüyor. Çit dışındaki 34 abonenin şüpheli oranı
0,6765; eğitim kümesinin genelinde bu oran 0,2222. Uçtaki abonelerin üçte ikisi şüpheli, yani uç
değerler gürültü değil, kümenin en bilgilendirici bölgesi.

## Aynı Kırpma, İki Model

```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 agac_tahmin(d, x):
    while "tahmin" not in d:
        d = d["sol"] if x[d["alan"]] < d["esik"] else d["sag"]
    return d["tahmin"]


def sikistir(z):
    if z >= 0:
        return 1.0 / (1.0 + math.exp(-z)) if z < 700 else 1.0
    e = math.exp(z) if z > -700 else 0.0
    return e / (1.0 + e)


def dogrusal(egt, alan, adim=0.5, tur=400):  # MODELDIR: egim temelli dogrusal model
    w, b, n = [0.0] * len(alan), 0.0, len(egt)
    for _ in range(tur):
        gw, gb = [0.0] * len(alan), 0.0
        for x in egt:
            h = sikistir(sum(w[i] * x[a] for i, a in enumerate(alan)) + b) - x["supheli"]
            for i, a in enumerate(alan):
                gw[i] += h * x[a]
            gb += h
        for i in range(len(alan)):
            w[i] -= adim * gw[i] / n
        b -= adim * gb / n
    return w, b


def standartla(egt, kumeler):               # OGRENME + UYGULAMA (onceki ders)
    p = {a: (statistics.fmean(x[a] for x in egt),
             statistics.pstdev([x[a] for x in egt])) for a in SAY}
    return [[dict(x, **{a: (x[a] - p[a][0]) / p[a][1] for a in SAY}) for x in k]
            for k in kumeler]


def kur(kaynak, kirpma):
    e = [dict(x, ort_tuketim=x[kaynak]) for x in EGT]
    s = [dict(x, ort_tuketim=x[kaynak]) for x in SIN]
    if kirpma:
        c = cit_ogren(e, UC)
        e, s = kirp(c, e), kirp(c, s)
    return e, s


SONUC = {}
print(f"{'durum':<38} {'egim temelli':>13} {'agac':>8}")
print(f"{'taban cizgisi':<38} {TABAN:>13.4f} {TABAN:>8.4f}")
for ad, kaynak, kirpma in (("yalniz gercek uc, kirpma yok", "ort_tuketim", False),
                           ("yalniz gercek uc, cit ile kirpildi", "ort_tuketim", True),
                           ("takili sayac da var, kirpma yok", "ariza", False),
                           ("takili sayac da var, cit ile kirpildi", "ariza", True)):
    e, s = kur(kaynak, kirpma)
    es, ss = standartla(e, [e, s])
    m = dogrusal(es, ALAN)
    d = sum(int(sikistir(sum(m[0][i] * x[a] for i, a in enumerate(ALAN)) + m[1]) > 0.5)
            == x["supheli"] for x in ss) / len(ss)
    t = agac(e, 6, ALAN)
    g = sum(agac_tahmin(t, x) == x["supheli"] for x in s) / len(s)
    SONUC[ad] = (d, g)
    print(f"{ad:<38} {d:>13.4f} {g:>8.4f}")
```

```
durum                                   egim temelli     agac
taban cizgisi                                 0.7579   0.7579
yalniz gercek uc, kirpma yok                  0.8016   0.7778
yalniz gercek uc, cit ile kirpildi            0.8056   0.7500
takili sayac da var, kirpma yok               0.7698   0.7857
takili sayac da var, cit ile kirpildi         0.8016   0.7500
```

Ağaç sütunu dört durumda üç ayrı sayı veriyor ve ilginç olan, kırpılmış iki satırın aynı sayıyı
okumasıdır. Kırpma her iki tabloyu da aynı yere getiriyor: çit üstündeki bütün değerler tek bir
noktaya toplandığında arızalı kayıtla gerçek uç birbirinden ayırt edilemez duruma geliyor.

## Katkı Kaç Abone Eder

```python
print(f"{'kirpma karari':<34} {'egim temelli':>13} {'abone':>6} "
      f"{'agac':>8} {'abone':>6}")
for ad, a, b in (("yalniz gercek uc", "yalniz gercek uc, kirpma yok",
                  "yalniz gercek uc, cit ile kirpildi"),
                 ("takili sayac da var", "takili sayac da var, kirpma yok",
                  "takili sayac da var, cit ile kirpildi")):
    kd, kg = SONUC[b][0] - SONUC[a][0], SONUC[b][1] - SONUC[a][1]
    print(f"{ad:<34} {kd:>+13.4f} {round(kd * 252):>6} "
          f"{kg:>+8.4f} {round(kg * 252):>6}")
e, s = kur("ariza", False)
c = cit_ogren(e, UC)
print(f"\narizali tabloda ogrenilen ust cit: ort_tuketim {c['ort_tuketim'][1]:.2f}, "
      f"oynaklik {c['oynaklik'][1]:.2f}")
print(f"kirpilan deger: egitim {sum(1 for x in e for a in UC if x[a] > c[a][1])}, "
      f"sinama {sum(1 for x in s for a in UC if x[a] > c[a][1])}; "
      f"silinen satir 0")
print(f"arizanin egim temelli modele maliyeti "
      f"{SONUC['takili sayac da var, kirpma yok'][0] - SONUC['yalniz gercek uc, kirpma yok'][0]:+.4f}, "
      f"agaca {SONUC['takili sayac da var, kirpma yok'][1] - SONUC['yalniz gercek uc, kirpma yok'][1]:+.4f}")
print(f"alti derste kullanilan oznitelik sayisi {len(ALAN)}, uretilen yeni buyukluk 0")
```

```
kirpma karari                       egim temelli  abone     agac  abone
yalniz gercek uc                         +0.0040      1  -0.0278     -7
takili sayac da var                      +0.0317      8  -0.0357     -9

arizali tabloda ogrenilen ust cit: ort_tuketim 36.20, oynaklik 29.41
kirpilan deger: egitim 41, sinama 12; silinen satir 0
arizanin egim temelli modele maliyeti -0.0317, agaca +0.0079
alti derste kullanilan oznitelik sayisi 11, uretilen yeni buyukluk 0
```

İki satırda da işaretler ters. Kırpma eğim temelli modelde artı, ağaçta eksi katkı veriyor ve
takılı sayaç bulunduğunda iki yön de okunacak büyüklüğe çıkıyor: sekiz abone ve dokuz abone.
Mekanizma iki modelin uç değeri işleme biçiminde. Eğim temelli model her turda bütün satırların
hatasını toplayıp ağırlıkları o toplama göre kaydırır; ortalamadan otuz kat uzak bir satır o
toplamı tek başına belirler ve on bir ağırlığın hepsini birden çeker. Ağaç ise uç satırı tek bir
bölmeyle kenara ayırabilir ve kalan kümeye dokunmaz — ama kırpma o bölmeyi ortadan kaldırır, çünkü
çit üstündeki sıralama silinir ve orada kalan 34 abonenin 0,6765'lik şüpheli oranı bir eşiğe
dönüştürülemez duruma gelir.

Arıza satırı bunu ikinci yönden doğruluyor. Dokuz satırlık bir kayıt hatası eğim temelli modele
0,0317 kaybettiriyor, ağaca ise 0,0079 kazandırıyor — yani ağaç için ölçülmemiş bir fark. Kırpma
uygulandığında eğim temelli model tam olarak 0,8016'ya, arıza hiç olmasaydı okuyacağı sayıya
dönüyor. Aynı adım aynı veride bir modelin zararını tamamen geri alırken ötekini tabanın 0,0079
üstüne kadar indiriyor.

Kırpmanın yordamsal yüzü de kayda değer. Çit yalnız eğitim kümesinden öğrenildi, arızalı tabloda
üst çit 36,20'ye kaydı, 41 değer kırpıldı ve **silinen satır sıfır**. Kaynağı bilinmeyen bir uç
için tek bir doğru yanıt yoktur; ölçülebilen tek şey, o yanıtın hangi modelde kaç abone ettiğidir.

## Özet

- Çit dışındaki 34 abonenin şüpheli oranı 0,6765, kümenin genelinde 0,2222; uç değerler bu tabloda
  gürültü değil, en bilgilendirici bölgedir.
- Aynı kırpma kararı eğim temelli doğrusal modelde artı, karar ağacında eksi katkı veriyor: gerçek
  uçlarda +0,0040 ve −0,0278, takılı sayaç kaydı da varken +0,0317 ve −0,0357.
- Eğim temelli model bütün satırların hatasını toplayarak ağırlık günceller ve ortalamadan otuz kat
  uzak bir satır o toplamı tek başına belirler; ağaç uç satırı tek bir bölmeyle ayırabilirken
  kırpma o bölmeyi ortadan kaldırır.
- Dokuz satırlık kayıt hatası eğim temelli modele 0,0317 kaybettiriyor, ağaçta 0,0079'luk
  ölçülmemiş bir fark bırakıyor; kırpma eğim temelli modeli tam olarak arızasız haldeki 0,8016'ya
  geri getiriyor.
- Çit yalnız eğitim kümesinden öğrenildi, 41 değer kırpıldı ve hiçbir satır silinmedi; sınama
  kümesindeki her abone için tahmin üretildi.

## Sonraki Adım

Son çıktının son satırı altı dersin ortak sınırını söylüyor: kullanılan öznitelik sayısı on bir ve
üretilen yeni büyüklük sıfır. Altı derste yapılan her şey **var olan bir alanın okunma biçimini**
değiştirmekti — birimi düzeltmek, ölçeği eğitimden öğrenmek, kategoriyi sayıya çevirmek, boşluğun
kendisini bir sütuna yazmak, satırların ağırlığını değiştirmek, ucu çite çekmek. Hiçbir derste iki
sütunun oranı, farkı ya da çarpımı alınmadı; bir tarihten dönemsel gösterge, bir metinden uzunluk
çıkarılmadı. Ve ters yönde de bir şey yapılmadı: hiçbir sütun "katkısı ölçülmedi" gerekçesiyle
tablodan çıkarılmadı, on bir öznitelik altı ders boyunca olduğu gibi kaldı. Sonraki konu bu iki işi
üstlenir. Önce alan bilgisinden yeni sütunlar türetilir ve her birinin katkısı tek tek ölçülür —
katkısı sıfır çıkanlar da yazılır. Sonra ters soru sorulur: hangi sütunlar tablodan çıkarılmalı, üç
seçim yöntemi aynı kümede kaç öznitelik seçiyor ve **seçimin kendisi** ayrılmış kümedeki sayıyı ne
kadar şişiriyor.
