Deux tentatives precedentes de porter chaque technique a 20 utterances
ont mesurablement degrade le F1 agrege (tech-step-eval.test.ts, 0.80 ->
0.79/0.791) au lieu de l'ameliorer : le generateur reposait surtout sur
des tournures modales generiques ("il faut ...", "make sure to ..."),
partagees identiquement par les 74 classes - un textcat bag-of-words lit
ca comme une separabilite reduite entre classes, pas un padding neutre.
augment_utterances.py revu : priorite a la substitution de synonyme
(l'un des synonyms propres a la technique en tete d'une utterance
existante, remplace par un autre - vocabulaire genuinement distinctif),
les tournures modales ne servant plus qu'de complement limite (5 par
locale, pas 12). Resultat : 13 a 20 utterances par technique/locale
(moyenne ~19.7), contre un forcage uniforme a 20 qui necessitait un
remplissage generique disproportionne pour les techniques au vocabulaire
propre pauvre (julienne, sweat, bainMarie - precisement celles qui
echouaient). Confiance mesuree nettement retablie sur ces techniques
(sweat ~0.99, bainMarie ~0.98, julienne ~0.88).
tests/test_training_data_balance.py : plancher abaisse a 12 (vise 20,
garanti seulement si le vocabulaire propre de la technique le permet
sans repasser par le piege ci-dessus) ; suppression de l'exigence
fr/en egaux, plus vraie avec cette strategie (le potentiel de
substitution differe naturellement entre les deux langues).
Suite complete locale : 35/35 verts (22m26s).
Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
34 lines
1.7 KiB
Python
34 lines
1.7 KiB
Python
"""Garde-fou de non-régression pour l'équilibrage du corpus (voir
|
|
`training_data.py`'s propre commentaire de tête) : un textcat entraîné sur
|
|
des classes très inégales en nombre d'exemples est une source réelle de
|
|
classifications confiantes mais fausses sur une phrase jamais vue (constaté
|
|
en pratique — voir l'historique Git de ce fichier).
|
|
|
|
`_MIN_UTTERANCES_PER_LOCALE` est volontairement `12`, pas `20` : la
|
|
génération vise `20` (`augment_utterances.py`'s `_TARGET`) mais s'arrête
|
|
avant si la technique n'a pas assez de vocabulaire distinctif propre
|
|
(`synonyms`) pour l'atteindre sans retomber massivement sur des tournures
|
|
génériques partagées par toutes les classes — une première version de ce
|
|
script forçait `20` partout via ce mécanisme et a mesurablement *dégradé*
|
|
`test/recipe-matching/tech-step-eval.test.ts` (F1 agrégé) plutôt que de
|
|
l'améliorer, en réduisant la séparabilité entre classes plus qu'en ajoutant
|
|
un vrai signal. `12` reste très au-dessus du plancher d'origine (3-7) tout
|
|
en laissant `augment_utterances.py` s'arrêter honnêtement plutôt que de
|
|
forcer un compte rond au prix de la qualité."""
|
|
|
|
from intent_service.training_data import TECH_STEP_TRAINING_DATA
|
|
|
|
_MIN_UTTERANCES_PER_LOCALE = 12
|
|
|
|
|
|
def test_every_technique_has_at_least_the_minimum_utterances_per_locale():
|
|
short = [
|
|
(entry.uid, locale, len(getattr(entry, locale).utterances))
|
|
for entry in TECH_STEP_TRAINING_DATA
|
|
for locale in ("fr", "en")
|
|
if len(getattr(entry, locale).utterances) < _MIN_UTTERANCES_PER_LOCALE
|
|
]
|
|
assert short == [], (
|
|
f"{len(short)} (uid, locale) pair(s) below the {_MIN_UTTERANCES_PER_LOCALE}-utterance "
|
|
f"floor: {short}"
|
|
)
|