---
title: 'Öznitelik Ölçekleme'
source: 'https://academia.sh/tr/kurslar/oznitelik-muhendisligi/oznitelik-olcekleme'
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'
---

# Öznitelik Ölçekleme

Standartlaştırma ve normalleştirme kararlarının üç model ailesinde ayrı ayrı ölçülmesi: standartlaştırma eğim temelli doğrusal modele +0,0437 katarken uzaklık temelli yordamda −0,0159 verir ve karar ağacında katkı tam olarak sıfırdır. Ölçek eğitim kümesinden öğrenilen bir nesnedir; sınama kümesine uygulandığında iki değer [0, 1] aralığının dışına çıkar ve standart puanlar 5,11'e kadar yükselir. On bir sütunun hepsi ölçeklendiğinde uzaklık temelli yordam bir abone daha kaybeder.

Önceki ders ham kayıttaki üç kusuru düzeltti ve uzaklık temelli yordamı 0,7540'tan 0,7857'ye
çıkardı. Bu sayı taban çizgisini yalnız 0,0278 geçiyor ve aynı tabloyla eğitilen karar ağacının
gerisinde. Sebep temizlenmemiş bir şey değil, hiç sorulmamış bir şey: sütunlar aynı birime
çevrildi ama **aynı büyüklüğe** çevrilmedi. Ortalama tüketim sıfır ile kırk üç arasında
değişirken hane büyüklüğü bir ile altı, bölge sütunları sıfır ile bir arasında değişiyor.
Farkların karelerini toplayan bir yordam için bu, sütunlara sessizce ağırlık vermektir.

Bu ders iki ölçekleme kararını ölçer. **Standartlaştırma** her değerden sütunun ortalamasını
çıkarıp değişkenliğine böler; sonuç standart puandır ve M26'nın Veri Toplama ve Hazırlama
kursunda tanımlanmıştı. **Normalleştirme** her sütunu en küçük değeri sıfır, en büyüğü bir olacak
biçimde aralığa sıkıştırır; M26/K03'ün metin normalleştirmesiyle adı ortaktır ama işi başkadır,
biri yazımı tekleştirir, bu sayıyı aralığa oturtur. İkisi de yordam olarak yeni değil; ölçülen
şey, her birinin **hangi model ailesinde** kaç abone ettiğidir.

- **HA9.** Bu dersin başlangıç tablosu önceki dersin çıktısıdır: üç kusuru düzeltilmiş 1.260
  abonelik kurgu tablo, aynı 756/252/252 bölmesi, sınama kümesinde taban çizgisi 0,7579.
- **HA10.** Üç model ailesi karşılaştırılır ve üçü de ders içinde yazılır: en yakın on beş komşuya
  bakan uzaklık temelli yordam, ağırlıklarını eğim yönünde güncelleyen doğrusal model ve derinlik
  6 karar ağacı. Ayarları kurs boyunca sabittir.
- **HA11.** Eğim temelli modelin çıktısı S biçimli bir işlevle sıfır ile bir arasına sıkıştırılır;
  0,5 eşiği aşan abone şüpheli sayılır. Eşik bir seçimdir ve bu kursta değişmez.
- **HA12.** Ölçekleme yalnız beş sayısal sütuna uygulanır: ortalama tüketim, oynaklık, hane
  büyüklüğü, memnuniyet, dönem sayısı. İkili sütunların ölçeklenmesi dersin sonunda ayrı bir karar
  olarak ölçülür.
- **HA13.** Ölçek **eğitilmiş bir nesnedir** ve iki yüzü vardır: **öğrenme**, ölçek sayılarının
  eğitim kümesinden çıkarılması; **uygulama**, o sayıların bir kümeye uygulanması. Kursun ikinci
  kuralı burada ilk kez yordama dönüşür: **her hazırlama adımı yalnız eğitim kümesinden öğrenilir
  ve ayrılmış kümeye uygulanır.**
- **HA14.** Bütün kümeden öğrenilen ölçek bir sızıntıdır. M27/K01 bunu dört sızıntı türünden biri
  olarak saymıştı; buradaki iş o sayıları tekrarlamak değil, sızmayan biçimi yordam olarak
  kurmaktır.
- **HA15.** Ölçü doğruluktur ve sınama kümesi 252 abonedir; bir abone 0,0040 eder.
- **HA16.** Kayan noktalı karşılaştırma `==` ile yapılmaz. Aralık dışı sayımında `0.0 <= v <= 1.0`
  kullanılır; sınır değerinin kendisi aralık içi sayılır.

## Üç Model, İki Ölçekleme Kararı

