Spaces:
Sleeping
Sleeping
Claude
feat(evaluation): Sprint A14-S15 — AltoView (vue canonique 2) + 3 métriques structurelles + pattern d'omission
99ad1af unverified | """``AltoView`` — vue canonique 2, Sprint A14-S15. | |
| Deuxième vue d'évaluation canonique : "quel pipeline produit le | |
| meilleur ALTO exploitable ?". | |
| Distinct de ``TextView`` (S14) | |
| ------------------------------ | |
| ``TextView`` projette tout vers texte plat et ignore la structure | |
| documentaire. ``AltoView`` fait l'inverse : exige un ``ALTO_XML`` | |
| en entrée et mesure la **fidélité structurelle** (validité, | |
| nombre de lignes, présence des bbox de mots, etc.). | |
| Un même pipeline peut être évalué dans les deux vues. Le rapport | |
| HTML (S22) présentera les deux côte-à-côte pour qu'un lecteur | |
| comprenne *pourquoi* deux pipelines avec le même CER produisent | |
| des ALTO de qualités différentes. | |
| Pipelines omis explicitement | |
| ---------------------------- | |
| Un pipeline qui ne produit pas d'``ALTO_XML`` (exemple : Tesseract | |
| texte brut sans ALTO) ne peut pas être évalué dans ``AltoView``. | |
| Le caller (typiquement un service applicatif au S19) doit | |
| **omettre** ce pipeline du résultat ``AltoView`` plutôt que de lui | |
| attribuer un score factice à 0. | |
| Le pattern est démontré dans le test | |
| ``tests/evaluation/views/test_sprint_a14_s15_alto_view.py`` : | |
| le caller boucle sur ``[TextView, AltoView]`` et pour chaque vue | |
| filtre les pipelines dont l'artefact n'est pas dans | |
| ``view.candidate_types``. | |
| Métriques par défaut | |
| -------------------- | |
| - ``alto_validity`` — l'hypothèse est-elle structurellement | |
| cohérente ? (≥ 1 page, ≥ 1 bloc, ≥ 1 ligne). | |
| - ``alto_line_count_ratio`` — ratio min/max du nombre de lignes. | |
| - ``alto_word_box_coverage`` — fraction des mots qui ont une bbox. | |
| Toutes ∈ [0, 1] avec ``higher_is_better=True``. | |
| Reportées à un sprint suivant | |
| ----------------------------- | |
| - ``textline_alignment`` (IoU des bbox de lignes). | |
| - ``reading_order_consistency`` (Kendall tau sur les IDs). | |
| - ``layout_f1`` (ICDAR 2015) via wrapper de | |
| ``evaluation/metrics/layout.py``. | |
| """ | |
| from __future__ import annotations | |
| from picarones.domain.artifacts import ArtifactType | |
| from picarones.domain.evaluation_spec import EvaluationView | |
| #: Métriques calculées par défaut. Toutes typées | |
| #: ``(ALTO_XML, ALTO_XML)``. | |
| DEFAULT_ALTO_METRICS: tuple[str, ...] = ( | |
| "alto_validity", | |
| "alto_line_count_ratio", | |
| "alto_word_box_coverage", | |
| ) | |
| #: Types acceptés. Volontairement strict : seul ``ALTO_XML`` | |
| #: passe. PAGE_XML pourrait être ajouté via une projection | |
| #: ``page_to_alto`` (post-livraison) si le besoin se présente. | |
| DEFAULT_ALTO_CANDIDATE_TYPES: frozenset[ArtifactType] = frozenset({ | |
| ArtifactType.ALTO_XML, | |
| }) | |
| #: Dimensions explicitement non évaluées. | |
| DEFAULT_ALTO_IGNORED_DIMENSIONS: tuple[str, ...] = ( | |
| # Qualité linguistique pure : c'est TextView (S14) qui la mesure. | |
| "linguistic_quality", | |
| # Recherchabilité fuzzy : c'est SearchView (S16). | |
| "search_recall", | |
| # Hallucinations contenu : c'est HallucinationView (post-S18). | |
| "content_hallucination", | |
| ) | |
| #: Avertissement par défaut affiché en tête du bloc AltoView. | |
| DEFAULT_ALTO_WARNINGS: tuple[str, ...] = ( | |
| "Cette vue mesure la fidélité STRUCTURELLE de l'ALTO produit " | |
| "(validité, nombre de lignes, bbox). La qualité TEXTUELLE de " | |
| "ce qui est dans cet ALTO est mesurée par TextView ; les deux " | |
| "doivent être lues ensemble pour juger un pipeline.", | |
| "Les pipelines qui ne produisent pas d'ALTO sont OMIS de cette " | |
| "vue. Aucun score factice n'est attribué à un pipeline absent.", | |
| ) | |
| def build_alto_view( | |
| *, | |
| name: str = "alto_documentary", | |
| description: str = ( | |
| "Mesure la fidélité structurelle de l'ALTO produit par un " | |
| "pipeline (validité, lignes, bbox)." | |
| ), | |
| metric_names: tuple[str, ...] | None = None, | |
| extra_warnings: tuple[str, ...] = (), | |
| extra_ignored_dimensions: tuple[str, ...] = (), | |
| ) -> EvaluationView: | |
| """Construit la vue canonique AltoView. | |
| Pas de ``candidate_types`` paramétrable (la vue exige par | |
| nature ALTO_XML uniquement) ni de ``projection`` | |
| (l'évaluation se fait sur l'ALTO tel quel, pas sur sa | |
| projection). | |
| Le caller qui veut une vue plus stricte (par exemple "exiger | |
| aussi le mapping vers une GT_ALTO précise") peut composer | |
| plusieurs ``AltoView`` paramétrées. | |
| """ | |
| return EvaluationView( | |
| name=name, | |
| description=description, | |
| candidate_types=DEFAULT_ALTO_CANDIDATE_TYPES, | |
| projection=None, | |
| projections_by_source_type={}, | |
| normalization_profile=None, | |
| metric_names=( | |
| metric_names if metric_names is not None | |
| else DEFAULT_ALTO_METRICS | |
| ), | |
| warnings=DEFAULT_ALTO_WARNINGS + extra_warnings, | |
| ignored_dimensions=DEFAULT_ALTO_IGNORED_DIMENSIONS + extra_ignored_dimensions, | |
| ) | |
| __all__ = [ | |
| "build_alto_view", | |
| "DEFAULT_ALTO_METRICS", | |
| "DEFAULT_ALTO_CANDIDATE_TYPES", | |
| "DEFAULT_ALTO_IGNORED_DIMENSIONS", | |
| "DEFAULT_ALTO_WARNINGS", | |
| ] | |