---
title: 'Kategorik Kodlama'
source: 'https://academia.sh/tr/kurslar/oznitelik-muhendisligi/kategorik-kodlama'
course: 'Veri Hazırlama ve Öznitelik Mühendisliği'
language: tr
updated: '2026-08-17T18:10:11+00:00'
license: 'CC BY-SA 4.0'
---

# Kategorik Kodlama

Bir kategorik alanın sayıya çevrilmesinde üç kodlamanın sütun sayısı ve katkı olarak ölçülmesi: bölgenin bir-sıcak kodlanması sınama doğruluğunu 0,7302'den 0,7778'e çıkarır, 240 kodluk okuma rotası alanı bir-sıcak kodlandığında 231 ek sütuna karşılık +0,0119, sıralı kodlandığında tek sütunla aynı +0,0119 verir. Hedef temelli kodlama eğitim doğruluğunu 0,9114'e şişirirken sınamada 0,7421'e düşürür; kat içinde hesaplandığında eğitimdeki şişme 0,0595 geri çekilir ve sınama 0,7540'a döner.

Önceki ders bölge bilgisini hazır beş ikili sütun olarak kullandı ve o sütunların nereden geldiğini
sormadı. Bölge bir metin alanıdır. Modelin girdisi sayıdır. Aradaki çeviri bir karardır ve
kararın en az iki bedeli vardır: kaç sütun ürettiği ve ayrılmış kümedeki sayıyı ne kadar oynattığı.

Bu ders üç kodlamayı aynı tabloda karşılaştırır. **Bir-sıcak kodlama** her kategori için ayrı bir
ikili sütun açar. **Sıralı kodlama** kategorilere birer tamsayı verir ve tek sütunla yetinir.
**Hedef temelli kodlama** her kategoriyi, o kategorinin eğitim kümesindeki şüpheli oranıyla
değiştirir; tek sütun üretir ama etiketi kodlamanın içine sokar. Ölçüm iki kategorik alan üzerinde
yapılır: beş kategorili bölge ve **kardinalitesi** iki yüz kırk olan okuma rotası kodu.

- **HA17.** Okuma rotası kodu ham kaydın bir alanıdır ve **kurgudur**: her abone bir okuma
  rotasına bağlıdır, rotalar bölgeye ve ağın genişleme dalgasına göre açılmıştır. M26 bu alanı
  kullanmamıştı.
- **HA18.** Rota kodu etiketle doğrudan üretilmez. Taşıdığı bilgi bölgeden ve ağa katılma
  dalgasından gelir; ikincisi öznitelik sütunlarında yoktur.
- **HA19.** Ölçüm kümesi, bölme ve taban çizgisi önceki derslerdekiyle aynıdır: 756/252/252 ve
  sınama kümesinde 0,7579.
- **HA20.** Model sabittir: derinlik 6 karar ağacı. Ölçekleme uygulanmaz, çünkü önceki derste
  ağaçtaki katkısının tam olarak sıfır olduğu gösterildi.
- **HA21.** Kodlama **eğitilmiş bir nesnedir**. Öğrenilen şey bir-sıcak kodlamada kategori
  listesi, sıralı kodlamada kategori–tamsayı eşlemesi, hedef temelli kodlamada kategori–oran
  tablosudur. Üçü de yalnız eğitim kümesinden çıkarılır.
- **HA22.** **Görülmemiş kategori**, ayrılmış kümede çıkıp eğitim kümesinde bulunmayan koddur. Her
  kodlama ona bir yanıt vermek zorundadır ve verdiği yanıt kodlamanın parçasıdır.
- **HA23.** Hedef temelli kodlamanın **kat içinde** hesaplanması şudur: eğitim kümesi beş kata
  bölünür ve her satırın kodlama değeri, o satırın bulunmadığı dört kattan hesaplanır. Böylece
  hiçbir satırın kendi etiketi kendi kodlama değerine girmez.
- **HA24.** Çapraz doğrulamanın kendisi bu derste kurulmuyor; kat yalnız kodlamanın hesaplandığı
  bölme olarak kullanılıyor.
- **HA25.** Sınama kümesi 252 abonedir, bir abone 0,0040 eder.

## Üç Kodlama, İki Sayı

Kurulum tabloyu yeniden üretir ve rota alanını ekler.

