← blog
article2025-07-30·8 min de lecture

data uniformity aticle

data uniformity aticle

1. Contexte et motivation

Au quotidien, une de mes prérogatives est de construire des classifieurs basés sur BERT et ses variantes pour traiter des volumes de texte toujours croissants. Mais plusieurs défis se posent :

  1. Croissance des jeux de données Chaque nouveau lot de données alourdit considérablement les temps d’évaluation. Ma connaissance empirique de mon dataset n'est plus suffisant pour déterminer l’impact de chaque ajout.

  2. Ajout de nouvelles classes On me demande régulièrement d’intégrer de nouvelles catégories qui peuvent se rapprocher des classes existantes. Le risque : un flou sémantique et des exemples difficiles à distinguer pour le modèle.

  3. Retour d’information côté métier Pour que les équipes produit et métier puissent suivre et piloter le cycle de vie des modèles, il leur faut un outil clair et interactif. Elles doivent visualiser rapidement comment une modification de données ou de labels affecte la couverture et la séparation des classes.

C’est dans ce contexte que le papier “Data Uniformity Improves Training Efficiency and More” (ArXiv:2506.24120v1) a retenu toute mon attention. Plutôt que de procéder au jugé, il propose de mesurer la uniformité des données textuelles dans l’espace d’embeddings via la métrique h_min (distance minimale entre deux points). Cette approche permettrait :

  • D’évaluer rapidement si les nouvelles données s’intègrent harmonieusement
  • De détecter les chevauchements ou les zones vides dans l’espace d’embedding
  • De fournir aux équipes un tableau de bord visuel pour piloter la qualité des jeux de données

Dans cet article, nous présenterons :

  1. Le concept de h_min et son intérêt pour l’entraînement des modèles.
  2. Un outil Python modulaire qui calcule cette métrique et d’autres indicateurs d’uniformité.
  3. Des visualisations (statique et interactive) pour aider les métiers à comprendre et anticiper l’impact de leurs choix de données.

L’objectif est d’assurer des jeux de données bien répartis, facilitant l’apprentissage et la maintenance des modèles de classification.

2. Compréhension du papier ArXiv

Le papier “Data Uniformity Improves Training Efficiency and More” (ArXiv:2506.24120v1) part d’une intuition simple : si vos points de données sont bien répartis dans l’espace, l’entraînement de votre modèle sera à la fois plus rapide et plus performant.


2.1 La métaphore de la fête bien organisée

Imaginez que vous organisez une grande fête :

  • Si tout le monde se bouscule autour du buffet, il faudra du temps pour que chacun puisse se servir.
  • En revanche, si vous placez les tables de façon uniforme et que les invités sont espacés, la circulation est fluide et personne ne reste bloqué dans un embouteillage humain.

Dans le papier, chaque échantillon de texte est comme un invité, et l’espace d’embedding (le nuage de vecteurs) est la salle de la fête. La distance minimale entre deux points, appelée h_min, joue donc le rôle de la distance minimale entre deux invités : plus elle est grande, plus vos données sont bien réparties.


2.2 Pourquoi ça accélère l’entraînement

  1. Théorie de la dynamique de l’apprentissage Les auteurs montrent mathématiquement que lorsque h_min diminue (c’est-à-dire que certains points sont trop proches), la descente de gradient (l’algorithme de base qui ajuste les poids du réseau) peut ralentir. À l’inverse, un h_min plus élevé garantit une convergence plus rapide oai_citation:0‡arXiv.

  2. Approximation et généralisation Ils établissent également qu’un plus grand h_min réduit l’erreur d’approximation : votre réseau de neurones se rapproche plus fidèlement de la fonction cible à apprendre oai_citation:1‡arXiv.


2.3 Au-delà du cas classique : un cadre général

