Ana içeriğe geç
Kesit SQL
Orta · Veri Bilimi

Örnekleme ve eğitim/test ayrımı

Rastgele örnek, tekrarlanabilir hash tabanlı bölme.

Uygulamada aç, 6 alıştırmayı çözÜcretsiz, hesap gerekmez, kurulum yok.

Bu sayfa dersin okuma sürümüdür. Metin bir kutuyu çalıştırmanı ya da adıma geçmeni söylüyorsa dersi uygulamada aç.

Rastgele örnek

SELECT * FROM customers ORDER BY RANDOM() LIMIT 5;

Her çalıştırmada farklı sonuç verir. Büyük tablolarda tüm tabloyu sıraladığı için pahalıdır; ambarlarda TABLESAMPLE SYSTEM (10 PERCENT) gibi yöntemler kullanılır.

Tekrarlanabilir bölme

Model eğitiminde aynı müşterinin her seferinde aynı kümeye düşmesi gerekir. Anahtarın hash'ine (veya burada basitçe ID'ye) göre mod almak bunu sağlar:

SELECT CASE WHEN customer_id % 10 < 8 THEN 'train' ELSE 'test' END AS kume,
       COUNT(*) AS n
FROM customers
GROUP BY kume;

BigQuery'de MOD(ABS(FARM_FINGERPRINT(CAST(id AS STRING))), 10), PostgreSQL'de hashtext(id::text) benzeri fonksiyonlar kullanılır.

Tabakalı örnekleme

Her segmentten eşit oranda örnek almak için ROW_NUMBER ile segment içinde sıra ver ve oranla filtrele.

WITH s AS (
  SELECT customer_id, segment,
         ROW_NUMBER() OVER (PARTITION BY segment ORDER BY customer_id) AS rn,
         COUNT(*) OVER (PARTITION BY segment) AS n
  FROM customers
)
SELECT segment, COUNT(*) AS ornek
FROM s WHERE rn <= n * 0.2
GROUP BY segment;

Derinleş: sızıntısız ve tekrarlanabilir bölme

Eğitim/test ayrımının amacı, modelin hiç görmediği veride nasıl çalışacağını dürüstçe ölçmektir. Bu amaç üç yoldan bozulur: aynı varlığın iki kümeye birden düşmesi, gelecekteki verinin eğitime karışması ve her çalıştırmada farklı bir bölme yapılması.

1. Bölme birimini doğru seç

Müşteri davranışını tahmin eden bir modelde birim müşteridir, sipariş değil. Siparişleri rastgele bölersen aynı müşterinin bazı siparişleri eğitimde, bazıları testte kalır; model müşteriyi “ezberler” ve test skoru şişer:

WITH a AS (
  SELECT customer_id,
         MAX(CASE WHEN order_id % 5 = 0 THEN 1 ELSE 0 END) AS testte,
         MAX(CASE WHEN order_id % 5 <> 0 THEN 1 ELSE 0 END) AS egitimde
  FROM orders
  GROUP BY customer_id
)
SELECT SUM(testte * egitimde) AS iki_kumede, COUNT(*) AS musteri
FROM a;

Sipariş bazlı bölmede 136 müşterinin 108'i iki kümede birden yer alıyor. Müşteri bazlı bölmede (customer_id % 5) bu sayı tanım gereği 0'dır.

2. Zaman varsa zamana göre böl

Tahmin gelecekte kullanılacaksa test kümesi eğitimden sonraki dönem olmalı (ör. 2024-07-01 öncesi eğitim, sonrası test). Rastgele bölme, modelin “gelecekten” öğrenmesine izin verir.

3. Tabakalı ve tekrarlanabilir örnek

Küçük segmentler rastgele örnekte kaybolabilir. Tabakalı örneklemede her tabakadan aynı oranda kayıt alınır. RANDOM() yerine kimlikten türetilen sabit bir “karıştırma anahtarı” kullanırsan örnek her çalıştırmada aynı çıkar:

WITH s AS (
  SELECT customer_id, segment,
         ROW_NUMBER() OVER (PARTITION BY segment
                            ORDER BY (customer_id * 7919) % 1000, customer_id) AS rn,
         COUNT(*) OVER (PARTITION BY segment) AS n
  FROM bank_customers
)
SELECT segment, MAX(n) AS tabaka, SUM(CASE WHEN rn * 10 <= n THEN 1 ELSE 0 END) AS ornek
FROM s
GROUP BY segment
ORDER BY segment;

Bireysel 400 müşteriden 40, KOBİ 48'den 4, Özel Bankacılık 52'den 5 kayıt seçilir: her tabakada yaklaşık %10. Gerçek projelerde karıştırma anahtarı bir hash fonksiyonudur (BigQuery FARM_FINGERPRINT, PostgreSQL hashtext, SQL Server CHECKSUM).

YöntemNe zaman?Risk
ORDER BY RANDOM()Hızlı keşifTekrarlanamaz, büyük tabloda pahalı
Kimlik/hash moduKalıcı eğitim/test ayrımıKimlik sırası anlamlıysa (ör. kayıt tarihi) yanlı olabilir
Zaman kesimiTahmin modelleriMevsimsellik varsa test dönemi temsil gücü düşük
TabakalıDengesiz sınıflar, küçük segmentlerTabaka tanımı yanlışsa yanlılık sürer
Alıştırmalara geç (6)