feat(ml): replace NetworkX/Louvain with PyTorch Geometric GraphSAGE for fleet detection

Rewrite fleet.py to use a GNN-based approach: nodes are src_ip with ML feature
vectors, edges connect IPs sharing (JA4, ASN) pairs, GraphSAGE (2 SAGEConv
layers, in→64→32) produces 32D embeddings clustered by HDBSCAN. PyG NeighborLoader
activates for >50k nodes. Update thesis docs (§5.2, §6.4, §2, §8) to reflect
GraphSAGE architecture and PyG scalability.

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
This commit is contained in:
Jacquin Antoine
2026-04-13 15:45:34 +02:00
parent c1821dcbc4
commit c6cb12981c
8 changed files with 378 additions and 264 deletions

View File

@ -583,17 +583,23 @@ La famille 7 combine la connaissance des bases de référence (JA4 connu, ASN, p
La famille 8 regroupe les features originales développées spécifiquement pour cette architecture, capturant des signaux comportementaux avancés non présents dans la littérature standard.
#### path_transition_entropy `[impl.]`
#### session_transformer_embedding `[impl.]` — Vecteur Float32, dimension 32
**Calcul** : entropie de Shannon sur la matrice de transition entre chemins successifs. Pour chaque paire de chemins consécutifs (path_i → path_{i+1}), construire la distribution de probabilité des transitions ; calculer H = -Σ p(a→b) × log2(p(a→b)).
**Calcul** : embedding dense produit par un *Transformer encoder* (2 couches, 4 têtes d'attention, `d_model=64`) prenant en entrée la séquence ordonnée des requêtes d'une session. Chaque requête est tokenisée en trois signaux : le chemin URL (hashé → embedding), la méthode HTTP (embedding catégoriel) et le délai inter-requête `Δt` (normalisé `log1p(Δt_ms)/10` → projection linéaire). Un *mean pooling* sur la sortie du Transformer, suivi d'une couche linéaire, produit le vecteur final de dimension 32. Les 32 dimensions sont exposées comme colonnes `seq_emb_0` à `seq_emb_31`.
**Signal** : navigation humaine = entropie élevée (imprévisible). Crawler systématique = entropie faible (suivi d'un pattern fixe). Bot répétitif = entropie proche de 0 (même transition répétée).
Ce vecteur remplace les statistiques agrégées basiques (`path_transition_entropy`, `cadence_cv`) par une représentation contextuelle capable de capturer les dépendances longues dans la séquence de navigation, au lieu de se limiter à une modélisation Markovienne d'ordre 1 ou à des moments statistiques isolés.
#### cadence_cv `[impl.]`
**Signal** : le Transformer encode conjointement la structure des chemins, les méthodes HTTP et le rythme temporel. Navigation humaine = vecteur structuré (transitions cohérentes, variabilité temporelle naturelle). Crawler systématique = vecteur concentré dans une région distincte de l'espace latent (séquences répétitives, Δt constants). Bot avancé avec randomisation = vecteur identifiable par l'absence de la structure attentionnelle propre à la navigation organique.
**Calcul** : `STDDEV(inter_request_intervals_ms) / MEAN(inter_request_intervals_ms)`
**Robustesse** : session ≤ 1 requête → vecteur nul (32 zéros). Session > 512 requêtes → troncation aux 512 dernières. Poids indisponibles → fallback à zéros avec avertissement journalisé.
**Signal** : coefficient de variation des intervalles inter-requêtes. Humain : CV ≈ 0.82.0 (variabilité naturelle). Bot à timer fixe : CV ≈ 0.010.05 (régularité mécanique). Bot avec jitter artificiel : CV ≈ 0.10.3 (moins régulier que timer fixe, moins variable qu'humain).
#### cadence_cv `[absorbé par session_transformer_embedding]`
**Note** : cette feature est désormais capturée par le *Session Transformer* (§5.1) via le signal `Δt` projeté et les couches de *self-attention*, qui modélisent la variabilité temporelle de manière contextuelle plutôt que par un coefficient de variation scalaire isolé. La colonne SQL subsiste dans `view_thesis_features_1h` pour compatibilité, mais n'est plus utilisée dans le vecteur feature du modèle.
**Ancien calcul** : `STDDEV(inter_request_intervals_ms) / MEAN(inter_request_intervals_ms)`
**Ancien signal** : coefficient de variation des intervalles inter-requêtes. Humain : CV ≈ 0.82.0 (variabilité naturelle). Bot à timer fixe : CV ≈ 0.010.05 (régularité mécanique). Bot avec jitter artificiel : CV ≈ 0.10.3.
#### lag1_autocorrelation `[impl.]`