Résultats — Pipeline de codification regex
Enquête Budget de Famille — Analyse des performances
1. Présentation des regex de codification
Répartition des règles par division de la COICOP
Détail des règles par division
| Motif regex | Code COICOP | Division (niveau 1) | |
|---|---|---|---|
| # | |||
| 2 | ^l[eéèêë]gum[eéèêë]s?$ | 01.1.7 | 01 — Alimentation |
| 6 | ^\s*boulangerie\s*$ | 01.1.1.3 | 01 — Alimentation |
| 33 | ^boucher$ | 01.1.2.2 | 01 — Alimentation |
| 7 | ^\s*billeterie\s*$ | 09.4 | 09 — Loisirs / culture |
| 39 | ^librairie\b | 09.7.1 | 09 — Loisirs / culture |
| 8 | ^\s*restaurant\s*$ | 11.1.1 | 11 — Restaurants / hôtels |
| 9 | ^\s*resto$ | 11.1.1 | 11 — Restaurants / hôtels |
| 10 | ^\s*restauration$ | 11.1.1 | 11 — Restaurants / hôtels |
| 35 | \bcantine\b | 11.1.2 | 11 — Restaurants / hôtels |
| 36 | ^d[eé]jeune[rs]? | 11.1.1 | 11 — Restaurants / hôtels |
| 42 | ^repas emporter$ | 11.1.1.2 | 11 — Restaurants / hôtels |
| 43 | ^repas midi$ | 11.1 | 11 — Restaurants / hôtels |
| 1 | fruits? l[eé]gumes? | 98.1.1.1 | 98 — Codes techniques (BdF) |
| 3 | ^fruits?$ | 98.1.1.1 | 98 — Codes techniques (BdF) |
| 4 | ^courses alimentaires$ | 98.1.1 | 98 — Codes techniques (BdF) |
| 5 | \b(divers\s+)?courses?\b | 98.1 | 98 — Codes techniques (BdF) |
| 11 | ^carte bancaire$ | 98.3 | 98 — Codes techniques (BdF) |
| 12 | ^alimentation?$ | 98.1.1 | 98 — Codes techniques (BdF) |
| 13 | ^alimentaire$ | 98.1.1 | 98 — Codes techniques (BdF) |
| 14 | ^reductions?$ | 98.5 | 98 — Codes techniques (BdF) |
| 15 | ^remises?$ | 98.5 | 98 — Codes techniques (BdF) |
| 18 | ^nourriture$ | 98.1 | 98 — Codes techniques (BdF) |
| 19 | ^boissons?$ | 98.1 | 98 — Codes techniques (BdF) |
| 20 | ^prelevement$ | 98.4 | 98 — Codes techniques (BdF) |
| 21 | ^-10 % abonnement.* | 98.5 | 98 — Codes techniques (BdF) |
| 22 | ^divers$ | 98.2 | 98 — Codes techniques (BdF) |
| 23 | ^epicerie$ | 98.1.1 | 98 — Codes techniques (BdF) |
| 25 | ^bon immediat$ | 98.5 | 98 — Codes techniques (BdF) |
| 26 | ^rabais 30 %$ | 98.5 | 98 — Codes techniques (BdF) |
| 27 | ^illisible$ | 98.4 | 98 — Codes techniques (BdF) |
| 28 | ^\s*$ | 98.4 | 98 — Codes techniques (BdF) |
| 29 | ^[^a-zA-Z]*$ | 98.4 | 98 — Codes techniques (BdF) |
| 30 | ^cb$ | 98 | 98 — Codes techniques (BdF) |
| 31 | ^marche$ | 98.1.1 | 98 — Codes techniques (BdF) |
| 32 | ^surgeles?$ | 98.1.1 | 98 — Codes techniques (BdF) |
| 34 | \bdrive\b | 98.1 | 98 — Codes techniques (BdF) |
| 24 | ^avantage carte 1028$ | 99 | 99 — Hors champ COICOP |
| 37 | ^amende$ | 99.4 | 99 — Hors champ COICOP |
| 38 | \bfoncier(e|ère)?s?\b | 99.4 | 99 — Hors champ COICOP |
| 40 | \bremboursement\b | 99.6 | 99 — Hors champ COICOP |
| 41 | ^retrait\b | 99.6 | 99 — Hors champ COICOP |
| 16 | ^reduction?.* | Reprise manuelle | Re |
| 17 | ^remise?.* | Reprise manuelle | Re |
2. Taux de couverture et répartition des codes prédits
Taux de couverture global
| Catégorie | Effectif | % du total | Description |
|---|---|---|---|
| Auto-codifiés | 1,420 | 1.23% | Code COICOP assigné directement par une règle regex |
| Reprise manuelle | 2,744 | 2.38% | Libellé capturé par une règle regex → transmis à un gestionnaire pour annotation |
| Non classifiés | 111,358 | 96.40% | Aucune règle regex ne correspond → transmis aux modèles de machine learning |
| Total | 115,522 | 100,00 % |
Le taux de couverture est intentionnellement faible : les règles regex ciblent les cas récurrents ou complexes, pas l’exhaustivité. Les libellés non classifiés sont transmis aux modèles de machine learning en aval.
Répartition des codes prédits
Libellés orientés vers la reprise manuelle
Les libellés ci-dessous ont été capturés par une règle regex, mais leur code cible est "Reprise manuelle" : ils sont volontairement transmis à un gestionnaire pour annotation humaine.
Libellés orientés vers la reprise manuelle : 2,744 (2.38% du total)
Règles déclenchant la reprise manuelle :
• pattern : '^reduction?.*'
• pattern : '^remise?.*'
| raw_product | s_pr_product | code | |
|---|---|---|---|
| 0 | REMISE SAUCISSES FUMEES | remise saucisses fumees | 01.1.2.5 |
| 1 | REMISE AXE | remise axe | 13.1.2.0 |
| 2 | remise 30 % pn. thon naturel | remise pn thon naturel | 01.1.3.3.1 |
| 3 | REMISE KIWI | remise kiwi | 01.1.6.5 |
| 4 | REMISE BOUDIN NOIR | remise boudin noir | 01.1.2.5 |
| 5 | REMISE PANNA COTA | remise panna cota | 01.1.4.6 |
| 6 | REMISE GLACE | remise glace | 01.1.8.6 |
| 7 | REMISE PAIN | remise pain | 01.1.1.3 |
| 8 | REMISE PRODUIT PHARMACEUTIQUE | remise produit pharmaceutique | 06.1.1.1 |
| 9 | REMISE PULL FEMME | remise pull femme | 03.1.2.2 |
| 10 | REMISE RUSTIQUE | remise rustique | 01.1.4.5 |
| 11 | REMISE CEREALE | remise cereale | 01.1.1.4 |
| 12 | REMISE PATERE | remise patere | 05.1.1.4 |
| 13 | REMISE TABLETTE CHOCOLAT | remise tablette chocolat | 01.1.8.5 |
| 14 | REMISE EMMENTAL | remise emmental | 01.1.4.5 |
| 15 | REMISE ORTOLAN | remise ortolan | 01.1.4.5 |
| 16 | REMISE MELON | remise melon | 01.1.6.5 |
| 17 | reduction paquito abc pomme bk | reduction paquito abc pomme bk | 01.2.1.0.1 |
| 18 | REMISE SUN TABLETTE | remise sun tablette | 05.6.1.1 |
| 19 | REMISE KETCHUP | remise ketchup | 01.1.9.3 |
| 20 | REMISE SUPER CROIX | remise super croix | 05.6.1.1 |
| 21 | REMISE GANT DE TOILETTE | remise gant toilette | 05.2.1.3 |
| 22 | REMISE REPAS | remise repas | 11.1.1.1 |
| 23 | REMISE PATE EN CROUTE | remise pate croute | 01.1.9.1 |
| 24 | REMISE PANTALON DAME | remise pantalon dame | 03.1.2.2 |
| 25 | REDUCTION YAOURT FRUITS | reduction yaourt fruits | 01.1.4.6 |
| 26 | REDUCTION YAOURT SOJA | reduction yaourt soja | 01.1.4.6 |
| 27 | REMISE FROMAGE RAPE | remise fromage rape | 01.1.4.5 |
| 28 | reduction lidl plus | reduction lidl | 01.1.6.2.1 |
| 29 | REMISE TARTE CHAMPIGNON | remise tarte champignon | 01.1.9.1 |
3. Fréquence d’application des règles
Règles utilisées : 34 / 43 (79%)
Règles non utilisées : 9 / 43 (21%)
Top 20 des règles les plus mobilisées
Règles non utilisées
9 règle(s) n'ont produit aucun match sur le jeu de test :
| # Règle | Motif regex | Code COICOP | Section COICOP | |
|---|---|---|---|---|
| 0 | 11 | ^carte bancaire$ | 98.3 | 98 — Codes techniques (BdF) |
| 1 | 21 | ^-10 % abonnement.* | 98.5 | 98 — Codes techniques (BdF) |
| 2 | 22 | ^divers$ | 98.2 | 98 — Codes techniques (BdF) |
| 3 | 24 | ^avantage carte 1028$ | 99 | 99 — Hors champ COICOP |
| 4 | 25 | ^bon immediat$ | 98.5 | 98 — Codes techniques (BdF) |
| 5 | 26 | ^rabais 30 %$ | 98.5 | 98 — Codes techniques (BdF) |
| 6 | 27 | ^illisible$ | 98.4 | 98 — Codes techniques (BdF) |
| 7 | 29 | ^[^a-zA-Z]*$ | 98.4 | 98 — Codes techniques (BdF) |
| 8 | 30 | ^cb$ | 98 | 98 — Codes techniques (BdF) |
Une règle inutilisée sur ce jeu de test n’est pas forcément inutile (libellé rare absent du jeu de test). Cependant, si elle reste inactive sur des corpus plus larges, elle est candidate à la révision ou suppression.
4. Accuracy sur les codes prédits
L’accuracy est calculée uniquement sur les libellés codifiés par les règles regex, c’est-à-dire les libellés pour lesquels predicted_code est non nul et différent de "Reprise manuelle". Les libellés non classifiés et ceux orientés vers la reprise manuelle ne participent pas à ce calcul.
Récapitulatif
| Indicateur | Valeur |
|---|---|
| Taux de couverture (tous libellés capturés) | 3.60% |
| dont codifiés par regex | 1.23% |
| dont reprise manuelle | 2.38% |
| Accuracy — code complet (codifiés par regex uniquement) | 29.01% |
| Accuracy — classe, 4 premiers chiffres | 72.68% |
| Accuracy — division, 2 premiers chiffres | 76.27% |
| Libellés codifiés par regex | 1,420 |
| Libellés en reprise manuelle | 2,744 |
| Libellés non classifiés | 111,358 |
Accuracy par niveau de la nomenclature COICOP
L’écart entre l’accuracy à 2 chiffres et l’accuracy au code complet quantifie les erreurs de voisinage : le système a identifié la bonne division COICOP mais un code détaillé incorrect.
Accuracy par code COICOP
Heatmap accuracy par code et par année
Heatmap accuracy par niveau 1 COICOP et par origine du libellé
5. Analyse des erreurs de prédiction pour les libellés codés avec les regex
Afficher le code
erreurs = classified_auto[classified_auto["code"] != classified_auto["predicted_code"]].copy()
n_erreurs = len(erreurs)
taux_erreur = n_erreurs / n_auto
print(f"Erreurs sur libellés : {n_erreurs:,}")
print(f"Taux d'erreur : {taux_erreur:.2%}")
print(f"Taux de précision : {1 - taux_erreur:.2%}")Erreurs sur libellés : 1,008
Taux d'erreur : 70.99%
Taux de précision : 29.01%
Exemples d’erreurs de prédiction
| raw_product | s_pr_product | code | predicted_code | |
|---|---|---|---|---|
| 0 | ALIMENTAIRE | alimentaire | 01 | 98.1.1 |
| 1 | legumes | legumes | 11.1.2.9 | 01.1.7 |
| 2 | RESTAURANT | restaurant | 11.1.1.1 | 11.1.1 |
| 3 | divers | 06.1 | 98.4 | |
| 4 | boisson | boisson | 11.1.1.1 | 98.1 |
| 5 | LEGUMES | legumes | 01.1.7.1 | 01.1.7 |
| 6 | courses | courses | 98.1.2 | 98.1 |
| 7 | ALIMENTATION | alimentation | 01 | 98.1.1 |
| 8 | resto | resto | 11.1.1.1 | 11.1.1 |
| 9 | intermarche courses | intermarche courses | 98.1.2 | 98.1 |
| 10 | REPAS DU MIDI | repas midi | 11.1.1.1 | 11.1 |
| 11 | DEJEUNER | dejeuner | 11.1.1.1 | 11.1.1 |
| 12 | RESTAURATION | restauration | 11.1.1.1 | 11.1.1 |
| 13 | courses | courses | 98.1.2 | 98.1 |
| 14 | repas midi | repas midi | 11.1.1.2 | 11.1 |
| 15 | COMPLEMENT COURSES | complement courses | 01 | 98.1 |
| 16 | Fruit | fruit | 01.1.6.5.9 | 98.1.1.1 |
| 17 | MARCHE | marche | 01 | 98.1.1 |
| 18 | boisson | boisson | 11.1.1.1 | 98.1 |
| 19 | nourriture | nourriture | 98.1.2 | 98.1 |
Analyse des paires d’erreurs (code vrai → code prédit)
| Confusion (vrai → prédit) | Occurrences | Occurrences (%) |
|---|---|---|
| 98.1.2 → 98.1 | 177 | 17.6 % |
| 11.1.1.1 → 11.1.1 | 153 | 15.2 % |
| 98.1.1 → 98.1 | 78 | 7.7 % |
| 11.1.2.1 → 11.1.2 | 39 | 3.9 % |
| 11.1.1.2 → 11.1.1 | 34 | 3.4 % |
| 05.2.1.9 → 98.1 | 31 | 3.1 % |
| 11.1.1.1 → 98.1 | 28 | 2.8 % |
| 11.1.1.2 → 11.1 | 27 | 2.7 % |
| 99.2 → 99.6 | 27 | 2.7 % |
| 01.2 → 98.1 | 23 | 2.3 % |
| 01.1.6 → 98.1.1.1 | 23 | 2.3 % |
| 01 → 98.1.1 | 20 | 2.0 % |
| 98.1.2 → 98.1.1 | 20 | 2.0 % |
| 11.1.1.1 → 11.1 | 18 | 1.8 % |
| 11.1.1.2 → 98.1 | 18 | 1.8 % |
6. Préconisations
6.1 Libellés fréquents non classifiés — pistes de patterns
Les libellés ci-dessous apparaissent souvent dans la partie non classifiée du jeu de test. Ce sont les candidats prioritaires pour la rédaction de nouvelles règles regex.
| Libellé normalisé (s_pr_product) | Occurrences |
|---|---|
| pain | 129 |
| baguette | 89 |
| cafe | 87 |
| repas | 76 |
| essence | 70 |
| baguettes | 67 |
| jus orange | 51 |
| oeufs | 50 |
| jambon | 50 |
| eau | 49 |
| sacs poubelle | 49 |
| fromage | 48 |
| fleurs | 47 |
| cigarettes | 43 |
| lait | 42 |
| sandwich | 42 |
| sac poubelle | 39 |
| carburant | 37 |
| coca cola | 37 |
| shampoing | 36 |
| pains | 36 |
| gasoil | 36 |
| lait ecreme | 36 |
| pomme terre | 35 |
| pizza | 35 |
| baguette pain | 34 |
| jus fruits | 34 |
| pain chocolat | 34 |
| coiffeur | 33 |
| poulet | 33 |
6.2 Anomalies détectées dans les règles actuelles
L’audit des patterns existants révèle plusieurs problèmes à corriger :
| # Règle | Pattern actuel | Problème | Correction suggérée | Sévérité |
|---|---|---|---|---|
| 16 | ^reduction?.* → Reprise manuelle | Le `?` rend le caractère `n` optionnel (`^reductio` + `n?`), non le `s` final. Le pattern capture donc `reductio.*` (sans `n`) en plus de `reduction.*`. Intent probable : `^reductions?.*` (s optionnel). | ^reductions?.* | Critique |
| 17 | ^remise?.* → Reprise manuelle | Le `?` rend le caractère `e` optionnel (`^remis` + `e?`), non le `s` final. Le pattern capture `remis.*` (sans `e`), ce qui peut produire des faux positifs (ex. : « remis en banque »). Intent probable : `^remises?.*` (s optionnel). | ^remises?.* | Critique |
6.3 Nouvelles règles suggérées
Sur la base des codes non couverts et des libellés fréquents, voici des patterns candidats à intégrer dans rules.yaml :
Ces suggestions sont à valider manuellement sur des exemples réels avant intégration. La définition du bon code COICOP dépend du contexte de la dépense et de la nomenclature BdF en vigueur.
| Pattern suggéré | Code cible | Libellés ciblés | Justification |
|---|---|---|---|
| ^d[eé]jeune[rs]? | 11.1.1 | dejeune, dejeuner, dejeuners, déjeuner | Correction de la règle 37 malformée — libellés de repas au restaurant |
| \bpharmaci[e]?\b | 06.1.1 | pharmacie, pharmacies | Dépenses de médicaments/pharmacie fréquentes dans les enquêtes ménages |
| ^\s*supermarch[eé]\s*$ | 98.1.1 | supermarche, supermarchés, supermarché | Libellé générique indiquant des courses alimentaires |
| ^\s*hypermarch[eé]\s*$ | 98.1.1 | hypermarche, hypermarché | Même logique que supermarché — achat alimentaire global |
| \b(sans[- ]?plomb|sp95|sp98|e10|e85|gazoil|gazole|diesel)\b | 07.2.2 | sans plomb, sp95, gazoil, diesel, e10… | Carburants — catégorie fréquente souvent absente des règles |
| ^\s*loyer\s*$ | 04.1.1 | loyer | Dépense de logement récurrente — libellé exact très fréquent |
| \b[eé]lectricit[eé]\b | 04.5.1 | electricite, électricité, facture electricite | Dépense énergétique récurrente |
| ^\s*coiffeur\s*$ | 12.1.1 | coiffeur, coiffeuse | Services de soins capillaires — libellé exact très courant |
| \b(sncf|tgv|ter|transilien|ouigo)\b | 07.3.1 | sncf, tgv, ter, transilien, ouigo | Transport ferroviaire — opérateurs nominatifs facilement identifiables |
| ^\s*tabac\s*$ | 02.2.0 | tabac, bureau de tabac | Dépense tabac — libellé exact fréquent |
- Ancrer les libellés exacts : utiliser
^\s*...\s*$plutôt qu’une sous-chaîne libre pour les libellés génériques (évite les faux positifs) - Gérer les variantes accentuées : remplacer
épar[eé],èpar[eè]carre.IGNORECASEne normalise pas les accents - Placer les règles spécifiques avant les générales : une règle ancrée doit précéder une règle libre qui couvre le même terme
- Tester sur le jeu de test avant intégration et vérifier l’absence de collision avec des règles existantes
- Valider le code COICOP : confirmer avec l’équipe métier que le code assigné est conforme à la nomenclature BdF en vigueur