---
title: 'Kategorik Değerlerin Düzeltilmesi'
source: 'https://academia.sh/tr/kurslar/veri-hazirlama/kategorik-degerlerin-duzeltilmesi'
course: 'Veri Toplama ve Hazırlama'
language: tr
updated: '2026-08-17T18:08:44+00:00'
license: 'CC BY-SA 4.0'
---

# Kategorik Değerlerin Düzeltilmesi

Devralınan 1.816 satırın tarife alanında 15 ayrı yazım geçer. Normalleştirme merdiveni kategori sayısını 15'ten sırayla 14, 9, 8 ve 6'ya, tarife cetvelinden gelen anlam eşlemesi 5'e indirir; dile duyarsız küçültme yalnız beş yazımı birleştirir ve iki yazımda görünmez bir iz bırakır. Satır sayısı hiç değişmez, ama sınıfların içi değişir: işyeri ile ticari birleştirilirse kategori 4'e iner ve 368 satır yanlış tarife basamağına taşınır, ticari sınıfı 389'dan 757'ye çıkar. Dile duyarsız küçültmeye göre yazılmış yedi girdilik bir eşleme tablosu 216 satırı sınıfsız bırakır, hiçbir hata üretmez ve tarife sınıfına göre gruplamada grupların toplamı 1.816 yerine 1.600 olur.

Önceki dört ders sayısal alanları temizledi ve kümede hiç bakılmamış bir alan kaldı: tarife sınıfı.
O alan bir sayı değil, saha formuna elle yazılmış bir metindir ve aynı sınıf birden çok biçimde
yazılmıştır.

Bu ders o alanı düzeltir ve düzeltirken iki ayrı işin karıştığını gösterir. **Yazım düzeltmesi**
metinden çıkar: aynı sözcüğün baştaki boşluğu, büyük harfi, iç boşluğu farklı yazılmıştır ve bunlar
aynı kategoridir. **Anlam kararı** ise metinden çıkmaz: iki farklı sözcüğün aynı sınıfı gösterip
göstermediğini ancak tarife cetveli söyler. Birincisi bir sayaç işidir, ikincisi bir yargıdır ve
yanlış olduğunda satır sayısını hiç oynatmadan **satırları yanlış kutuya** koyar.

- **VZ17.** Küme önceki dört dersten devralınır ve 1.816 satırdır. Küme `node` ile **modellenir** ve
  **kurgudur**; tarife sınıfları ve cetvel de kurgudur.
- **VZ18.** Küçük harfe çevirme **dile bağlıdır**. Dile duyarsız çevirim bazı harfleri gözle
  görünmeyen bir işaretle bırakır ve iki metin aynı görünüp farklı kalır; bu yüzden merdivende iki
  ayrı basamak sayılır.
- **VZ19.** **Kategori birleştirme** yazım farklarını kaldırır. Anlam eşlemesi ayrı bir adımdır ve
  kaynağı tarife cetvelidir.
- **VZ20.** Bir eşleme tablosunda karşılığı olmayan yazım **hata üretmez**: satır sınıfsız kalır ve
  sınıfa göre gruplayan ilk işlemde sessizce dışarıda kalır.

## Kaç Kategori Kalıyor

