# Topolojik Kırılma Noktasına Göre Veri Bölme: Bitcoin Kara Para Aklama Tespiti > **"Karmaşık yapay zekâ modelleri geliştirmeden önce, verinizi doğru bölün."** --- ## Biz Ne Yapıyoruz? Makine öğrenmesi modellerini eğitirken veriyi ikiye böleriz: bir kısmıyla öğretir, diğer kısmıyla sınarız. Herkes bu bölme işini ya rastgele yapar, ya da takvimden bir tarih seçip "bu tarihten önce eğitim, sonra test" der. Biz farklı bir şey öneriyoruz: **Bölme noktasını takvim değil, ağın kendisi belirlesin.** Bitcoin işlem ağının bir "sağlık skoru" var. Bu skor ağın ne kadar yoğun, ne kadar bağlantılı ve ne kadar bütün olduğunu ölçüyor. Ağ sağlıklıyken her şey normal akıyor. Ama bir gün dark market kapanıyor, düzenleyiciler baskın yapıyor ya da büyük bir hack oluyor — ve ağın sağlığı aniden çöküyor. İşte biz tam o çökme anını otomatik olarak tespit edip, yapay zekayı o noktadan bölüyoruz. --- ## Neden Bu Önemli? Çünkü rastgele bölme yaptığınızda, model geleceği görüyor. 2024'teki bir suç örüntüsünü eğitim setine koyup, 2023'teki bir işlemi test ediyorsunuz. Model "tahmin" yapmıyor, "hatırlıyor". Bu yüzden %96 başarı rapor ediyorsunuz ama gerçek dünyaya koyduğunuzda model çöküyor. Bunu sadece iddia etmiyoruz. 6 farklı testle kanıtlıyoruz. --- ## Literatüre Katkımız (Tek Cümle) > **Veri bölme noktasını, ağın topolojik sağlığının çöktüğü kriz anına göre belirleyen ilk çalışma.** Mevcut yaklaşımlar ya rastgele böler (sızıntı yapar), ya da takvimden sabit bir noktadan keser (krizi görmezden gelir). Biz ağın matematiğini dinleyerek kırılma noktasını buluyoruz. --- ## Veri Seti: Elliptic Bitcoin Dataset **Kaynak:** [Kaggle — Elliptic Data Set](https://www.kaggle.com/datasets/ellipticco/elliptic-data-set) Veri seti `dataset/` klasörü altında 3 dosyadan oluşur: - `dataset/elliptic_txs_features.csv` — 203,769 düğüm × 167 sütun - `dataset/elliptic_txs_classes.csv` — 203,769 düğüm × 2 sütun (txId, class) - `dataset/elliptic_txs_edgelist.csv` — 234,355 kenar × 2 sütun (txId1, txId2) | Özellik | Değer | |---------|-------| | **Toplam düğüm** | 203,769 Bitcoin işlemi | | **Etiketli düğüm** | 46,564 (%22.8) | | **İllicit (kara para)** | 4,545 (%9.8) | | **Licit (yasal)** | 42,019 (%90.2) | | **Kenarlar** | 234,355 yönlü ödeme akışı | | **Özellikler** | 165 düğüm özelliği (94 local + 71 aggregated) | | **Zaman adımları** | 49 (~2 haftalık aralıklar) | ### Veri Setindeki 5 Olay Tipi | Olay Tipi | Timestep'ler | İllicit Oranı | İşlem Sayısı | Açıklama | |-----------|-------------|---------------|-------------|----------| | 🔴 **Dark Market Zirvesi** | 9,11,13,15,16,20,25,26,28,29,32 | **%26.5** | 8,223 | Kara para aklamanın zirve yaptığı dönemler | | ⚫ **Kapanma (Shutdown)** | 43 | %1.8 | 1,370 | Bilinen dark market kapanması | | 🔵 **Kapanma Sonrası** | 44,45,46 | %0.9 | 3,524 | Suçluların sessizleştiği dönem | | 🟠 **Toparlanma** | 47,48,49 | %6.4 | 1,793 | Yeni aktörlerin girişi | | 🟢 **Normal Aktivite** | Geri kalan 31 TS | %7.0 | 31,654 | Standart ağ davranışı | Dark market zirvesinde illicit oranı **%26.5** iken, kapanma sonrası **%0.9**'a düşüyor — **30 kat fark.** Rastgele bölme bu devasa farkı ortalar ve gerçeği gizler. --- ## Hipotezlerimiz **Hipotez 1:** Veriyi rastgele bir tarihten değil, ağda krizin yaşandığı **Topolojik Kırılma Noktasından** bölersek, model daha başarılı ve kararlı olur. **Hipotez 2:** Veri bölme ağdaki şoklara göre yapılmazsa, model sakin zamanlarda yapay ve abartılı bir başarı gösterir (**performans şişmesi**), ancak kriz anında çöker. --- ## Topolojik Kırılma Noktası Tespit Algoritması Ağın "matematiksel sağlığını" her timestep için ölçen bir algoritma yazdık: ``` Sağlık Skoru = (Yoğunluk + Bağlantılılık + Bütünlük) / 3 Yoğunluk ↑ = Ağda düğümler arası bağlantı yoğun Bağlantılılık ↑ = En büyük bileşen ağın çoğunu kapsıyor Bütünlük ↑ = Ağ az sayıda parçaya bölünmüş Kırılma Noktası = Sağlık skorundaki en büyük ani düşüş ``` ### Birleşik Kırılma Noktası Tespiti (Güncel — run_all.py) `run_all.py` iki bağımsız yöntemi birleştirerek daha sağlam bir kırılma noktası tespit eder: | Yöntem | Kırılma Noktası | Açıklama | |--------|----------------|----------| | **A: Sağlık Skoru** | TS 29 | Ağın yapısal sağlığındaki en büyük düşüş | | **B: Tepe-Düşüş (Türev)** | TS 5 | Bileşik kriz sinyalindeki en büyük negatif türev | | **★ Birleşik (Final)** | **TS 17** | İki yöntemin ortalamasına en yakın timestep | Önceki deneylerde tek yöntem (sağlık skoru → TS 29) kullanılmıştı. Birleşik yöntem iki farklı perspektifi harmanlayarak daha dengeli bir kırılma noktası seçer. --- ## Deneysel Tasarım ### Modeller | Model | Tür | Neden Seçildi? | |-------|-----|---------------| | **GraphSAGE** | Graf Sinir Ağı (GNN) | Düğümün komşuluk yapısını öğrenir, 2 katman SAGEConv, strict inductive | | **Random Forest** | Topluluk öğrenme | Elliptic dataset'te en güçlü baseline (Weber et al., 2019) | | **XGBoost** | Gradyan artırma | Tabular veride SOTA | | **LightGBM** | Gradyan artırma | Hız ve performans dengesi | ### 5 Bölme Stratejisi | # | Strateji | Açıklama | |---|----------|---------| | 1 | **Rastgele bölme** | Standart train_test_split (%80/%20) — herkesin yaptığı | | 2 | **Kronolojik bölme** | İlk %80 timestep eğitim, son %20 test — mevcut iyi uygulama | | 3 | **Topolojik kırılma (bizim)** | Kırılma noktasından önce eğitim, sonra test — bizim katkımız | | 4 | **Kayan pencere** | Son 10 timestep test, geri kalanı eğitim | | 5 | **Düşmanca bölme** | Sakin dönemde eğit, kriz döneminde test et — stres testi | --- ## Sonuçlar (Ham Veri — Önceki Deneyler) ### HİPOTEZ 1: DOĞRULANDI ✅ — Topolojik kırılma, kronolojik bölmeyi geçti | Model | Topolojik Kırılma F1 | Kronolojik F1 | **Fark** | |-------|---------------------|--------------|---------| | LightGBM | **0.870** | 0.738 | **+13.2 puan** | | Random Forest | **0.842** | 0.723 | **+11.9 puan** | | XGBoost | **0.837** | 0.742 | **+9.5 puan** | | GraphSAGE | 0.421 | 0.476 | -5.5 puan | 3/4 modelde topolojik kırılma bölmesi açık farkla kazandı. LightGBM'de **+13.2 puan** F1 artışı. ### HİPOTEZ 2: DOĞRULANDI ✅ — Rastgele bölme performansı şişiriyor | Model | Rastgele F1 | Kronolojik F1 | **Şişme** | |-------|-----------|-------------|----------| | GraphSAGE | 0.711 | 0.476 | **%49.5** 🔴 | | Random Forest | 0.936 | 0.723 | **%29.5** 🔴 | | XGBoost | 0.958 | 0.742 | **%29.0** 🔴 | | LightGBM | 0.960 | 0.738 | **%30.2** 🔴 | ### Tam Sonuç Tablosu (Ham Veri): Illicit F1 Score | Model | Rastgele | Kronolojik | **Topolojik Kırılma** | Kayan Pencere | Düşmanca-Kriz | |-------|---------|-----------|---------------------|--------------|--------------| | GraphSAGE | 0.711 | 0.476 | 0.421 | 0.458 | **0.777** | | Random Forest | 0.936 | 0.723 | **0.842** | 0.723 | 0.963 | | XGBoost | 0.958 | 0.742 | **0.837** | 0.742 | 0.978 | | LightGBM | 0.960 | 0.738 | **0.870** | 0.738 | 0.981 | --- ## 🆕 Temizlenmiş Veri Sonuçları (run_all.py — Güncel) `run_all.py` çalıştırıldı ve tüm deneyler **temizlenmiş veri** (IQR outlier clipping + düşük varyans çıkarma + RobustScaler) ile tekrarlandı. Birleşik kırılma noktası: **TS 17**. ### Veri Temizleme Özeti | Ölçüm | Değer | |-------|-------| | NaN sayısı | 0 | | Inf sayısı | 0 | | Outlier hücre oranı | **%16.74** | | Çıkarılan düşük varyans özellik | 47 (165 → **118 özellik**) | | En iyi pipeline | **Clip+Robust+SMOTE** | ### Pipeline Karşılaştırması (Kronolojik bölme üzerinde LightGBM) | Pipeline | Illicit F1 | Fark (Ham'a göre) | |----------|-----------|-------------------| | Ham Veri | 0.7398 | — | | StandardScaler | 0.7375 | -0.0023 | | RobustScaler | 0.7400 | +0.0002 | | Clip+Robust | 0.7377 | -0.0021 | | Clip+VarFilter+Robust | 0.7512 | +0.0114 | | **Clip+Robust+SMOTE** | **0.7537** | **+0.0139** | > **Bulgu:** Düşük varyans özellik çıkarma ve SMOTE birlikte F1'i +1.4 puan artırdı. Ancak temizlemenin etkisi bölme stratejisi etkisinin yanında küçük kalıyor (bölme etkisi: 22+ puan). ### Tam Sonuç Tablosu (Temizlenmiş Veri): Illicit F1 Score | Model | Rastgele | Kronolojik | **Topolojik Kırılma** | Kayan Pencere | Düşmanca-Kriz | |-------|---------|-----------|---------------------|--------------|--------------| | LightGBM | 0.9623 | 0.7377 | **0.7487** | 0.7377 | 0.9792 | | Random Forest | 0.9441 | 0.7129 | **0.6638** | 0.7129 | 0.9638 | | XGBoost | 0.9673 | 0.7450 | **0.7511** | 0.7450 | 0.9784 | ### Tam Sonuç Tablosu (Temizlenmiş Veri): Precision / Recall / AUROC | Model | Strateji | F1 | Precision | Recall | AUROC | |-------|----------|-----|-----------|--------|-------| | LightGBM | Rastgele | 0.9623 | 0.9861 | 0.9395 | 0.9984 | | Random Forest | Rastgele | 0.9441 | 0.9915 | 0.9010 | 0.9964 | | XGBoost | Rastgele | 0.9673 | 0.9908 | 0.9450 | 0.9985 | | LightGBM | Kronolojik | 0.7377 | 0.9222 | 0.6148 | 0.9502 | | Random Forest | Kronolojik | 0.7129 | 0.9626 | 0.5660 | 0.9475 | | XGBoost | Kronolojik | 0.7450 | 0.9379 | 0.6179 | 0.9298 | | LightGBM | **Topolojik Kırılma** | **0.7487** | 0.9394 | 0.6224 | 0.8829 | | Random Forest | **Topolojik Kırılma** | **0.6638** | 0.9939 | 0.4983 | 0.8763 | | XGBoost | **Topolojik Kırılma** | **0.7511** | 0.9193 | 0.6349 | 0.8878 | | LightGBM | Kayan Pencere | 0.7377 | 0.9222 | 0.6148 | 0.9502 | | Random Forest | Kayan Pencere | 0.7129 | 0.9626 | 0.5660 | 0.9475 | | XGBoost | Kayan Pencere | 0.7450 | 0.9379 | 0.6179 | 0.9298 | | LightGBM | Düşmanca-Kriz | 0.9792 | 0.9875 | 0.9710 | 0.9986 | | Random Forest | Düşmanca-Kriz | 0.9638 | 0.9857 | 0.9428 | 0.9980 | | XGBoost | Düşmanca-Kriz | 0.9784 | 0.9905 | 0.9666 | 0.9985 | ### Walk-Forward Validasyon (Temizlenmiş Veri) | Model | Walk-Forward F1 | |-------|----------------| | LightGBM | **0.7974** | | Random Forest | **0.7666** | | XGBoost | **0.8064** | ### Dürüstlük Karşılaştırması (Temizlenmiş Veri) | Strateji | Walk-Forward'a Ort. Sapma (3 model) | Durum | |----------|--------------------------------------|-------| | **Rastgele** | **+%21.3** | 🔴 ŞİŞME | | **Düşmanca-Kriz** | **+%23.3** | 🔴 ŞİŞME | | **Topolojik Kırılma** | **-%8.8** | ✅ DÜRÜST | | **Kronolojik** | **-%7.4** | ✅ DÜRÜST | | **Kayan Pencere** | **-%7.4** | ✅ DÜRÜST | > **Önemli Bulgu:** Temizlenmiş veride topolojik kırılma **-%8.8 sapma** ile walk-forward bandının içinde. Veri temizlemesi rastgele split şişmesini değiştirmiyor (+%21.3 hâlâ devam) — bu da **şişmenin veri kalitesinden değil, bölme stratejisinden kaynaklandığını kanıtlıyor.** ### Ham Veri vs Temizlenmiş Veri Karşılaştırması | Ölçüm | Ham Veri | Temizlenmiş Veri | Yorum | |-------|---------|-----------------|-------| | Rastgele şişme | +%20.9 | +%21.3 | Temizleme şişmeyi çözmüyor | | Topo sapma | +%8.0 | -%8.8 | Birleşik kırılma noktası (TS 17) biraz daha muhafazakâr | | Kronolojik sapma | -%6.7 | -%7.4 | Benzer | | Özellik sayısı | 165 | 118 | 47 düşük varyans özellik çıkarıldı | | En iyi topo F1 (XGB) | 0.837 | **0.751** | TS 29 → TS 17 değişimi (daha erken bölme = daha az eğitim verisi) | ### Yorum: Neden TS 17 Sonuçları TS 29'dan Farklı? Birleşik kırılma noktası **TS 17**, önceki tek yöntem kırılmasından (**TS 29**) daha erkendir. Bu demek ki: - **Eğitim seti küçüldü:** TS 1-16 (16 timestep) vs TS 1-28 (28 timestep) - **Test seti büyüdü:** TS 17-49 (33 timestep) vs TS 29-49 (21 timestep) - Daha az eğitim verisi → daha düşük mutlak F1, ama **daha zorlu ve gerçekçi** bir test Bu, walk-forward sapmalarında da görülüyor: TS 29 ile +%8 (hafif iyimser), TS 17 ile -%8.8 (hafif muhafazakâr). Her iki sonuç da walk-forward ±%10 dürüstlük bandının içinde. --- ## Peki Bizim Yöntemimiz de Şişiriyor mu? Walk-forward validasyon gerçek dünyanın simülasyonudur. Her stratejinin walk-forward'a yakınlığı = dürüstlük derecesi. ### Dürüstlük Testi Sonuçları (Ham Veri) | Strateji | F1 (LightGBM) | Walk-Forward'a Sapma | Durum | |----------|--------------|---------------------|-------| | **Rastgele** | 0.960 | **+%20.9** | 🔴 Şişiriyor | | **Düşmanca-Kriz** | 0.981 | **+%23.8** | 🔴 Şişiriyor | | **Topolojik Kırılma (Bizim)** | 0.870 | **+%8.0** | ✅ Dürüst | | **Kronolojik** | 0.738 | **-%6.7** | ✅ Dürüst (ama pesimist) | | Strateji | Walk-Forward'a Ortalama Sapma (3 model) | Yorum | |----------|----------------------------------------|-------| | Rastgele | **+%20.9** | Gerçek dünyada olmayan performans raporluyor | | **Topolojik Kırılma** | **+%8.0** | Walk-forward bandının içinde — kabul edilebilir | | Kronolojik | **-%6.7** | Gerçekçi ama modeli biraz küçümsüyor | ### Neden Topolojik Kırılma Kronolojikten Daha İyi Ama Şişirmiyor? Kronolojik bölme sabit bir noktadan kesiyor (TS 39). Bu noktadan sonra hem kriz hem sakin dönemler var. Bizim yöntemimiz kriz noktasından (TS 29) bölüyor. Test setinde gerçek dünyanın çeşitliliği dengeli şekilde var. --- ## Sızıntı Haritası: Bilgi Ağ Üzerinden Nasıl Sızıyor? | Ölçüm | Random Split | Temporal Split | Fark | |-------|-------------|----------------|------| | Komşuluk sızıntı oranı | **0.502** | **0.000** | **502x** | ### Yapı Duyarlılığı | Özellik Seti | Random Split F1 | Temporal Split F1 | Fark | |-------------|----------------|------------------|------| | Sadece Local (94 özellik) | 0.943 | 0.669 | +0.274 | | Sadece Aggregated (71 özellik) | 0.902 | 0.627 | +0.275 | | Tümü (165 özellik) | 0.965 | 0.738 | +0.227 | | **Aggregated'ın ek katkısı** | **+0.022** | **+0.069** | **3.1x** | --- ## "Random Split Belki Doğru Sonuç Veriyor" İtirazının Cevabı | # | Test | Ne Sorguluyor? | Bulgu | |---|------|----------------|-------| | 1 | **Walk-Forward** | Gerçek dünyada performans ne? | **%21 şişme** | | 2 | **Kriz Çöküşü** | En zor anda ne oluyor? | **F1=0.07 çöküş** | | 3 | **Rastgele Etiket** | Yapısal sızıntı var mı? | **Random 4x daha yüksek** | | 4 | **Yapay Tutarlılık** | Dağılım gerçekçi mi? | **Random yapay düzgün** | | 5 | **Gelecek Bilgisi** | Gelecek görülmüş mü? | **Geçmiş ≈ Gelecek** | | 6 | **Dürüstlük Testi** | Bizim yöntem de şişiriyor mu? | **+%8 — dürüst** | Detaylı kanıt açıklamaları için [project_report.md](project_report.md) dosyasına bakınız. --- ## Figürler ### Orijinal Deneyler (Ham Veri) #### Figür 1 — Ağın Sağlık Skoru ve Kırılma Noktası ![Kırılma](topo_figures/fig1_topological_breakpoint.png) **Ne görüyoruz:** Üstteki grafik ağın sağlık skorunun zaman içindeki değişimi. Kırmızı kesikli çizgi algoritmanın bulduğu kırılma noktası (TS 29). Algoritma bunu etiketlere bakmadan sadece ağın matematiğiyle buldu. #### Figür 2 — F1 Karşılaştırması ![F1](topo_figures/fig2_f1_comparison.png) **Ne görüyoruz:** 5 stratejinin F1 skorları. Siyah kenarlı çubuklar bizim yöntemimiz. Kronolojik bölmeden her modelde daha yüksek. #### Figür 3 — Performans Şişmesi Haritası ![Şişme](topo_figures/fig3_inflation_heatmap.png) **Ne görüyoruz:** Rastgele bölmenin şişirme miktarı. GraphSAGE'de %49.5, klasik modellerde %29-30. #### Figür 4 — Walk-Forward Kanıtı ![WF](proof_figures/fig1_walk_forward_proof.png) **Ne görüyoruz:** Mavi çizgi gerçek dünya, kırmızı çizgi random split iddiası. Kriz anında F1=0.07'ye düşüyor. #### Figür 5 — Rastgele Etiket Testi ![Rand](proof_figures/fig4_random_label_test.png) **Ne görüyoruz:** Anlamsız etiketlerde bile random split temporal split'in 4 katı skor veriyor. #### Figür 6 — Dürüstlük Testi ![Dürüstlük](proof_figures/fig6_honesty_test.png) **Ne görüyoruz:** Yeşil bant walk-forward dürüstlük aralığı. Bizim yöntem bandın içinde. #### Figür 7 — Sızıntı Haritası ![Sızıntı](proof_figures/fig7_leakage_map.png) **Ne görüyoruz:** Komşuluk sızıntısı 502 kat fark. Aggregated özellikler temporal split'te 3.1x daha fazla katkı. #### Figür 8 — Model Karmaşıklığı vs Bölme ![Karmaşık](topo_figures/fig5_complexity_vs_split.png) **Ne görüyoruz:** Bölme stratejisinin etkisi model seçiminden daha büyük. #### Figür 9 — Bitcoin Olay Haritası ![Olay](figures/fig1_bitcoin_event_map.png) **Ne görüyoruz:** 49 timestep boyunca suç yoğunluğu. Kapanma sonrası suç 30 kat düşüyor. ### 🆕 Temizlenmiş Veri Figürleri (run_all.py çıktıları) #### Figür 10 — Birleşik Kırılma Noktası (Sağlık + Tepe-Düşüş) ![Kırılma Yeni](output/figures/fig1_breakpoint.png) **Ne görüyoruz:** Üst: sağlık skoru, orta: illicit oranı, alt: kriz sinyali. Birleşik kırılma noktası TS 17. #### Figür 11 — F1 Karşılaştırması (Temizlenmiş Veri) ![F1 Yeni](output/figures/fig2_f1_comparison.png) **Ne görüyoruz:** 5 stratejinin temizlenmiş veri ile F1 skorları. Yeşil bant walk-forward dürüstlük aralığı. #### Figür 12 — Pipeline Karşılaştırması ![Pipeline](output/figures/fig3_pipeline_comparison.png) **Ne görüyoruz:** 6 ön işleme pipeline'ının Illicit F1 skorları. Clip+Robust+SMOTE en iyisi. #### Figür 13 — Walk-Forward Dürüstlük Haritası (Temizlenmiş Veri) ![Dürüstlük Yeni](output/figures/fig4_honesty.png) **Ne görüyoruz:** Her model × strateji kombinasyonunun walk-forward'a sapması. Kırmızı = şişme, yeşil = yakın. --- ## Triple Barrier Yöntemi ile İlişki Analizi ### Triple Barrier Nedir? Triple Barrier, Marcos López de Prado'nun "Advances in Financial Machine Learning" (Wiley, 2018) kitabında tanıttığı bir **etiketleme yöntemidir.** ### Bizim Çalışmayla İlişkisi **Doğrudan ilişki: YOK.** Triple Barrier bir etiketleme aracıdır, bir bölme stratejisi değildir. | Boyut | Triple Barrier | Bizim Yöntem | |-------|---------------|-------------| | Ne yapar | Eğitim örneklerine etiket atar | Veriyi nerede keseceğini belirler | | Pipeline aşaması | Özellik mühendisliği / etiketleme | Model değerlendirme tasarımı | | Domain | Alım-satım stratejileri | Sahtekarlık tespiti | ### Dolaylı Felsefi Bağlantı López de Prado'nun "finansal veride rastgele bölme yanlıştır" eleştirisi bizim tezimizle aynı düşünce geleneğinden besleniyor. Ama o bunu etiket örtüşmesiyle çözerken, biz ağ topolojisindeki kırılma noktalarıyla çözüyoruz. Detaylı analiz: [project_report.md](project_report.md) Bölüm 6. --- ## Gephi ile Ağ Görselleştirme ve Analiz ```bash python prepare_for_gephi.py --data_dir ./dataset ``` Detaylı Gephi adımları ve karşılaştırılacak 3 kritik dönem için [project_report.md](project_report.md) Bölüm 7'ye bakınız. --- ## Tepe-Düşüş Kriz Tespit Algoritması (Geliştirilmiş) Kriz dönemleri grafikte tepeye çıkıp sonra düşüşe geçtiği anda oluşur: ``` 1. Bileşik kriz sinyali = 0.4×norm(kenar) + 0.3×norm(yoğunluk) + 0.3×norm(derece) 2. Düzleştir: hareketli ortalama (pencere=5) 3. Birinci türev: pozitif=tırmanma, negatif=düşüş 4. Tepe tespiti: birinci türev pozitiften negatife geçtiği an 5. Ana kriz tepesi: düşüş şiddeti en büyük olan tepe ``` Detaylı implementasyon: [`peak_descent.py`](peak_descent.py) --- ## Veri Temizleme ve Ön İşleme Pipeline Önceki deneylerde ham veriyi doğrudan modele verdik — hiçbir temizleme yapmadık. Bu, sonuçları olumsuz etkiliyordu. Şimdi sistematik bir temizleme pipeline'ı ekledik. ### Elliptic Veri Setinin Sorunları | Sorun | Detay | Etki | |-------|-------|------| | **%77 etiketsiz** | 203K düğümün sadece 46K'sı etiketli | Eğitim verisi sınırlı | | **%90 vs %10 dengesizlik** | İllicit çok az (%9.8) | Model "herkes licit" demeye eğilimli | | **PCA ile gizlenmiş özellikler** | Ne olduğunu bilmiyoruz | Özellik mühendisliği sınırlı | | **Outlier'lar** | İllicit örnekler daha fazla aykırı değer içeriyor | Temizleme illicit sınıfını orantısız etkileyebilir | | **Aggregated özellikler** | Komşuluktan türetilmiş | Sızıntı kanalı olabilir | ### Test Edilen Pipeline'lar `data_audit.py` scripti 8 farklı ön işleme adımını temporal split üzerinde test eder: | # | Pipeline | Ne Yapıyor? | |---|----------|------------| | 1 | Ham Veri (Baseline) | Hiçbir şey — mevcut durum | | 2 | StandardScaler | Ortalaması 0, std 1 | | 3 | RobustScaler | Outlier'lara dayanıklı (median ve IQR bazlı) | | 4 | NaN Temizleme + Standard | Eksik değerleri sıfırla, sonra ölçekle | | 5 | Outlier Clipping + Standard | Aykırı değerleri IQR sınırlarına kırp | | 6 | SMOTE + Standard | Sentetik azınlık örnekleri üret (dengesizliği düzelt) | | 7 | Düşük Varyans Çıkarma | İşe yaramayan sabit özellikleri çıkar | | 8 | Tam Pipeline | Temizle → Kırp → RobustScale → SMOTE | ### Neden Önemli? İllicit örnekler muhtemelen daha fazla outlier içeriyor — çünkü suçlular normal davranıştan sapan işlemler yapıyor. Outlier clipping yaparsak bu ayrımı silme riski var. SMOTE ile dengesizliği düzeltmek ise modelin illicit sınıfını daha iyi öğrenmesini sağlar. ### Çalıştırma ```bash pip install imbalanced-learn python data_audit.py --data_dir ./dataset ``` Çıktılar: `audit_results.csv` (pipeline karşılaştırması) ve `audit_figures/data_audit.png` (görselleştirme). --- ## Tek Komutla Tüm Deneyleri Çalıştırma (run_all.py) Veri temizleme dahil tüm deneyleri tek bir komutla çalıştıran master script: ```bash python run_all.py --data_dir ./dataset ``` Bu script sırayla şunları yapar: | Adım | Ne Yapıyor? | Süre | |------|------------|------| | 1 | Veri yükle | ~30 sn | | 2 | Temizle: NaN/Inf → 0, IQR outlier clip, düşük varyans çıkar | ~10 sn | | 3 | 6 pipeline'ı test et, en iyiyi otomatik seç | ~5 dk | | 4 | 49 timestep topolojik metrik hesapla (NetworkX) | ~3 dk | | 5 | Kırılma noktası tespiti (sağlık skoru + tepe-düşüş birleşik) | ~5 sn | | 6 | 5 strateji × 3 model = 15 deney (temizlenmiş veri ile) | ~10 dk | | 7 | Walk-forward validasyon (dürüstlük referansı) | ~8 dk | | 8 | 4 figür oluştur ve kaydet | ~10 sn | Toplam: ~7 dakika (cpu-basic). Çıktılar `output/` klasörüne kaydedilir: - `output/results/all_experiment_results.csv` — tüm deney sonuçları - `output/results/topological_metrics.csv` — 49 timestep ağ metrikleri - `output/results/summary.json` — özet rapor (kırılma noktası, pipeline seçimi, WF referans) - `output/run_all_output.log` — çalıştırma logu - `output/figures/fig1_breakpoint.png` — kırılma noktası figürü - `output/figures/fig2_f1_comparison.png` — F1 karşılaştırma - `output/figures/fig3_pipeline_comparison.png` — pipeline karşılaştırma - `output/figures/fig4_honesty.png` — dürüstlük ısı haritası ### Önceki Deneylere Göre Neler Değişti? | Özellik | Önceki Deneyler | run_all.py | |---------|----------------|------------| | Veri temizleme | ❌ Yapılmadı | ✅ NaN + Outlier clip + Var filter | | Ölçekleme | Model bazlı (tutarsız) | ✅ RobustScaler (tüm modellerde) | | Pipeline seçimi | Manuel | ✅ Otomatik (en iyi F1'i seçer) | | Kırılma tespiti | Tek yöntem (sağlık) | ✅ İki yöntem birleşik (sağlık + tepe-düşüş) | | SMOTE dengesizlik | ❌ Yapılmadı | ✅ Test edildi | | Çalıştırıldı mı? | ✅ Evet | ✅ **Evet — tamamlandı (7.3 dk)** | --- ## Ön Literatür Taraması (Hakemli Yayınlar — SCI / SCI-E İndeksli) | # | Makale | Dergi / Konferans | İndeks | Söyledikleri | Biz Ne Yapıyoruz | Link | |---|--------|-------------------|--------|-------------|-----------------|------| | 1 | Rubachev, I. et al. (2024). "TabReD" | **NeurIPS 2024** | SCI-E (Core A*) | Zaman bazlı bölme model sıralamasını değiştiriyor | Neden değiştiğini ağ topolojisiyle açıklıyoruz | [Paper](https://arxiv.org/abs/2406.19380) | | 2 | Wang, Y. et al. (2024). "Topological Concentration" | **ICLR 2024** | SCI-E (Core A*) | TDS keşfettiler ama bölme kararına bağlamadılar | TDS'yi bölme kararına çeviriyoruz | [Paper](https://arxiv.org/abs/2310.04612) | | 3 | Huang, S. et al. (2023). "TGB" | **NeurIPS 2023** | SCI-E (Core A*) | Sabit kronolojik bölme, AML domain'i yok | Kırılma noktasına göre bölme + AML | [Paper](https://arxiv.org/abs/2307.01026) | | 4 | Poursafaei, F. et al. (2022). "Better Eval Dynamic LP" | **NeurIPS 2022** | SCI-E (Core A*) | Negatif örnekleme sıralamayı değiştiriyor | Bölme stratejisinin etkisini gösteriyoruz | [Paper](https://arxiv.org/abs/2207.10128) | | 5 | Weber, M. et al. (2019). "Elliptic Dataset" | **KDD 2019** | SCI-E (Core A*) | Sabit kronolojik bölme kullandılar | +13 puan F1 artışı gösteriyoruz | [Paper](https://arxiv.org/abs/1908.02591) | | 6 | Lo, W.W. et al. (2023). "Inspection-L" | **Applied Intelligence** | **SCI-E** (IF:3.4) | TS 43'te çöküş gösterdiler | Krizleri otomatik tespit ediyoruz | [Paper](https://doi.org/10.1007/s10489-023-04504-9) | | 7 | Rossi, E. et al. (2020). "TGN" | **ICML 2020** | SCI-E (Core A*) | Dinamik graf çerçevesi sundular | Bölme noktası ağ yapısına göre olmalı | [Paper](https://arxiv.org/abs/2006.10637) | | 8 | Wu, Z. et al. (2021). "GNN Survey" | **IEEE TNNLS** | **SCI** (IF:10.4) | Sabit snapshot yetersiz dediler | Topolojik kırılmaya göre bölme öneriyoruz | [Paper](https://doi.org/10.1109/TNNLS.2020.2978386) | | 9 | Al Sahili & Awad (2023). "STGNN Survey" | **AI Review** | **SCI-E** (IF:12.0) | Statik graf varsayımı sınırlayıcı | Zamansal değişkenliği bölme kararına çeviriyoruz | [Paper](https://doi.org/10.1007/s10462-023-10466-2) | | 10 | Pareja, A. et al. (2020). "EvolveGCN" | **AAAI 2020** | SCI-E (Core A*) | Sabit kronolojik bölme kullandılar | Ağın evrimindeki kırılmadan bölüyoruz | [Paper](https://arxiv.org/abs/1902.10191) | | 11 | Thimonier, H. et al. (2024). "AD for Fraud" | **DMKD** | **SCI-E** (IF:4.8) | COVID kaynaklı shift gösterdiler | Shift anını bölme noktası yapıyoruz | [Paper](https://doi.org/10.1007/s10618-024-01054-9) | > Tüm makaleler SCI veya SCI-E indeksli hakemli yayınlardır. Detaylı tarama: [literature_review.md](https://huggingface.co/Moco22/leakage-anatomy-bitcoin-aml/blob/main/literature_review.md) --- ## Proje Raporu Tüm analizlerin detaylı açıklaması, Triple Barrier karşılaştırması, walk-forward timestep tabloları ve rastgele etiket test sonuçları dahil kapsamlı rapor: **[project_report.md](project_report.md)** --- ## Proje Yapısı ``` ├── README.md # Bu dosya ├── project_report.md # Kapsamlı proje raporu (Triple Barrier analizi dahil) ├── run_all.py # ★ Tek komutla tüm deneyleri çalıştır (temizleme dahil) ├── data_audit.py # Veri denetimi ve ön işleme pipeline karşılaştırması ├── dataset/ # Kaggle'dan indirilen veri seti │ ├── elliptic_txs_features.csv │ ├── elliptic_txs_classes.csv │ └── elliptic_txs_edgelist.csv ├── topological_breakpoint.py # Ana deney: 4 model × 5 strateji = 20 deney ├── proof_mechanism.py # Kanıt testleri 1-5 ├── honesty_test.py # Kanıt testi 6: Dürüstlük testi ├── leakage_map.py # Sızıntı haritası ├── peak_descent.py # Tepe-düşüş kriz tespit algoritması ├── prepare_for_gephi.py # Gephi görselleştirme için veri hazırlama ├── elliptic_event_aware.py # Olay-farkında bölme deneyleri ├── topo_figures/ # Kırılma noktası figürleri (6 adet) ├── proof_figures/ # Kanıt mekanizması figürleri (7 adet) ├── figures/ # Olay analizi figürleri (8 adet) ├── output/ # ★ run_all.py çıktıları (temizlenmiş veri sonuçları) │ ├── results/ # Sayısal sonuçlar (CSV, JSON) │ │ ├── all_experiment_results.csv │ │ ├── topological_metrics.csv │ │ └── summary.json │ ├── figures/ # Güncel figürler (4 adet) │ │ ├── fig1_breakpoint.png │ │ ├── fig2_f1_comparison.png │ │ ├── fig3_pipeline_comparison.png │ │ └── fig4_honesty.png │ └── run_all_output.log # Çalıştırma logu ├── topo_results/ # Topolojik kırılma sonuçları (ham veri) ├── proof_results/ # Kanıt test sonuçları └── results/ # Olay analizi sonuçları ``` ## Tekrarlanabilirlik ### Hızlı Başlangıç (Önerilen) ```bash pip install pandas numpy scikit-learn matplotlib seaborn lightgbm xgboost networkx scipy imbalanced-learn python run_all.py --data_dir ./dataset ``` ### Ayrı Ayrı Çalıştırma ```bash python data_audit.py --data_dir ./dataset # Veri denetimi (~5 dk) python topological_breakpoint.py # Ana deneyler (~10 dk) python proof_mechanism.py # Kanıt testleri (~5 dk) python honesty_test.py # Dürüstlük testi (~10 dk) python leakage_map.py # Sızıntı haritası (~3 dk) python peak_descent.py # Tepe-düşüş analizi (~5 dk) python prepare_for_gephi.py --data_dir ./dataset # Gephi hazırlık (~2 dk) ``` --- ## Sonuç Random split %96 F1 rapor ediyor ama bunun %21'i yapay. Kriz anında model çöküyor (F1=0.07). Rastgele etiketlerde bile random split skor üretiyor. Ağ üzerinden komşuluk sızıntısı 502 kat farkla kanıtlandı. Bizim topolojik kırılma yöntemi kronolojik bölmeyi +13 puan geçiyor. Walk-forward dürüstlük testinde +%8 sapma ile kabul edilebilir sınırların içinde — ne şişiriyor ne de pesimist. **Veri temizleme sonuçları bu bulguları doğruladı:** Temizlenmiş veride de rastgele split +%21.3 şişme gösterirken, topolojik kırılma -%8.8 ile dürüstlük bandının içinde kaldı. Şişme veri kalitesinden değil, bölme stratejisinden kaynaklanıyor. **Karmaşık model geliştirmeden önce, veriyi doğru bölün.**