vecteurs

2025-09-16 07:52:01 +02:00
parent ef6d61504a
commit 8af9720cea
6 changed files with 542 additions and 100 deletions

@@ -0,0 +1,73 @@
# Classification et clustering
Dans lanalyse de données, lobjectif est souvent de **catégoriser les individus** ou mieux encore de **découvrir des structures cachées**.
Deux grandes approches existent : la **classification supervisée** et le **clustering non supervisé**.
## Variables cibles et explicatives
### Variable cible (ou variable dépendante, output, $Y$)
Cest la variable que lon cherche à prédire, expliquer ou classifier.
Elle dépend des autres variables.
Elle est connue dans lapprentissage supervisé (ex. classification, régression).
### Variable explicative (ou variable indépendante, feature, $X$)
Ce sont les caractéristiques observées qui servent à expliquer ou prédire la variable cible.
Elles sont indépendantes entre elles (en théorie) mais influencent la variable cible.
## Classification supervisée
La **classification** consiste à **attribuer une observation à une classe prédéfinie**.
On dispose dun ensemble de données dapprentissage étiquetées (chaque observation appartient à une classe connue) et lalgorithme apprend une règle de décision.
### Méthodologie
1. **Constitution du jeu dapprentissage** : données avec variables explicatives (âge, revenu, historique dachat…) et une variable cible (classe : « fidèle », « risque »).
2. **Choix dun algorithme de classification**.
3. **Apprentissage du modèle** : lalgorithme ajuste ses paramètres pour minimiser lerreur de prédiction.
4. **Évaluation** : mesurer la précision sur de nouvelles données (validation croisée, matrice de confusion).
5. **Prédiction** : classer les nouvelles observations.
### Algorithmes courants
* **Arbres de décision (CART, C4.5, Random Forest)** : règles simples de type « si… alors… ».
* **k-Nearest Neighbors (k-NN)** : un individu est classé selon la majorité de ses plus proches voisins.
* **Naïve Bayes** : modèle probabiliste basé sur le théorème de Bayes.
* **Régression logistique** : adaptée aux classes binaires.
* **SVM (Support Vector Machines)** : séparateurs optimaux entre classes.
* **Réseaux de neurones** : pour des problèmes complexes et volumineux.
## Clustering (non supervisé)
Le **clustering** (ou classification automatique) consiste à **regrouper des individus en classes (clusters) non connues à lavance**, en fonction de leur similarité.
Il ny a pas de variable cible : lalgorithme cherche à découvrir des structures naturelles dans les données.
### Méthodologie
1. **Choisir une mesure de similarité** (distance euclidienne, Manhattan, cosinus…).
2. **Appliquer un algorithme de regroupement**.
3. **Évaluer la qualité des clusters** (compacité, séparation, indice de silhouette).
4. **Interpréter les groupes** : leur donner un sens métier (ex. « clients premium », « clients occasionnels »).
Lindice de silhouette (Silhouette Coefficient) mesure à quel point un objet (une donnée) est bien placé dans son cluster par rapport aux autres clusters.
Il évalue deux choses :
Cohésion intra-cluster → à quel point lobjet est proche des autres membres de son cluster.
Séparation inter-cluster → à quel point il est éloigné des membres des autres clusters.
### Algorithmes courants
* **k-Means** : partitionne en *k* clusters en minimisant la variance intra-classe.
* **Clustering hiérarchique** : construit un arbre (dendrogramme) de regroupement.
* **DBSCAN** : identifie des zones de densité et détecte les anomalies.
* **Gaussian Mixture Models (GMM)** : modèles probabilistes où chaque cluster suit une distribution normale.

60
vecteurs.index.md Normal file