Kurulum tabloyu üretir ve beş sayısal sütunun ham aralıklarını basar.

```python
# olcekleme.py — MODELDIR. M27/K01'in kurgu abone tablosu, onceki derste
# temizlenmis haliyle yeniden uretilir.
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)


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)
SAYISAL = ["ort_tuketim", "oynaklik", "hane", "memnuniyet", "donem"]
ALAN = SAYISAL + ["sifir_okuma", "b_kuzey", "b_guney", "b_dogu", "b_bati", "b_merkez"]
print(f"egitim {len(EGT)}, sinama {len(SIN)}, taban cizgisi {TABAN:.4f}")
print(f"{'sutun':<12} {'en kucuk':>9} {'en buyuk':>9} {'ortalama':>9}")
for a in SAYISAL:
    v = [x[a] for x in EGT]
    print(f"{a:<12} {min(v):>9.2f} {max(v):>9.2f} {statistics.fmean(v):>9.2f}")
```

```
egitim 756, sinama 252, taban cizgisi 0.7579
sutun         en kucuk  en buyuk  ortalama
ort_tuketim       0.00     42.90     19.77
oynaklik          0.00     40.57      9.62
hane              1.00      6.00      3.22
memnuniyet        1.00      5.00      3.37
donem             1.00      3.00      2.53
```

Aralıklar arasındaki oran doksan katı buluyor. Şimdi üç model ve iki ölçekleme kararı yazılır.
Ölçekleme işlevlerinin **öğrenme** ve **uygulama** olarak ikiye ayrılması bir biçim tercihi değil,
kursun kuralının koda geçmiş halidir.

```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 komsu_tahmin(egt, x, alan, k=15):       # MODELDIR: uzaklik temelli yordam
    u = sorted((sum((x[a] - y[a]) ** 2 for a in alan), y["supheli"]) for y in egt)[:k]
    return int(sum(t[1] for t in u) * 2 > k)


def sikistir(z):                            # S bicimli isleve tasma korumasi
    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 dogrusal_tahmin(m, x, alan):
    return int(sikistir(sum(m[0][i] * x[a] for i, a in enumerate(alan)) + m[1]) > 0.5)


def uc_model(egt, sin, alan=None):
    alan = alan or ALAN
    m1, m3 = agac(egt, 6, alan), dogrusal(egt, alan)
    return (sum(komsu_tahmin(egt, x, alan) == x["supheli"] for x in sin) / len(sin),
            sum(dogrusal_tahmin(m3, x, alan) == x["supheli"] for x in sin) / len(sin),
            sum(agac_tahmin(m1, x) == x["supheli"] for x in sin) / len(sin))


def standart_ogren(egt, sutun):             # OGRENME: ortalama ve degiskenlik
    return {a: (statistics.fmean(x[a] for x in egt),
                statistics.pstdev([x[a] for x in egt])) for a in sutun}


def standart_uygula(p, s):                  # UYGULAMA
    return [dict(x, **{a: (x[a] - p[a][0]) / p[a][1] for a in p}) for x in s]


def normal_ogren(egt, sutun):               # OGRENME: en kucuk ve en buyuk
    return {a: (min(x[a] for x in egt), max(x[a] for x in egt)) for a in sutun}


def normal_uygula(p, s):                    # UYGULAMA
    return [dict(x, **{a: (x[a] - p[a][0]) / (p[a][1] - p[a][0]) for a in p}) for x in s]


PS, PN = standart_ogren(EGT, SAYISAL), normal_ogren(EGT, SAYISAL)
DURUM = [("olceksiz (ham sutun)", EGT, SIN),
         ("standartlastirma", standart_uygula(PS, EGT), standart_uygula(PS, SIN)),
         ("normallestirme", normal_uygula(PN, EGT), normal_uygula(PN, SIN))]
S = {}
print(f"{'karar':<24} {'uzaklik':>8} {'egim temelli':>13} {'agac':>8}")
print(f"{'taban cizgisi':<24} {TABAN:>8.4f} {TABAN:>13.4f} {TABAN:>8.4f}")
for ad, e, s in DURUM:
    S[ad] = uc_model(e, s)
    print(f"{ad:<24} {S[ad][0]:>8.4f} {S[ad][1]:>13.4f} {S[ad][2]:>8.4f}")
h = S["olceksiz (ham sutun)"]
for ad in ("standartlastirma", "normallestirme"):
    k = [S[ad][i] - h[i] for i in range(3)]
    print(f"{ad + ' katkisi':<24} {k[0]:>+8.4f} {k[1]:>+13.4f} {k[2]:>+8.4f}")
```

