This commit is contained in:
Executable
+78
@@ -0,0 +1,78 @@
|
||||
# Derin Teknik Düzeltmeler ve Analiz Günlüğü
|
||||
|
||||
**Dosya:** `02_deep_fixes_log.md`
|
||||
**Amaç:** Son geliştirme döngüsünde çözülen karmaşık sorunların teknik detaylarını belgelemek.
|
||||
|
||||
---
|
||||
|
||||
## 1. Live Match Synchronization & DB Safety
|
||||
|
||||
### Sorun Tanımı
|
||||
|
||||
Canlı maçlar (Live Matches), ana `matches` tablosuna henüz işlenmemiş olabiliyor. Ancak sistem bunları analiz etmeye çalıştığında:
|
||||
|
||||
1. `match_player_participation` tablosuna oyuncu eklemeye çalışıyor -> `matches` tablosunda ID olmadığı için **Foreign Key Constraint Error** alıyordu.
|
||||
2. Veri tabana yazılamadığı için Python scripti "Lineup not found" hatasıyla patlıyordu.
|
||||
|
||||
### Uygulanan Çözüm
|
||||
|
||||
**Dual-Persistence Strategy (Çift Yazma Stratejisi):**
|
||||
|
||||
- **Logic:** `FeederPersistenceService.saveLineups` ve `saveOdds` metodları artık önce `matches` tablosunda `matchId` var mı diye kontrol ediyor.
|
||||
- **Varsa:** Hem ilişkisel tablolara (`match_player_participation`) hem de `live_matches` JSON kolonuna yazıyor.
|
||||
- **Yoksa (Sadece Canlı):** İlişkisel tabloları tamamen pas geçiyor (SKIP), veriyi sadece `live_matches.lineups` ve `live_matches.odds` JSON kolonlarına strüktüre edilmiş olarak yazıyor.
|
||||
|
||||
**Fallback Mechanism (Python & NestJS):**
|
||||
|
||||
- **NestJS:** `getPlayerCount` metodu önce ilişkisel tabloyu sayıyor. Sayı 0 ise `live_matches` JSON'ını parse edip oradaki oyuncu sayısını dönüyor.
|
||||
- **Python:** `_run_model` içinde önce SQL sorgusu ile kadro çekmeye çalışıyor. Liste boşsa, `live_matches` tablosundaki JSON kolonunu çekip manuel parse ediyor.
|
||||
|
||||
---
|
||||
|
||||
## 2. Model Score & Context Mapping (Kritik)
|
||||
|
||||
### Sorun Tanımı
|
||||
|
||||
Kullanıcı, modelin skor tahminlerinin ve maç sonucu (1/X/2) tercihlerinin tutarsız olduğundan şikayetçiydi ("Home win diyor ama skor 0-1" gibi).
|
||||
|
||||
### Tespit Edilen Kök Nedenler
|
||||
|
||||
1. **HT/FT Sıralaması:** Model eğitimi `ht*3 + ft` (0=X, 1=1, 2=2) mantığıyla yapılmıştı. Ancak tahmin scripti etiketleri `1/1, 1/X...` gibi rastgele bir sırayla diziyordu. Bu yüzden `1/1` tahmini `X/X` gibi görünüyordu.
|
||||
2. **Beraberlik (Draw) Körlüğü:** Data Feeder, beraberlik oranını `X` etiketiyle kaydediyordu (Mackolik verisi). Python scripti ise sadece `0` etiketini "Beraberlik" olarak kabul ediyordu. Sonuç olarak model "Beraberlik Oranı: 0.0" görüyordu (yani oran yok). Bu, modelin maçın dengesini yanlış anlamasına neden oluyordu.
|
||||
3. **Away Bias (Deplasman Yanlılığı):** Backtest verileri, modelin sistematik olarak deplasman takımına fazla gol yazdığını (%15-20 fazla) gösterdi.
|
||||
|
||||
### Uygulanan Çözüm
|
||||
|
||||
1. **Etiket Düzeltmesi:** `htft_labels` listesi `[X/X, X/1, X/2, 1/X, 1/1, 1/2, 2/X, 2/1, 2/2]` olarak, eğitim verisiyle %100 uyumlu hale getirildi.
|
||||
2. **Oran Normalizasyonu:** Python scripti artık hem `0` hem `X` etiketlerini beraberlik oranı olarak kabul ediyor.
|
||||
3. **Skor Kalibrasyonu:** Backtest sonrası optimizasyon katsayıları eklendi.
|
||||
- `HOME_GOAL_SCALE = 1.00`
|
||||
- `AWAY_GOAL_SCALE = 0.85`
|
||||
|
||||
---
|
||||
|
||||
## 3. Akıllı Kupon Servisi (Smart Coupon)
|
||||
|
||||
### Yapı
|
||||
|
||||
NestJS tarafında `SmartCouponService` ve Python tarafında `smart_coupon_service.py` (CLI) işbirliği ile çalışır.
|
||||
|
||||
### Akış
|
||||
|
||||
1. **Request:** POST `/api/coupon/analyze-match` { matchId }
|
||||
2. **Pre-Check 1 (Kadro):** DB'de kadro var mı?
|
||||
- Yoksa -> `FeederService.refreshMatch(lineups)` -> Tekrar kontrol -> Hâlâ yoksa Hata Fırlat ("Yetersiz Veri").
|
||||
3. **Pre-Check 2 (Oran):** DB'de oran var mı?
|
||||
- Yoksa -> `FeederService.refreshMatch(odds)` -> Log bas (Engelleyici değil).
|
||||
4. **Prediction:** Python scripti çalıştırılır (`--analyze --json`).
|
||||
- Script: DB veya JSON Fallback'ten veriyi okur.
|
||||
- Script: Modeli çalıştırır, kalibrasyon katsayılarını uygular.
|
||||
- Script: JSON döner.
|
||||
5. **Response:** NestJS JSON'ı parse edip kullanıcıya döner.
|
||||
|
||||
---
|
||||
|
||||
## Gelecek İçin Notlar
|
||||
|
||||
- **Database:** `live_matches` tablosundaki JSON kolonları artık kritik öneme sahip. Bunların şeması `Prisma` tarafında `Json` olarak tanımlı ama iç yapısı kod içinde (`FeederPersistence`) belirleniyor. Yapıyı değiştirirken dikkatli olunmalı.
|
||||
- **Model:** V17 modeli şu an stabil. V18'e geçilirse `player_model_v17.py` değiştirilmeli ve `smart_coupon_service.py` içindeki scale faktörleri sıfırlanıp tekrar backtest yapılmalı.
|
||||
Reference in New Issue
Block a user