@@ -0,0 +1,60 @@
# Indexation vectorielle
## Structures exactes
### Kd-Tree (k-dimensional tree)
Un Kd-Tree est une structure darbre binaire qui permet dorganiser des points dans un espace de dimension k.
- Chaque nœud de larbre représente un point (vecteur).
- À chaque niveau de larbre, on découpe lespace selon une dimension spécifique.
Ainsi, lespace est récursivement partitionné en hyperplans (droites en 2D, plans en 3D, hyperplans en kD).
- On choisit une dimension de séparation (ex. la dimension x).
- On prend le point médian selon cette dimension → il devient le nœud racine.
- Les points avec des coordonnées inférieures vont dans le sous-arbre gauche, les autres dans le sous-arbre droit.
- On recommence récursivement en changeant la dimension (ex. au niveau suivant on coupe selon y, puis z, ... puis de nouveau x).
Chaque étape partitionne lespace en rectangles de plus en plus petits.
### Ball-Tree
Au lieu de couper par des hyperplans, on coupe par des hypersphères → mieux adapté pour distances euclidiennes.
Le Kd-Tree est une structure dindexation exacte, très efficace pour la recherche de voisins proches en faible dimension. Mais il ne passe pas à léchelle en haute dimension, ce qui a conduit au développement des méthodes approximatives.
## Structures approximatives
### Locality Sensitive Hashing (LSH)
Lidée est de construire des fonctions de hachage probabilistes qui envoient :
les vecteurs similaires → dans le même seau (bucket) avec forte probabilité,
les vecteurs différents → dans des seaux distincts avec forte probabilité.
Contrairement à un hachage classique (qui disperse les données), ici le hachage est conçu pour conserver la notion de proximité.
### Inverted File (IVF)
Appliquer k-means pour créer C clusters.
Assigner chaque vecteur au centroïde le plus proche.
Dans chaque cluster, stocker uniquement les résidus (différence vecteur centroïde).
Utiliser Product Quantization (PQ) pour encoder ces résidus en codes compacts (ex. 8 bits par sous-espace).
### Hierarchical Navigable Small World (HNSW)
Basé sur les graphes de proximité : chaque vecteur est un nœud relié à ses voisins proches.
On construit un graphe navigable qui permet de trouver les plus proches voisins sans explorer toute la base.
Inspiré des graphes "small-world" : on peut atteindre rapidement un point du graphe en peu de sauts.
> Le choix d'un index est un compromis
- Exact = lent mais précis.
- Approximatif = rapide mais avec une petite perte de précision.

