Veri bilimine yeni başlayan herkes aynı hayali kurar: şık modeller, yüksek skorlar, güzel grafikler. Sonra ilk gerçek veri setini açarsın ve manzara şudur yarısı eksik bir sütun, tarihlerin üç farklı formatta yazıldığı bir alan, "Erkek / erkek / E / M / 1" diye beş ayrı şekilde girilmiş bir cinsiyet kolonu..

İşte veri biliminin söylenmeyen kısmı burada başlıyor bence. "Verinin %80'i temizlikte gider" lafını duymuşsundur. Abartı değil. Modeli kurmak çoğu zaman işin en kolay (sayılır) ve en kısa kısmı; asıl zaman, veriyi modele sokulabilir hale getirmekte geçiyor.

Bu yazıda eksik ve bozuk veriyle başa çıkarken en sık karşılaşılan durumları ve bunlarda yapılan klasik hataları konuşacağız.

İlk iş: neyin eksik olduğunu görmek

Hiçbir şey yapmadan önce, elindeki hasarın boyutunu görmen lazım. En basit ama en çok atlanan adım bu:

// ERK TERMINAL python
import pandas as pd

df = pd.read_csv("veri.csv")

# Her kolonda kaç eksik değer var?
print(df.isnull().sum())

# Yüzde olarak görmek daha anlamlı
print((df.isnull().mean() * 100).round(1))

isnull().sum() sana ham sayıyı verir, ama asıl karar verdiren şey yüzdedir. Bir kolonun %2'si mi eksik yoksa %70'i mi bu ikisi tamamen farklı stratejiler gerektirir. Farkındayım kafa karıştırıcı..

Eksik veri: silmek mi, doldurmak mı?

Bir sütunda boş değerler (NaN) gördüğünde ilk refleks genelde ikisinden biri olur: ya o satırları silersin, ya bir şeyle doldurursun. İkisi de doğru olabilir, ikisi de felaket olabilir duruma bağlı.

Silmek (dropna) kolay yol. Ama çok tehlikeli. Eğer eksik veri rastgele dağılmadıysa, sildiğin satırlarla birlikte veriden bir deseni de atmış olabilirsin. Diyelim ki bir ankette yüksek gelirli insanlar gelir sorusunu boş bırakma eğilimindeyse ve sen o satırları silersen, elindeki veri artık gerçeği yansıtmaz. Üstelik az veriyle çalışıyorsan, silmek lüksüne hiç sahip olmayabilirsin. Ya da daha da korkunç senaryo büyük veri tabanlarında büyük kayıplar verebilirsin.

// ERK TERMINAL python
# Tüm eksik satırları sil (dikkatli kullan!)
df_temiz = df.dropna()

# Daha kontrollü: sadece belirli kolon boşsa sil
df_temiz = df.dropna(subset=["gelir"])

# Bir kolonun çoğu boşsa, kolonu komple çıkarmak daha mantıklı olabilir
df_temiz = df.drop(columns=["cok_bos_kolon"])

Doldurmak (fillna) daha çok kontrol verir ama öylesine yapılırsa kendi kendini kandırmaya dönüşür. Eksik sayısal değerleri ortalamayla doldurmak en yaygın yöntem ki ben de çok yaparım, ama ortalama aykırı değerlerden (outlier) çok etkilenir. Birkaç uç değer ortalamayı bozuyorsa, medyan çoğu zaman daha güvenli bir tercih.

Aynı olması gereken değerler aslında aynı değil

İkinci büyük baş ağrısı: tutarsız kategorik veriler... Aynı şeyi ifade eden ama farklı yazılmış değerler. "İstanbul", "istanbul", "ISTANBUL", "Istanbul " (sonunda fazladan boşluk olan hali)... Senin için hepsi aynı şehir, ama bilgisayar için bunlar dört ayrı kategori.

// ERK TERMINAL python
# Önce hasarı gör: kaç farklı yazım var?
print(df["sehir"].value_counts())

# Standartlaştır: boşlukları kırp + küçük harfe çevir
df["sehir"] = df["sehir"].str.strip().str.lower()

# Eş anlamlıları tek değere indir
df["sehir"] = df["sehir"].replace({
    "ist": "istanbul",
    "ankara ": "ankara"
})

Bunları temizlemeden gruplama (groupby) yaparsan, tek bir İstanbul yerine dört parçaya bölünmüş sonuçlar alırsın ve farkına bile varmayabilirsin. Buradaki tuzak şu bu tür hatalar sessizdir. Kod patlamaz, hata vermez, program çalışır.Sen de her şey yolunda sanarsın. Sadece sonucun yanlış çıkar ve sen bunu fark etmezsen rapora öyle gider.

Tip uyuşmazlıkları yani sayı gibi görünüp sayı olmayanlar

Bir kolona bakarsın, içinde sayılar var. Ama toplama yapmaya kalkarsın, hata alırsın. Çünkü o kolon aslında metin (string) olarak saklanıyor. Çoğu zaman sebebi tek bir bozuk satırdır araya kaçmış bir "yok", bir "-", ya da binlik ayıracı olarak konmuş bir nokta.

// ERK TERMINAL python
# Kolon tiplerini kontrol et
print(df.dtypes)

# Metni sayıya çevir çevrilemeyenler NaN olur (hata vermez)
df["fiyat"] = pd.to_numeric(df["fiyat"], errors="coerce")

# Tarihi gerçek tarihe çevir
df["tarih"] = pd.to_datetime(df["tarih"], errors="coerce")

errors="coerce" burada olay çevrilemeyen bozuk değeri patlatmak yerine NaN'a çeviriyor, böylece önce hangi satırların bozuk olduğunu görüp sonra onlara ayrıca karar verebiliyorsun. Tarih kolonu metin olarak durduğu sürece ne sıralayabilirsin ne de aradaki farkı hesaplayabilirsin.

Veri temizleme göz alıcı bir iş değil başta aşırı heyecanlı gelir. Kimse "harika bir fillna yaptım" diye övünmez. Ama bir analizin ya da modelin sağlamlığı, büyük ölçüde bu sessiz aşamada belirleniyor. Çöp veriyle beslenen en gelişmiş model bile çöp üretir — "garbage in, garbage out" lafı boşuna değil.Periodt.

Veriye hayranlık duyan ve bu yoldan ilerlemek isteyen bir öğrenci olarak şimdiden biliyorum modelden önce veriye saygı duymak gerekiyor. Kafanızı çevirdiğinizde gördüğünüz her şey veri. Veriye sahip çıkalım :)

Nisa Kaya, 4. sınıf Bilgisayar Mühendisliği okuyan, veriyle uğraşmayı seven biri