```js
// kategori.mjs — ayni ham kume MODELIDIR. Kume kurgudur: bolgesel olcum aginin
// 1400 abonesi ve saha ziyaret kayitlari; ayni tohum, ayni satirlar. Onceki dort
// dersin karari uygulanir ve bu adima 1816 satir girer.
export const TOHUM = 20260305, ABONE = 1400;
const karistir = (x) => { x = Math.imul(x ^ (x >>> 16), 2246822507);
  x = Math.imul(x ^ (x >>> 13), 3266489909); return (x ^ (x >>> 16)) >>> 0; };
export const uretec = (t) => { let s = karistir(t);
  return () => (s = (s * 1664525 + 1013904223) >>> 0) / 4294967296; };
export const ayrik = (u, w) => { let t = 0;
  for (let i = 0; i < w.length; i++) { t += w[i]; if (u < t) return i; } return w.length - 1; };
// Son alan: ziyaretin okuma uretmeme orani. Bolgeler bu oranda ayrisir.
export const BOLGE = [["kuzey", "KZ", 0.28, 21, 0.06], ["guney", "GN", 0.22, 17, 0.03],
  ["dogu", "DG", 0.18, 26, 0.27], ["bati", "BT", 0.14, 14, 0.03],
  ["merkez", "MR", 0.18, 23, 0.08]]
  .map(([ad, kod, pay, taban, eksik]) => ({ ad, kod, pay, taban, eksik }));
const SOKAK = ["Çınar", "Söğüt", "Işık", "Ihlamur", "Zeytin", "Menekşe", "Palmiye", "Ceviz"];
const TARIFE = ["Mesken", "mesken", "MESKEN", " Mesken ", "Konut", "konut", "Ticari",
  "ticari", "TİCARİ", "Is yeri", "İş Yeri", "isyeri", "Sanayi", "sanayi", "Tarimsal"];

export const HAM = [];
let bir = null;
for (let i = 0; i < ABONE; i++) {
  const r = uretec(TOHUM + i);
  const b = BOLGE[ayrik(r(), BOLGE.map((x) => x.pay))];
  const taban = Math.max(1.2, b.taban * Math.exp((r() + r() + r() - 1.5) * 0.62));
  const sayac = `${b.kod}-${String(1000 + i).padStart(4, "0")}`;
  const paylas = bir && bir.b === b.ad && r() < 0.03;   // ayni binada ikinci sayac
  const sk = paylas ? bir.sk : SOKAK[Math.floor(r() * SOKAK.length)];
  const kapi = paylas ? bir.kapi : 1 + Math.floor(r() * 60);
  const daire = paylas ? bir.daire : r() < 0.26 ? `/${1 + Math.floor(r() * 9)}` : "";
  bir = { b: b.ad, sk, kapi, daire };   // adres alanlari ders 06'da kullanilir
  const endeks0 = 8000 + Math.floor(r() * 11000);
  for (const d of r() < 0.34 ? ["2026-01", "2026-02"] : ["2026-01"]) {
    const q = uretec(TOHUM + 7000 + HAM.length), u = q();
    const gercek = Math.round(taban * (d === "2026-02" ? 0.94 : 1) * 100) / 100;
    // Eksiklik uc bicimde gorunur: hucre bos, hucrede yalniz bosluk, "yok" yazili.
    const eksik = u < b.eksik ? ayrik(q(), [0.52, 0.19, 0.29]) : -1;
    const kayma = eksik < 0 && q() < 0.008;   // ondalik kaymasi: okuma on kat yazilmis
    const yazilan = kayma ? Math.round(gercek * 1000) / 100 : gercek;
    const okuma = eksik === 0 ? "" : eksik === 1 ? "  " : eksik === 2 ? "yok"
      : q() < 0.31 ? yazilan.toFixed(2).replace(".", ",") : yazilan.toFixed(2);
    const gun = 1 + Math.floor(q() * 27), ay = d.slice(5);
    const tb = ayrik(q(), [0.55, 0.21, 0.24]);
    const tarih = tb === 0 ? `${d}-${String(gun).padStart(2, "0")}`
      : tb === 1 ? `${String(gun).padStart(2, "0")}.${ay}.2026`
      : `${String(gun).padStart(2, "0")}/${ay}/2026`;
    const endeks = endeks0 + Math.round(gercek * (d === "2026-02" ? 2 : 1));
    const eb = q() < 0.22;
    // Adres alani bu derste kullanilmiyor; yalniz yazim bicimi saklanir.
    const av = ayrik(q(), [0.30, 0.18, 0.18, 0.16, 0.18]);
    HAM.push({ abone_no: 10001 + i, sayac_no: q() < 0.011 ? "" : sayac, bolge: b.ad,
      donem: d, okuma_metni: okuma,
      endeks_metni: eb ? `${Math.floor(endeks / 1000)}.${String(endeks % 1000).padStart(3, "0")}`
        : `${endeks}`,
      tarih_metni: tarih, tarife_metni: TARIFE[ayrik(q(), Array(15).fill(1 / 15))],
      adres_bicim: av, gercek_m3: gercek, yazilan_m3: eksik < 0 ? yazilan : null });
    if (q() < 0.09) {   // ayni ziyaret ikinci kez girilmis
      const on = HAM[HAM.length - 1], bicim = ayrik(q(), [0.34, 0.28, 0.38]);
      HAM.push({ ...on,
        sayac_no: bicim === 0 ? ` ${sayac}` : bicim === 1 ? sayac.toLowerCase() : sayac,
        adres_bicim: av === 2 ? 4 : 2,
        tarife_metni: TARIFE[ayrik(q(), Array(15).fill(1 / 15))] });
    }
  }
}

// Okumayi sayiya cevirir. Ondalik ayraci virgul de olabilir; donusumun kendi
// tuzaklari bu konunun ucuncu dersinde olculur, burada tolere edilir.
export const sayiya = (t) => { const s = String(t).trim().replace(",", ".");
  return s === "" || !/^\d+(\.\d+)?$/.test(s) ? null : Number(s); };
export const medyan = (a) => { const l = [...a].sort((x, y) => x - y);
  return l.length % 2 ? l[(l.length - 1) / 2] : (l[l.length / 2 - 1] + l[l.length / 2]) / 2; };
export const y = (w) => (h) => h.map((v, j) => (j ? String(v).padStart(w[j])
  : String(v).padEnd(w[0]))).join("");

// Onceki dersin karari: kimlik alani bos olan satirlar elendi, eksik okumali
// satirlar isaretlenip bolge ortancasiyla dolduruldu. Bu adima 2068 satir girer.
const kimlikli = HAM.filter((s) => s.sayac_no.trim() !== "");
const olculen = kimlikli.filter((s) => sayiya(s.okuma_metni) !== null);
const bolgeMed = new Map(BOLGE.map((b) => [b.ad, medyan(olculen
  .filter((s) => s.bolge === b.ad).map((s) => sayiya(s.okuma_metni)))]));
export const GIREN = kimlikli.map((s) => sayiya(s.okuma_metni) === null
  ? { ...s, okuma_metni: bolgeMed.get(s.bolge).toFixed(2) } : s);

// Onceki dort dersin karari: eksik doldurma, tekillestirme, bicim farkinda
// donusum ve ceyrekler acikligiyla isaretlenen 64 satirin ayrilmasi.
const tekille = (l, k) => { const m = new Map();
  for (const s of l) if (!m.has(k(s))) m.set(k(s), s); return [...m.values()]; };
const OKUMA = tekille(GIREN, (s) => `${s.abone_no}|${s.donem}|${s.sayac_no.trim().toUpperCase()}`)
  .map((s) => ({ ...s, okuma_m3: Number(s.okuma_metni.trim().replace(",", ".")) }));
const ceyrek = (a, p) => { const l = [...a].sort((x, z) => x - z);
  const h = (l.length - 1) * p, i = Math.floor(h);
  return l[i] + (h - i) * (l[Math.min(i + 1, l.length - 1)] - l[i]); };
const dd = OKUMA.map((s) => s.okuma_m3);
const q1 = ceyrek(dd, 0.25), q3 = ceyrek(dd, 0.75), ca = q3 - q1;
export const GIREN4 = OKUMA.filter((s) => s.okuma_m3 >= q1 - 1.5 * ca && s.okuma_m3 <= q3 + 1.5 * ca);

// Normallestirme merdiveni. Her adim bir oncekinin uzerine biner; her adimdan
// sonra kac ayri kategori kaldigi sayilir.
export const N = [
  ["N0 ham metin", (t) => t],
  ["N1 kirpma", (t) => t.trim()],
  ["N2 kucuk harf (dile duyarsiz)", (t) => t.trim().toLowerCase()],
  ["N3 kucuk harf (dile duyarli)", (t) => t.trim().toLocaleLowerCase("tr")],
  ["N4 isaret ve bosluk sadelestirme", (t) => t.trim().toLocaleLowerCase("tr")
    .replace(/\u0307/g, "").replace(/ş/g, "s").replace(/ı/g, "i").replace(/\s+/g, "")],
];
// Anlam eslemesi metinden cikmaz; tarife cetvelinden gelir.
export const ESLEME = { mesken: "mesken", konut: "mesken", ticari: "ticari",
  isyeri: "isyeri", sanayi: "sanayi", tarimsal: "tarimsal" };
export const anahtar = N[4][1];

if (import.meta.url === `file://${process.argv[1]}`) {
  console.log(`model (tohum ${TOHUM}): onceki adimdan devralinan kume ${GIREN4.length} satir; ` +
    `tarife alaninda ${new Set(GIREN4.map((s) => s.tarife_metni)).size} ayri yazim geciyor`);
  const y1 = y([36, 11, 11]);
  console.log("\n" + y1(["normallestirme adimi", "kategori", "birlesen"]));
  let onceki = null;
  for (const [ad, f] of N) { const k = new Set(GIREN4.map((s) => f(s.tarife_metni))).size;
    console.log(y1([ad, k, onceki === null ? 0 : onceki - k])); onceki = k; }
  const sinif = new Set(GIREN4.map((s) => ESLEME[anahtar(s.tarife_metni)]));
  console.log(y1(["N5 anlam eslemesi (tarife cetveli)", sinif.size, onceki - sinif.size]));

  const y2 = y([12, 14, 14, 14]);
  console.log("\n" + y2(["yazim", "N2", "N3", "N4"]));
  for (const yz of [" Mesken ", "TİCARİ", "Ticari", "İş Yeri", "Is yeri", "isyeri"])
    console.log(y2([JSON.stringify(yz), ...N.slice(2).map(([, f]) => JSON.stringify(f(yz)))]));
}
```

```
model (tohum 20260305): onceki adimdan devralinan kume 1816 satir; tarife alaninda 15 ayri yazim geciyor

