Externalize dictionaries and add anonymization review corpus
This commit is contained in:
26
tests/synthetic_regression/README.md
Normal file
26
tests/synthetic_regression/README.md
Normal file
@@ -0,0 +1,26 @@
|
||||
# Tests synthétiques de non-régression
|
||||
|
||||
Cette suite fournit 10 cas synthétiques courts, relisibles et diffables, pensés
|
||||
comme première barrière de sécurité avant la revue humaine.
|
||||
|
||||
Principe :
|
||||
- `test.txt` contient le document synthétique d'entrée à relire ou diff-er.
|
||||
- `expected.txt` contient la sortie anonymisée attendue, normalisée.
|
||||
- `expected.audit.json` contient un résumé stable de l'audit attendu.
|
||||
- `config_overlay.yml` est optionnel et permet de tester une surcharge locale.
|
||||
|
||||
Objectif :
|
||||
- bloquer les régressions évidentes sur les règles critiques ;
|
||||
- rendre les écarts lisibles dans un diff Git ou dans la sortie de `pytest` ;
|
||||
- compléter, et non remplacer, la validation humaine sur corpus réel.
|
||||
|
||||
Portée de cette première version :
|
||||
- texte uniquement ;
|
||||
- pas encore de PDF/OCR/layout ;
|
||||
- pas encore de cas `xfail` pour les bugs connus.
|
||||
|
||||
Exécution :
|
||||
|
||||
```bash
|
||||
pytest -q tests/unit/test_synthetic_regression.py
|
||||
```
|
||||
@@ -0,0 +1,22 @@
|
||||
[
|
||||
{
|
||||
"kind": "DATE_NAISSANCE",
|
||||
"original": "Né le 12/03/1980",
|
||||
"replacement": "[DATE_NAISSANCE]"
|
||||
},
|
||||
{
|
||||
"kind": "NOM_GLOBAL",
|
||||
"original": "ETCHEVERRY",
|
||||
"replacement": "[NOM]"
|
||||
},
|
||||
{
|
||||
"kind": "NOM_GLOBAL",
|
||||
"original": "CLAUDE",
|
||||
"replacement": "[NOM]"
|
||||
},
|
||||
{
|
||||
"kind": "NOM_GLOBAL",
|
||||
"original": "JEAN",
|
||||
"replacement": "[NOM]"
|
||||
}
|
||||
]
|
||||
@@ -0,0 +1,3 @@
|
||||
[NOM] [NOM] [NOM]
|
||||
[DATE_NAISSANCE]
|
||||
Consultation du 14/03/2024
|
||||
@@ -0,0 +1,3 @@
|
||||
ETCHEVERRY JEAN CLAUDE
|
||||
Né le 12/03/1980
|
||||
Consultation du 14/03/2024
|
||||
@@ -0,0 +1,3 @@
|
||||
ETCHEVERRY JEAN CLAUDE
|
||||
Né le 12/03/1980
|
||||
Consultation du 14/03/2024
|
||||
@@ -0,0 +1,12 @@
|
||||
[
|
||||
{
|
||||
"kind": "EMAIL",
|
||||
"original": "jean.dupont@example.com",
|
||||
"replacement": "[EMAIL]"
|
||||
},
|
||||
{
|
||||
"kind": "TEL",
|
||||
"original": "01 23 45 67 89",
|
||||
"replacement": "[TEL]"
|
||||
}
|
||||
]
|
||||
@@ -0,0 +1 @@
|
||||
Contact : [EMAIL] ou [TEL]
|
||||
@@ -0,0 +1 @@
|
||||
Contact: jean.dupont@example.com ou 01 23 45 67 89
|
||||
@@ -0,0 +1 @@
|
||||
Contact: jean.dupont@example.com ou 01 23 45 67 89
|
||||
@@ -0,0 +1,7 @@
|
||||
[
|
||||
{
|
||||
"kind": "NDA",
|
||||
"original": "1234567",
|
||||
"replacement": "[NDA]"
|
||||
}
|
||||
]
|
||||
@@ -0,0 +1,3 @@
|
||||
N° venue :
|
||||
[NDA]
|
||||
Date de séjour : 14/03/2024
|
||||
@@ -0,0 +1,3 @@
|
||||
N° venue :
|
||||
1234567
|
||||
Date de séjour : 14/03/2024
|
||||
@@ -0,0 +1,3 @@
|
||||
N° venue :
|
||||
1234567
|
||||
Date de séjour : 14/03/2024
|
||||
@@ -0,0 +1,27 @@
|
||||
[
|
||||
{
|
||||
"kind": "RPPS",
|
||||
"original": "12345678901",
|
||||
"replacement": "[RPPS]"
|
||||
},
|
||||
{
|
||||
"kind": "FINESS",
|
||||
"original": "123456789",
|
||||
"replacement": "[FINESS]"
|
||||
},
|
||||
{
|
||||
"kind": "IPP",
|
||||
"original": "ABC12345",
|
||||
"replacement": "[IPP]"
|
||||
},
|
||||
{
|
||||
"kind": "OGC",
|
||||
"original": "12",
|
||||
"replacement": "[OGC]"
|
||||
},
|
||||
{
|
||||
"kind": "IBAN",
|
||||
"original": "FR76 3000 6000 0112 3456 7890 189",
|
||||
"replacement": "[IBAN]"
|
||||
}
|
||||
]
|
||||
@@ -0,0 +1,5 @@
|
||||
RPPS : [RPPS]
|
||||
FINESS : [FINESS]
|
||||
IPP : [IPP]
|
||||
N° OGC : [OGC]
|
||||
IBAN : [IBAN]
|
||||
@@ -0,0 +1,5 @@
|
||||
RPPS : 12345678901
|
||||
FINESS : 123456789
|
||||
IPP : ABC12345
|
||||
N° OGC : 12
|
||||
IBAN : FR76 3000 6000 0112 3456 7890 189
|
||||
@@ -0,0 +1,5 @@
|
||||
RPPS : 12345678901
|
||||
FINESS : 123456789
|
||||
IPP : ABC12345
|
||||
N° OGC : 12
|
||||
IBAN : FR76 3000 6000 0112 3456 7890 189
|
||||
@@ -0,0 +1,7 @@
|
||||
[
|
||||
{
|
||||
"kind": "force_term",
|
||||
"original": "CHCB",
|
||||
"replacement": "[MASK]"
|
||||
}
|
||||
]
|
||||
@@ -0,0 +1 @@
|
||||
Patient adressé au [MASK] pour avis. Retour au [MASK] demain.
|
||||
@@ -0,0 +1 @@
|
||||
Patient adressé au CHCB pour avis. Retour au CHCB demain.
|
||||
@@ -0,0 +1 @@
|
||||
Patient adressé au CHCB pour avis. Retour au CHCB demain.
|
||||
@@ -0,0 +1 @@
|
||||
[]
|
||||
@@ -0,0 +1 @@
|
||||
La classification internationale reste visible. La prise en charge est correcte.
|
||||
@@ -0,0 +1 @@
|
||||
La classification internationale reste visible. La prise en charge est correcte.
|
||||
@@ -0,0 +1 @@
|
||||
La classification internationale reste visible. La prise en charge est correcte.
|
||||
@@ -0,0 +1,3 @@
|
||||
blacklist:
|
||||
force_mask_terms:
|
||||
- LOCAL_SIGLE
|
||||
@@ -0,0 +1,7 @@
|
||||
[
|
||||
{
|
||||
"kind": "force_term",
|
||||
"original": "LOCAL_SIGLE",
|
||||
"replacement": "[MASK]"
|
||||
}
|
||||
]
|
||||
@@ -0,0 +1 @@
|
||||
Réorientation vers [MASK] en urgence.
|
||||
@@ -0,0 +1 @@
|
||||
Réorientation vers LOCAL_SIGLE en urgence.
|
||||
@@ -0,0 +1 @@
|
||||
Réorientation vers LOCAL_SIGLE en urgence.
|
||||
@@ -0,0 +1,7 @@
|
||||
[
|
||||
{
|
||||
"kind": "VILLE",
|
||||
"original": "Bayonne",
|
||||
"replacement": "[VILLE]"
|
||||
}
|
||||
]
|
||||
@@ -0,0 +1,2 @@
|
||||
[VILLE], le 12/03/2024
|
||||
Compte rendu adressé au patient.
|
||||
@@ -0,0 +1,2 @@
|
||||
Bayonne, le 12/03/2024
|
||||
Compte rendu adressé au patient.
|
||||
@@ -0,0 +1,2 @@
|
||||
Bayonne, le 12/03/2024
|
||||
Compte rendu adressé au patient.
|
||||
@@ -0,0 +1,17 @@
|
||||
[
|
||||
{
|
||||
"kind": "NOM_GLOBAL",
|
||||
"original": "ETCHEVERRY",
|
||||
"replacement": "[NOM]"
|
||||
},
|
||||
{
|
||||
"kind": "NOM_GLOBAL",
|
||||
"original": "CLAUDE",
|
||||
"replacement": "[NOM]"
|
||||
},
|
||||
{
|
||||
"kind": "NOM_GLOBAL",
|
||||
"original": "JEAN",
|
||||
"replacement": "[NOM]"
|
||||
}
|
||||
]
|
||||
@@ -0,0 +1,2 @@
|
||||
[NOM] [NOM] [NOM]
|
||||
Le patient [NOM] revient ce jour.
|
||||
@@ -0,0 +1,2 @@
|
||||
ETCHEVERRY JEAN CLAUDE
|
||||
Le patient ETCHEVERRY revient ce jour.
|
||||
@@ -0,0 +1,2 @@
|
||||
ETCHEVERRY JEAN CLAUDE
|
||||
Le patient ETCHEVERRY revient ce jour.
|
||||
@@ -0,0 +1,7 @@
|
||||
[
|
||||
{
|
||||
"kind": "ETAB_SPACED",
|
||||
"original": "C E N T R E H O S P I T A L I E R D E L A C O T E B A S Q U E",
|
||||
"replacement": "[ETABLISSEMENT]"
|
||||
}
|
||||
]
|
||||
@@ -0,0 +1,2 @@
|
||||
[ETABLISSEMENT]
|
||||
Service de cardiologie
|
||||
@@ -0,0 +1,2 @@
|
||||
C E N T R E H O S P I T A L I E R D E L A C O T E B A S Q U E
|
||||
Service de cardiologie
|
||||
@@ -0,0 +1,2 @@
|
||||
C E N T R E H O S P I T A L I E R D E L A C O T E B A S Q U E
|
||||
Service de cardiologie
|
||||
110
tests/synthetic_regression/manifest.json
Normal file
110
tests/synthetic_regression/manifest.json
Normal file
@@ -0,0 +1,110 @@
|
||||
{
|
||||
"001_patient_header_and_birth": {
|
||||
"description": "En-tête patient en majuscules avec date de naissance masquée et date de soin conservée.",
|
||||
"must_contain": [
|
||||
"[DATE_NAISSANCE]",
|
||||
"Consultation du 14/03/2024"
|
||||
],
|
||||
"must_not_contain": [
|
||||
"ETCHEVERRY",
|
||||
"JEAN",
|
||||
"CLAUDE",
|
||||
"12/03/1980"
|
||||
]
|
||||
},
|
||||
"002_contact_bundle": {
|
||||
"description": "Email et téléphone dans une même ligne de contact.",
|
||||
"must_contain": [
|
||||
"[EMAIL]",
|
||||
"[TEL]"
|
||||
],
|
||||
"must_not_contain": [
|
||||
"jean.dupont@example.com",
|
||||
"01 23 45 67 89"
|
||||
]
|
||||
},
|
||||
"003_multiline_venue_number": {
|
||||
"description": "Numéro de venue éclaté sur deux lignes.",
|
||||
"must_contain": [
|
||||
"N° venue :",
|
||||
"[NDA]",
|
||||
"Date de séjour : 14/03/2024"
|
||||
],
|
||||
"must_not_contain": [
|
||||
"1234567"
|
||||
]
|
||||
},
|
||||
"004_identifier_bundle": {
|
||||
"description": "Bloc d'identifiants structurés variés.",
|
||||
"must_contain": [
|
||||
"[RPPS]",
|
||||
"[FINESS]",
|
||||
"[IPP]",
|
||||
"[OGC]",
|
||||
"[IBAN]"
|
||||
],
|
||||
"must_not_contain": [
|
||||
"12345678901",
|
||||
"123456789",
|
||||
"ABC12345",
|
||||
"FR76 3000 6000 0112 3456 7890 189"
|
||||
]
|
||||
},
|
||||
"005_force_mask_default_term": {
|
||||
"description": "Terme forcé par la configuration par défaut.",
|
||||
"must_contain": [
|
||||
"[MASK]"
|
||||
],
|
||||
"must_not_contain": [
|
||||
"CHCB"
|
||||
]
|
||||
},
|
||||
"006_whitelist_phrases_preserved": {
|
||||
"description": "Expressions métier explicitement préservées.",
|
||||
"must_contain": [
|
||||
"classification internationale",
|
||||
"prise en charge"
|
||||
],
|
||||
"must_not_contain": []
|
||||
},
|
||||
"007_overlay_force_mask_local": {
|
||||
"description": "Terme local masqué via surcharge runtime.",
|
||||
"must_contain": [
|
||||
"[MASK]"
|
||||
],
|
||||
"must_not_contain": [
|
||||
"LOCAL_SIGLE"
|
||||
]
|
||||
},
|
||||
"008_ville_header": {
|
||||
"description": "Ville en en-tête de courrier, date conservée.",
|
||||
"must_contain": [
|
||||
"[VILLE], le 12/03/2024"
|
||||
],
|
||||
"must_not_contain": [
|
||||
"Bayonne"
|
||||
]
|
||||
},
|
||||
"009_header_and_repeated_name": {
|
||||
"description": "Propagation globale d'un nom vu dans l'en-tête.",
|
||||
"must_contain": [
|
||||
"Le patient [NOM] revient ce jour."
|
||||
],
|
||||
"must_not_contain": [
|
||||
"ETCHEVERRY",
|
||||
"JEAN",
|
||||
"CLAUDE"
|
||||
]
|
||||
},
|
||||
"010_spaced_establishment_header": {
|
||||
"description": "En-tête d'établissement avec lettres espacées.",
|
||||
"must_contain": [
|
||||
"[ETABLISSEMENT]",
|
||||
"Service de cardiologie"
|
||||
],
|
||||
"must_not_contain": [
|
||||
"C E N T R E",
|
||||
"H O S P I T A L I E R"
|
||||
]
|
||||
}
|
||||
}
|
||||
25
tests/synthetic_regression/tests.md
Normal file
25
tests/synthetic_regression/tests.md
Normal file
@@ -0,0 +1,25 @@
|
||||
# Jeux de tests synthétiques
|
||||
|
||||
Ces fichiers sont les cas de test relisibles à la main. Chaque dossier contient :
|
||||
- `test.txt` : document synthétique d'entrée
|
||||
- `expected.txt` : sortie anonymisée attendue
|
||||
- `expected.audit.json` : résumé d'audit attendu
|
||||
|
||||
Cas disponibles :
|
||||
- `001_patient_header_and_birth`
|
||||
- `002_contact_bundle`
|
||||
- `003_multiline_venue_number`
|
||||
- `004_identifier_bundle`
|
||||
- `005_force_mask_default_term`
|
||||
- `006_whitelist_phrases_preserved`
|
||||
- `007_overlay_force_mask_local`
|
||||
- `008_ville_header`
|
||||
- `009_header_and_repeated_name`
|
||||
- `010_spaced_establishment_header`
|
||||
|
||||
Exemples de fichiers à ouvrir :
|
||||
- [001 test](</home/dom/ai/anonymisation/tests/synthetic_regression/cases/001_patient_header_and_birth/test.txt:1>)
|
||||
- [001 attendu](</home/dom/ai/anonymisation/tests/synthetic_regression/cases/001_patient_header_and_birth/expected.txt:1>)
|
||||
- [004 test](</home/dom/ai/anonymisation/tests/synthetic_regression/cases/004_identifier_bundle/test.txt:1>)
|
||||
- [004 attendu](</home/dom/ai/anonymisation/tests/synthetic_regression/cases/004_identifier_bundle/expected.txt:1>)
|
||||
- [007 surcharge locale](</home/dom/ai/anonymisation/tests/synthetic_regression/cases/007_overlay_force_mask_local/config_overlay.yml:1>)
|
||||
Reference in New Issue
Block a user