← Back to list

Aykırı Değerler (Outliers) — Bölüm 1: Bir Hata mı, Yoksa Bir Sinyal mi?

Eksik verilerin nasıl ele alındığını öğrendik. Şimdi sırada verideki aykırı değerlerin (outliers) bir hata mı yoksa sinyal mi olduğunu…

Barış Yıldırım in Kahve Yanı Veri · 2026-06-01 10:35 · 102 claps · 6.7 min read
#outliers #veri-bilimi #aykırı-değer #interquartile-range #z-score
Open on Medium ↗

Aykırı Değerler (Outliers) — Bölüm 1: Bir Hata mı, Yoksa Bir Sinyal mi?

Eksik verilerin nasıl ele alındığını öğrendik. Şimdi sırada verideki aykırı değerlerin (outliers) bir hata mı yoksa sinyal mi olduğunu öğrenelim.

Aykırı Değer Nedir?

Teknik tanım olarak aykırı değer, verinin genel dağılımından istatistiksel olarak anlamlı biçimde uzaklaşan gözlemdir. Bu tanım tek başına bir şey ifade etmiyor veri toplama aykırı değerleri analiz ederken iki ana senaryoda ele almalıyız.

1. Aykırı Değerler Bir “Hata” Olduğunda (Gürültü/Noise)

Eğer aykırı değer, veri toplama sürecinde insani hatalardan, cihaz bozukluklarından veya yazılımsal bug’lardan kaynaklanıyorsa bu bir gürültüdür ve temizlenmelidir.

  • Bir e-ticaret veri setinde kullanıcı yaşının klavye sürçmesiyle 320 yazılması.
  • Bir hastanın nabzı 70–80 bpm arasındayken, bir ölçümde 220 bpm çıkmış. Bu büyük olasılıkla cihaz hatası

2. Aykırı Değer Bir “SİNYAL” Olduğunda (Anlamlı Bilgi/İnsight)

Aykırı değer gerçek bir olaydan kaynaklanıyorsa o değer aslında veri setinin içindeki en kıymetli veridir.

  • Bir sağlık verisinde herkes günde 7.000 adım atarken bir kişinin 45.000 adım atması. O kişi o gün maraton koşmuş bir atlet olabilir.
  • Bir finans verisinde her ay 5.000 TL harcanan bir kredi kartından gecenin bir yarısı tek seferde 500.000 TL harcanması. Bu, silinmesi gereken bir aykırı değer değil; acilen müdahale edilmesi gereken bir sahtekarlık (Fraud) sinyalidir.

Aykırı Değer Türleri

Aykırı değerlerin tek tip olmadığını anlamak doğru yöntemi seçmek için kritiktir.

  • Tek Değişkenli (Univariate) Aykırı Değerler: Tek bir sütunun dağılımına bakıldığında görülen aykırılıktır. En yaygın türdür.

Görsel yazara aittir.

Görsel yazara aittir.

  • Çok Değişkenli (Multivariate) Aykırı Değerler: Tek tek bakıldığında normal görünen ama birlikte ele alındığında anlamsız olan değerler.

Görsel yazara aittir.

Görsel yazara aittir.

  • Bağlamsal (Contextual) Aykırı Değerler: Bağlama göre aykırı olan değerlerdir.

Görsel yazara aittir.

Görsel yazara aittir.

Aykırı Değerlerin İstatistiksel Teşhis Yöntemleri

Aykırı değer türlerini anladık. Peki elimizdeki binlerce satırlık büyük verilerde bu yalnız süvarileri istatistiksel olarak nasıl yakalayacağız?

Bu bölümde yapacağımız analizleri canlı canlı görebilmek için öncelikle içinde hem normal dağılan hem de ekstrem uç değerler barındıran örnek bir veri seti oluşturalım:

import numpy as np
import pandas as pd
import matplotlib.pyplot as plt
import seaborn as sns
from scipy import stats

# Görsel ayarlar
plt.rcParams['figure.figsize'] = (12, 5)
plt.rcParams['font.size'] = 12
sns.set_theme(style='whitegrid', palette='muted')

# Örnek veri — normal dağılım + kasıtlı aykırı değerler
np.random.seed(42)
normal_data = np.random.normal(loc=50, scale=10, size=200)
outliers    = np.array([5, 8, 95, 102, 110])
data        = np.concatenate([normal_data, outliers])

print(f"Veri boyutu : {len(data)}")
print(f"Ortalama    : {data.mean():.2f}")
print(f"Medyan      : {np.median(data):.2f}")
print(f"Std         : {data.std():.2f}")
print(f"Min / Max   : {data.min():.1f} / {data.max():.1f}")