normallestirme adimi                   kategori   birlesen
N0 ham metin                                 15          0
N1 kirpma                                    14          1
N2 kucuk harf (dile duyarsiz)                 9          5
N3 kucuk harf (dile duyarli)                  8          1
N4 isaret ve bosluk sadelestirme              6          2
N5 anlam eslemesi (tarife cetveli)            5          1

yazim                   N2            N3            N4
" Mesken "        "mesken"      "mesken"      "mesken"
"TİCARİ"        "ti̇cari̇"      "ticari"      "ticari"
"Ticari"          "ticari"      "ticari"      "ticari"
"İş Yeri"       "i̇ş yeri"     "iş yeri"      "isyeri"
"Is yeri"        "is yeri"     "ıs yeri"      "isyeri"
"isyeri"          "isyeri"      "isyeri"      "isyeri"
```

Merdiven altı basamakta 15 yazımı 5 sınıfa indiriyor ve her basamağın kaç yazım birleştirdiği ayrı
yazılıyor. Asıl işi küçük harfe çevirme yapar: **beş** yazım birleşir. Sonraki basamak bir yazım
daha birleştirir, yani dile duyarsız çevirim **bir yazımı çözememiştir**.

İkinci tablo bunu gösteriyor. `"TİCARİ"` dile duyarsız çevrildiğinde ortaya çıkan metin ekranda
`"ticari"` gibi görünür ama değildir: harfin üstündeki nokta ayrı bir işaret olarak kalır ve iki
metin karşılaştırıldığında farklı çıkar. `"Is yeri"` ile `"İş Yeri"` çifti aynı sorunun tersidir —
dile duyarlı çevirim ikisini `"ıs yeri"` ve `"iş yeri"` yapar ve **hâlâ ayrıdır**; ancak işaretleri
ve boşlukları sadeleştiren basamak ikisini `"isyeri"` altında birleştirir.

Son basamak metinle ilgili değildir: `"konut"` ile `"mesken"` iki ayrı sözcüktür ve hiçbir
normalleştirme onları birleştirmez; tarife cetveli aynı basamağa baktıklarını söylediği için
birleşirler. Merdivenin tek **yargı** basamağı budur.

## Yanlış Birleştirme

```js
// birlestirme.mjs — ayni kume, iki soru: iki kategoriyi birlestirmek kac satiri
// yanlis sinifa tasiyor ve eksik bir esleme tablosu kac satiri sinifsiz birakiyor.
import { GIREN4, ESLEME, anahtar, N, y } from "./kategori.mjs";