Beaucoup de théories d’apprentissage s’appuient sur le « Neural Tangent Kernel » (NTK), qui n’est pas toujours réaliste pour des architectures profondes comme les transformers. Ici, les auteurs développent un cadre de convergence qui :

  • Ne requiert pas les hypothèses fortes de Lipschitz-smoothness.
  • S’applique à une large famille d’architectures (couches feed-forward, attention, résidus, GELU, etc.).
  • Explique pourquoi les connexions résiduelles et la composition de fonctions améliorent la stabilité de l’entraînement oai_citation:2‡arXiv.

2.4 Validation empirique

Sur des tâches de fine-tuning supervisé, plusieurs modèles (dont LLaMA-1-13B) ont été entraînés sur :

  • Un sous-ensemble uniforme (sélectionné pour maximiser la distance pairwise)
  • Un sous-ensemble aléatoire de même taille
  • Le jeu complet

Résultat : le sous-ensemble uniforme atteint les mêmes seuils de perte en deux à trois fois moins de temps qu’avec le jeu complet ou l’échantillon aléatoire.


2.5 Pourquoi ce papier est pertinent pour mon cas d’usage

  • Montée en charge des datasets : il offre un principe simple (maximiser h_min) pour rester efficace même quand le volume de données explose.
  • Ajout de classes : une distribution uniforme met en évidence les zones de chevauchement entre anciennes et nouvelles classes, ce qui guide le rééquilibrage.
  • Outil visuel pour le métier : en calculant h_min et ses dérivés, on peut montrer aux équipes produit les données sont trop « serrées » ou « vides », et prendre des décisions éclairées.

Ce papier m’a donc paru tout à fait adapté : il fournit à la fois un fondement théorique solide et une démarche opérationnelle pour mesurer et visualiser l’uniformité de mes jeux de données, exactement ce qu’il me fallait pour faciliter la collaboration entre data scientists et métiers.

3. Implémentation et mise en œuvre

La solution se décompose en quatre briques Python, organisées dans le dossier src/ :

  1. Chargement des données (data_loader.py)
  2. Génération des embeddings (embedder.py)
  3. Calcul des métriques d’uniformité (uniformity_analyzer.py)
  4. Création de visualisations (visualizer.py)

Le script principal main.py orchestre ces étapes :

from src import DataLoader, Embedder, UniformityAnalyzer, Visualizer

### 1. Chargement

dataset = DataLoader.load_csv(
    "/…/data/input/intent_root_V_1_5.csv",
    separator=";", text_column="text", label_column="label"
)

### 2. Embeddings

embedder  = Embedder.create_camembertav2_embedder(batch_size=16, use_cache=True)
embeddings = embedder.embed_dataset(dataset)

### 3. Analyse

analyzer = UniformityAnalyzer()
metrics  = analyzer.analyze(embeddings, dataset.labels)

### 4. Visualisations

visualizer = Visualizer()
saved_files = visualizer.create_all_visualizations(
    embeddings, dataset.labels, metrics, dataset.texts, "output/viz"
)

### Optionnel : afficher les textes détectés comme outliers

outlier_texts = [dataset.texts[i] for i in metrics.outlier_indices]
print(outlier_texts)

#### 3.1 DataLoader (data_loader.py)

    •    Classe TextDataset
    •    Stocke texts: List[str] et labels: List[str].
    •    Méthodes utilitaires : get_label_distribution(), filtrage et validation.
    •    CSVDataLoader (hérite de BaseDataLoader)
    •    validate_source() : vérifie l’existence et l’extension .csv.
    •    load() redirige vers _load_with_headers() ou _load_with_indices().
    •    Nettoie les lignes incomplètes et gère l’encodage.
    •    DataLoader (factory)
    •    load_csv(...) simplifie la création et l’appel de CSVDataLoader.

#### 3.2 Embedder (embedder.py)

    •    TransformerEmbedder
    •    Charge un modèle Hugging-Face (almanach/camembertav2-base) et son tokenizer.
    •    Transforme List[str] en batchs PyTorch, récupère last_hidden_state.
    •    Pooling (cls, mean, max), normalisation L2.
    •    Renvoie un np.ndarray de taille (n_texts, dim_embedding).
    •    CachedEmbedder
    •    Wrapper qui calcule un hash MD5 des textes.
    •    Si un fichier pickle existe, il est rechargé ; sinon on calcule et on sauvegarde.
    •    Embedder.create_camembertav2_embedder(...)
    •    Usine permettant d’activer ou non le cache en un seul appel.