Görsel yazara aittir.

Görsel yazara aittir.

IQR — Interquartile Range (Çeyrekler Arası Aralık)

Veriyi küçükten büyüye dizdiğimizde, tam ortada kalan ve verinin ana karakterini oluşturan %50'lik merkez kitleyi baz alır. Bu merkez kitlenin genişliğine (IQR) bağlı olarak yasal alt ve üst sınırlar çizer; bu sınırların ötesinde kalan, yani merkeze aşırı uzaklaşmış ekstrem uç değerleri tespit eder.

Ne zaman kullanılır?

  • Çarpık (skewed) dağılımlarda: Veri sağa veya sola doğru kuyruk oluşturuyorsa en güvenli limandır.
  • Normal dağılım varsayımı yapmak istemediğinizde: Verinin nasıl bir dağılıma sahip olduğunu bilmediğiniz anlarda hayat kurtarır.
  • Küçük-orta boyutlu veri setlerinde: Hesaplanması kolay ve maliyetsizdir.
  • Aşırı uç değerlere karşı dayanıklı (robust) bir yöntem istediğinizde: Medyan bazlı bir mantık kullandığı için uç değerlerin kendisinden etkilenmez.

Sektörde kod yazarken işleri otomatize etmek ve tekrar kullanılabilir (reusable) yapılar kurmak kritiktir. İşte verimizi analiz edip sınırları konsola basacak o fonksiyonel IQR kodumuz:

def detect_outliers_iqr(series: pd.Series, multiplier: float = 1.5) -> pd.Series:
    """IQR yöntemi ile aykırı değer tespiti.

    Returns:
        Boolean mask — True = aykırı değer
    """
    Q1 = series.quantile(0.25)
    Q3 = series.quantile(0.75)
    IQR = Q3 - Q1

    alt_sinir = Q1 - multiplier * IQR
    ust_sinir = Q3 + multiplier * IQR

    print(f"Q1            : {Q1:.2f}")
    print(f"Q3            : {Q3:.2f}")
    print(f"IQR           : {IQR:.2f}")
    print(f"Alt Sınır     : {alt_sinir:.2f}")
    print(f"Üst Sınır     : {ust_sinir:.2f}")

    return (series < alt_sinir) | (series > ust_sinir)

# Hazırladığımız data dizisini Pandas Series'e çevirip fonksiyona paslıyoruz
s = pd.Series(data)
outlier_mask_iqr = detect_outliers_iqr(s)

print(f"\nToplam gözlem : {len(s)}")
print(f"Tespit edilen : {outlier_mask_iqr.sum()} aykırı değer")
print(f"Aykırı değerler: {s[outlier_mask_iqr].values}")

Görsel yazara aittir.

Görsel yazara aittir.

Gördüğünüz gibi kusursuz çalıştı; alt sınır olan 24.31'in altındaki 5, 8, 23.80254896 ile, üst sınır olan 73.76'nin üzerindeki 74.63242112, 77.20169167, 95, 102, 110 değerleri tam isabetle yakalandı.

Yazdığımız bu fonksiyonun arkasındaki sınır çizgilerini ve yakaladığımız o yalnız noktaları kutu grafiğiyle (box-plot) görselleştirelim:

# Seaborn ile yatay bir kutu grafiği çiziyoruz
sns.boxplot(x=s, color='skyblue', medianprops=dict(color='red', linewidth=2), flierprops={"marker": "o", "markerfacecolor": "red", "markersize": 8})

plt.title("IQR Yöntemi ile Aykırı Değerlerin Box-plot Üzerinde Teşhisi", fontsize=14, pad=15)
plt.xlabel("Skor Dağılımı")
plt.show()

Görsel yazara aittir.

Görsel yazara aittir.