```
karar                     uzaklik  egim temelli     agac
taban cizgisi              0.7579        0.7579   0.7579
olceksiz (ham sutun)       0.7857        0.7579   0.7778
standartlastirma           0.7698        0.8016   0.7778
normallestirme             0.7619        0.7817   0.7778
standartlastirma katkisi  -0.0159       +0.0437  +0.0000
normallestirme katkisi    -0.0238       +0.0238  +0.0000
```

Ağaç sütunu üç durumda da aynı sayıyı veriyor ve bu, ölçüm gürültüsünün altında kalmış küçük bir
fark değil, **tam bir sıfırdır**. Sebebi gösterilebilir: ağaç her sütunda yalnız değerlerin
sırasına bakar, adayları sıralı ayrık değerler arasından seçer ve bir eşikle böler.
Standartlaştırma ile normalleştirme artan dönüşümlerdir; sırayı değiştirmezler, dolayısıyla ağacın
seçebileceği bölmeler birebir aynı kalır. Ağaç temelli bir yordamın önüne ölçekleme adımı koymak
sonucu değiştirmez; katkısı sıfırdır ve bu, adımın alışkanlık olduğunun tanımıdır.

Eğim temelli doğrusal model ters uçtadır. Ölçeksiz tabloda 0,7579 okuyor — yani tam olarak taban
çizgisi. Bu sayı iyi bir sayı değil, bir çöküş belirtisidir: model her aboneye aynı yanıtı veriyor.
Ortalama tüketim kırk üçe kadar çıkarken hane büyüklüğü altıyı geçmiyor, bu yüzden aynı adım
büyüklüğü bir sütun için çok büyük, öteki için çok küçük kalıyor ve ağırlıklar dört yüz turda
kullanılabilir bir yere ulaşamıyor. Standartlaştırma bu modele 0,0437, yani on bir abone katıyor.

Uzaklık temelli yordamın satırı ise yaygın bir beklentiyi bozuyor. Standartlaştırma ona
**0,0159 kaybettiriyor**, normalleştirme 0,0238. Ölçekleme uzaklık temelli yordamlara yardım eden
bir adım değildir; sütunlara **eşit ağırlık veren** bir adımdır. Bu tabloda ham ölçek zaten en
geniş aralığı en bilgilendirici iki sütuna, ortalama tüketim ile oynaklığa vermişti. Eşitleme o
ağırlığı alıp hane büyüklüğüne ve dönem sayısına dağıtıyor. Kararın işareti, ölçeğin kendisinin
kazara taşıdığı bilgiye bağlıdır ve bu ancak ölçülerek bilinir.

## Ölçek Eğitilmiş Bir Nesnedir

Ölçekleme adımının öğrendiği şey birkaç sayıdır ve o sayılar yalnız eğitim kümesinden gelir.

```python
print(f"{'sutun':<12} {'ortalama':>9} {'degiskenlik':>12} "
      f"{'en kucuk':>9} {'en buyuk':>9}")
for a in SAYISAL:
    print(f"{a:<12} {PS[a][0]:>9.3f} {PS[a][1]:>12.3f} "
          f"{PN[a][0]:>9.2f} {PN[a][1]:>9.2f}")
sn = normal_uygula(PN, SIN)
print(f"\nsinamada [0, 1] araligi disina cikan deger "
      f"{sum(1 for x in sn for a in SAYISAL if not 0.0 <= x[a] <= 1.0)}, "
      f"abone {sum(1 for x in sn if any(not 0.0 <= x[a] <= 1.0 for a in SAYISAL))}")
ss = standart_uygula(PS, SIN)
print(f"{'sutun':<12} {'sinamada en dusuk':>18} {'en yuksek':>10} (standart puan)")
for a in SAYISAL:
    v = [x[a] for x in ss]
    print(f"{a:<12} {min(v):>18.2f} {max(v):>10.2f}")
PT = standart_ogren(EGT, ALAN)
t = uc_model(standart_uygula(PT, EGT), standart_uygula(PT, SIN))
print(f"\non bir sutunun hepsi standartlastirilinca: uzaklik {t[0]:.4f}, "
      f"egim temelli {t[1]:.4f}, agac {t[2]:.4f}")
```