const dagit = (esleme, anh) => { const m = new Map();
  for (const s of GIREN4) { const k = esleme[anh(s.tarife_metni)];
    m.set(k, (m.get(k) ?? 0) + 1); } return m; };
const dogru = dagit(ESLEME, anahtar);
// Tarife cetvelinde isyeri ve ticari ayri basamaklardir; ikisini birlestirmek
// bir yazim duzeltmesi degil, bir anlam kararidir.
const YANLIS = { ...ESLEME, isyeri: "ticari" };
const yanlis = dagit(YANLIS, anahtar);

const y1 = y([12, 12, 14, 12]);
console.log(y1(["sinif", "dogru esleme", "isyeri>ticari", "fark"]));
for (const k of [...dogru.keys()].sort())
  console.log(y1([k, dogru.get(k), yanlis.get(k) ?? 0, (yanlis.get(k) ?? 0) - dogru.get(k)]));
console.log(`toplam ${[...dogru.values()].reduce((a, b) => a + b, 0)} satir her iki eslemede de ` +
  `yerinde duruyor; kategori sayisi ${dogru.size}'ten ${yanlis.size}'e iniyor ve ` +
  `${dogru.get("isyeri")} satir yanlis sinifa tasiniyor`);

// Yaygin esleme tablosu: dile duyarsiz kucultmeden gecen yazimlarla yazilmis.
// Tabloda karsiligi olmayan yazim bir hata uretmez, sinifsiz kalir.
const YAYGIN = { mesken: "mesken", konut: "mesken", ticari: "ticari",
  "is yeri": "isyeri", isyeri: "isyeri", sanayi: "sanayi", tarimsal: "tarimsal" };
