Tahmin modelleri için tablo
Günlük sipariş tahmini yapan bir model; dünün, geçen haftanın aynı gününün değerine ve hareketli ortalamalara ihtiyaç duyar.
WITH RECURSIVE gun(d) AS (
SELECT '2024-10-01' UNION ALL SELECT date(d, '+1 day') FROM gun WHERE d < '2024-12-31'
),
g AS (
SELECT gun.d, COUNT(o.order_id) AS y
FROM gun LEFT JOIN orders o ON o.order_date = gun.d
GROUP BY gun.d
)
SELECT d, y,
LAG(y, 1) OVER w AS lag_1,
LAG(y, 7) OVER w AS lag_7,
ROUND(AVG(y) OVER (ORDER BY d ROWS BETWEEN 7 PRECEDING AND 1 PRECEDING), 2) AS ort_7_onceki,
CAST(strftime('%w', d) AS INTEGER) AS hafta_gunu,
CASE WHEN CAST(strftime('%w', d) AS INTEGER) IN (0, 6) THEN 1 ELSE 0 END AS hafta_sonu
FROM g
WINDOW w AS (ORDER BY d)
ORDER BY d;
Dikkat: Hareketli ortalama 1 PRECEDING'de bitiyor. Bugünün değerini içeren bir özellik, bugünü tahmin ederken sızıntı olur.
Özellik türleri
| Tür | Örnek | SQL |
|---|---|---|
| Gecikme (lag) | Dünün, geçen haftanın aynı gününün değeri | LAG(y, 1), LAG(y, 7) |
| Hareketli istatistik | Son 7 günün ortalaması, en büyüğü | AVG(y) OVER (ORDER BY d ROWS BETWEEN 7 PRECEDING AND 1 PRECEDING) |
| Takvim | Haftanın günü, ay, hafta sonu, tatil | Tarih fonksiyonları ve bir tatil tablosuyla birleştirme |
| Fark ve oran | Geçen haftaya göre değişim | y - LAG(y, 7), y * 1.0 / NULLIF(LAG(y, 7), 0) |
Boş günleri doldurmak şart
Sipariş olmayan günler tabloda yoksa LAG(y, 7) yedi takvim günü öncesine değil, yedi satır öncesine bakar. Bu yüzden yukarıdaki örnek önce özyinelemeli CTE ile tüm günleri üretiyor, siparişleri LEFT JOIN ile bağlıyor ve eksik günler 0 sayılıyor.
Eğitim ve test ayrımı zamana göre yapılır
Zaman serisinde satırları rastgele bölmek, modelin geleceği görerek geçmişi tahmin etmesine yol açar. Bir kesim tarihi seçilir: öncesi eğitim, sonrası test.
WITH m AS (
SELECT strftime('%Y-%m', order_date) AS ay, COUNT(*) AS y
FROM orders
GROUP BY strftime('%Y-%m', order_date)
)
SELECT ay, y,
LAG(y) OVER (ORDER BY ay) AS lag_1,
CASE WHEN ay < '2024-10' THEN 'egitim' ELSE 'test' END AS bolum
FROM m
ORDER BY ay;
1 PRECEDING'de bitirmek bu kuralın SQL'deki karşılığıdır.