```python
# kodlama.py — MODELDIR. Kurgu abone tablosu ayni tohumla uretilir; ham kayittan
# gelen KURGU okuma rotasi kodu kategorik sutun olarak eklenir.
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, rr = [], uretec(TOHUM + 41000)
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),
         "bolge": k["bolge"][0]}
    dalga = min(7, int((k["no"] - 10001) / 1399 * 8))       # aga katilma dalgasi
    x["rota"] = "R%03d" % ([b[0] for b in BOLGE].index(k["bolge"][0]) * 48
                           + dalga * 6 + int(rr() * 6) + 1)
    VERI.append(x)


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", "sifir_okuma"]
EK = {x["rota"] for x in EGT}
BOY = {}
for x in EGT:
    BOY[x["rota"]] = BOY.get(x["rota"], 0) + 1
print(f"rota kodu: tabloda {len({x['rota'] for x in VERI})}, egitimde {len(EK)}, "
      f"en kalabalik rota {max(BOY.values())} abone, ortalama "
      f"{sum(BOY.values()) / len(BOY):.1f}")
print(f"sinamada gorulmemis rota kodu {len({x['rota'] for x in SIN} - EK)}, "
      f"bu kodlardaki abone {sum(1 for x in SIN if x['rota'] not in EK)}")
print(f"bolge {len({x['bolge'] for x in EGT})} kategori, taban cizgisi {TABAN:.4f}")
```

```
rota kodu: tabloda 240, egitimde 231, en kalabalik rota 9 abone, ortalama 3.3
sinamada gorulmemis rota kodu 6, bu kodlardaki abone 10
bolge 5 kategori, taban cizgisi 0.7579
```

Rota başına ortalama 3,3 abone düşüyor ve en kalabalık rota dokuz abone. Bu sayı dersin ikinci
yarısında belirleyici olacak. Şimdi dört kodlama sırayla uygulanır.

```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 bir_sicak(sutun, egt, sin):             # OGRENME: egitimdeki kategori listesi
    kat = sorted({x[sutun] for x in egt})
    ac = (lambda s: [dict(x, **{sutun + "_" + k: int(x[sutun] == k) for k in kat})
                     for x in s])
    return [sutun + "_" + k for k in kat], ac(egt), ac(sin)


def sirali(sutun, egt, sin, sira=None):     # OGRENME: kategori -> tamsayi eslemesi
    kat = sira or {k: i for i, k in enumerate(sorted({x[sutun] for x in egt}))}
    ac = lambda s: [dict(x, rota_s=kat.get(x[sutun], -1)) for x in s]
    return ["rota_s"], ac(egt), ac(sin)


def oran(satirlar):
    m = {}
    for x in satirlar:
        m.setdefault(x["rota"], []).append(x["supheli"])
    return {k: sum(v) / len(v) for k, v in m.items()}


def hedef(egt, sin):                        # OGRENME: kategori basina supheli orani
    g, t = sum(x["supheli"] for x in egt) / len(egt), oran(egt)
    ac = lambda s: [dict(x, rota_h=t.get(x["rota"], g)) for x in s]
    return ["rota_h"], ac(egt), ac(sin)


def hedef_kat_icinde(egt, sin, kat=5):      # her satir kendi katinin disindan
    g, t = sum(x["supheli"] for x in egt) / len(egt), oran(egt)
    tablo = [oran([y for j, y in enumerate(egt) if j % kat != i]) for i in range(kat)]
    e = [dict(x, rota_h=tablo[i % kat].get(x["rota"], g)) for i, x in enumerate(egt)]
    return ["rota_h"], e, [dict(x, rota_h=t.get(x["rota"], g)) for x in sin]


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(alan), de, ds)
    print(f"{ad:<28} {len(alan):>6} {de:>8.4f} {ds:>8.4f}")


print(f"{'kodlama':<28} {'sutun':>6} {'egitim':>8} {'sinama':>8}")
olc("kategorik sutun yok", SAY, EGT, SIN)
ab, eb, sb = bir_sicak("bolge", EGT, SIN)
olc("bolge bir-sicak", SAY + ab, eb, sb)
for ad, fn in (("+ rota bir-sicak", lambda: bir_sicak("rota", eb, sb)),
               ("+ rota sirali", lambda: sirali("rota", eb, sb)),
               ("+ rota hedef temelli", lambda: hedef(eb, sb)),
               ("+ rota hedef, kat icinde", lambda: hedef_kat_icinde(eb, sb))):
    a, e, s = fn()
    olc(ad, SAY + ab + a, e, s)
```