const kaba = N[2][1];
const sinifsiz = GIREN4.filter((s) => YAYGIN[kaba(s.tarife_metni)] === undefined);
const y2 = y([26, 8, 16]);
console.log("\n" + y2(["esleme tablosu", "girdi", "sinifsiz satir"]));
console.log(y2(["yaygin (N2 anahtarlari)", Object.keys(YAYGIN).length, sinifsiz.length]));
console.log(y2(["N4 anahtarlari", Object.keys(ESLEME).length,
  GIREN4.filter((s) => ESLEME[anahtar(s.tarife_metni)] === undefined).length]));
console.log(`sinifsiz kalan ${sinifsiz.length} satirin tarife yazimlari: ` +
  [...new Set(sinifsiz.map((s) => s.tarife_metni))].map((v) => JSON.stringify(v)).join(", "));
console.log(`tarife sinifina gore gruplama bu ${sinifsiz.length} satiri sessizce disarida ` +
  `birakir: gruplarin toplami ${GIREN4.length - sinifsiz.length}, kume ise ${GIREN4.length} satir`);

console.log(`\nsatir hesabi: giren ${GIREN4.length}, cikan ${GIREN4.length}; ` +
  `0 satir elendi, 0 satir sessizce dustu. 15 yazim ${dogru.size} sinifta birlesti; ` +
  `isyeri ile ticari birlestirilseydi ${dogru.get("isyeri")} satir yanlis sinifa gider, ` +
  `yaygin esleme tablosu kullanilsaydi ${sinifsiz.length} satir sessizce duserdi`);
```

```
sinif       dogru esleme isyeri>ticari        fark
isyeri               368             0        -368
mesken               713           713           0
sanayi               215           215           0
tarimsal             131           131           0
ticari               389           757         368
toplam 1816 satir her iki eslemede de yerinde duruyor; kategori sayisi 5'ten 4'e iniyor ve 368 satir yanlis sinifa tasiniyor

esleme tablosu               girdi  sinifsiz satir
yaygin (N2 anahtarlari)          7             216
N4 anahtarlari                   6               0
sinifsiz kalan 216 satirin tarife yazimlari: "TİCARİ", "İş Yeri"
tarife sinifina gore gruplama bu 216 satiri sessizce disarida birakir: gruplarin toplami 1600, kume ise 1816 satir