#### 3.3 UniformityAnalyzer (uniformity_analyzer.py)

    •    Pipeline d’analyse dans analyze(embeddings, labels) :
    1.    pdist() pour toutes les distances pairwise.
    2.    Calcul de
    •    h_min (min non-zéro)
    •    h_mean, h_std
    •    uniformity_score (entropie normalisée + coefficient de variation)
    •    coverage_score (effective rank via SVD)
    •    density_variance (variance de densité locale, K-NN)
    3.    Détection d’outliers (z-score sur plus proches voisins).
    4.    Clustering (DBSCAN, estimation automatisée de eps).
    5.    Analyse par classe (mêmes métriques calculées pour chaque label).
    6.    Stockage dans un dataclass UniformityMetrics.
    •    Modularité : chaque étape privée (_compute_…) est découplée pour faciliter l’extension.

#### 3.4 Visualizer (visualizer.py)

    •    Statique (Matplotlib/Seaborn) et interactif (Plotly).
    •    Réductions de dimension : PCA, t-SNE, UMAP.
    •    Fichiers générés
    •    Scatter plots 2D (*.png + *.html)
    •    Histogrammes et bar charts des distances et métriques clés
    •    Tables de bord (dashboard HTML avec subplots Plotly)
    •    Sections Outliers, Clusters, Par-classe
    •    Fonction principale : create_all_visualizations(...)
    •    Crée un dossier output_dir
    •    Appelle successivement les méthodes privées
    •    Retourne un dict {nom_de_la_viz: chemin_fichier}

## 4. Conclusion et perspectives

Ce projet m’a permis de transformer une intuition issue d’un papier théorique en un outil opérationnel et visuel, adapté à mes contraintes de terrain.

En résumé, nous avons :

- **Exploré le concept d’uniformité des données textuelles** à travers la métrique _h_min_, issue du papier *"Data Uniformity Improves Training Efficiency and More"*.
- **Mis en œuvre un pipeline complet** : chargement des données, embeddings avec CamemBERT, analyse de l’uniformité, et visualisations interactives.
- **Obtenu des métriques exploitables** et des graphiques lisibles pour identifier les classes trop proches, les outliers, les déséquilibres, et les zones sous-représentées dans l’espace vectoriel.

Ce travail apporte donc une réponse concrète à plusieurs problématiques :

- mieux comprendre l’impact d’un ajout de données ou de classes,
- faciliter la collaboration avec les métiers,
- et évaluer la qualité d’un dataset sans devoir relancer un entraînement complet.

---

### Perspectives

Actuellement, tous les calculs sont basés sur les embeddings générés par **CamemBERT**. C’est un modèle performant et adapté au français, mais il n’est pas exempt de biais : sa manière de représenter le langage influence forcément la forme de l’espace vectoriel.

> Est-ce qu’un autre modèle (par exemple XLM-R, RoBERTa ou FlauBERT) percevrait mieux certaines nuances ?
> Est-ce que certaines classes semblent proches uniquement *du point de vue* de CamemBERT ?

Une piste à explorer serait donc de **comparer l’uniformité du même dataset avec plusieurs modèles d’embedding**, et peut-être même :

- **croiser les analyses** pour identifier les cas de chevauchement récurrents ou spécifiques à un modèle,
- voire **moyenner les distances** issues de plusieurs espaces vectoriels pour une vision plus robuste.

En d’autres termes :
**"Un seul embedding ne dit pas toute la vérité"**, et comme souvent en machine learning, la diversité des points de vue pourrait améliorer la compréhension globale.

Ce sera peut-être l’objet du prochain chapitre... j'ai trouvé un papier qui parle de ça justement...