```
kodlama                       sutun   egitim   sinama
kategorik sutun yok               6   0.8492   0.7302
bolge bir-sicak                  11   0.8466   0.7778
+ rota bir-sicak                242   0.8452   0.7897
+ rota sirali                    12   0.8651   0.7897
+ rota hedef temelli             12   0.9114   0.7421
+ rota hedef, kat icinde         12   0.8519   0.7540
```

İlk iki satır kodlamanın kendisinin ne ettiğini söylüyor. Kategorik alanlar hiç kullanılmadığında
model 0,7302 okuyor ve taban çizgisinin 0,0277 altında kalıyor. Beş kategorili bölge alanı beş
ikili sütuna açıldığında sayı 0,7778'e çıkıyor: on iki abone. Bu, kursun şimdiye kadarki en büyük
tek katkısıdır ve kararın kendisi görünmezdir, çünkü bölgenin sayıya çevrilmesi genellikle
tartışılmadan yapılır.

## Aynı Katkı, İki Yüz Otuz Bir Sütun Farkı

Rota alanının üç kodlaması aynı tabloda yan yana durunca ödenen bedel görünür oluyor.

```python
t = SONUC["bolge bir-sicak"]
print(f"{'kodlama':<28} {'ek sutun':>9} {'egitim katki':>13} {'sinama katki':>13}")
for ad in ("+ rota bir-sicak", "+ rota sirali", "+ rota hedef temelli",
           "+ rota hedef, kat icinde"):
    v = SONUC[ad]
    print(f"{ad:<28} {v[0] - t[0]:>9} {v[1] - t[1]:>+13.4f} {v[2] - t[2]:>+13.4f}")

kod = sorted(EK)
kr = uretec(TOHUM + 43000)
kk = list(range(len(kod)))
for i in range(len(kk) - 1, 0, -1):
    j = int(kr() * (i + 1))
    kk[i], kk[j] = kk[j], kk[i]
a, e, s = sirali("rota", eb, sb, {k: kk[i] for i, k in enumerate(kod)})
m = agac(e, 6, SAY + ab + a)
print(f"\nsirali kodlama, kod sirasi karistirilinca: sinama "
      f"{sum(tahmin(m, x) == x['supheli'] for x in s) / len(s):.4f}")

g = sum(x["supheli"] for x in EGT) / len(EGT)
_, _, sh = hedef(eb, sb)
yeni = [x for x in sh if x["rota"] not in EK]
print(f"gorulmemis rotadaki {len(yeni)} abone: bir-sicak kodlamada 231 sutunun hepsi 0, "
      f"sirali kodlamada -1, hedef temelli kodlamada {g:.4f}")
print(f"kat icinde hesaplanan kodlamanin egitimdeki sismesi "
      f"{SONUC['+ rota hedef temelli'][1] - SONUC['+ rota hedef, kat icinde'][1]:+.4f}, "
      f"sinamada geri alinan "
      f"{SONUC['+ rota hedef, kat icinde'][2] - SONUC['+ rota hedef temelli'][2]:+.4f}")
```

```
kodlama                       ek sutun  egitim katki  sinama katki
+ rota bir-sicak                   231       -0.0013       +0.0119
+ rota sirali                        1       +0.0185       +0.0119
+ rota hedef temelli                 1       +0.0648       -0.0357
+ rota hedef, kat icinde             1       +0.0053       -0.0238

sirali kodlama, kod sirasi karistirilinca: sinama 0.7778
gorulmemis rotadaki 10 abone: bir-sicak kodlamada 231 sutunun hepsi 0, sirali kodlamada -1, hedef temelli kodlamada 0.2222
kat icinde hesaplanan kodlamanin egitimdeki sismesi +0.0595, sinamada geri alinan +0.0119
```

İlk iki satır aynı katkıyı iki farklı fiyata veriyor: bir-sıcak kodlama 231 ek sütun karşılığında
0,0119, sıralı kodlama tek sütun karşılığında yine 0,0119. Üç abonelik bu fark tek başına
okunmazdı; okunan şey **fiyat farkıdır.** Bir-sıcak kodlamanın maliyeti kardinaliteyle birlikte
doğrusal büyür ve 756 satırlık bir eğitim kümesinde 231 sütun, her sütuna ortalama üç satır
düşmesi demektir.