Yukarıdaki çıktımızın grafik üzerindeki incelenmesi tam olarak şöyledir:

  • Mavi Kutunun İçi (%50'lik Gövde): Sol kenar 42.86 (Q1) noktasından başlar, sağ kenar 55.22 (Q3) noktasında biter. Ortadaki çizgi (kırmızı) medyanımızdır (50.05).
  • Bıyıklar (Whiskers): Soldaki bıyık çizgisi 24.31 sınırında durur, sağdaki bıyık ise 73.76 sınırında kesilir.
  • Kırmızı Noktalar: Sınırların tamamen dışında, sağda ve solda tek başına duran o kırmızı yuvarlaklar, kodumuzun maskelediği ve kasıtlı eklediğimiz [5, 8, 23.80, 74.63, 77.20, 95, 102, 110] aykırı değerleridir.

Z-Score — Standart Sapma

Verinin normal dağıldığı (Çan Eğrisi) senaryolarda tercih edilir. Her bir veri noktasının ortalama çizgisinden kaç standart sapma uzakta olduğunu hesaplar. Genel kabul olarak, ortalamadan 3 standart sapma uzaktaki (‭Z > 3‬‭‬ veya ‭Z < -3) değerleri aykırı ilan eder.

Ne zaman kullanılır?

  • Normal (Gaussian) dağılımlarda: Veri simetrik bir çan eğrisi oluşturuyorsa en ideal istatistiksel silahtır.

Görsel yazara aittir.

Görsel yazara aittir.

  • Büyük veri setlerinde: Ortalama ve standart sapma tüm evreni iyi temsil ettiğinde harika çalışır.
  • Standardizasyon gerektiğinde: Veriyi ölçeklendirirken aynı esnada aykırı değer tespiti yapmak istediğinizde.

Z-Score mantığını da tıpkı IQR gibi fonksiyonel hale getirip, bizim ana verimiz üzerinde çalıştıralım:

def detect_outliers_zscore(series: pd.Series, threshold: float = 3.0) -> pd.Series:
    """Z-Score yöntemi ile aykırı değer tespiti.

    Returns:
        Boolean mask — True = aykırı değer
    """
    # Her noktanın Z-Skorunun mutlak değerini hesaplıyoruz
    z_scores = np.abs(stats.zscore(series))

    mean_val = series.mean()
    std_val = series.std()

    alt_sinir = mean_val - threshold * std_val
    ust_sinir = mean_val + threshold * std_val

    print(f"Ortalama      : {mean_val:.2f}")
    print(f"Standart Sapma: {std_val:.2f}")
    print(f"Alt Sınır (-3σ): {alt_sinir:.2f}")
    print(f"Üst Sınır (+3σ): {ust_sinir:.2f}")

    return z_scores > threshold

# Fonksiyonu ana serimiz üzerinde çalıştırıyoruz
outlier_mask_z = detect_outliers_zscore(s)

print(f"\nToplam gözlem : {len(s)}")
print(f"Tespit edilen : {outlier_mask_z.sum()} aykırı değer")
print(f"Aykırı değerler: {s[outlier_mask_z].values}")

Görsel yazara aittir.

Görsel yazara aittir.

Z-Score yöntemi 23.80, 74.63, 77.20 değerlerini aykırı olarak yakalayamadı. Standart sapma şişince yasal alt sınır 13.93’e yasal üst sınır 85.96’ya kadar genişledi ve 23.80, 74.63, 77.20 sayıları bu sınırın içinde kalarak kurtuldu. Bu duruma istatistikte maskeleme etkisi (masking effect) denir.

Sınırların ve dağılımın çan eğrisi üzerindeki görsel olarak yerini görelim:

# Verinin dağılım eğrisini çiziyoruz
sns.histplot(s, kde=True, color='purple', alpha=0.4)

# Z-Score sınır çizgilerini grafiğe ekliyoruz
plt.axvline(x=49.94 - 3*12.00, color='red', linestyle='--', label='Alt Sınır (-3σ)')
plt.axvline(x=49.94 + 3*12.00, color='red', linestyle='--', label='Üst Sınır (+3σ)')

plt.title("Z-Score Sınırlarının Veri Dağılımı Üzerindeki Gösterimi", fontsize=14, pad=15)
plt.xlabel("Değerler")
plt.legend()
plt.show()

Görsel yazara aittir.

Görsel yazara aittir.

İki teşhis yöntemini de görsel olarak karşılaştırırsak:

# Yan yana iki grafik alanı (Subplots) oluşturuyoruz
fig, axes = plt.subplots(1, 2, figsize=(16, 6), sharex=True)

# İki yöntemin bulduğu sınırları net sayılar olarak buraya giriyoruz
iqr_alt, iqr_ust = 24.31, 73.76
z_alt, z_ust = 13.93, 85.96

sns.histplot(s, kde=True, color='skyblue', alpha=0.5, ax=axes[0])
axes[0].axvline(x=iqr_alt, color='darkblue', linestyle='--', linewidth=2, label=f'Alt Sınır ({iqr_alt})')
axes[0].axvline(x=iqr_ust, color='darkblue', linestyle='--', linewidth=2, label=f'Üst Sınır ({iqr_ust})')

# IQR'ın yakaladığı anomali noktalarını grafikte kırmızıyla işaretleyelim
outliers_iqr = s[(s < iqr_alt) | (s > iqr_ust)]
axes[0].scatter(outliers_iqr, np.zeros_like(outliers_iqr) + 0.5, 
                color='red', s=80, zorder=5, label=f'Yakalanan ({len(outliers_iqr)} Adet)')

axes[0].set_title("IQR (Medyan Tabanlı) Sınır Analizi\n(Aykırı Değerlerden Etkilenmez - Robust)", fontsize=13, pad=10)
axes[0].set_xlabel("Değerler")
axes[0].set_ylabel("Frekans")
axes[0].legend(loc='upper right', facecolor='white')

sns.histplot(s, kde=True, color='purple', alpha=0.4, ax=axes[1])
axes[1].axvline(x=z_alt, color='crimson', linestyle='--', linewidth=2, label=f'Alt Sınır ({z_alt})')
axes[1].axvline(x=z_ust, color='crimson', linestyle='--', linewidth=2, label=f'Üst Sınır ({z_ust})')

# Z-Score'un yakaladığı (maskelemeden kaçamayan) noktaları işaretleyelim
outliers_z = s[(s < z_alt) | (s > z_ust)]
axes[1].scatter(outliers_z, np.zeros_like(outliers_z) + 0.5, 
              color='red', s=80, zorder=5, label=f'Yakalanan ({len(outliers_z)} Adet)')

axes[1].set_title("Z-Score (Ortalama Tabanlı) Sınır Analizi\n(Maskeleme Etkisiyle Sınırlar Genişler)", fontsize=13, pad=10)
axes[1].set_xlabel("Değerler")
axes[1].set_ylabel("")
axes[1].legend(loc='upper right', facecolor='white')

plt.tight_layout()
plt.show()

Görsel yazara aittir.

Görsel yazara aittir.

  • IQR (Medyan Tabanlı — Robust): Aykırı değerlerin baskısından etkilenmez, sınırları esnemez. Merkezdeki %50'lik kitleyi baz alarak yasal sınırları 24.31 ve 73.76 olarak belirledi ve 8 adet aykırı değerin tamamını kusursuzca yakaladı.
  • Z-Score (Ortalama Tabanlı): Ekstrem uç değerlerin kurbanı oldu. Ortalama ve standart sapma şiştiği için yasal sınırlar bir lastik gibi dışarıya doğru esnedi (13.93–85.96). Bu esneme yüzünden bazı sınır değerler içeride kalarak kendini gizledi ve yöntem sadece 5 adet aykırı değer yakalayabildi.

Sonuç olarak kısaca hangisini seçmeliyim diye sorarsanız:

  • Veriniz çarpıksa (skewed) veya içinde çok sert uç değerler barındırıyorsa, maskeleme tuzağına düşmemek için kesinlikle IQR yöntemini seçmelisiniz.
  • Veriniz temiz, simetrik bir çan eğrisi (Gaussian) çiziyorsa ve amacınız veriyi ölçeklendirmekse, Z-Score sizin en ideal silahınızdır.

Buraya kadar tek bir sütun içindeki (Tek Değişkenli / Univariate aykırı değerleri) istatistiksel olarak nasıl avlayacağımızı, IQR ve Z-Score’un birbirine karşı üstünlüklerini canlı örneklerle gördük.

Peki ya verimiz Çok Değişkenli (Multivariate) ise? Yazının başında bahsettiğimiz o Boyu 180 cm ama kilosu 35 kg olan gizli anomalileri bu tek boyutlu istatistiksel yöntemler yakalayamaz.

Bir sonraki yazımızda bu çok değişkenli verilerin anomali tespitlerinde kullanılan yöntemlerini inceleyeceğiz.

Bu yazı, veri bilimi topluluğuna katkı sağlamak amacıyla ortaklaşa kaleme alınmıştır.

[embed]Batuhan Bilgili - Medium Read writing from Batuhan Bilgili on Medium. Veri bilimi ve makine öğrenmesine ilgi duyuyorum ve ilgilendiğim alanlarla…medium.com


메타데이터
post_id
7c1d2a7cdb3a
slug
aykırı-değerler-outliers-bölüm-1-bir-hata-mı-yoksa-bir-sinyal-mi-7c1d2a7cdb3a
url
https://medium.com/kahve-yan%C4%B1-veri/ayk%C4%B1r%C4%B1-de%C4%9Ferler-outliers-b%C3%B6l%C3%BCm-1-bir-hata-m%C4%B1-yoksa-bir-sinyal-mi-7c1d2a7cdb3a
canonical_url
https://medium.com/kahve-yan%C4%B1-veri/ayk%C4%B1r%C4%B1-de%C4%9Ferler-outliers-b%C3%B6l%C3%BCm-1-bir-hata-m%C4%B1-yoksa-bir-sinyal-mi-7c1d2a7cdb3a
author_url
https://medium.com/@brsyldrm0
status
ok
fetched_at
2026-08-06 07:02:41