```
sutun         ortalama  degiskenlik  en kucuk  en buyuk
ort_tuketim     19.767        6.200      0.00     42.90
oynaklik         9.622        8.120      0.00     40.57
hane             3.224        1.270      1.00      6.00
memnuniyet       3.372        1.147      1.00      5.00
donem            2.532        0.715      1.00      3.00

sinamada [0, 1] araligi disina cikan deger 2, abone 2
sutun         sinamada en dusuk  en yuksek (standart puan)
ort_tuketim               -2.63       3.83
oynaklik                  -1.19       5.11
hane                      -1.75       2.19
memnuniyet                -2.07       1.42
donem                     -2.14       0.66

on bir sutunun hepsi standartlastirilinca: uzaklik 0.7659, egim temelli 0.8016, agac 0.7778
```

Öğrenilen nesne on sayıdır ve hepsi 756 abonelik eğitim kümesinden çıkmıştır. Uygulanan yerde
bunun görünür bir sonucu var: normalleştirme "her değeri sıfır ile bir arasına oturtur" diye
tanımlanır, ama sınama kümesinde iki değer o aralığın dışına çıkıyor. Bu bir hata değildir ve
düzeltilmez. Düzeltmenin tek yolu en küçüğü ve en büyüğü sınama kümesine de bakarak seçmek
olurdu; o da ölçeği ayrılmış kümeden öğrenmek, yani sızdırmak olurdu. M27/K01 ayrımdan önce
ölçeklemeyi dört sızıntı türünden biri olarak saymıştı; buradaki iş o sayıları tekrarlamak değil,
sızmayan biçimi bir nesne olarak kurmaktır. Standart puan tablosu aynı şeyi öteki yönden gösterir:
oynaklık sütununda sınama kümesindeki en yüksek değer 5,11 standart puandır ve eğitim kümesinden
öğrenilmiş ölçek onu kırpmadan geçirir.

Son satır üçüncü bir kararı ölçüyor: **hangi sütunlar ölçeklenir.** Beş sayısal sütun yerine
ikili sütunlar da dahil on bir sütunun hepsi standartlaştırıldığında eğim temelli model 0,8016'da
kalıyor, ağaç 0,7778'de kalıyor, uzaklık temelli yordam ise 0,7698'den 0,7659'a düşüyor. Bir
abonelik bu fark tek başına okunmaz, ama yönü açıklanabilir: bir ikili sütun standartlaştırıldığında
seyrek olan kategori büyük bir standart puana taşınır ve bölge farkı uzaklık toplamında olduğundan
ağır basar. Ölçekleme kararı tek bir düğme değildir; hangi sütuna uygulandığı da karardır ve o da
ayrılmış kümede ölçülür.

## Özet

- Standartlaştırma eğim temelli doğrusal modele 0,0437, yani on bir abone katıyor; aynı karar
  uzaklık temelli yordamda −0,0159, karar ağacında tam olarak 0,0000 veriyor.
- Ağaçtaki sıfır ölçüm gürültüsü değil kanıtlanabilir bir sonuçtur: standartlaştırma ve
  normalleştirme artan dönüşümlerdir, sütun içindeki sırayı değiştirmezler ve ağaç yalnız sıraya
  bakar.
- Eğim temelli model ölçeksiz tabloda tam olarak taban çizgisini, 0,7579'u okuyor; bu iyi bir sayı
  değil, tek adım büyüklüğünün doksan kat farklı aralıklara yetmediğinin belirtisidir.
- Ölçek eğitim kümesinden öğrenilen on sayıdır; sınama kümesine uygulandığında iki değer [0, 1]
  aralığının dışına çıkar ve bu düzeltilmez, çünkü düzeltmenin tek yolu ölçeği ayrılmış kümeden
  öğrenmektir.
- Ölçeklenecek sütunların seçimi ayrı bir karardır: ikili sütunlar da ölçeklendiğinde uzaklık
  temelli yordam 0,7698'den 0,7659'a iniyor, öteki iki model değişmiyor.

## Sonraki Adım

Bu derste bölge bilgisi hazır beş ikili sütun olarak kullanıldı ve o beş sütunun nereden geldiği
sorulmadı. Oysa bölge bir metin alanıdır ve sayıya çevrilmesi bir karardır: her kategori için bir
sütun açılabilir, kategorilere sıra numarası verilebilir ya da her kategori kendi eğitim
kümesindeki şüpheli oranıyla değiştirilebilir. Üçünün maliyeti farklıdır; birincisi sütun sayısını
kategori sayısı kadar büyütür, üçüncüsü tek sütunla yetinir ama etiketi kodlamanın içine sokar.
Sonraki ders bu üç kodlamayı iki yüz kırk kodluk bir okuma rotası alanında ölçer, ayrılmış kümede
görülmemiş kategorileri sayar ve hedef temelli kodlamanın eğitim kümesinde ürettiği şişmenin kat
içinde hesaplandığında ne kadar geri çekildiğini basar.