Sıralı kodlamanın bu tabloda işe yaramasının bir sebebi var ve karıştırma sınaması onu ortaya
koyuyor. Kod numaraları rastgele verilmemiş; önce bölgeye, sonra ağa katılma dalgasına göre
sıralanmışlar, dolayısıyla "rota numarası küçüktür" demek bir şeyler söylüyor. Eşleme
karıştırıldığında sınama sayısı 0,7778'e, yani rota alanı hiç kullanılmamış gibi bir yere düşüyor.
Sıralı kodlamanın katkısı kategorilerden değil, **kodun kendi sırasından** gelir; sıra uydurma
olduğunda katkı sıfırdır.

Üçüncü satır dersin asıl sayısıdır. Hedef temelli kodlama eğitim kümesinde 0,0648 kazandırıyor ve
sınama kümesinde 0,0357 kaybettiriyor. İki sayının ters işareti tesadüf değil, aynı olayın iki
yüzüdür. Rota başına ortalama 3,3 abone düşüyor; üç abonelik bir rotanın şüpheli oranı, o üç
satırın etiketlerinin ortalamasıdır ve her satırın kendi etiketi o ortalamanın üçte biridir. Ağaç
bu sütunu okuduğunda satırın etiketinin bir kopyasını okumuş olur. Eğitim kümesinde 0,9114 çıkması
öğrenmenin değil, kendini okumanın sonucudur.

Kat içinde hesaplama bunu düzeltir. Her satırın kodlama değeri, o satırın bulunmadığı dört kattan
çıkarıldığında eğitimdeki şişmenin 0,0595'i kayboluyor ve sınama sayısı 0,0119 geri geliyor. Yine
de kalan katkı −0,0238'dir: sızıntı geri çekildikten sonra bile hedef temelli kodlama bu alanda
tabanın altında kalıyor. Ölçülen sonuç şudur — sızıntıyı gidermek adımı iyi yapmaz, yalnız adımın
gerçek katkısını görünür kılar.

Son satır kodlamanın sessiz yüzüdür. Sınama kümesinde on abone, eğitim kümesinde hiç görülmemiş
altı rotaya bağlı. Bir-sıcak kodlama onlara 231 sıfırdan oluşan bir satır veriyor, sıralı kodlama
eğitim aralığının dışında bir −1 veriyor, hedef temelli kodlama eğitim kümesinin genel oranını,
0,2222'yi veriyor. Üçü de bir karardır ve üçü de kodlamanın parçasıdır; hiçbiri kendiliğinden
doğru değildir.

## Özet

- Kategorik alanlar hiç kullanılmadığında model 0,7302 ile taban çizgisinin altında kalıyor; beş
  kategorili bölge alanı bir-sıcak kodlandığında 0,7778'e çıkıyor, katkı +0,0476.
- Kardinalitesi 240 olan rota alanı bir-sıcak kodlandığında 231 ek sütuna karşılık +0,0119, sıralı
  kodlandığında tek sütuna karşılık yine +0,0119 veriyor; aynı katkının iki farklı fiyatı vardır.
- Sıralı kodlamanın katkısı kodun kendi sırasından gelir: kategori–tamsayı eşlemesi
  karıştırıldığında sınama sayısı 0,7778'e, yani alan hiç kullanılmamış düzeye düşüyor.
- Hedef temelli kodlama eğitimde +0,0648, sınamada −0,0357 veriyor; rota başına 3,3 abone düştüğü
  için her satırın kendi etiketi kendi kodlama değerinin içindedir.
- Kat içinde hesaplama eğitimdeki şişmenin 0,0595'ini siliyor ve sınamada 0,0119 geri getiriyor,
  ama kalan katkı −0,0238'dir; sızıntıyı gidermek adımı iyi yapmaz, gerçek katkısını gösterir.

## Sonraki Adım

Bu 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. Şimdiye kadarki bütün derslerde o boşluk
sessizce eğitim kümesinin ortancasıyla dolduruldu ve doldurmanın kendisi hiç ölçülmedi. Sonraki
ders boşluğu geri koyar ve üç seçeneği yan yana basar: ortanca ile doldurmak, doldurup yanına bir
eksiklik göstergesi eklemek ve eksik satırı eğitim kümesinden atmak. Eksikliğin abonenin kendisi
hakkında bilgi taşıdığı durumda göstergenin katkısı ölçülür ve satır atmanın ayrılmış kümede
niçin uygulanamayacağı sayıyla gösterilir.