@@ -4,10 +4,10 @@
La solution la plus utilisée consiste à projeter ces données dans un **espace vectoriel** : chaque objet est représenté par un vecteur de nombres réels.
Cela permet dutiliser les outils de lalgèbre linéaire, de la statistique et de linformatique pour :
Cela permet dutiliser les outils de lalgèbre linéaire et de la statistique pour :
- rechercher des objets similaires,
- regrouper ou classifier des individus,
- détecter des anomalies ou recommander des produits.
- identifier des anomalies, fraudes ou défauts de fabrication (vecteurs très éloignés).
Aujourdhui, ces méthodes sont utilisées partout : moteur de recherche, recommandation Netflix/Spotify, détection de fraude bancaire, IA générative (ChatGPT encode les phrases en vecteurs pour raisonner dessus).
@@ -18,7 +18,7 @@ Aujourdhui, ces méthodes sont utilisées partout : moteur de recherche, reco
Un **vecteur** est une suite ordonnée de nombres réels :
$$
v = [x_1, x_2, \dots, x_n] \in \mathbb{R}^n
\vec{v} = [v_1, v_2, \dots, v_n] \in \mathbb{R}^n
$$
Un **espace vectoriel** est un ensemble de vecteurs où sappliquent deux opérations :
@@ -39,7 +39,7 @@ Elle définit aussi une distance entre deux vecteurs, invariante par translation
#### Norme $L_2$ (euclidienne)
Dans le plan, si le vecteur _u_ a pour coordonnées (x , y), sa norme s'écrit :
Dans le plan, si le vecteur $\vec{v}$ a pour coordonnées (x , y), sa norme s'écrit :
$$
||\vec{v}|| = \sqrt{x^2 + y^2}
@@ -59,26 +59,143 @@ $$
### Distances
À partir dune norme, on définit une **distance** entre vecteurs $u$ et $v$. Exemple :
À partir dune norme, on définit une **distance** entre vecteurs $\vec{u}$ et $\vec{v}$.
* Distance euclidienne :
La distance euclidienne :
$$
d(u,v) = ||u-v||_2
d(\vec{u},\vec{v}) = ||\vec{u}-\vec{v}||_2
$$
### Produit scalaire et similarité cosinus
Le **produit scalaire** est défini par :
Le **produit scalaire** (_inner product_ ou _dot product_ en anglais) est une opération qui prend deux vecteurs et donne un scalaire (nombre).
$$
u \cdot v = \sum_{i=1}^n u_i v_i
\vec{u} \cdot \vec{v} = \sum_{i=1}^n u_i v_i
$$
ou
$$
\vec{u} \cdot \vec{v} = ||\vec{u}|| \cdot ||\vec{v}|| \cdot cos(\theta)
$$
Le produit scalaire relie longueurs et angles. Il permet d'exploiter les notions de la géométrie euclidienne traditionnelle : longueurs, angles, orthogonalité en deux, trois ou plus de dimensions.
La **similarité cosinus** est donnée par :
$$
\cos(\theta) = \frac{u \cdot v}{||u|| \cdot ||v||}
\cos(\theta) = \frac{\vec{u} \cdot \vec{v}}{||\vec{u}|| \cdot ||\vec{v}||}
$$
Utilisé pour comparer deux vecteurs indépendamment de leur taille (ex. documents textuels).
Elle est utilisée pour comparer deux vecteurs indépendamment de leur taille (ex. documents textuels).
Si = 0 soit θ = 90°, les vecteurs sont orthogonaux (perpendiculaires) Il n'y a aucune similarité.
Si = 1 les vecteurs pointent exactement dans la même direction (très similaires).
Si = -1 les vecteurs pointent dans des directions opposées (complètement dissemblables).
## Statistique multivariée
### Moyenne, variance et covariance
Pour une variable $X$ :
**Moyenne** : $\mu = \frac{1}{n}\sum x_i$
**Variance** : $\sigma^2 = \frac{1}{n}\sum (x_i - \mu)^2$
Pour deux variable $X$ et $Y$
**Covariance** : $\text{Cov}(X,Y) = E[(X-\mu_X)(Y-\mu_Y)]$
La covariance mesure comment deux variables X et Y varient ensemble.
$E$ est l'esperance (ou moyenne théorique). En statistique pratique, on remplace $E[X]$ par la moyenne empirique
D'où de manière empirique
$$
\widehat{\mathrm{Cov}}(X,Y) = \frac{1}{n} \sum_{i=1}^n (x_i - \bar{x})(y_i - \bar{y})
$$
Si $X$ et $Y$ sont corrélés alors la covariance est positive. Si la covariance est nulle il n'y a pas de lien. Si la covariance est négative alors la probabilité est trés faible.
**Corrélation** est la covariance normalisée sur une échelle de -1 à 1.
$$
\rho(X,Y) = \frac{\mathrm{Cov}(X,Y)}{\sigma_X \sigma_Y}
$$
Ces mesures servent à comprendre la dispersion et les corrélations.
### Normalisation des données
Avant de comparer des vecteurs, il faut rendre les dimensions comparables en grandeur.
**Min-Max scaling** :
$$
x' = \frac{x - \min}{\max - \min}
$$
**Standardisation (z-score)** :
$$
x' = \frac{x - \mu}{\sigma}
$$
### Réduction de dimension
Lorsquune base de données contient de nombreuses variables (ou dimensions), il devient difficile danalyser efficacement les données. On parle alors de malédiction de la dimensionnalité : plus il y a de dimensions, plus les calculs sont coûteux, et plus il est difficile de visualiser ou dinterpréter les résultats.
La réduction des dimensions vise donc à simplifier lespace de représentation en conservant linformation la plus pertinente.
- Alléger les données : diminuer la taille et la complexité des tables.
- Améliorer les performances : réduire le temps de calcul dans les requêtes analytiques et les algorithmes.
- Faciliter la visualisation : rendre possible une représentation graphique (2D, 3D).
- Éliminer le bruit : supprimer les variables redondantes ou peu informatives.
Il existe deux grandes familles dapproches
**Sélection de variables** (feature selection) : On conserve uniquement les dimensions les plus pertinentes :
- **Analyse de corrélation** : suppression d'une des variables fortement corrélées.
- **Méthodes statistiques** (tests dhypothèses, chi², ANOVA) pour éliminer les variables peu discriminantes.
- **Méthodes incrémentales** : ajout ou retrait progressif de variables en fonction de critères de qualité (erreur de prédiction, pouvoir explicatif)
**Extraction de nouvelles dimensions** (feature extraction)
On crée de nouvelles variables synthétiques à partir des variables initiales :
- **ACP (Analyse en Composantes Principales, PCA)**
- Transforme les données en un nouvel espace en combinant linéairement les variables.
- Les premières composantes expliquent la plus grande partie de la variance.
- Très utilisée en statistique et en apprentissage automatique.
- **Analyse factorielle** : Identifie des facteurs latents expliquant les corrélations entre variables.
- **t-SNE, UMAP** (méthodes modernes) : Plus adaptées pour la visualisation et la détection de structures non linéaires dans des données complexes.
## Théorie de la similarité
### Problème des plus proches voisins
Pour un vecteur $\vec{q}$, trouver les $k$ vecteurs les plus proches parmi une base de données.
Méthode naïve : comparer $q$ avec tous les vecteurs un par un.
Mais quand la dimension n augmente, les distances entre points tendent à se ressembler,
- [Classification et clustering](vecteurs.classification)
- [Indexation vectorielle](vecteurs.index)
## Exercice
1. Construire une base de produits avec vecteurs nutritionnels.
2. Normaliser les données par z-score.
3. Créer un index HNSW.
4. Classer un produit inconnu avec k-NN.
5. Détecter les produits extrêmes.

