feat(clustering): limites sensibilité et k étendues pour classification maximale

Backend:
- k max: 30 → 100 (Query le=100), default: 14 → 20
- sensitivity max: 3.0 → 5.0 (Query le=5.0)
- k_actual cap: min(50,...) → min(300,...) — plus de coupure silencieuse
- n_init adaptatif: 3 quand k≤60, 1 quand k>60 (maintient performance)
- Résultat max effectif: k=100 × sens=5.0 = 500, plafonné à 300 clusters

Frontend:
- Slider sensibilité: max 3.0 → 5.0, step 0.5
- Libellés: Grossière/Normale/Fine/Très fine/Maximale/Extrême
- Label affiche '(N clusters effectifs)' au lieu de '(N clusters)'
- Slider k avancé: max 30 → 100
- Label k avancé: 'k → N clusters effectifs' (montre le résultat réel)
- Default k: 14 → 20

Test: k=20 × sens=5.0 = 100 clusters, Scanner pur detecté à 0.43, Bot UA simulé 0.38

Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
This commit is contained in:
SOC Analyst
2026-03-19 11:20:11 +01:00
parent 6ff59a36d7
commit 185518fd92
2 changed files with 20 additions and 14 deletions

View File

@ -94,7 +94,7 @@ function hexToRgba(hex: string, alpha = 255): [number, number, number, number] {
// ─── Composant principal ──────────────────────────────────────────────────────
export default function ClusteringView() {
const [k, setK] = useState(14);
const [k, setK] = useState(20);
const [hours, setHours] = useState(24);
const [sensitivity, setSensitivity] = useState(1.0);
const [data, setData] = useState<ClusterResult | null>(null);
@ -344,15 +344,15 @@ export default function ClusteringView() {
<div className="flex justify-between text-xs text-text-secondary">
<span>Sensibilité</span>
<span className="font-mono text-white">
{sensitivity === 0.5 ? 'Grossière' : sensitivity <= 1.0 ? 'Normale' : sensitivity <= 1.5 ? 'Fine' : sensitivity <= 2.0 ? 'Très fine' : 'Maximum'}
{' '}({Math.round(k * sensitivity)} clusters)
{sensitivity <= 0.5 ? 'Grossière' : sensitivity <= 1.0 ? 'Normale' : sensitivity <= 2.0 ? 'Fine' : sensitivity <= 3.5 ? 'Très fine' : sensitivity <= 4.5 ? 'Maximale' : 'Extrême'}
{' '}({Math.round(k * sensitivity)} clusters effectifs)
</span>
</div>
<input type="range" min={0.5} max={3.0} step={0.5} value={sensitivity}
<input type="range" min={0.5} max={5.0} step={0.5} value={sensitivity}
onChange={e => setSensitivity(+e.target.value)}
className="w-full accent-accent-primary" />
<div className="flex justify-between text-xs text-text-disabled">
<span>Grossière</span><span>Maximum</span>
<span>Grossière</span><span>Fine</span><span>Extrême</span>
</div>
</div>
@ -362,10 +362,10 @@ export default function ClusteringView() {
<div className="mt-2 space-y-2">
<label className="block">
Clusters de base (k)
<input type="range" min={4} max={30} value={k}
<input type="range" min={4} max={100} value={k}
onChange={e => setK(+e.target.value)}
className="w-full mt-1 accent-accent-primary" />
<span className="font-mono text-white">{k}</span>
<span className="font-mono text-white">{k} {Math.round(k * sensitivity)} clusters effectifs</span>
</label>
<label className="block">
Fenêtre