5. Codif TTC

Rôle de l’étape

classify-ttc code les libellés avec un classifieur neuronal pré-entraîné (à l’aide du package torchTextClassifiers).

Le modèle utilisé est le classifieur basique (« flat ») . Il a été :

  1. entraîné sur des données de caisses (tickets de la grande distribution : hypermarchés / grandes surfaces uniquement) ;
  2. puis fine-tuné sur les annotations produites lors du test de l’enquête BDF de 2024.

C’est l’une des quatre prédictions « candidates » (avec LCS, RAG notices et RAG annotations) que l’arbitrage final combinera.

  • Code : classify-ttc/ — classifieur basique (classify-ttc/src/classifiers/basic_classifier.py)
  • L’étape Argo construit depuis les sources comme les autres étapes : git clone du dépôt puis uv sync + uv run main.py predict-basic … dans classify-ttc/.

Entrées

Argument Chemin
--file …/{run}/classify-regex/raw_test_without_regex.parquet
--model mlflow-artifacts:/…/artifacts/model (paramètre de workflow classify-ttc-model-uri)

La prédiction porte sur la colonne l_pr_product (normalisation légère).

Note

L’URI du modèle TTC est un paramètre de workflow (classify-ttc-model-uri, défini dans argo/codif-pipeline.yaml) plutôt qu’une valeur codée en dur. La même URI est propagée à l’étape report, qui la loggue dans MLflow (paramètre ttc_model_uri) pour tracer quel modèle a servi à chaque run.

Traitement

Le classifieur est basique (« flat ») : il prédit directement le code COICOP à partir du libellé, sans cascade par niveaux. Architecture (classify-ttc/src/classifiers/basic_classifier.py, package torchTextClassifiers) :

  • tokenisation par n-grammes de caractères (type fastText) : robuste aux abréviations et fautes des libellés de tickets (bagu, tradit…) ;
  • un classifieur plat multi-classes sur l’ensemble des codes COICOP vus à l’entraînement (les codes techniques 98.x/99.x sont exclus des données d’entraînement) ;
  • le texte passe par le même prétraitement que s_pr_product (unidecode, minuscules, retrait du bruit et des stopwords) avant tokenisation.

L’entraînement et le fine-tuning ont leurs propres sous-commandes (train-basic, fine-tune-basic dans classify-ttc/main.py) et se lancent à la main, hors Argo — comme l’entraînement de SIRUS, et pour la même raison : le modèle est destiné à des runs futurs, son URI doit être connue au moment du argo submit, ce qui rend la fuite train-sur-test impossible par construction. Le modèle entraîné est stocké dans MLflow et référencé par l’URI classify-ttc-model-uri.

Avertissementargo/ttc-pipeline.yaml n’est pas le workflow d’entraînement

Malgré son nom, ce fichier décrit un workflow de prédiction (main.py predict-basic sur un parquet figé, avec une URI de modèle codée en dur). Il est de surcroît invalide en l’état : argo lint échoue sur inputs.parameters.sample_size was not supplied, son unique tâche de DAG ne passant aucun argument aux inputs du template. Ne pas s’y fier ; l’entraînement passe par les sous-commandes train-* ci-dessus.

À noter : les codes des données d’entraînement sont tronqués au niveau 4 (classify-ttc/src/data/build_training_data.py), mais sans l’élagage des hiérarchies linéaires — le modèle peut donc prédire un code replié (ex. 11.2.0) ; c’est la normalisation de reconcile-llm qui le ramène au code canonique.

Pour chaque produit, le classifieur renvoie les 10 meilleurs codes avec leur score de confiance (--top-k 10).

"bagu tradition u ble bretagne"
  → ttc_code_1 : 01.1.1.x (pain…)   conf. ttc_conf_1
  → ttc_code_2 : …                  conf. ttc_conf_2
  → … jusqu'à ttc_code_10
AvertissementBiais d’entraînement à garder en tête

Le modèle a été entraîné sur des données de caisses de la grande distribution puis fine-tuné sur le test BDF 2024. Il est donc le plus fiable sur les produits de supermarché/hypermarché ; il l’est moins sur les libellés issus d’autres circuits (petits commerces, restauration, services…). C’est l’une des raisons d’être de l’arbitrage final, qui croise TTC avec LCS et RAG.

Les colonnes produites sont predicted_code (+ confidence) et predicted_code_top2 … predicted_code_top10 (+ confiances), classées par confiance décroissante — renommées ttc_code_1..3 / ttc_conf_1..3 par reconcile-llm, qui ne lit que le top-3 et utilise surtout le top-1 pour le court-circuit consensus.

Exemple sur le fil rouge

Libellé (l_pr_product) ttc_code_1 (illustratif) ttc_conf_1
bagu tradition u ble bretagne 01.1.1 (pains et céréales) élevée
max garden flowers balle surprise code jouet/jardin plus faible (libellé ambigu)

Quand la confiance top-1 est ≥ 0,90 et que tous les autres codes disponibles (LCS, RAG notices, RAG annotations) donnent le même code, l’arbitrage tranche sans appeler le LLM (voir reconcile-llm).

Sorties

Argument Chemin
--output …/{run}/classify-ttc/predictions.parquet (predicted_code[_topN], confidence[_topN])

➡️ Étape suivante : 6. Codification RAG