Spaces:
Sleeping
Sleeping
Claude
feat(sprint-E.4): 3 modules hooks/registres migrΓ©s vers evaluation/metrics/
ad8d926 unverified | """MΓ©triques natives enregistrΓ©es dans le registre typΓ© (Sprint 34). | |
| Ce module est un dΓ©monstrateur d'enregistrement : il expose les | |
| mΓ©triques scalaires existantes (CER, WER, MER, WIL) sous une forme | |
| unitaire dans le registre, plus un stub typé hétérogène pour les | |
| jonctions ``(TEXT, ALTO)``. | |
| L'import du module suffit Γ peupler le registre β le dΓ©corateur | |
| ``@register_metric`` s'exΓ©cute Γ l'import. Les sprints suivants (axe A | |
| du plan d'Γ©volution) ajouteront ici les mΓ©triques structurelles | |
| (``reading_order_f1``, ``layout_f1``), philologiques (``unicode_block_*``, | |
| ``mufi_coverage``), et de fiabilitΓ© (``ece``, ``mce``). | |
| Important β pas de double calcul | |
| ------------------------------- | |
| Ces wrappers ne **remplacent pas** ``compute_metrics`` du module | |
| ``metrics.py``. Ils existent pour les nouveaux chemins (pipelines | |
| composΓ©es qui calculent par jonction). Le rapport HTML existant | |
| continue Γ passer par ``compute_metrics`` et reste donc strictement | |
| identique octet par octet (critère de la Phase 0.3). | |
| """ | |
| from __future__ import annotations | |
| import logging | |
| from picarones.evaluation.metric_registry import register_metric | |
| from picarones.domain.artifacts import ArtifactType | |
| logger = logging.getLogger(__name__) | |
| try: | |
| import jiwer | |
| _JIWER_AVAILABLE = True | |
| except ImportError: | |
| _JIWER_AVAILABLE = False | |
| # ββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββ | |
| # MΓ©triques scalaires (TEXT, TEXT) β wrappers fins autour de jiwer | |
| # ββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββ | |
| def _safe_jiwer_call(fn, reference: str, hypothesis: str) -> float: | |
| """Wrapper qui gère les cas dégénérés (références ou hypothèses vides).""" | |
| if not _JIWER_AVAILABLE: | |
| raise RuntimeError( | |
| "jiwer n'est pas installΓ© β installer avec `pip install jiwer`" | |
| ) | |
| if not reference: | |
| return 0.0 if not hypothesis else 1.0 | |
| if not hypothesis: | |
| return 1.0 | |
| return fn(reference, hypothesis) | |
| def cer(reference: str, hypothesis: str) -> float: | |
| """CER brut sur les caractères, via jiwer.""" | |
| return _safe_jiwer_call(jiwer.cer, reference, hypothesis) | |
| def wer(reference: str, hypothesis: str) -> float: | |
| """WER brut, via jiwer.""" | |
| return _safe_jiwer_call(jiwer.wer, reference, hypothesis) | |
| def mer(reference: str, hypothesis: str) -> float: | |
| return _safe_jiwer_call(jiwer.mer, reference, hypothesis) | |
| def wil(reference: str, hypothesis: str) -> float: | |
| return _safe_jiwer_call(jiwer.wil, reference, hypothesis) | |
| # ββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββ | |
| # MΓ©trique typΓ©e hΓ©tΓ©rogΓ¨ne (TEXT, ALTO) β stub dΓ©monstrateur | |
| # ββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββ | |
| def text_preservation_after_reconstruction( | |
| reference_text: str, | |
| hypothesis_alto: str, | |
| ) -> float: | |
| """Stub dΓ©monstrateur d'une jonction texte β ALTO. | |
| Sprints Γ venir (axe A du plan d'Γ©volution) remplaceront cette | |
| implΓ©mentation par une vraie mesure de prΓ©servation : extraction | |
| structurΓ©e du texte ALTO via le parser dΓ©diΓ©, alignement, calcul | |
| dΓ©terministe. Pour l'instant la mesure est volontairement simple | |
| pour dΓ©montrer le mΓ©canisme. | |
| Parameters | |
| ---------- | |
| reference_text: | |
| Texte GT (niveau ``ArtifactType.RAW_TEXT``). | |
| hypothesis_alto: | |
| ALTO XML brut produit par un module de reconstruction (niveau | |
| ``ArtifactType.ALTO``). | |
| Returns | |
| ------- | |
| float | |
| Taux de tokens uniques de ``reference_text`` apparaissant dans | |
| ``hypothesis_alto`` (case-insensitive). ``1.0`` = tous les | |
| tokens prΓ©servΓ©s. | |
| """ | |
| if not reference_text: | |
| return 1.0 | |
| ref_tokens = {tok.lower() for tok in reference_text.split() if tok} | |
| if not ref_tokens: | |
| return 1.0 | |
| alto_text = hypothesis_alto.lower() | |
| preserved = sum(1 for tok in ref_tokens if tok in alto_text) | |
| return preserved / len(ref_tokens) | |
| __all__ = [ | |
| "cer", | |
| "wer", | |
| "mer", | |
| "wil", | |
| "text_preservation_after_reconstruction", | |
| ] | |