satir hesabi: giren 1816, cikan 1816; 0 satir elendi, 0 satir sessizce dustu. 15 yazim 5 sinifta birlesti; isyeri ile ticari birlestirilseydi 368 satir yanlis sinifa gider, yaygin esleme tablosu kullanilsaydi 216 satir sessizce duserdi
```

İlk tablo yanlış bir yargının bedelini gösteriyor. İşyeri ile ticari abonelik cetvelde ayrı
basamaklardır, ama iki sözcük gündelik dilde birbirinin yerine kullanıldığı için birleştirmek akla
yatkın görünür. Uygulandığında kategori sayısı 5'ten 4'e iner, **satır sayısı hiç değişmez** ve 368
satır ticariye taşınır: 389 olan ticari 757'ye çıkar, işyeri sınıfı kaybolur. Kümede hiçbir şey
eksilmez; yalnız her tarife kırılımı bundan sonra yanlış çıkar.

İkinci tablo sessiz kaybı ölçüyor. Yaygın eşleme tablosu dile duyarsız küçültmeden geçmiş
yazımlarla yazılmıştır ve yedi girdi taşır. İki yazımın — `"TİCARİ"` ve `"İş Yeri"` — o tabloda
karşılığı yoktur; bu yazımları taşıyan **216 satır sınıfsız kalır**. Hiçbir hata üretilmez, hiçbir
işlem durmaz. Tarife sınıfına göre gruplandığında grupların toplamı **1.600**'dür, oysa küme 1.816
satırdır. Aradaki 216 satır tabloda hiçbir yerde görünmez.

Aynı eşleme tablosu, sadeleştirilmiş anahtarlarla yazıldığında altı girdiyle **sıfır** satır
sınıfsız bırakır. Fark tablonun büyüklüğünde değil, **hangi normalleştirmeden sonra yazıldığında**.

Adımın hesabı şudur: **giren 1.816 satır, çıkan 1.816 satır.** Hiçbir satır elenmedi, hiçbir satır
sessizce düşmedi; 15 yazım 5 sınıfta birleşti. Bu adımın bedeli yine yapılmadığında ortaya çıkar:
işyeri ile ticari birleştirilseydi 368 satır yanlış sınıfa gider, yaygın eşleme tablosu
kullanılsaydı 216 satır sessizce düşerdi. **Satır sayısı bir denetim ölçüsü değildir**; bu adımda
giren ile çıkan eşittir ve kümenin içi yine de baştan aşağı değişmiştir.

## Özet

- Tarife alanında 15 ayrı yazım geçer; normalleştirme merdiveni kategori sayısını 15, 14, 9, 8, 6
  ve anlam eşlemesiyle 5'e indirir.
- Dile duyarsız küçültme beş yazım birleştirir ama iki yazımda görünmeyen bir işaret bırakır.
  Yazım düzeltmesi metinden, anlam eşlemesi tarife cetvelinden gelir.
- İşyeri ile ticariyi birleştirmek kategori sayısını 4'e indirir, satır sayısını hiç oynatmaz ve
  368 satırı yanlış sınıfa taşır: ticari 389'dan 757'ye çıkar.
- Dile duyarsız anahtarlarla yazılmış yedi girdilik eşleme tablosu 216 satırı sınıfsız bırakır ve
  gruplamada toplam 1.816 yerine 1.600 çıkar; sadeleştirilmiş anahtarlarla yazılan altı girdilik
  tablo sıfır satır düşürür.
- Adımın hesabı: giren 1.816, çıkan 1.816; 0 elendi, 0 sessizce düştü, 15 yazım 5 sınıfta birleşti.

## Sonraki Adım

Tarife alanı düzeldi, ama aynı iş kümenin bütün metin alanları için yapılmadı. Sayaç kodu iki
derste kırpıldı ve harf birliğine getirildi; adres alanına hiç dokunulmadı ve kümedeki her adres,
abone kütüğündeki karşılığından farklı yazılmıştır. Sonraki ders normalleştirme merdivenini adres
alanına uygular, her basamağın kütükle eşleşmeyi kaç kayıtta **kurtardığını** sayar ve bir basamak
daha ileri gitmenin kaç kaydı **ayırt edilemez** hale getirdiğini ölçer.