@@ -8,8 +8,6 @@
FAISS (Facebook), Milvus, Pinecone, Weaviate.
1. ****
* Définitions (vecteur, dimension, norme).
@@ -230,53 +228,23 @@ Aujourdhui, ces méthodes sont utilisées partout : moteur de recherche, reco
---
## Chapitre 2 : Statistique multivariée
## Chapitre 2 :
### 2.1 Moyenne, variance, covariance
### 2.1
Pour une variable $X$ :
* Moyenne : $\mu = \frac{1}{n}\sum x_i$
* Variance : $\sigma^2 = \frac{1}{n}\sum (x_i - \mu)^2$
* Covariance entre $X$ et $Y$ : $\text{Cov}(X,Y) = E[(X-\mu_X)(Y-\mu_Y)]$
👉 Ces mesures servent à comprendre la dispersion et les corrélations.
---
### 2.2 Normalisation des données
Avant de comparer des vecteurs, il faut rendre les dimensions comparables :
* **Min-Max scaling** :
$$
x' = \frac{x - \min}{\max - \min}
$$
* **Standardisation (z-score)** :
$$
x' = \frac{x - \mu}{\sigma}
$$
👉 Le z-score est très utilisé pour détecter les valeurs extrêmes.
---
### 2.3 Réduction de dimension
* **ACP (PCA)** : projette les données sur des axes qui maximisent la variance.
* **T-SNE, UMAP** : techniques non linéaires pour visualiser des vecteurs en 2D ou 3D.
---
## Chapitre 3 : Théorie de la similarité
### 3.1 Problème des plus proches voisins
Donné un vecteur $q$, trouver les $k$ vecteurs les plus proches parmi une base de données.
* Méthode naïve : comparer $q$ avec tous les vecteurs ($O(N)$).
---
@@ -297,55 +265,6 @@ Quand la dimension $n$ augmente :
* Cosinus → données textuelles ou normalisées.
* Jaccard/Hamming → données catégorielles.
---
## Chapitre 4 : Classification et clustering
### 4.1 Classification supervisée
* **k-NN** : attribue la classe majoritaire parmi les $k$ plus proches voisins.
* Analyse discriminante.
---
### 4.2 Clustering (non supervisé)
* **k-means** : partitionne les données en $k$ groupes.
* **Clustering hiérarchique**.
* **DBSCAN** : détecte des regroupements denses.
---
### 4.3 Évaluation
* Taux derreur, précision, rappel.
* Indice de silhouette.
---
## Chapitre 5 : Indexation vectorielle
### 5.1 Structures exactes
* **kd-tree**, **ball-tree** : efficaces en basse dimension (< 30).
---
### 5.2 Structures approximatives
* **LSH (Locality Sensitive Hashing)**.
* **IVF (Inverted File)**.
* **HNSW (Hierarchical Navigable Small World)** :
* Graphe de proximité hiérarchique.
* Recherche rapide et précise.
---
### 5.3 Compromis
* Exact = lent mais précis.
* Approximatif = rapide mais avec une petite perte de précision.
---
@@ -427,11 +346,7 @@ Grâce à des outils comme PostgreSQL + pgvector, on peut manipuler ces techniqu
## Exercices finaux
1. Construire une base de produits avec vecteurs nutritionnels.
2. Normaliser les données par z-score.
3. Créer un index HNSW.
4. Classer un produit inconnu avec k-NN.
5. Détecter les produits extrêmes.
---
@@ -445,3 +360,159 @@ Grâce à des outils comme PostgreSQL + pgvector, on peut manipuler ces techniqu
---
Voulez-vous que je complète ce cours avec **schémas explicatifs et illustrations** (par exemple représentation dun espace vectoriel, graphe HNSW, courbe du z-score), pour en faire un véritable poly visuel ?
Très bonne question 👍, car la **covariance** est une des notions centrales de la statistique et elle fait intervenir lopérateur $E$, qui est l**espérance mathématique**.
---
# 📘 La covariance et lespérance
## 1. Lespérance $E[X]$
L**espérance** (ou **moyenne théorique**) dune variable aléatoire $X$ est une mesure de sa valeur moyenne à long terme.
* **Variable discrète** :
$$
E[X] = \sum_i x_i \, P(X = x_i)
$$
* **Variable continue** :
$$
E[X] = \int_{-\infty}^{+\infty} x \, f(x)\, dx
$$
où $f(x)$ est la densité de probabilité.
👉 Intuitivement, $E[X]$ = **moyenne pondérée** par les probabilités.
👉 En statistique pratique, on remplace $E[X]$ par la **moyenne empirique** :
$$
\bar{x} = \frac{1}{n} \sum_{i=1}^n x_i
$$
---
## 2. Définition de la covariance
La **covariance** mesure comment deux variables $X$ et $Y$ **varient ensemble**.
$$
\mathrm{Cov}(X,Y) = E\big[(X - E[X])(Y - E[Y])\big]
$$
Autrement dit :
* Si $X$ est grand quand $Y$ est grand → covariance **positive**.
* Si $X$ est grand quand $Y$ est petit → covariance **négative**.
* Si aucun lien → covariance proche de **0**.
---
## 3. Formule pratique
On peut développer la définition :
$$
\mathrm{Cov}(X,Y) = E[XY] - E[X]E[Y]
$$
En version empirique (données observées $(x_i,y_i)$) :
---
## 4. Exemple simple
Données :
$X = (1, 2, 3)$, $Y = (2, 4, 6)$.
* Moyennes : $\bar{x} = 2$, $\bar{y} = 4$.
* Produits centrés :
$(1-2)(2-4) = (+2)$,
$(2-2)(4-4) = (0)$,
$(3-2)(6-4) = (+2)$.
* Moyenne : $(2 + 0 + 2)/3 = 1.33$.
👉 Covariance positive : $X$ et $Y$ croissent ensemble.
---
## 5. Interprétation
* **Unité** : la covariance sexprime dans les unités combinées de $X$ et $Y$ (ex. kg·cm).
* **Problème** : sa valeur dépend des échelles de mesure → difficile à comparer.
* **Solution** : on utilise la **corrélation** (covariance normalisée) :
$$
\rho(X,Y) = \frac{\mathrm{Cov}(X,Y)}{\sigma_X \sigma_Y}
$$
où $\sigma_X, \sigma_Y$ sont les écarts-types.
---
## 6. Application à vos vecteurs nutritionnels
Si $X =$ teneur en sucre et $Y =$ teneur en énergie (kcal) sur une base de produits :
* $\mathrm{Cov}(X,Y) > 0$ : les produits sucrés apportent plus dénergie (logique).
* $\mathrm{Cov}(X,Y) \approx 0$ : pas de lien.
* $\mathrm{Cov}(X,Y) < 0$ : plus de sucre = moins dénergie (peu probable).
---
📌 **Résumé**
* $E[\cdot]$ = espérance = moyenne théorique.
* $\mathrm{Cov}(X,Y)$ mesure la tendance de deux variables à varier ensemble.
* Corrélation = covariance **normalisée** pour comparer entre variables.
---
Voulez-vous que je montre un **exemple SQL avec PostgreSQL** pour calculer la covariance (et corrélation) entre sucre et énergie dans votre table `produits` ?
Parfait 👍 Développons maintenant la partie **classification et clustering**, qui est un volet essentiel de lanalyse multidimensionnelle.
---
### Applications
* Segmentation client sans étiquette.
* Analyse de comportements sur un site web.
* Regroupement de documents ou dimages.
* Détection danomalies (points isolés).
---
## 3. Comparaison Classification vs Clustering
| Critère | Classification (supervisée) | Clustering (non supervisée) |
| ----------------------- | --------------------------- | ----------------------------- |
| Données dapprentissage | Avec classes connues | Sans classes connues |
| Objectif | Prédire une classe | Découvrir des regroupements |
| Exemple | Spam / Non Spam | Segmenter des clients |
| Méthodes | SVM, arbres, k-NN, Bayes | k-Means, DBSCAN, hiérarchique |
---
## 4. Liens avec lanalyse multidimensionnelle
* **En Data Warehouse** : on peut utiliser la classification pour prédire une variable clé (ex. prédire si une campagne marketing réussira).
* **Dans un cube OLAP** : le clustering peut permettre de **réduire les dimensions** en regroupant des modalités similaires (ex. fusionner des catégories de produits qui se vendent de manière identique).
---
✅ En résumé :
* La **classification** sappuie sur des classes connues et cherche à **prédire**.
* Le **clustering** ne connaît pas les classes à lavance et cherche à **découvrir** des structures cachées.
---
Voulez-vous que je développe un **exemple pratique illustré** (par ex. segmentation de clients avec un tableau de variables, appliquant à la fois classification supervisée et clustering) pour rendre cette partie plus concrète ?

BIN
vecteurs/kd-tree.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 19 KiB

121
vecteurs/kd-tree.svg Normal file

@@ -0,0 +1,121 @@
<svg viewBox="0 0 980 560" xmlns="http://www.w3.org/2000/svg" role="img" aria-label="Illustration Kd-Tree 2D">
<defs>
<marker id="arrow" viewBox="0 0 10 10" refX="6" refY="5" markerWidth="6" markerHeight="6" orient="auto-start-reverse">
<path d="M 0 0 L 10 5 L 0 10 z" fill="#0b1a2b"/>
</marker>
<filter id="soft" x="-20%" y="-20%" width="140%" height="140%">
<feDropShadow dx="0" dy="1" stdDeviation="2" flood-color="#000" flood-opacity="0.08"/>
</filter>
</defs>
<!-- Background grid area (left) -->
<rect x="10" y="10" width="640" height="540" rx="8" ry="8" fill="#ffffff" stroke="#e6eef6" />
<!-- Title inside SVG -->
<text x="30" y="34" font-size="14" fill="#0b1a2b" font-weight="600">Plan 2D — Zones partitionnées</text>
<!-- Example points (with insertion order labels) -->
<!-- Points coordinates are within the 640x540 box offset by (10,10) -->
<!-- Points array: [ {x,y,label} ] -->
<!-- Level 0 split (vertical line by x) -->
<line x1="330" y1="10" x2="330" y2="550" stroke="#ef4444" stroke-width="2.5" stroke-dasharray="" />
<text x="334" y="30" font-size="12" fill="#ef4444">Level 0 (x)</text>
<!-- Level 1 splits (horizontal lines) -->
<line x1="10" y1="310" x2="330" y2="310" stroke="#1f8ef1" stroke-width="2" />
<text x="32" y="326" font-size="12" fill="#1f8ef1">Level 1 (y)</text>
<line x1="330" y1="130" x2="650" y2="130" stroke="#1f8ef1" stroke-width="2" />
<!-- Level 2 splits (vertical inside left quadrant) -->
<line x1="150" y1="10" x2="150" y2="310" stroke="#f59e0b" stroke-width="1.8" />
<text x="152" y="30" font-size="11" fill="#f59e0b">Level 2 (x)</text>
<!-- Level 2 split (vertical inside right-bottom quadrant) -->
<line x1="460" y1="130" x2="460" y2="550" stroke="#f59e0b" stroke-width="1.8" />
<!-- Level 3 splits (horizontal inside a small cell) -->
<line x1="150" y1="180" x2="330" y2="180" stroke="#10b981" stroke-width="1.6" />
<!-- Points left-top quadrant -->
<g fill="#0b1a2b" font-size="11" text-anchor="middle">
<circle cx="120" cy="60" r="6" fill="#0b1a2b" filter="url(#soft)" />
<text x="120" y="64" fill="#fff" font-weight="700" font-size="9">1</text>
<circle cx="210" cy="90" r="6" fill="#0b1a2b" filter="url(#soft)" />
<text x="210" y="94" fill="#fff" font-weight="700" font-size="9">4</text>
<circle cx="180" cy="220" r="6" fill="#0b1a2b" filter="url(#soft)" />
<text x="180" y="224" fill="#fff" font-weight="700" font-size="9">7</text>
</g>
<!-- Points left-bottom quadrant -->
<g>
<circle cx="80" cy="360" r="6" fill="#0b1a2b" filter="url(#soft)" />
<text x="80" y="364" fill="#fff" font-weight="700" font-size="9" text-anchor="middle">2</text>
<circle cx="260" cy="260" r="6" fill="#0b1a2b" filter="url(#soft)" />
<text x="260" y="264" fill="#fff" font-weight="700" font-size="9" text-anchor="middle">5</text>
</g>
<!-- Points right-top quadrant -->
<g>
<circle cx="420" cy="80" r="6" fill="#0b1a2b" filter="url(#soft)" />
<text x="420" y="84" fill="#fff" font-weight="700" font-size="9" text-anchor="middle">3</text>
<circle cx="540" cy="170" r="6" fill="#0b1a2b" filter="url(#soft)" />
<text x="540" y="174" fill="#fff" font-weight="700" font-size="9" text-anchor="middle">6</text>
<circle cx="500" cy="410" r="6" fill="#0b1a2b" filter="url(#soft)" />
<text x="500" y="414" fill="#fff" font-weight="700" font-size="9" text-anchor="middle">8</text>
</g>
<!-- Small inset: tree structure on the right -->
<g transform="translate(680,40)">
<rect x="0" y="0" width="280" height="420" rx="8" ry="8" fill="#ffffff" stroke="#e6eef6" />
<text x="18" y="24" font-size="13" fill="#0b1a2b" font-weight="600">Kd-Tree (structure)</text>
<!-- Nodes -->
<!-- Root -->
<g>
<rect x="98" y="48" width="84" height="28" rx="6" fill="#ef4444" opacity="0.12" stroke="#ef4444" />
<text x="140" y="68" font-size="12" fill="#ef4444" text-anchor="middle">Root (split x)</text>
</g>
<!-- Left child -->
<g>
<rect x="18" y="128" width="84" height="28" rx="6" fill="#1f8ef1" opacity="0.12" stroke="#1f8ef1" />
<text x="60" y="148" font-size="12" fill="#1f8ef1" text-anchor="middle">L (split y)</text>
</g>
<!-- Right child -->
<g>
<rect x="178" y="128" width="84" height="28" rx="6" fill="#1f8ef1" opacity="0.12" stroke="#1f8ef1" />
<text x="220" y="148" font-size="12" fill="#1f8ef1" text-anchor="middle">R (split y)</text>
</g>
<!-- Lines -->
<line x1="140" y1="76" x2="60" y2="128" stroke="#94a3b8" stroke-dasharray="3 4" />
<line x1="140" y1="76" x2="220" y2="128" stroke="#94a3b8" stroke-dasharray="3 4" />
<!-- Deeper nodes -->
<rect x="18" y="208" width="84" height="28" rx="6" fill="#f59e0b" opacity="0.12" stroke="#f59e0b" />
<text x="60" y="228" font-size="12" fill="#f59e0b" text-anchor="middle">LL (split x)</text>
<rect x="98" y="208" width="84" height="28" rx="6" fill="#10b981" opacity="0.12" stroke="#10b981" />
<text x="140" y="228" font-size="12" fill="#10b981" text-anchor="middle">LR (split y)</text>
<rect x="178" y="208" width="84" height="28" rx="6" fill="#f59e0b" opacity="0.12" stroke="#f59e0b" />
<text x="220" y="228" font-size="12" fill="#f59e0b" text-anchor="middle">RR (split x)</text>
</g>
<!-- Legend -->
<g transform="translate(30,500)">
<rect x="0" y="0" width="600" height="46" rx="8" ry="8" fill="#fbfdff" stroke="#eef2ff" />
<text x="12" y="18" class="legend">Légende :</text>
<text x="12" y="34" class="legend">• Couleur rouge = coupe selon x (verticale). • Couleur bleue = coupe selon y (horizontale).</text>
</g>
</svg>

After

Width:  |  Height:  |  Size: 5.6 KiB