From 26ac02b0cbf21d1b915f678ed1c990d6d9de1f0d Mon Sep 17 00:00:00 2001 From: Domi31tls Date: Mon, 9 Mar 2026 12:01:46 +0100 Subject: [PATCH] =?UTF-8?q?feat(phase2):=20Multi-signal=20NER=20=E2=80=94?= =?UTF-8?q?=20BDPM=20gazetteers,=20confiance=20EDS,=20safe=20patterns,=20G?= =?UTF-8?q?LiNER?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Chantier 1: Intégration BDPM (5737 médicaments officiels) dans medication whitelist Chantier 2: Safe patterns contextuels (dosages mg/mL/cpr, formes pharma, même ligne) Chantier 3: Scores de confiance NER réels (edsnlp 0.20 ner_confidence_score) Chantier 4: GLiNER zero-shot (urchade/gliner_multi_pii-v1) en vote croisé Chantier 5: Scripts export silver annotations + fine-tuning CamemBERT-bio 0 fuite, 0 régression, -18 FP supplémentaires éliminés. Sécurité: GLiNER ne peut rejeter que si confiance NER < 0.70. Co-Authored-By: Claude Opus 4.6 --- anonymizer_core_refactored_onnx.py | 72 +- data/bdpm/medication_names.txt | 5737 +++++++++++++++++ eds_pseudo_manager.py | 11 +- gliner_manager.py | 180 + ...LETTRE DE SORTIE 23087212.pseudonymise.txt | 4 +- ...3135847_07003136_23135847.pseudonymise.txt | 2 +- ...3124019_11004431_23124019.pseudonymise.txt | 4 +- ...3034958_14025311_23034958.pseudonymise.txt | 2 +- ...3018396_23000862_23018396.pseudonymise.txt | 2 +- ...3177582_99252128_23177582.pseudonymise.txt | 4 +- ...3076655_BA067657_23076655.pseudonymise.txt | 8 +- ...3135726_BA127127_23135726.pseudonymise.txt | 12 +- ...3214501_BA171849_23214501.pseudonymise.txt | 22 +- run_batch_30_audit.py | 11 + scripts/export_silver_annotations.py | 145 + scripts/finetune_camembert_bio.py | 256 + 16 files changed, 6431 insertions(+), 41 deletions(-) create mode 100644 data/bdpm/medication_names.txt create mode 100644 gliner_manager.py create mode 100644 scripts/export_silver_annotations.py create mode 100644 scripts/finetune_camembert_bio.py diff --git a/anonymizer_core_refactored_onnx.py b/anonymizer_core_refactored_onnx.py index 68f3fa6..b7890a3 100644 --- a/anonymizer_core_refactored_onnx.py +++ b/anonymizer_core_refactored_onnx.py @@ -97,6 +97,23 @@ def _load_edsnlp_drug_names() -> set: return set() +def _load_bdpm_medication_names() -> set: + """Charge les noms de médicaments depuis la base BDPM (data/bdpm/medication_names.txt). + Retourne un set lowercase. ~5700 noms commerciaux et DCI.""" + bdpm_path = Path(__file__).parent / "data" / "bdpm" / "medication_names.txt" + if not bdpm_path.exists(): + return set() + try: + names = set() + for line in bdpm_path.read_text(encoding="utf-8").splitlines(): + w = line.strip() + if w and len(w) >= 3: + names.add(w.lower()) + return names + except Exception: + return set() + + # ----------------- Whitelists Médicales ----------------- _MEDICAL_STRUCTURAL_TERMS = set() _MEDICATION_WHITELIST = set() @@ -117,15 +134,16 @@ def load_medical_whitelists(): except Exception as e: log.warning(f"Erreur chargement whitelist médicale: {e}") - # 2. Charger la whitelist des médicaments + # 2. Charger la whitelist des médicaments (edsnlp + BDPM + manuels) _MEDICATION_WHITELIST = _load_edsnlp_drug_names() + _MEDICATION_WHITELIST.update(_load_bdpm_medication_names()) # Ajouter médicaments manquants additional_meds = { "idacio", "salazopyrine", "infliximab", "apranax", "ketoprofene", "prevenar", "pneumovax", "bétadine" } _MEDICATION_WHITELIST.update(additional_meds) - log.info(f"Whitelist médicaments chargée: {len(_MEDICATION_WHITELIST)} médicaments") + log.info(f"Whitelist médicaments chargée: {len(_MEDICATION_WHITELIST)} médicaments (edsnlp+BDPM)") # Charger les whitelists au démarrage du module load_medical_whitelists() @@ -1828,13 +1846,41 @@ def _mask_with_eds_pseudo(text: str, ents: List[Dict[str, Any]], cfg: Dict[str, # Vérifier si c'est un médicament connu if w.lower() in _MEDICATION_WHITELIST: continue - # Règles de validation heuristiques par type d'entité + # Chantier 3+4 : Confiance NER + vote croisé GLiNER (combinés) + # Sécurité d'abord : haute confiance NER → toujours masquer + # GLiNER peut rejeter SEULEMENT si confiance NER basse + gliner_vote = e.get("gliner_confirmed") # True=PII, False=médical, None=neutre if label in ("NOM", "PRENOM"): - # Rejeter si le contexte précédent (15 chars) contient un dosage + score = e.get("score", 1.0) + if isinstance(score, float) and score < 0.70: + # Basse confiance NER : GLiNER peut trancher + if gliner_vote is False: + continue # NER pas sûr + GLiNER dit "médical" → skip + if score < 0.30: + continue # Très basse confiance → skip même sans GLiNER + # Chantier 2 : Safe patterns contextuels (Philter-style) + # Token suivi/précédé de dosages ou formes pharma → jamais un nom de personne pos = text.find(w) - if pos > 0: - ctx_before = text[max(0, pos - 15):pos] - if re.search(r"\d+\s*(?:mg|UI|ml|µg|mcg)\b", ctx_before, re.IGNORECASE): + if pos >= 0: + # Contexte MÊME LIGNE seulement ([ \t] pas \n) + line_start = text.rfind('\n', 0, pos) + line_start = 0 if line_start < 0 else line_start + 1 + line_end = text.find('\n', pos + len(w)) + line_end = len(text) if line_end < 0 else line_end + ctx_before = text[max(line_start, pos - 30):pos] + ctx_after = text[pos + len(w):min(line_end, pos + len(w) + 30)] + # Safe pattern: précédé ou suivi d'un dosage (mg, mL, UI, comprimé, etc.) + _RE_DOSAGE = r"\d+[ \t]*(?:mg|ml|ui|µg|mcg|g|kg|cp|cpr|gel|amp|fl|dos|inh)\b" + if re.search(_RE_DOSAGE, ctx_before, re.IGNORECASE): + continue + if re.search(_RE_DOSAGE, ctx_after, re.IGNORECASE): + continue + # Safe pattern: suivi d'une forme pharmaceutique + _RE_PHARMA_FORM = r"^\s*(?:comprim[ée]s?|g[ée]lules?|sachets?|ampoules?|flacons?|solutions?|injectable|suppo(?:sitoire)?s?|sirop|pommade|cr[eè]me|gouttes?|patch|inhal)" + if re.search(_RE_PHARMA_FORM, ctx_after, re.IGNORECASE): + continue + # Safe pattern: précédé de "taux de", "score de", "dosage de" + if re.search(r"(?:taux|score|dosage|indice|index|grade|stade|type)\s+(?:de\s+)?$", ctx_before, re.IGNORECASE): continue elif label == "HOPITAL": _STRUCTURAL_WORDS = {"SERVICE", "POLE", "PÔLE", "UNITE", "UNITÉ", "SECTEUR"} @@ -1848,8 +1894,9 @@ def _mask_with_eds_pseudo(text: str, ents: List[Dict[str, Any]], cfg: Dict[str, return out -def apply_eds_pseudo_on_narrative(text_out: str, cfg: Dict[str, Any], manager: "EdsPseudoManager") -> Tuple[str, List[PiiHit]]: - """Applique EDS-Pseudo sur le narratif (même structure que apply_hf_ner_on_narrative).""" +def apply_eds_pseudo_on_narrative(text_out: str, cfg: Dict[str, Any], manager: "EdsPseudoManager", + gliner_mgr: Any = None) -> Tuple[str, List[PiiHit]]: + """Applique EDS-Pseudo sur le narratif avec validation croisée GLiNER optionnelle.""" if manager is None or not manager.is_loaded(): return text_out, [] # isoler [TABLES] @@ -1871,6 +1918,10 @@ def apply_eds_pseudo_on_narrative(text_out: str, cfg: Dict[str, Any], manager: " for pg in pages: paras = [p for p in re.split(r"\n\s*\n", pg) if p.strip()] ents_per_para = manager.infer_paragraphs(paras) + # Chantier 4 : Validation croisée GLiNER (vote majoritaire) + if gliner_mgr is not None and hasattr(gliner_mgr, 'validate_entities') and gliner_mgr.is_loaded(): + for i, (para, ents) in enumerate(zip(paras, ents_per_para)): + ents_per_para[i] = gliner_mgr.validate_entities(para, ents, threshold=0.4) buf = [] for para, ents in zip(paras, ents_per_para): masked = _mask_with_eds_pseudo(para, ents, cfg, hits) @@ -2309,6 +2360,7 @@ def process_pdf( ner_thresholds=None, ogc_label: Optional[str] = None, vlm_manager=None, + gliner_manager=None, ) -> Dict[str, str]: out_dir.mkdir(parents=True, exist_ok=True) cfg = load_dictionaries(config_path) @@ -2331,7 +2383,7 @@ def process_pdf( if use_hf and ner_manager is not None and ner_manager.is_loaded(): # Détecter le type de manager et appeler la bonne fonction if EdsPseudoManager is not None and isinstance(ner_manager, EdsPseudoManager): - final_text, hf_hits = apply_eds_pseudo_on_narrative(final_text, cfg, ner_manager) + final_text, hf_hits = apply_eds_pseudo_on_narrative(final_text, cfg, ner_manager, gliner_mgr=gliner_manager) else: final_text, hf_hits = apply_hf_ner_on_narrative(final_text, cfg, ner_manager, ner_thresholds) anon.audit.extend(hf_hits) diff --git a/data/bdpm/medication_names.txt b/data/bdpm/medication_names.txt new file mode 100644 index 0000000..0f88a7d --- /dev/null +++ b/data/bdpm/medication_names.txt @@ -0,0 +1,5737 @@ +A.D.E.C +A.D.N +ABACAVIR +ABASAGLAR +ABECMA +ABELMOSCHUS +ABEVMY +ABIES +ABILIFY +ABIRATERONE +ABRAXANE +ABROTANUM +ABRYSVO +ABSINTHIUM +ABSTRAL +ABUFENE +ACALYPHA +ACAMPROSATE +ACARBOSE +ACARIZAX +ACCOFIL +ACCUSOL +ACEBUTOLOL +ACECLOFENAC +ACETANILIDUM +ACETATE +ACETICUM +ACETLAB +ACETONIDE +ACETONUM +ACETYLCYSTEINE +ACETYLLEUCINE +ACETYLSALICYLIQUE +ACICLOVIR +ACID +ACIDE +ACIDRINE +ACIDUM +ACLASTA +ACLOTINE +ACNETRAIT +ACODORON +ACONITUM +ACORSPRAY +ACRE +ACS +ACT-HIB +ACTAEA +ACTHEANE +ACTICARBINE +ACTIFED +ACTILYSE +ACTIQ +ACTISKENAN +ACTISOUFRE +ACTIVELLE +ACTIVIR +ACTIVOX +ACTONEL +ACTONELCOMBI +ACTOSOLV +ACTRAPID +ACTRON +ACTYNOX +ACUILIX +ACUITEL +ACULAR +ACULEATUS +ACUPAN +ACUSPOT +ACÉTYLSALICYLIQUE +ADAFLEX +ADAKVEO +ADAPALENE +ADARTREL +ADCETRIS +ADCIRCA +ADEMPAS +ADENOSCAN +ADENOSINE +ADENURIC +ADEPAL +ADHATODA +ADIAZINE +ADNR +ADONIS +ADONTEX +ADOPORT +ADRENALINE +ADRENALINEE +ADRENALINUM +ADREVIEW +ADRIBLASTINE +ADRIGYL +ADROIQ +ADROVANCE +ADTRALZA +ADULAIRE +ADVAGRAF +ADVANZ +ADVATE +ADVIL +ADVILCAPS +ADVILMED +ADZYNMA +AERIUS +AEROSPHERE +AERRANE +AESCULUS +AETHIOPS +AETHUSA +AETOXISCLEROL +AFINITOR +AFLAVIS +AFQLIR +AFSTYLA +AFTAGEL +AGARICUS +AGATHOL +AGAVE +AGEPHA +AGILUS +AGIOLAX +AGNUS +AGOMELATINE +AGOMÉLATINE +AGRAPHIS +AGRASTAT +AGRIMONIA +AGRUMES +AGYRAX +AGÉS +AH-HP +AILANTHUS +AIMOVIG +AIR +AIRMASTER +AIROMIR +AJOVY +AJVACCINES +AKEEGA +AKINETON +AKLIEF +AKYNZEO +ALAIRGIX +ALBA +ALBEY +ALBICANS +ALBUM +ALBUMINE +ALBUNORM +ALBUREX +ALBUS +ALBUTEIN +ALCAPHOR +ALCHEMILLA +ALCON +ALCOOL +ALCOOLIQUE +ALDACTAZINE +ALDACTONE +ALDARA +ALDOMET +ALDOSTERONE +ALDURAZYME +ALECENSA +ALENDRONATE +ALENDRONIQUE +ALEPSAL +ALETRIS +ALEVETABS +ALFA +ALFA-AMYLASE +ALFACALCIDOL +ALFALASTIN +ALFALFA +ALFATIL +ALFENTANIL +ALFUZOSINE +ALGERIENNE +ALGESAL +ALGINATE +ALIMTA +ALIZEM +ALKA +ALKALON +ALKEKENGI +ALKERAN +ALLERGAN +ALLERGIE +ALLERGIFLASH +ALLERGIQUE +ALLERGOCOMOD +ALLERGODIL +ALLERGÉNIQUE +ALLERVI +ALLIUM +ALLOPURINOL +ALLOXANUM +ALLUZIENCE +ALMOGRAN +ALMOTRIPTAN +ALNUS +ALODONT +ALOE +ALOFISEL +ALONEST +ALOPEXY +ALOPLASTINE +ALOSTIL +ALOXI +ALPEX +ALPHA-AMYLASE +ALPHACAINE +ALPHAGAN +ALPRAZOLAM +ALPRESS +ALPROLIX +ALPROSTADIL +ALTAN +ALTEIS +ALTEISDUO +ALTHAEA +ALTIZIDE +ALTUVOCT +ALUMINA +ALUNBRIG +ALVESCO +ALYMSYS +ALYOSTAL +AMANITA +AMARA +AMAREL +AMBISOME +AMBRA +AMBRISENTAN +AMBROSIA +AMBROXOL +AMBULATOIRE +AMDIPHARM +AMELGEN +AMERICANA +AMERICANUS +AMGEVITA +AMGLIDIA +AMIFAMPRIDINE +AMIKACINE +AMILORIDE +AMINOMIX +AMINOPHYLLINE +AMINOPLASMAL +AMINOSTAB +AMINOVEN +AMIODARONE +AMIRIOX +AMISULPRIDE +AMITRIPTYLINE +AMIVAS +AMLODIPINE +AMLOR +AMMI +AMMONAPS +AMMONIUM +AMOROLFINE +AMOXICILLINE +AMPELOPSIS +AMPHOSCA +AMPHOTERICINE +AMPICILLINE +AMSALYO +AMSPARITY +AMUKINE +AMVUTTRA +AMYCOR +AMYGDALES +AMYLIUM +AMYLMETACRESOL +ANACARDIUM +ANAFRANIL +ANAGALLIS +ANAGRELIDE +ANANDRON +ANANTHERUM +ANAPEN +ANASTROZOLE +ANCOTIL +ANDRACTIM +ANDROCUR +ANDROGEL +ANDROTARDYL +ANESDERM +ANETENA +ANGELICA +ANGELIQ +ANGI-SPRAY +ANGIPAX +ANGUSTA +ANGUSTIFOLIA +ANGUSTURA +ANIMALIS +ANIS +ANISEE +ANISUM +ANNUUM +ANNUUS +ANORO +ANS +ANSATIPINE +ANTADYS +ANTALCALM +ANTALNOX +ANTALYRE +ANTARENE +ANTASOL +ANTHELMIA +ANTHELMINTICUM +ANTHEMIS +ANTHRACINUM +ANTI +ANTI-XA +ANTIBIO +ANTICOLIBACILLAIRE +ANTIGONE +ANTIGRIPPAL +ANTIGÈNE +ANTIGÈNES +ANTILLES +ANTIMONIUM +ANTISTAX +ANXEMIL +ANY +ANZUPGO +AORTE +AOTAL +AP-HP +APAISYLGEL +APARINE +APATITE +APEXELSIN +APIDRA +APIS +APIUM +APOCYNUM +APOKINON +APOMORPHINE +APRANAX +APREMILAST +APREPITANT +APREXEVO +APROKAM +APROVEL +APTIVUS +AQUA +AQUAREST +AQUATICUM +AQUEUSE +AQUEUX +AQUIFOLIUM +AQUILEGIA +AQUIPTA +ARACYTINE +ARALIA +ARANEA +ARANESP +ARAVA +ARBUTUS +ARCALION +ARCHANGELICA +ARCOXIA +AREXVY +ARGANOVA +ARGATROBAN +ARGEMONE +ARGENT +ARGENTITE +ARGENTUM +ARGININE +ARICEPT +ARIKAYCE +ARIMIDEX +ARIPIPRAZOLE +ARISTOLOCHIA +ARIXTRA +ARKOGELULES +ARLUNIS +ARMEES +ARMISARTE +ARMORACIA +ARNICA +ARNICAGEL +ARNICALME +ARNICAN +ARNIGEL +ARNITROSIUM +AROMA +AROMASINE +AROMASOL +AROMATICA +AROME +ARPHOS +ARSENIC +ARSENICOSUM +ARSENICUM +ART +ARTANE +ARTELAC +ARTEMISIA +ARTEMISIAEFOLIA +ARTENSIUM +ARTERE +ARTESUNATE +ARTEX +ARTHROCINE +ARTICADENT +ARTIFICIELLES +ARTINIBSA +ARTIREM +ARTISIAL +ARTISS +ARUM +ARUNDO +ARVENSE +ARVENSIS +ASA +ASARED +ASARUM +ASCABIOL +ASCLEPIAS +ASCOFER +ASCORBATE +ASIATICA +ASIMINA +ASMANEX +ASMELOR +ASPARAGUS +ASPARTE +ASPAVELI +ASPEGIC +ASPEN +ASPERGILLUS +ASPERULA +ASPIDIUM +ASPIRINE +ASPRO +ASTACUS +ASTERIAS +ASTERLUNA +ATACAND +ATANTO +ATARAX +ATAZANAVIR +ATEBEMYXINE +ATECTURA +ATENATIV +ATENOLOL +ATEPADENE +ATGAM +ATORVASTATINE +ATOSIBAN +ATOVAQUONE +ATRACURIUM +ATRIANCE +ATRIPLA +ATROPINE +ATROPINUM +ATROVENT +ATURGYL +AUBAGIO +AUBEPINE +AUGMENTIN +AUREA +AUREOMYCINE +AUREUM +AURICULARUM +AURIGOUTTE +AURUM +AUTOHALER +AUTUMNALE +AVAMYS +AVASTIN +AVAXIM +AVENA +AVENOC +AVIAIRE +AVICULARE +AVODART +AVONEX +AVTOZMA +AXA +AXE +AXELER +AXEPIM +AXICA +AXITINIB +AXUMIN +AYBINTIO +AYVAKYT +AZACITIDINE +AZACTAM +AZADOSE +AZARGA +AZATHIOPRINE +AZELASTINE +AZILECT +AZITHROMYCINE +AZOPT +AZURITE +AZYTER +AZZALURE +B.A.L +B.BRAUN +B.T.G +B.V +B12 +BA.1 +BA.4-5 +BACCATA +BACLOCUR +BACLOFENE +BACTRIM +BACTROBAN +BADIAGA +BAILLEUL +BALSAMINA +BALSAMORHINOL +BALSAMUM +BALSOLENE +BALVERSA +BAMBUSA +BAPTISIA +BAQSIMI +BAR +BARACLUDE +BARBATA +BARDANE +BARITEKAL +BARYTA +BARYTINE +BASCELLEX +BASDENE +BASILICUM +BAUDRY +BAUME +BAVENCIO +BCG +BCG-MEDAC +BEAGYNE +BEBE +BEBEGEL +BECAT +BECILAN +BECLO-RHINO +BECLOJET +BECLOMETASONE +BECLOSPIN +BECLOSPRAY +BECONASE +BECOTIDE +BECOZYME +BEDELIX +BEFIZAL +BEKEMV +BELAMONT +BELANETTE +BELARA +BELARACONTINU +BELIVAIR +BELLADONNA +BELLIS +BELLOC +BELLON +BELUSTINE +BEMEDREX +BEMFOLA +BENAZEPRIL +BENDAMUSTINE +BENEDICTUS +BENEFIX +BENEPALI +BENERVA +BENLYSTA +BENSERAZIDE +BENTA +BENZALKONIUM +BENZOE +BENZOICUM +BENZOLUM +BENZOYLE +BENZYLIQUE +BEOVU +BEPANTHEN +BEPANTHENE +BERBERIS +BERINERT +BERNARD +BEROMUN +BESINS +BESPONSA +BETA +BETADINE +BETAFACT +BETAFERON +BETAGAN +BETAHISTINE +BETAINE +BETAMETHASONE +BETAPHARM +BETASELEN +BETASERC +BETAXOLOL +BETESIL +BETMIGA +BETNESOL +BETNEVAL +BETOPTIC +BETULA +BEVITINE +BEXAROTENE +BEXSERO +BEYFORTUS +BGRCONTINU +BI-FLUORE +BI-IODATUS +BIAFINE +BIAFINEACT +BICAFRES +BICALUTAMIDE +BICARBONATE +BICAVERA +BICHROMICUM +BICLOTYMOL +BICNU +BIENNIS +BIFONAZOLE +BIKTARVY +BILASKA +BILASTINE +BILIAIRE +BILINUM +BILLEROL +BILOBA +BILTRICIDE +BIMATOPROST +BIMZELX +BINOCRIT +BIO +BIOCALYPTOL +BIOCARDE +BIOCIDAN +BIODALGIC +BIODIM +BIOGARANCONTINU +BIOLUZ +BIOMAG +BIONOLYTE +BIORGASEPT +BIOSEDRA +BIOTINE +BIOXYOL +BIPHAR +BIPHOZYL +BIPRETERAX +BIRODOGYL +BISACODYL +BISEPTINE +BISEPTINESPRAID +BISMUTH +BISMUTHUM +BISOCE +BISOLVON +BISOPROLOL +BITIFRIN +BIVALENT +BIVALIRUDINE +BLATTA +BLENDE +BLEOMYCINE +BLEU +BLINCYTO +BLISSEL +BLUEFISH +BMS +BOCEAL +BOCOUTURE +BOIRON +BOLDO +BOLDOFLORINE +BOLINAN +BOMYNTRA +BON +BONASOL +BONDRONAT +BONVIVA +BOOSTRIXTETRA +BORAX +BORIQUE +BORNITE +BOROCITRICA +BORRAGO +BORTEZOMIB +BOSENTAN +BOSULIF +BOSUTINIB +BOTHROPS +BOTOX +BOUCHARA-RECORDATI +BOULEAU +BOVISTA +BRADEX +BRAFTOVI +BRASILIENSIS +BRASSICA +BRAUN +BRAVA +BREAKYL +BREEZHALER +BREVIBLOC +BREXIN +BREYANZI +BRICANYL +BRIDION +BRILIQUE +BRIMAZED +BRIMONIDINE +BRINEURA +BRINTELLIX +BRINZOLAMIDE +BRIVIACT +BROMATUM +BROMAZEPAM +BROMHYDRATE +BROMUM +BRONCALENE +BRONCATHIOL +BRONCHES +BRONCHEX +BRONCHIALIS +BRONCHODERMINE +BRONCHODUAL +BRONCHOKOD +BRONPHYTO +BRONWEL +BRUFEN +BRUKINSA +BRULEX +BRYONIA +BRYOPHYLLUM +BUCCOBET +BUCCOLAM +BUDESONIDE +BUFO +BUGVI +BULBINUM +BULBOSUS +BUPENSAN +BUPIVACAINE +BUPRENORPHINE +BURINEX +BUSILVEX +BUSPIRONE +BUSSEROLE +BUSULFAN +BUTYLBROMURE +BUVIDAL +BUXUS +BYDUREON +BYETTA +BYFAVO +BYLVAY +BYOOVIZ +CA-DTPA +CABAZITAXEL +CABERGOLINE +CABESOL +CABLIVI +CABOMETYX +CACAO +CACIT +CACTI +CACTUS +CADDERA +CADELIUS +CADMIUM +CADRON +CADUET +CAELYX +CAESIUM +CAFEINE +CAJUPUTUM +CALADIUM +CALAMINE +CALCAREA +CALCAREUM +CALCIBRONAT +CALCIDIA +CALCIDOSE +CALCIFEDIOL +CALCIFORTE +CALCIPARINE +CALCIPOTRIOL +CALCIPRAT +CALCIQUE +CALCITONINE +CALCIUM +CALENDORON +CALENDULA +CALIFORNICA +CALIFORNICUM +CALOTROPIS +CALPEROS +CALQUENCE +CALTHA +CALTRATE +CALYCINUM +CALYPTOL +CAMILIA +CAMPESTRE +CAMPESTRIS +CAMPHORA +CAMPHRICE +CAMZYOS +CANADA +CANADENSIS +CANCRI +CANDAZOL +CANDESARTAN +CANDICANS +CANDIDUM +CANEPHRON +CANINA +CANINUM +CANNABINUM +CANTABILINE +CANTALENE +CANTHARIS +CANUM +CAPECITABINE +CAPENSIS +CAPILLAIRE +CAPRELSA +CAPRIFOLIUM +CAPSICUM +CAPTOPRIL +CAPVAXIVE +CARBACTIVE +CARBAGLU +CARBAMAZEPINE +CARBETOCINE +CARBIDOPA +CARBO +CARBOCAINE +CARBOCISTEINE +CARBOLEVURE +CARBOLICUM +CARBONATE +CARBONEUM +CARBONICA +CARBONICUM +CARBOPLATINE +CARBOSYLANE +CARBOSYMAG +CARBOXYMALTOSE +CARDENSIEL +CARDINALIS +CARDINE +CARDIOCALM +CARDIOGEN-82 +CARDIOMIBI +CARDIOXANE +CARDUUS +CARGLUMIQUE +CARIBAN +CARICA +CARINOPHARM +CARLIN +CARLYTENE +CARMIN +CARMUSTINE +CARMYNE +CAROLINENSE +CAROMINTHE +CARTEOL +CARTIFIT +CARTILAGE +CARTILAGO +CARTREX +CARVECORAL +CARVEDILOL +CARVYKTI +CASCARA +CASCARILLA +CASGEVY +CASODEX +CASPOFUNGINE +CASTANEA +CASTOR +CASTUS +CATAPRESSAN +CATARIA +CATIOLANZE +CAULOPHYLLUM +CAUSTICUM +CAVERJECT +CAYSTON +CCD +CEANOTHUS +CEBEMYXINE +CEBESINE +CEBUTID +CEDACONDA +CEDRON +CEFADROXIL +CEFALINE +CEFAZOLINE +CEFEPIME +CEFIXIME +CEFOTAXIME +CEFOXITINE +CEFPODOXIME +CEFTAZIDIME +CEFTRIAXONE +CEFUROXIME +CEGFILA +CEIP +CELEBREX +CELECOXIB +CELECTOL +CELESTENE +CELIPROLOL +CELLCEPT +CELLTOP +CELLULES +CELLUVISC +CELOCURINE +CELSENTRI +CELSIOR +CEMAUKOR +CENCHRIS +CENTRALE +CENTRAPHARM +CEPA +CEPHALANDRA +CEPROTIN +CERAZETTE +CERDELGA +CEREBELLUM +CEREBRAL +CEREBRINUM +CERESTAB +CERETEC +CEREZYME +CERIFERA +CERIS +CERNEVIT +CERNITOL +CERTICAN +CERUBIDINE +CERULYSE +CERVAGEME +CERVARIX +CERVICALES +CETAFEN +CETAVLEX +CETAVLON +CETHEXONIUM +CETINOR +CETIRIZINE +CETORNAN +CETRARIA +CETROTIDE +CETYLPYRIDINIUM +CEVIDRA +CEZIBOE +CHALCOPYRITE +CHAMOMILLA +CHAMPIX +CHARBON +CHAUVIN +CHEIRANTHUS +CHEIRI +CHELIDONIUM +CHELONE +CHEMINEAU +CHENODEOXYCHOLIC +CHENOPODIUM +CHEPLAPHARM +CHIBRET +CHIBRO +CHIBRO-PROSCAR +CHIBROXINE +CHIESI +CHIMAPHILA +CHIMOS +CHINA +CHININUM +CHIONANTHUS +CHIROCAÏNE +CHLORALUM +CHLORAMINOPHENE +CHLORAPREP +CHLORHEXIDINE +CHLORHYDRATE +CHLORICUM +CHLORMADINONE +CHLOROBUTANOL +CHLOROFORMIUM +CHLORPHENAMINE +CHLORUMAGENE +CHLORURE +CHOAY +CHOCOLAT +CHOLECALCIFEROL +CHOLEDIAM +CHOLEODORON +CHOLESTERINUM +CHOLURSO +CHONDROITINE +CHONDROSULF +CHOPHYTOL +CHORIONIQUE +CHRONO +CHRONO-INDOCID +CHRONODOSE +CHRYSANTHUM +CHRYSOLITHE +CIALIS +CIBACENE +CIBADREX +CIBINQO +CICADERMA +CICLETANINE +CICLOPIROX +CICUTA +CIDERMEX +CIDOFOVIR +CIELLA +CIFLOX +CILASTATINE +CILOXADEX +CILOXAN +CIMETIDINE +CIMZIA +CINA +CINABRE +CINACALCET +CINERARIA +CINEREA +CINNABARIS +CINNAMOMUM +CINRYZE +CIPLA +CIPROFIBRATE +CIPROFLOXACINE +CIRCADIN +CIS +CISATRACURIUM +CISNAF +CISPLATINE +CITALOPRAM +CITRAFLEET +CITRATE +CITRON +CITRUS +CIVARON +CLAIRYG +CLAMOXYL +CLARADOL +CLAREAL +CLARELUX +CLARISCAN +CLARITHROMYCINE +CLARITYNE +CLARIX +CLASSICS +CLASTOBAN +CLAVATUM +CLAVENTIN +CLAVULANIQUE +CLEMATIS +CLEMATITIS +CLEMIS +CLEVIPREX +CLIMASTON +CLIMAXOL +CLIMENE +CLINDAMYCINE +CLINIMIX +CLINOLEIC +CLIPTOL +CLOBETASOL +CLOBEX +CLOFARABINE +CLOMID +CLOMIPRAMINE +CLOPIDOGREL +CLOPIXOL +CLOROTEKAL +CLOSALIS +CLOTRIMAZOLE +CLOTTAFACT +CLOXACILLINE +CLOZAPINE +CM2 +CNICUS +CO-RENITEC +COAGADEX +COAPROVEL +COBALT +COBALTUM +COCA +COCCULINE +COCCULUS +COCCUS +COCHLEARIA +COCHON +COCYNTAL +CODEINE +CODEINE-ERYSIMUM +CODEX +CODOLIPRANE +COFFEA +COGYR +COKENZEN +COLCHICINE +COLCHICUM +COLCHIMAX +COLIBACILLINUM +COLINA +COLISTIMETHATE +COLLINSONIA +COLLUDOL +COLOBREATHE +COLOCYNTHIS +COLOFOAM +COLOKIT +COLON +COLOPEG +COLORE +COLOREE +COLPERMIN +COLPOTROPHINE +COLPRONE +COLUMVI +COMBANTRIN +COMBIGAN +COMBIVIR +COMBODART +COMIRNATY +COMMUNIS +COMPLEXE +COMPOSE +COMTAN +CONCERTA +CONCHIOLINUM +CONDURANGO +CONDYLINE +CONEBILOX +CONEXXENCE +CONFEROPORT +CONFIDEX +CONGLOMERAT +CONIUM +CONJONCTIVITE +CONJUGAISON +CONJUGUÉ +CONSEIL +CONSERVATEUR +CONSTIPATION +CONTALAX +CONTINU +CONTINUE +CONTORTRIX +CONTRACNE +CONTRAMAL +CONTRATHION +CONTRE +CONTRE-COUPS +CONTROL +CONTROLE +CONVALLARIA +CONVAMEO +CONVOLVULUS +CONVULINE +COOLMETEC +COPAXONE +COPIES +COQUELUSEDAL +COR +CORALLINUS +CORALLIUM +CORAZED +CORBILTA +CORDARONE +CORGARD +CORICIDE +CORNUTUM +CORONAIRE +COROTROPE +CORROSIVUS +CORTANCYL +CORTAPAISYL +CORTEX +CORTICO-HYPOTHALAMIQUE +CORTIMENT +CORTISEDERMYL +CORTISONE +CORVASAL +CORYZALIA +COSENTYX +COSIDIME +COSIMPREL +COSMEGEN +COSOPT +COSTEC +COTAREG +COTELLIC +COTRIATEC +COTRIMOXAZOLE +COUMADINE +COVERAM +COVERSYL +COVID-19 +COZAAR +CRABRO +CRATAEGUS +CREON +CRESEMBA +CRESOLUM +CRESTOR +CRINEX +CRINONE +CRISE +CRISPUS +CRISTAL +CRISTERS10 +CROCATA +CROCUS +CROMABAK +CROMADOSES +CROMEDIL +CROMOGLICATE +CROMOPTIC +CROMORHINOL +CRONOMIR +CROTALUS +CROTON +CRUDA +CRUDUM +CRUSIA +CRYSVITA +CRÈME +CUBICIN +CUCURBITA +CUFENCE +CUIVRE +CUIVRE-OR-ARGENT +CUPRESSUS +CUPRIOR +CUPRUM +CURACNE +CURARE +CURASPOT +CURCUMA +CURETHYL +CURIUM +CURIUMPHARMA +CUROSURF +CURRASSAVICUM +CUTACNYL +CUTANEE +CUTAQUIG +CUVITRU +CYAMEMAZINE +CYANATUS +CYANOKIT +CYCLADOL +CYCLAMEN +CYCLO +CYCLODYNON +CYCLOPHOSPHAMIDE +CYMBALTA +CYMEVAN +CYNAPIUM +CYNARA +CYNOMEL +CYPRIPEDIUM +CYPROTERONE +CYRAMZA +CYSTADANE +CYSTADROPS +CYSTAGON +CYSTEINE +CYSTINE +CYTARABINE +CYTEAL +D'ABEILLE +D'ACIDES +D'ALUMINIUM +D'ANGUILLE +D'ARGENT +D'AZOTE +D'ERBIUM +D'ESTOMAC +D'HEPTAMINOL +D'INDE +D'INDIUM +D'IODE +D'OLIGO-ELEMENTS +D'OR +D'ORNITHINE +D'OXYBUPROCAINE +D'YTTRIUM +D.D +DABIGATRAN +DACARBAZINE +DACRYOSERUM +DACRYUM +DACTYLIS +DACUDOSES +DAFALGAN +DAFALGANCAPS +DAFALGANHOP +DAFALGANTABS +DAFLON +DAILY +DAIVOBET +DAIVONEX +DAKIN +DAKTARIN +DALACINE +DALFEINE +DALIBOUR +DAMASCENA +DAMIANA +DANATROL +DANTRIUM +DAONIL +DAPTOMYCINE +DARUNAVIR +DARZALEX +DASATINIB +DATSCAN +DEBRICALM +DEBRIDAT +DECANDRA +DECANOAS +DECAPEPTYL +DECOCTE +DECTANCYL +DECTOVA +DECUMANA +DEDROGYL +DEFANYL +DEFERASIROX +DEFERIPRONE +DEFITELIO +DEFLATINE +DEFLORATUM +DEGARELIX +DELAGRANGE +DELALANDE +DELBERT +DELIDOSE +DELIPROCT +DELPRIM +DELSTRIGO +DELTYBA +DELURSAN +DEMANGEAISONS +DEMECLOCYCLINE +DEMILOS +DENGVAXIA +DENS +DENSICAL +DENTEX +DENTINEA +DENTOBAUME +DEPAKINE +DEPAKOTE +DEPAMIDE +DEPO +DEPO-MEDROL +DEPRENYL +DERINOX +DERMAFUSONE +DERMAZOL +DERMESTRIL +DERMIQUE +DERMO +DERMO-6 +DERMOBACTER +DERMOCUIVRE +DERMOFENAC +DERMOPHIL +DERMOVAL +DEROXAT +DESARENA +DESCOVY +DESFERAL +DESFLURANE +DESINTEX +DESLORATADINE +DESMA +DESMOPRESSINE +DESOBEL +DESOGESTREL +DESOMEDINE +DESOPOP +DETENSIEL +DETICENE +DETRUSITOL +DEVELOPPEMENT +DEXAFREE +DEXAMBUTOL +DEXAMETHASONE +DEXATOPIA +DEXDOR +DEXLIQ +DEXMEDETOMIDINE +DEXMÉDÉTOMIDINE +DEXOCOL +DEXPANTHENOL +DEXTRION +DEXTROMETHORPHANE +DI-HYDAN +DIABENE +DIABLE +DIACEREINE +DIACIDE +DIACOMIT +DIADEMA +DIAMICRON +DIAMOX +DIANE +DIANEAL +DIAPHRAGME +DIARALIA +DIARETYL +DIARFIX +DIASEPTYL +DIASTROLIB +DIAZEPAM +DICETEL +DICHLOROBENZYLIQUE +DICLOFENAC +DICODIN +DICYNONE +DIENCEPHALE +DIENOGEST +DIERGOSPRAY +DIF +DIFFERINE +DIFFU-K +DIFICLIR +DIFRAREL +DIGEDRYL +DIGESTODORON +DIGITALIS +DIGITATA +DIGLUCONATE +DIGOXINE +DILANTIN +DILATRANE +DILTIAZEM +DIMETANE +DIMETHYL +DIMETRUM +DIOICA +DIOICUM +DIOPSIDE +DIOSCOREA +DIOSMECTITE +DIOSMINE +DIOVENOR +DIPENTUM +DIPEPTIVEN +DIPHANTE +DIPHARMA +DIPHTERICUM +DIPHTEROTOXINUM +DIPIPERON +DIPOTASSIQUE +DIPRIVAN +DIPROLENE +DIPROSALIC +DIPROSONE +DIPROSTENE +DISCI +DISCOTRINE +DISKUS +DISOPROXIL +DISQUES +DISULONE +DITROPAN +DIVALCOTE +DIVARIUS +DIVINA +DMSA +DOBFAR +DOBUTAMINE +DOCETAXEL +DODECAVIT +DOGMATIL +DOLENIO +DOLICHOS +DOLIPRANE +DOLIPRANECAPS +DOLIPRANELIQUIZ +DOLIPRANEORODOZ +DOLIPRANETABS +DOLIPRANEVITAMINEC +DOLIRHUME +DOLIRHUMEPRO +DOLKO +DOLODENT +DOLOSOFT +DOLOSPASMYL +DOMILA +DOMPERIDONE +DONASERT +DONAX +DONEPEZIL +DONORMYL +DOPACEPTIN +DOPACIS +DOPAMINE +DOPAVIEW +DOPRAM +DORMICALM +DORSALES +DORZOLAMIDE +DOSE +DOSISEPTINE +DOSOXYGENEE +DOSTINEX +DOTAREM +DOUBLESTAR +DOUCE +DOVATO +DOVPRELA +DOXAZOSINE +DOXIUM +DOXORUBICINE +DOXY +DOXYCYCLINE +DOXYLAMINE +DOXYLIS +DOXYPALU +DOZURSO +DRACUNCULUS +DRAFORA +DRAGEES +DRILL +DRIPTANE +DROLEPTAN +DROPERIDOL +DROPIZAL +DROSERA +DROSETUX +DROSPIBEL +DROSPIRENONE +DROVELIS +DRYMIS +DTPA +DUALKOPT +DUGRESSA +DUKORAL +DULCAMARA +DULCE +DULCILARMES +DULCIS +DULCOLAX +DULOXETINE +DUODENUM +DUODOPA +DUOFILM +DUOPLAVIN +DUORESP +DUOTRAV +DUOVA +DUPHALAC +DUPHASTON +DUPIXENT +DURAPHAT +DURILLON +DUROGESIC +DUSPATALIN +DUTASTERIDE +DYMISTA +DYNASTAT +DYNEXAN +DYNEXANGIVAL +DYSALFA +DYSCRASITE +DYSPORT +DZUVEO +D’ARGENT +D’AZOTE +D’INDIGO +D’ORNITHINE +DÉCOCTÉ +DÉGRÉ +EASYHALER +EAU +EBASTINE +EBERTHINUM +EBEWE +EBGLYSS +EBILFUMIN +EBIXA +EBVALLO +ECALTA +ECBIRIO +ECHINACEA +ECHINACEE +ECOBEC +ECONAZOLE +EDETATE +EDEX +EDUCTYL +EDURANT +EFAVIRENZ +EFDEGE +EFFALA +EFFEDERM +EFFENTORA +EFFERALGAN +EFFERALGANMED +EFFERVESCENT +EFFERVESCENTE +EFFEXOR +EFFICORT +EFFIK +EFFIZINC +EFFORTIL +EFIENT +EFLUELDA +EFUDIX +EGATEN +EGYSTOL +ELAHERE +ELAPRASE +ELAPS +ELAVIL +ELDISINE +ELEBRATO +ELETRIPTAN +ELFASETTE +ELIGARD +ELIQUIS +ELLAONE +ELLIPTA +ELMIRON +ELOCTA +ELONVA +ELOXATINE +ELREXFIO +ELSEP +ELTROMBOPAG +ELUCIREM +ELUDRIL +ELUDRILPERIO +ELUDRILPRO +ELUSANES +ELVORINE +EMBLAVEO +EMCITATE +EMEND +EMERADE +EMGALITY +EMLA +EMLAPATCH +EMTRICITABINE +EMTRIVA +EMULGEL +EMYLIF +ENALAPRIL +ENANTONE +ENBREL +ENCALLIK +ENCEPUR +ENDHOMETROL +ENDOTELON +ENDOVELA +ENDOXAN +ENERZAIR +ENGERIX +ENHERTU +ENJAYMO +ENOXAPARINE +ENRYLAZE +ENSPRYNG +ENSTILAR +ENTACAPONE +ENTALGINE +ENTECAVIR +ENTECET +ENTEROCOCCINUM +ENTOCORT +ENTONOX +ENTRESTO +ENTYVIO +ENVARSUS +EOLIP +EOSINE +EPCLUSA +EPHEDRA +EPHEDRINE +EPIDUO +EPIDYOLEX +EPINITRIL +EPIPEN +EPIPHYSE +EPIRUBICINE +EPITOMAX +EPITOPIC +EPIVIR +EPLERENONE +EPORATIO +EPREX +EPTAVIT +EPTIFIBATIDE +EPYSQLI +EQUI +EQUISETUM +EQWILATE +ERAZABAN +ERBITUX +ERECTA +ERELZI +ERIBULINE +ERIGERON +ERINUS +ERIODICTYON +ERIVEDGE +ERLEADA +ERLOTINIB +ERTAPENEM +ERWINASE +ERY +ERYFLUID +ERYLIK +ERYNGIUM +ERYNJA +ERYSIMUM +ERYTHEDERMYL +ERYTHROCINE +ERYTHROGEL +ERYTHROMYCINE +ESBERIVEN +ESBRIET +ESCHSCHOLTZIA +ESCITALOPRAM +ESCULENTUM +ESIDREX +ESKAZOLE +ESKESIA +ESKETAMINE +ESLICARBAZEPINE +ESMERON +ESMOCARD +ESOMEPRAZOLE +ESPERAL +ESPIZENE +ESSENCE +ESSENTIAL +ESSENTIELLE +ESTERS +ESTEVE +ESTIMA +ESTOMAC +ESTRACYT +ESTRADIOL +ESTRAGON +ESTRAPATCH +ESTREVA +ESTRING +ESTROFEM +ESTROTEP +ETAIN +ETARTILEN +ETAT +ETEXILATE +ETHER +ETHINYLESTRADIOL +ETHINYLOESTRADIOL +ETHYLICUM +ETHYLIQUES +ETHYPHARM +ETIFOXINE +ETILEFRINE +ETIOVEN +ETOMIDATE +ETONOGESTREL +ETOPOPHOS +ETOPOSIDE +ETORICOXIB +ETORING +EUCALYPTUS +EUCREAS +EUDION +EUGENIA +EUGIA +EUMEDICA +EUPANTOL +EUPATORIA +EUPATORIUM +EUPHON +EUPHONYLL +EUPHORBIA +EUPHORBIUM +EUPHRASIA +EUPHYTOSE +EUPRESSYL +EURARTESIM +EURAX +EURELIX +EUROBIOL +EUROGENERICS +EUROPAEA +EUROPAEUM +EUTHYRAL +EVANECIA +EVANS +EVENITY +EVEPAR +EVER +EVEROLIMUS +EVICEL +EVIPLERA +EVISTA +EVKEEZA +EVOLTRA +EVRA +EVRENZO +EVRYSDI +EVUSHELD +EXACOR +EXACYL +EXBLIFEP +EXELON +EXELTIS +EXEMESTANE +EXFORGE +EXJADE +EXOCINE +EXOMUC +EXOTIQUE +EXOTIQUES +EXPECTORANT +EXTAVIA +EXTENCILLINE +EXTOVYL +EXTRAIT +EXTRANASE +EXTRANEAL +EYLEA +EZETIMIBE +EZETROL +FABHALTA +FABRAZYME +FABRE +FACTANE +FAGOPYRUM +FAIBLE +FAIRMED +FAMENPAX +FAMOTIDINE +FAMPRIDINE +FAMPYRA +FARESTON +FARFARA +FARINOSA +FARMORUBICINE +FARYDAK +FASENRA +FASIGYNE +FASLODEX +FASTURTEC +FAURE +FAZOL +FDG +FEBUXOSTAT +FEGENOR +FEIBA +FEL +FELDENE +FELDSPATH +FELODIPINE +FEMARA +FEMELIS +FEMI +FEMSEPT +FEMSEPTEVO +FENOFIBRATE +FENTANYL +FENTICONAZOLE +FENUGRENE +FER +FERINJECT +FERO-GRAD +FEROX +FERRI +FERRIER +FERRING +FERRIPROX +FERRIQUE +FERROSO-FERRI +FERROSTRANE +FERRUGINEUM +FERRUM +FERTIFOL +FERTISTARTKIT +FERULA +FERVEX +FERVEXRHUME +FESOTERODINE +FETCROJA +FEUILLE +FEXOFENADINE +FIASP +FIBROGAMMIN +FIBROVEIN +FIBRYGA +FICARIA +FICUS +FILAMENTOSA +FILIOP +FILIX +FILSUVEZ +FINACEA +FINASTERIDE +FINCREZO +FINGOLIMOD +FINLEE +FINTEPLA +FIRAZYR +FIRDAPSE +FIRMAGON +FIVASA +FIXAPOST +FIXICAL +FIXORINOX +FLAGYL +FLAMMACERIUM +FLAMMAZINE +FLAVAN +FLAVONOIDES +FLAVONOIQUE +FLAVONOÏDES +FLEBOGAMMA +FLECAINE +FLECAINIDE +FLECAÏNE +FLECAÏNIDE +FLECTOR +FLECTOREFFIGEL +FLECTORTISSUGELEP +FLEXEA +FLEXPEN +FLEXPRO +FLEXTOUCH +FLIXABI +FLIXONASE +FLIXOTIDE +FLIXOVATE +FLODIL +FLORALAC +FLORGYNAL +FLORIDE +FLOXYFRAL +FLUAD +FLUANXOL +FLUARIXTETRA +FLUCELVAX +FLUCIS +FLUCLOXACILLINE +FLUCON +FLUCONAZOLE +FLUCORTAC +FLUDARA +FLUDARABINE +FLUDESOXYGLUCOSE +FLUDEX +FLUDROCORTISONE +FLUIDABAK +FLUIMUCIL +FLUISEDAL +FLUMAZENIL +FLUOCARIL +FLUOCYNE +FLUODONTYL +FLUOGEL +FLUOR +FLUORE +FLUORESCEINE +FLUORICA +FLUORICUM +FLUORITE +FLUOROCHOL +FLUOROCHOLINE +FLUOROURACILE +FLUORURE +FLUOSELGINE +FLUOSTEROL +FLUOXETINE +FLUSTIMEX +FLUTICASONE +FLUTIFORM +FLUVASTATINE +FLUVERMAL +FLUVIATILIS +FLUVOXAMINE +FLÉOLE +FOENUM +FOETIDA +FOETIDUS +FOINS +FOLINATE +FOLINORAL +FOLIQUE +FOLLICULINUM +FOMEPIZOLE +FOMICYT +FONCITRIL +FONDAPARINUX +FONGAMIL +FONGILEINE +FONX +FORADIL +FORLAX +FORMANT +FORMICA +FORMICUM +FORMOAIR +FORMOCARBINE +FORMODUAL +FORMOTEROL +FORMULE +FORSPIRO +FORSTEO +FORTACIN +FORTIGEL +FORTRANS +FORTUM +FORTZAAR +FORXIGA +FOSAMAX +FOSAVANCE +FOSCARNET +FOSCAVIR +FOSFOCINE +FOSFOMYCINE +FOSFOPHARM +FOSINOPRIL +FOSOMEL +FOSRENOL +FOSTIMONKIT +FOURNIER +FRACTION +FRAGARIA +FRAGMINE +FRAGON +FRAICHE +FRAICHEUR +FRAISE +FRAKIDEX +FRAMBOISE +FRAMYXONE +FRANGULA +FRAXINUS +FRAXIPARINE +FRAXODI +FRAÎCHE +FRILAB +FROVATRIPTAN +FRUCTINES +FRUIT +FRUITS +FRUZAQLA +FUCA +FUCIDINE +FUCITHALMIC +FUCUS +FULPHILA +FULVESTRANT +FUMAFER +FUMARATE +FUMARIA +FUMETERRE +FUNGIZONE +FUNGSTER +FURADANTINE +FUROATE +FUROSEMIDE +FUSIDATE +FUSIDIQUE +FUZEON +FYCOMPA +FYREMADEL +FÉBUXOSTAT +G.L +G10 +G13% +G15 +G16%E +G19%E +G20 +G25 +GABAPENTINE +GABITRIL +GADOTERIQUE +GADOVIST +GADOVISTAUTO +GADOVISTMANUEL +GALAFOLD +GALANTAMINE +GALENE +GALIUM +GALLIAD +GALLIAPHARM +GALLIUM +GALVUS +GAMMA-OH +GAMMAGARD +GAMMANORM +GAMMATETANOS +GAMUNEX +GANCICLOVIR +GANFORT +GANGLIONS +GANIRELIX +GARDASIL +GARDENAL +GARNIERITE +GASTRO +GASTROCYNESINE +GASTROGRAFINE +GASTROPAX +GASTROPULGITE +GAVISCON +GAVISCONELL +GAVISCONPRO +GAVRETO +GAZYVARO +GBQ +GCFORM +GEFITINIB +GEL +GELASPAN +GELDENE +GELOFUSINE +GELOX +GELSEMIUM +GELTIM +GELUCYSTINE +GELUTROPHYL +GEMCITABINE +GEMZAR +GEN.ORPH +GENCEBOK +GENISTA +GENOPHARM +GENOPTOL +GENOTONORM +GENTAMICINE +GENTIANA +GENVOYA +GERANIUM +GESTODENE +GESTODENE-ETHINYLESTRADIOL +GEUM +GHRYVELIN +GIAPREZA +GIBITER +GIGANTEA +GILENYA +GINGEMBRE +GINKGO +GINKOGINK +GINKOPLANT +GINKOR +GINSENG +GIOTRIF +GIPHAR +GIVLAARI +GLABRA +GLACIALE +GLANDIUM +GLANDULOSA +GLATIRAMER +GLAUCONIE +GLECHOMA +GLIADEL +GLIBENCLAMIDE +GLIBENESE +GLICLAZIDE +GLIMEPIRIDE +GLIMEZIT +GLIOLAN +GLIPIZIDE +GLIVEC +GLOBULUS +GLOMERATA +GLONOINUM +GLOSSITHIASE +GLUCAGEN +GLUCANTIME +GLUCIDION +GLUCONATE +GLUCOPHAGE +GLUCOR +GLUCOSE +GLUCOTEP +GLUCOTRACE +GLUCOVANCE +GLUSCAN +GLUTINOSA +GLYCERINE +GLYCERINUM +GLYCEROL +GLYCO-THYMOLINE +GLYCOCOLLE +GLYCOPYRRONIUM +GLYCYRRHIZA +GLYCÉRINÉ +GLYDO +GLYPRESSINE +GMD +GNAPHALIUM +GNR +GOMENOL +GOMENOLEE +GONADOTROPHINE +GONAL-F +GONAPEPTYL +GONNON +GONOTOXINUM +GORGE +GOSSYPIUM +GRAECUM +GRAFALON +GRAINS +GRAMME +GRANATUM +GRANDIFLORA +GRANDIFLORUS +GRANIONS +GRANISETRON +GRANOCYTE +GRANPIDAM +GRANUDOXY +GRANULATA +GRANUPAS +GRAPHITES +GRAS +GRASUSTEK +GRATIOLA +GRAVEOLENS +GRAZAX +GRELE +GRES +GRIMPANT +GRINAZOLE +GRINDELIA +GRIPPAL +GRISEA +GROUPE +GUAIACUM +GUAIFENESINE +GUARANA +GUEPE +GUERBET +GURONSAN +GUTRON +GUYANE +GYDRELLE +GYMISO +GYNERGENE +GYNO +GYNO-PEVARYL +GYNOPURA +GÉNOME +GÉNOMES +H.S.A +HAEMOPRESSIN +HAIMA +HALAVEN +HALDOL +HAMAMELIS +HARMONET +HARPAGOPHYTON +HARPAGOPHYTUM +HARVONI +HAUTH +HAVLANE +HAVRIX +HBVAXPRO +HCS +HCT +HDP +HEC +HEDERA +HEDERACEA +HEDETUS +HEKLA +HELENIUM +HELIANTHUS +HELICIDINE +HELICOBACTER +HELIKIT +HELIX +HELLEBORUS +HELMINTOX +HELONIAS +HEMANGIOL +HEMATITE +HEMGENIX +HEMI-DAONIL +HEMIGOXINE +HEMLIBRA +HEMOCLAR +HEMOLEVEN +HEMORROIDAIRE +HEMOSOL +HENNING +HEP +HEPANEPHROL +HEPAR +HEPARGITOL +HEPARINE +HEPATATE +HEPATINE +HEPCLUDEX +HEPSERA +HEPTAMINOL +HERACLEUM +HERBACEUM +HERBION +HERCEPTIN +HERPESEDERMYL +HERZUMA +HEURE +HEURES +HEXA +HEXALYSE +HEXAQUINE +HEXASPRAY +HEXASTAT +HEXATRIONE +HEXETIDINE +HEXICID +HEXOMEDINE +HEXTRIL +HEXVIX +HEXYON +HIBI +HIBIDIL +HIBISCRUB +HIDONAC +HIEMALE +HINARTUM +HIPPOCASTANUM +HIPPOVENO +HISPANA +HISPIDUS +HISTAMINE +HISTAMINUM +HISTOFLUINE +HIZENTRA +HOANG +HOLOXAN +HOMEOAFTYL +HOMEOGENE +HOMEOMUNYL +HOMEOPLASMINE +HOMEOPTIC +HOMEOQUINTYL +HOMEORYL +HOMEOVOX +HORRIDUS +HORUS +HOSPASOL +HUILE +HUKYNDRA +HULIO +HUMAINE +HUMALOG +HUMEX +HUMEXLIB +HUMEXPHYTO +HUMIRA +HUMULUS +HURA +HYALGAN +HYCAMTIN +HYDRASTIS +HYDREA +HYDROCHLOROTHIAZIDE +HYDROCHLOROTIAZIDE +HYDROCORTANCYL +HYDROCORTISONE +HYDROCOTYLE +HYDROCYANICUM +HYDROPHILE +HYDROSOL +HYDROXYCARBAMIDE +HYDROXYDE +HYDROXYZINE +HYOSCYAMUS +HYPERICUM +HYPERIUM +HYPERTONIQUE +HYPNOMIDATE +HYPOPHYSINE +HYPOTHALAMUS +HYQVIA +HYRIMOZ +HYTACAND +HYTRINE +HYZAAR +IASOCHOLINE +IASODOPA +IASOGLIO +IBANDRONIQUE +IBERIS +IBIRON +IBRANCE +IBSA +IBUFETUM +IBUPRADOLL +IBUPROFENE +ICATIBANT +ICAZ +ICECA +ICLUSIG +IDACIO +IDARUBICINE +IDEFIRIX +IDELVION +IDEOS +IDRYLINE +IFIRMACOMBI +IFIRMASTA +IGNATIA +IKERVIS +IKOREL +ILARIS +ILEX +ILLUCCIX +ILOMEDINE +ILOPROST +ILUMETRI +ILUVIEN +IMATINIB +IMAVER +IMBRUVICA +IMCIVREE +IMENOR +IMETH +IMFINZI +IMIGRANE +IMIJECT +IMIPENEM +IMJUDO +IMMEDICA +IMMUNOGLOBULINE +IMNOVID +IMODIUM +IMODIUMCAPS +IMODIUMDUO +IMODIUMLINGUAL +IMODIUMLIQUICAPS +IMOGAM +IMOVANE +IMOVAX +IMPLANTABLE +IMPORTAL +IMRALDI +IMUKIN +IMULDOSA +IMUREL +INACTIVÉ +INCARNATA +INCRELEX +INCRUSE +INDAPAMIDE +INDIARAL +INDICA +INDICUS +INDIEN +INDIGO +INDOBIOTIC +INDOCID +INDOCOLLYRE +INDUCTOS +INEGY +INEUROPE +INEXIUM +INFAI +INFANRIX +INFANRIXQUINTA +INFLATA +INFLECTRA +INFLUDO +INFLUENZINUM +INFLUVAC +INFRACYANINE +INFUSAT +INHALANT +INHALER +INHALEUR +INHIXA +INIPOMP +INJECTABLES +INLYTA +INNOHEP +INNOLET +INNOVAIR +INOFER +INOMAX +INONGAN +INORIAL +INOTYOL +INOVELON +INREBIC +INSPRA +INSTANYL +INSTILLAGEL +INSULATARD +INSULINE +INSUMAN +INTEGRILIN +INTELENCE +INTENSE +INTERCYTON +INTERNATIONALES +INTESTIN +INTETRIX +INTRACERVICAL +INTRALIPIDE +INTRAROSA +INTRATECT +INTRAVEINEUX +INTSEL +INULA +INVANZ +INVOKANA +IODATA +IODATUM +IODE +IODEE +IODUM +IODURE +IODÉE +IOFLUPANE +IOMERON +IONOVEN +IOPAMIRON +IOPIDINE +IPECA +IPERTEN +IPRAALOX +IPRAFEINE +IPRATROPIUM +IQIRVO +IRBESARTAN +IRESSA +IRICRYN +IRIDIUM +IRINOTECAN +IRIS +IRRITEE +ISALIA +ISENTRESS +ISIMIG +ISLANDICA +ISOCARD +ISOFLURANE +ISOFUNDINE +ISOPEDIA +ISOPRENALINE +ISOPROPYLIQUE +ISOPTINE +ISOPTO +ISORYTHM +ISOSORBIDE +ISOTRETINOINE +ISOVOL +ISTENDO +ISTOPEN +ISTURISA +ISUPREL +ITOVEBI +ITRACONAZOLE +ITULAZAX +IVABRADINE +IVERMECTINE +IVHEBEX +IVOZALL +IXCHIQ +IXIARO +IXPRIM +IZALGI +IZEANE +IZILOX +IZINOVA +IZIXATE +JABORANDI +JAKAVI +JALAPA +JAMBOLANA +JAMBOSA +JAMYLENE +JANUMET +JANUVIA +JARDIANCE +JASMINE +JASMINELLE +JASMINELLECONTINU +JASPE +JAVLOR +JAYDESS +JAYEMPI +JCOVDEN +JEMPERLI +JEQUIRITY +JEUNES +JEVTANA +JEXT +JINARC +JN.1 +JOFRE +JORVEZA +JOSACINE +JOUR +JOUVENCE +JUBBONTI +JUBEREQ +JUGLANS +JULUCA +JUNALIZA +JUNIMIN +JUNIOR +JUNIPERUS +JUSTICIA +JYSELECA +K.S +KABIVEN +KADCYLA +KAFTRIO +KALCEKS +KALDENN +KALEORID +KALETRA +KALI +KALINOX +KALIUM +KALMIA +KALOBA +KALYDECO +KANJINTI +KANOKAD +KANUMA +KAPRUVIA +KARDEGIC +KARNODYL +KAYEXALATE +KAYFANDA +KEAL +KEFORAL +KENACORT +KENDIX +KENGREXAL +KENZEN +KEPPRA +KERAFILM +KERLONE +KESIMPTA +KESTIN +KESTINLYO +KETAMINE +KETAZED +KETESSE +KETOCONAZOLE +KETODERM +KETOPROFENE +KETOSTERIL +KETREL +KETUM +KEVZARA +KEYTRUDA +KIGABEQ +KILATIM +KIMMTRAK +KINERET +KINOX +KIOVIG +KIPOS +KISPLYX +KISQALI +KIT +KIVEXA +KIVIZIDIALE +KLEAN-PREP +KLIOGEST +KLIPAL +KOLA +KOMBOGLYZE +KOSELUGO +KOVALTRY +KREDEX +KRENOSIN +KREOSOTUM +KRKA +KRONALIS +KRYPTOSCAN +KUVAN +KWIKPEN +KYLEENA +KYMRIAH +KYNTHEUM +KYPROLIS +KYTRIL +L'ABBE +L'HEPATITE +L-THYROXIN +L-THYROXINE +L.A +L.P +L107 +L114 +L52 +L72 +LABETALOL +LABIAMEO +LABO-LABORATOIRES +LABODAL +LAC +LACHESIS +LACHNANTHES +LACOSAMIDE +LACRIFLUID +LACRIGEL +LACRINORM +LACRYADEX +LACRYVISC +LACTATE +LACTEOL +LACTICUM +LACTIS +LACTUCA +LACTULOSE +LAEVOLAC +LAFARGE +LAITER +LAMALINE +LAMICTAL +LAMIDERM +LAMINARIA +LAMISIL +LAMISILATE +LAMISILDERMGEL +LAMIUM +LAMIVUDINE +LAMOTRIGINE +LAMPRENE +LAMPSANA +LAMZEDE +LANCEOLATUS +LANGLEBERT +LANSOPRAZOLE +LANSOYL +LANTHANE +LANTUS +LANVIS +LANZOR +LAPIS +LAPPA +LARGACTIL +LARIAM +LARMABAK +LARMES +LAROSCORBINE +LAROXYL +LASILIX +LATANOPROST +LATAZED +LATERIFLORA +LATHYRIS +LATHYRUS +LATIFOLIA +LATRODECTUS +LAURILSULFOACETATE +LAUROCERASUS +LAVA +LAVANDE +LAVANDULA +LAVEMENT +LAVENTAIR +LAXAMALT +LAXARON +LAZULITE +LBR +LEADIANT +LEANDRI +LECIGIMON +LECTIL +LEDAGA +LEDERFOLINE +LEDUM +LEELOO +LEFLUNOMIDE +LEGALON +LEHNING +LEMNA +LENALIDOMIDE +LENIA +LENVIMA +LEONIS +LEPIDOLITE +LEPONEX +LEPTAX +LEPTICUR +LEPTOPROL +LERCAN +LERCANIDIPINE +LERCAPRESS +LERGYPAX +LESCOL +LETROZOLE +LETYBO +LEUSTATINE +LEVEMIR +LEVETIRACETAM +LEVICO +LEVIDCEN +LEVISTICUM +LEVITRA +LEVMENTIN +LEVOBUPIVACAINE +LEVOCARNIL +LEVOCETIRIZINE +LEVODOPA +LEVOFLOXACINE +LEVOFOLINATE +LEVOFREE +LEVONORGESTREL +LEVOPHTA +LEVOSIMENDAN +LEVOSOLO +LEVOTHYROX +LEVOTONINE +LEVRES +LEVULOSE +LEVUNIQUE +LEXOMIL +LFB +LHF +LHRH +LIBERTY +LIBMELDY +LIBMYRIS +LIBRAX +LIBTAYO +LIDBREE +LIDENE +LIDOCAINE +LIDOCAÏNE +LIERRE +LIFOG +LIGAMENT +LIGAMENTS +LIGASINE +LIGUSTRUM +LIKOZAM +LILIUM +LIMONUM +LINDE +LINDILANE +LINEZOLIDE +LINUM +LIORESAL +LIPANOR +LIPANTHYL +LIPERCOSYL +LIPIDE +LIPIDEM +LIPIODOL +LIPOMED +LIPOPHILE +LIPOROSA +LIPOSIC +LIPOSOMAL +LIPPIZA +LIPTRUZET +LIPUR +LIPURO +LIQUIDA +LIQUIDE +LIRAGLUTIDE +LISINOPRIL +LITAK +LITFULO +LITHIODERM +LITHIQUE +LITHIUM +LIVIAL +LIVMARLI +LIVOGIVA +LIVTENCITY +LOARGYS +LOBAMINE +LOBELIA +LOCAMETZ +LOCAPRED +LOCATOP +LOCERYL +LOCERYLPRO +LOCOID +LODINE +LODOZ +LOGIFLOX +LOGIMAX +LOGIRENE +LOJUXTA +LOKELMA +LOLISTREL +LOLIUM +LOMBAIRES +LOMEXIN +LOMUSTINE +LONGA +LONICERA +LONOTEN +LONQUEX +LONSURF +LONVECT +LOPERAMIDE +LOPHOPHYTUM +LOPINAVIR +LOPRESSOR +LORAMYC +LORATADINE +LORAZEPAM +LORIEN +LORMETAZEPAM +LORVIQUA +LOSARTAN +LOVENOX +LOXAPAC +LOXAPINE +LOXEN +LP.8.1 +LUCENTIS +LUDEAL +LUDIOMIL +LUMBALES +LUMBALGINE +LUMIGAN +LUMIRELAX +LUMOBRY +LUMYKRAS +LUNPLORO +LUPULUS +LUTATHERA +LUTEA +LUTEINUM +LUTENYL +LUTERAN +LUTRELEF +LUVERIS +LUXTURNA +LUZADEL +LYCOPERSICUM +LYCOPODIUM +LYCOPUS +LYFNUA +LYMECYCLINE +LYMPHATIQUES +LYMPHOSEEK +LYNPARZA +LYOC +LYRICA +LYSAKARE +LYSANXIA +LYSO +LYSODREN +LYSOPAÏNE +LYSORYNX +LYSOZYME +LYTGOBI +LYTHRUM +LYTOS +LYUMJEV +L’ABBE +LÉVOSIMENDAN +M-M-RVAXPRO +M.O +M.U.I +MAALOX +MABELIO +MABTHERA +MACERAT +MACOPHARMA +MACROGOL +MACTANS +MACULATUM +MACÉRAT +MADECASSOL +MAG +MAGINJECTABLE +MAGNE +MAGNESIA +MAGNESIE +MAGNESITE +MAGNESIUM +MAGNESPASMYL +MAGNEVIE +MAGNOLIA +MAINS +MAINTELYTE +MAINTENA +MAIS +MAJALIS +MAJOR +MAJORANA +MAJORELLE +MAJUS +MAL +MALACOXYLON +MALARONE +MALOCIDE +MALUS +MAMELLINE +MANDARINE +MANDRAGORA +MANGANESE +MANGANESE-COBALT +MANGANESE-CUIVRE +MANGANESE-CUIVRE-COBALT +MANGANUM +MANIDIPINE +MANNITOL +MANTADIX +MAPAKNA +MARAVIROC +MARBRE +MARGA +MARIANUS +MARINA +MARITIMA +MARRONNIER +MARRUBIUM +MARSILID +MARTINET +MARUM +MAS +MATE +MATRIFEN +MAUX +MAVENCLAD +MAVIRET +MAXALT +MAXALTLYO +MAXIDEX +MAXIDROL +MAXILASE +MAYOLY +MDK +MEBEVERINE +MECIR +MEDAC +MEDIALIPIDE +MEDIAM +MEDIATENSYL +MEDIBRONC +MEDICAL +MEDICINAL +MEDIFLOR +MEDIKINET +MEDIPHA +MEDISOL +MEDIVEINE +MEDNUTRIFLEX +MEDROL +MEDULLAIRE +MEDULLINE +MEDULLO-SURRENALE +MEDULOSS +MEGACE +MEGAMAG +MEGAMAGNESIA +MEKINIST +MEKTOVI +MELADININE +MELATONINE +MELAXIB +MELAXOSE +MELIANE +MELILOTUS +MELISSA +MELISSE +MELLIFERA +MELLIFICA +MELLITUM +MELODIA +MELOXICAM +MELPHALAN +MELSUNGEN +MEMANTINE +MEMOREEL +MENJUGATE +MENOPUR +MENQUADFI +MENSIFEM +MENTHA +MENTHE +MENTHOL +MENVEO +MENYANTHES +MEPHITIS +MEPIVACAINE +MEPSEVII +MEQ +MERCALM +MERCILON +MERCRYL +MERCRYLSPRAY +MERCUR +MERCURIALIS +MERCURIUS +MERE +MERONEM +MEROPENEM +MESNA +MESOCAÏNE +MESSER +MESTINON +METAFLU +METALDEHYDUM +METALLICUM +METALYSE +METATRACE +METEOSPASMYL +METEOXANE +METFORMINE +METHACHOLINE +METHADONE +METHERGIN +METHOCARBAMOL +METHOTREXATE +METHOXSALENE +METHYLPHENIDATE +METHYLPREDNISOLONE +METHYLTHIONINIUM +METHYSTICUM +METOCLOPRAMIDE +METOJECT +METOPIMAZINE +METOPIRONE +METOPROLOL +METOTAB +METRONIDAZOLE +METVIXIA +METYRAPONE +MEXICANA +MEZEREUM +MIACALCIC +MIANSERINE +MIBG +MIBITEC +MICAFUNGINE +MICARDIS +MICARDISPLUS +MICROGRAMME +MICROGRAMMES +MICROGRAMMESG +MICROLAX +MICROLITRES +MICRONISÉ +MICROPAKINE +MICROPAQUE +MICROTAB +MICROTRAST +MICROVAL +MIDAZOLAM +MIDODRINE +MIEL +MIFEGYNE +MIFLASONE +MIFLONIL +MIGLUSTAT +MIGPRIV +MIKICORT +MILDAC +MILEVONI +MILLE +MILLEFOLIUM +MILLEPERTUIS +MILNACIPRAN +MILRINONE +MIMPARA +MINCEUR +MINERALIS +MINERVA +MINESSE +MINI-SINTROM +MINIDRIL +MINIQUICK +MINIRIN +MINIRINMELT +MINJUVI +MINOR +MINOXIDIL +MINULET +MIOCHOLE +MIOREL +MIOSTAT +MIP +MIRCERA +MIRENA +MIRTAZAPINE +MIRVASO +MISOLFA +MISOONE +MISSILOR +MITOMYCINE +MITOXANTRONE +MIVACRON +MIX25 +MIX50 +MIXTARD +MIZOCLER +MIZOLLEN +MOBIC +MOCLAMINE +MODAFINIL +MODAMIDE +MODANE +MODIFIE +MODIGRAF +MODIODAL +MODOPAR +MODUCREN +MODURETIC +MOFETIL +MOGADON +MOLSIDOMINE +MOMETASONE +MOMORDICA +MONAZITE +MONAZOL +MONILIA +MONO +MONOALGIC +MONOCRIXO +MONODOSE +MONOFLOCET +MONOKETO +MONOOX +MONOPOTASSIQUE +MONOPROST +MONOSEPT +MONOT +MONOXYDE +MONTANA +MONTELUKAST +MONURIL +MOPRAL +MOPRALPRO +MORPHINE +MOSCHATA +MOSCHUS +MOSCONTIN +MOTILIUM +MOUNJARO +MOUSSANTE +MOVENTIG +MOVICOL +MOVIPREP +MOVYMIA +MOXIFLOXACINE +MOXONIDINE +MOXYDAR +MOZOBIL +MRESVIA +MUCEDO +MUCILAGE +MUCODRILL +MUCOMYST +MUCOPLEXIL +MUCOPRET +MUCOR +MUCOTHIOL +MUI +MULTAQ +MULTIBIC +MULTICROM +MULTIHANCE +MULTILARM +MUPHORAN +MUPIDERM +MUPIROCINE +MUQUEUSE +MUREX +MURIATICA +MURIATICUM +MURICATUM +MUSCARIUS +MUSCLE +MUTUS +MUXOL +MVASI +MYALEPTA +MYAMBUTOL +MYCAMINE +MYCOAPAISYL +MYCOHYDRALIN +MYCONAIL +MYCOPHENOLATE +MYCOSEDERMYL +MYCOSKIN +MYCOSTATINE +MYCOSTER +MYDRANE +MYDRIASERT +MYDRIATICUM +MYFENAX +MYFORTIC +MYLERAN +MYLEUGYNE +MYLOTARG +MYNOCINE +MYOVIEW +MYOZYME +MYRELEZ +MYRICA +MYRISTICA +MYRRHA +MYRRHIS +MYRTUS +MYSILDECARD +MYSOLINE +MYTELASE +MÉNINGOCOCCIQUE +N12 +N12E +N4E +N7E +N9E +NAABAK +NAAXIA +NAAXIAFREE +NABUCOX +NAF +NAFTIDROFURYL +NAFTILUX +NAGLAZYME +NAJA +NALADOR +NALBUPHINE +NALGESIC +NALOXONE +NALTREXONE +NAMUSCLA +NAN +NANOCIS +NANOCOLL +NAPELLUS +NAPHTALINUM +NAPROSYNE +NAPROXENE +NAPUS +NARAMIG +NARATRIPTAN +NARAVELA +NARCAN +NAROPEINE +NASACORT +NASONEX +NASTURTIUM +NATECAL +NATI-K +NATIF +NATISPRAY +NATIVELLE +NATRIXAM +NATRONATUM +NATRUM +NATULAN +NATURALE +NAUSICALM +NAUTAMINE +NAVELBINE +NAVERUCLIF +NAVIDOXINE +NEBCINE +NEBIDO +NEBILOX +NEBIVOLOL +NECYRANE +NEFOPAM +NEGABAN +NEGATIF +NEISVAC +NEITUM +NEMLUVIO +NEO-CODION +NEO-MERCAZOLE +NEOFORDEX +NEORAL +NEORECORMON +NEOSTIGMINE +NEOSYNEPHRINE +NEPETA +NEPEXTO +NEPHROMAG +NEPRESSOL +NEREDIEM +NERF +NERFS +NERISONE +NERIUM +NERVOPAX +NETAXEN +NEULASTA +NEULEPTIL +NEUPOGEN +NEUPRO +NEURACEQ +NEURAXPHARM +NEUROBLOC +NEURODORON +NEUROLITE +NEURONTIN +NEUROSTHENOL +NEUTRAVERA +NEUTROSES +NEVIRAPINE +NEXAVAR +NEXIUM +NEXPLANON +NEXPOVIO +NEXTHALER +NEXVIADYME +NGENLA +NICARDIPINE +NICCOLUM +NICOBION +NICOPASS +NICOPATCHLIB +NICORANDIL +NICORETTE +NICORETTESKIN +NICORETTESPRAY +NICOSAN +NICOTINAMIDE +NICOTINE +NICOTINELL +NIFEDIPINE +NIFEXINE +NIFLUGEL +NIFLURIL +NIGELLA +NIGER +NIGRA +NIGRUM +NILEMDO +NILEVAR +NILOTINIB +NIMBEX +NIMENRIX +NIMOTOP +NINLARO +NIPENT +NIQUITIN +NIQUITINMINIS +NISIS +NISISCO +NITISINONE +NITRATE +NITRENDIPINE +NITRICA +NITRICUM +NITRIDERM +NITRONAL +NITROSUM +NIVAQUINE +NIVESTIM +NOBILIS +NOCERTONE +NODEX +NODOSA +NOISETTE +NOLVADEX +NOMANESIT +NOMEGESTROL +NOOTROPYL +NORADRENALINE +NORCHOLESTEROL +NORDAZ +NORDIMET +NORDITROPINE +NORFLOXACINE +NORGALAX +NORGINE +NORIDEM +NORLEVO +NORMACOL +NORMAFIBE +NORMOSANG +NORPROLAC +NORSET +NORVIR +NOTEZINE +NOUVEAU-NE +NOVANTRONE +NOVATREX +NOVOEIGHT +NOVOFEMME +NOVOLIZER +NOVOMIX +NOVONORM +NOVOPTINE +NOVOPULMON +NOVORAPID +NOVOSEVEN +NOXAFIL +NOXAP +NOXIBEN +NOYADA +NOZINAN +NP100 +NPH +NPLATE +NUBEQA +NUCALA +NUCEIVA +NUCTALON +NUIT +NULOJIX +NUMETAH +NUREFLEX +NUROFEN +NUROFENCAPS +NUROFENFEM +NUROFENFLASH +NUROFENPLAST +NUROFENPRO +NUROFENTABS +NUTANS +NUTRINEAL +NUTRIVISC +NUTROPINAQ +NUTRYELT +NUVARING +NUVAXOVID +NUWIQ +NUX +NYCKTERINIA +NYMPHAEA +NYVEPRIA +NYXOID +N°1 +N°100 +N°103 +N°11 +N°111 +N°113 +N°115 +N°12 +N°122 +N°15 +N°18 +N°20 +N°26 +N°29 +N°39 +N°47 +N°49 +N°5 +N°61 +N°62 +N°64 +N°7 +N°70 +N°75 +N°78 +N°81 +N°83 +N°88 +N°89 +N°9 +N°96 +N°98 +NÉBULISEUR +OBCONICA +OBIZUR +OBODENCE +OBSIDIENNE +OCALIVA +OCCIDENTALE +OCCIDENTALIS +OCIMUM +OCREVUS +OCTAFIX +OCTAGAM +OCTANATE +OCTAPLASLG +OCTAPLEX +OCTIM +OCTREOSCAN +OCTREOTIDE +OCUFEN +ODDIBIL +ODEFSEY +ODOMZO +ODORATA +ODORATISSIMUM +ODRIK +OEDIEN +OENANTHE +OENOTHERA +OESCLIM +OESTRODOSE +OFEV +OFFICINALE +OFFICINALIS +OFFICINARUM +OFLOCET +OFLOXACINE +OGAST +OGASTORO +OGIVRI +OHRE +OKIMUS +OLAMINE +OLAMY +OLANZAPINE +OLEA +OLEANDER +OLERACEA +OLIBANUM +OLIGO-ELEMENTS +OLIGOSOL +OLIGOSTIM +OLIMEL +OLIVENITE +OLMETEC +OLUMIANT +OMACOR +OMEGA +OMEGAVEN +OMEPRAZOLE +OMEXEL +OMEZELIS +OMICRON +OMIX +OMJJARA +OMLYCLO +OMNIPAQUE +OMNITROPE +ONAFLU +ONBREZ +ONCASPAR +ONCOVIN +ONCTOSE +ONDANSETRON +ONGENTYS +ONGLYZA +ONIVYDE +ONONIS +ONOSMODIUM +ONPATTRO +ONTOZRY +ONTRUZANT +ONUREG +ONYCHOSET +ONYTEC +OPALGYNE +OPATANOL +OPDIVO +OPDUALAG +OPFOLDA +OPHTACALM +OPHTACALMFREE +OPHTESIC +OPHTIM +OPIUM +OPOCALCIUM +OPRYMEA +OPTICRON +OPTIDRIL +OPTIJECT +OPTIKINZY +OPTILOVA +OPTIMIZETTE +OPTIQUE +OPTIRAY +OPTRUMA +OPULUS +OPUNTIA +OPZELURA +ORABLOC +ORACILLINE +ORALAIR +ORAMORPH +ORANGE +ORAP +ORAQIX +ORAVERSE +ORAVIR +ORBENINE +ORCHITINUM +ORCHITYN +ORDIPHA +ORELOX +ORENCIA +ORFADIN +ORGALUTRAN +ORGARAN +ORGOVYX +ORIENTALE +ORIENTALIS +ORIGANUM +ORIGINAL +ORKAMBI +ORLADEYO +ORLISTAT +ORNITHOGALUM +OROBUPRE +OROCAL +OROFLUCO +OROKEN +OROMONE +OROZAMUDOL +ORPHACOL +ORPIMENT +ORSERDU +ORTHOSIPHON +ORTIE +ORTIS +ORYLMYTE +OSAFLEXAN +OSCILLOCOCCINUM +OSELTAMIVIR +OSENVELT +OSMOGEL +OSMUNDA +OSPERZO +OSSEINE +OSSOPAN +OSTEOCIS +OSTEOCYNESINE +OSTREARUM +OSVYRTI +OTEZLA +OTIPAX +OTOFA +OTULFI +OTYLOL +OVALEAP +OVARINUM +OVARYN +OVITRELLE +OXACILLINE +OXALICUM +OXALIPLATINE +OXAZEPAM +OXBRYTA +OXCARBAZEPINE +OXEOL +OXINATE +OXLUMO +OXOGLURATE +OXOMEMAZINE +OXSYNIA +OXYACANTHA +OXYBATE +OXYBOLDINE +OXYBUTYNINE +OXYCODONE +OXYCONTIN +OXYDATUM +OXYGENE +OXYGENEE +OXYNORM +OXYNORMORO +OXYNOX +OXYPLASTINE +OXYPRONAL +OXYTHYOL +OXYTOCINE +OYAVAS +OZALIN +OZAWADE +OZEMPIC +OZIDIA +OZURDEX +PABAL +PACILIA +PACLITAXEL +PACLITAXELSANDOZ +PADCEV +PADERYL +PAEONIA +PALEXIA +PALFORZIA +PALIPERIDONE +PALIURUS +PALLADIUM +PALMIER +PALONOSETRON +PALUSTRE +PALUSTRIS +PAMIDRONATE +PANCREINE +PANCRELASE +PANOTILE +PANSORAL +PANTESTONE +PANTOPRAZOLE +PAPAVER +PAPAVERINE +PAPAYA +PARACETAMOL +PARAFFINE +PARAGRIPPE +PARAGUARIENSIS +PARALYOC +PARAPSYLLIUM +PARASYMPATHIQUE +PARATERAX +PARATHYROIDINUM +PARATYPHOIDINUM +PAREIRA +PARIET +PARIETARIA +PARIS +PARKINANE +PARLODEL +PAROCLINE +PAROEX +PAROTIDINUM +PAROXETINE +PARSABIV +PASSAGERE +PASSEDYL +PASSIFLORA +PASSIFLORE +PASSIFLORINE +PASTEUR +PATENTE +PATES +PATIENTIA +PAVBLU +PAXELADINE +PAXLOVID +PAZENIR +PAZOPANIB +PD4 +PEAU +PECFENT +PECTINATA +PECTORALES +PEDEA +PEDIATRIQUE +PEDIAVEN +PEGASYS +PEGYLATED +PELARGONIUM +PELGRAZ +PELLEGRINO +PELMEG +PELTATUM +PEMAZYRE +PEMETREXED +PENDULUM +PENFILL +PENICILLINE +PENICILLINUM +PENICILLIUM +PENTACARINAT +PENTAMIDINE +PENTASA +PENTAVAC +PENTETATE +PENTHROX +PENTOXIFYLLINE +PENTOXYVERINE +PEPO +PEPSANE +PERCUTAFEINE +PERDRIGEON +PERENNIS +PERFALGAN +PERFANE +PERFOLIATUM +PERFORATUM +PERGOVERIS +PERIACTINE +PERIKABIVEN +PERINDOPRIL +PERINUTRIFLEX +PERIOLIMEL +PERISOC +PERJETA +PERLEANE +PERMIXON +PERNAZENE +PEROXYDE +PERPRUP +PERSANTINE +PERTUDORON +PERUBORE +PERUVIANUM +PETASITES +PETROLEUM +PETROSELINUM +PEVARYL +PEVISONE +PHAPAX +PHARLON +PHARMACEUTICAL +PHARMACIE +PHARMATEX +PHARMY +PHASEOLUS +PHEBURANE +PHELINUN +PHELLANDRIUM +PHENERGAN +PHENIRAMINE +PHENOBARBITAL +PHENOBARBITALUM +PHENOLE +PHENYLEPHRINE +PHESGO +PHIZOE +PHLEUM +PHLOROGLUCINOL +PHOCYTAN +PHOLCODINE +PHOLCONES +PHOS +PHOSPHALUGEL +PHOSPHAS +PHOSPHATE +PHOSPHONEUROS +PHOSPHORE +PHOSPHORICA +PHOSPHORICUM +PHOSPHORUS +PHOSPHOSORB +PHOXILIUM +PHYSALIS +PHYSIOGINE +PHYSIOLOGIQUE +PHYSIOMYCINE +PHYSIONEAL +PHYSIOTENS +PHYSOSTIGMA +PHYTOCLARIX +PHYTOLACCA +PHYTOTUX +PIASCLEDINE +PICOPREP +PICOSULFATE +PICRATA +PICRICUM +PIERRE +PIFELTRO +PILOCARPINE +PILULIFERA +PIMPINELLA +PINAVERIUM +PINUS +PIPER +PIPERACILLINE +PIPERITA +PIPORTIL +PIQRAY +PIRACETAM +PIRAMAL +PIRFENIDONE +PIRFÉNIDONE +PIRILENE +PIROXICAM +PIVALONE +PIX +PIXCYCLIC +PIXUVRI +PLACENTINE +PLACYNOX +PLAGES +PLANIFOLIA +PLANTA +PLANTAGO +PLANTAIN +PLAQUENIL +PLASMALYTE +PLASMION +PLATANUS +PLATINA +PLAVIX +PLEGISOL +PLEGRIDY +PLENVU +PLERIXAFOR +PLEXUS +PLITICAN +PLUMBUM +PLUREXID +PLUVICTO +PNEUMOCOCCIQUE +PNEUMOVAX +PODHALER +PODOPHYLLINUM +PODOPHYLLUM +POLARAMINE +POLERY +POLIO +POLLEN +POLLENS +POLPHARMA +POLY-KARAYA +POLYCEPHALUM +POLYDEXA +POLYGONUM +POLYGYNAX +POLYIONIQUE +POLYOSIDIQUE +POLYSILANE +POLYSTYRENE +POLYVITAMINE +POMALIDOMIDE +POMBILITI +PONAXEM +PONSTYL +PONVORY +POPULUS +POSACONAZOLE +POSITIF +POTASSIUM +POTELIGEO +POTHOS +POUMON +POURPRE +POVIDONE +PRADAXA +PRALUENT +PRAMIPEXOLE +PRAMOCAINE +PRASUGREL +PRATENSE +PRAVASTATINE +PRAXBIND +PRAZEPAM +PREDESIC +PREDNISOLONE +PREDNISONE +PREGABALINE +PRELINIUM +PREMATURES +PREMINOR +PRENOXAD +PREP +PREPARATIONS +PREPIDIL +PRES +PRESTOLE +PRET +PRETERAX +PRETERVAL +PREVENAR +PREVISCAN +PREVYMIS +PREXATE +PREXIDINE +PREZISTA +PRIALT +PRICK +PRILIGY +PRILOCAINE +PRILOCAÏNE +PRIMACAINE +PRIMALAN +PRIMAQUINE +PRIMENE +PRIMOVIST +PRIMPERAN +PRIMULA +PRINCI +PRIORIX +PRISMASOL +PRITOR +PRITORPLUS +PRIVIGEN +PROAMP +PROCAINE +PROCORALAN +PROCUTA +PROCYSBI +PRODASONE +PRODILAB +PRODILANTIN +PRODINAN +PRODUCTS +PROFEMIGR +PROFENID +PROFIL +PROGESTAN +PROGESTERONE +PROGESTERONUM +PROGESTOGEL +PROGIRON +PROGLICEM +PROGRAF +PROGUANIL +PROGYNOVA +PROHANCE +PROKINYL +PROLASTIN +PROLEUKIN +PROLIA +PROLONGEE +PROMETHAZINE +PRONTADOL +PRONTALGINE +PROPAFENONE +PROPECIA +PROPESS +PROPIONATE +PROPOFOL +PROPRANOLOL +PROPYLEX +PRORHINEL +PROSOFT +PROSPAN +PROSTATE +PROSTATEP +PROSTIGMINE +PROSTINE +PROTAMINE +PROTECT +PROTEINE +PROTEUS +PROTEXEL +PROTHIADEN +PROTO-IODATUS +PROTOPIC +PROTOXYDE +PROVAMES +PROVEBLUE +PROVENCALE +PROVEPHARM +PROVERA +PROVINGO +PROZAC +PRUNE +PRUNIFOLIUM +PRUNUS +PRURIENS +PRÉ-REMPLI +PRÉREMPLIE +PRÉREMPLIE.VACCIN +PRÉS +PSEUDO-ACACIA +PSEUDOEPHEDRINE +PSYLIA +PSYLLIUM +PTELEA +PUBESCENS +PULMICORT +PULMINE +PULMOCIS +PULMODEXANE +PULMOFLUIDE +PULMONARIA +PULMOSERUM +PULMOTEC +PULMOZYME +PULSATILLA +PULVÉRISATION +PUMPCART +PUNICA +PUR +PUREGON +PURIFIEE +PURINETHOL +PURIVIST +PURPUREA +PURPUREUM +PURSENNIDE +PUTORIUS +PUTRESCINUM +PYLCLARI +PYLERA +PYOSTACINE +PYP +PYRALVEX +PYRETHRUM +PYRIDOSTIGMINE +PYRIDOXINE +PYRITE +PYROGENIUM +PYROLUSITE +PYZCHIVA +QARZIBA +QDENGA +QIADE +QILU +QINLOCK +QLAIRA +QUADRAMET +QUADRASA +QUADRATIQUE +QUADRIFOLIA +QUARTZ +QUASYM +QUERCUS +QUESTRAN +QUETIAPINE +QUIETUDE +QUILOGA +QUINAPRIL +QUINIMAX +QUININE +QUINOFREE +QUINQUEFOLIA +QUINZE +QUITAXON +QUIVER +QUOFENIX +QUOTANE +QUTENZA +QUVIVIQ +QVAR +QVARSPRAY +RABEPRAZOLE +RABIPUR +RABIQUE +RACECADOTRIL +RACEMOSA +RACEMOSUS +RACHIANESTHESIE +RADELUMIN +RADIOGARDASE +RADIOSELECTAN +RADIUM +RADIX +RAGE +RALOXIFENE +RALTEGRAVIR +RAMET +RAMIPRIL +RANA +RANEXA +RANIVISIO +RANUNCULOIDES +RANUNCULUS +RAPAMUNE +RAPHANUS +RAPIBLOC +RAPIDE +RAPIFEN +RAPIHALER +RAPISCAN +RASAGILINE +RATANHIA +RATIOGRASTIM +RAUWOLFIA +RAVICTI +RAXONE +REACTINE +REANUTRIFLEX +REBETOL +REBIF +REBLOZYL +RECARBRIO +RECHOLAN +RECIVIT +RECORDATI +RECOSTIM +RECTOGESIC +RECTOPANBILINE +RECTOQUOTANE +REDDY +REDI +REF +REFACTO +REFLOXAR +REFLUX +REFRESH +REGALIS +REGIA +REGIOCIT +REGLISSE +REIG +REIN +REINE +REKAMBYS +REKOVELLE +RELFYDESS +RELIGIOSA +RELISTOR +RELPAX +RELVAR +REMICADE +REMIFENTANIL +REMINYL +REMODULIN +REMSIMA +RENAGEL +RENINE +RENITEC +RENNAXT +RENNIE +RENNIELIQUO +RENOCIS +RENVELA +REPAGLINIDE +REPARIL +REPATHA +REPENS +REPEVAX +REPLAGAL +REQUIP +RESCUEFLOW +RESELIP +RESIDUUM +RESIKALI +RESINIFERA +RESITUNE +RESOLOR +RESPIHALER +RESPIMAT +RESPREEZA +RESTORVOL +RESTRICAL +RETACNYL +RETACRIT +RETARD +RETROVIR +RETSEVMO +REUNION +REVATIO +REVAXIS +REVERPLEG +REVESTIVE +REVINTY +REVITALOSE +REVLIMID +REVOLADE +REXORUBIA +REYATAZ +REZDIFFRA +REZZAYO +RHAMNUS +RHENIUM +RHEOFLUX +RHINADVIL +RHINADVILCAPS +RHINALLERGY +RHINEA +RHINEDRINE +RHINITE +RHINO +RHINO-PHARYNGEE +RHINOCORT +RHINOFEBRAL +RHINOFLUIMUCIL +RHINOMAXIL +RHINOTROPHYL +RHODODENDRON +RHODONITE +RHOEAS +RHONE +RHOPHYLAC +RHUBARBE +RHUMAGRIP +RHUME +RHUS +RIAMET +RIASTAP +RIBAVIRINE +RIBES +RICHARD +RICINUS +RIEMSER +RIFADINE +RIFAMYCINE +RIFATER +RIFINAH +RILMENIDINE +RILUTEK +RILUZOLE +RIMACTAN +RIMIFON +RIMMYRAH +RINGER +RINOCLENIL +RINVOQ +RISEDRONATE +RISORDAN +RISPERDAL +RISPERDALCONSTA +RISPERIDONE +RITALINE +RITONAVIR +RIVAROXABAN +RIVASTIGMINE +RIVOTRIL +RIXATHON +RIXUBIS +RIZATRIPTAN +RIZMOIC +ROACCUTANE +ROACTEMRA +ROBERTIANUM +ROBINIA +ROCALTROL +ROCEPHINE +ROCGEL +ROCLANDA +ROCURONIUM +RODOGYL +RODULOS +ROPINIROLE +ROPIVACAINE +ROPIVACAÏNE +ROSA +ROSAT +ROSE +ROSMARINUS +ROSUVASTATINE +ROTARIX +ROTATEQ +ROTOP +ROTOP-NANOHSA +ROUGE +ROUGEOLEUX +ROUGES +ROUSSEL +ROVALCYTE +ROVAMYCINE +ROWASA +ROXITHROMYCINE +ROZACREME +ROZAGEL +ROZEX +RUBENS +RUBIA +RUBOZINC +RUBRA +RUBRACA +RUBRUM +RUCONEST +RUFA +RUKOBIA +RULID +RUMEX +RUPATADINE +RUSCUS +RUTA +RUXIENCE +RYALTRIS +RYBREVANT +RYDAPT +RYEQO +RYLIGENCY +RYSTIGGO +RYTHMODAN +RYTHMOL +RÉCIPIENT +S.E.R.B +S.O.L +SABADILLA +SABAL +SABINA +SABRIL +SACCHAROIDE +SACCHARUM +SACREES +SAGRADA +SAINT +SAINT-BERNARD +SAIZEN +SALAGEN +SALAZOPYRINE +SALBUMOL +SALBUTAMOL +SALFLUAIR +SALICAIRINE +SALICARIA +SALICYLICUM +SALIX +SALMESON +SALMETEROL +SALVACYL +SALVIA +SAMBUCUS +SAN +SANDIMMUN +SANDOSTATINE +SANGUINARIA +SANGUINARINA +SANICULA +SANMIGRAN +SANTAHERBA +SANTAMED +SANTE +SANTURIL +SAPHNELO +SAPONARIA +SAPROPTERINE +SARCLISA +SARCOLACTICUM +SARGENOR +SARSAPARILLA +SATIVA +SATIVUM +SATIVUS +SAULE +SAVENE +SAWIS +SAXAGLIPTINE +SAXENDA +SAXIFRAGA +SCANDONEST +SCANNER +SCELERATUS +SCEMBLIX +SCHWABE +SCIATIQUE +SCILLA +SCINTIMUN +SCLEREMO +SCLEROCALCINE +SCOBUREN +SCOLYMUS +SCOPARIA +SCOPODERM +SCOPOLAMINE +SCORODITE +SCORODONIA +SCROFULARIA +SCRUB +SCUTELLARIA +SCYOVA +SEACROSS +SEASONIQUE +SEBIFERA +SEBIPROX +SECALE +SECHE +SECNOL +SECTRAL +SEDACOLLYRE +SEDATIF +SEDERMYL +SEDINAX +SEDORRHOIDE +SEDUM +SEEBRI +SEGUINUM +SELENIUM +SELEXID +SELGINE +SELINCRO +SELOKEN +SELOZOK +SELTZER +SEMGLEE +SEMI-PROLONGEE +SEMPERVIRENS +SEMPERVIVUM +SENAJOR +SENEGA +SENNA +SENOPHILE +SENSIVISION +SEPIA +SEPTANEST +SEPTEAL +SEPTEM +SEPTIVON +SEPTOMIXINE +SEQUOIA +SERB +SERC +SERECOR +SEREPROSTA +SERESTA +SERETIDE +SEREVENT +SEROPLEX +SEROPRAM +SEROTONINUM +SERPENTINA +SERPYLLUM +SERRULATA +SERTACONAZOLE +SERTRALINE +SERUM +SESTAMIBI +SETOFILM +SEVAMEO +SEVE +SEVELAMER +SEVIKAR +SEVOFLURANE +SEVORANE +SEVREDOL +SFDB +SHINGRIX +SIALANAR +SIBELIUM +SIBNAYAL +SICCAFLUID +SICCUM +SIDEREUM +SIEGESBECKIA +SIFROL +SIGNIFOR +SIKLOS +SILANDYLTEC +SILDENAFIL +SILICEA +SILICICA +SILICICUM +SILIGAZ +SILKIS +SILODOSINE +SILODYX +SILVATICA +SIMBRINZA +SIMPLE +SIMPONI +SIMULECT +SIMVASTATINE +SINAPIS +SINEMET +SINETRAV +SINGULAIR +SINTROM +SINUFIX +SINUPHYL +SINUSALE +SINUSPAX +SIROCTID +SIRTURO +SITAGLIPTINE +SIVEXTRO +SIXMO +SKENAN +SKIACOL +SKINOREN +SKUDEXUM +SKYCLARYS +SKYRIZI +SLENYTO +SLINDA +SMECTA +SMECTALIA +SMOFKABIVEN +SMOFLIPID +SODIQUE +SODIUM +SOFTACORT +SOGAL +SOGIG +SOGROYA +SOJOURN +SOL +SOLACY +SOLAIRE +SOLANUM +SOLARAZE +SOLIAN +SOLIDAGO +SOLIFENACINE +SOLIRIS +SOLOSTAR +SOLU-MEDROL +SOLUBILIS +SOLUBLE +SOLUDACTONE +SOLUMEDROL +SOLUPRED +SOLUPRICK +SOLUTE +SOLUTRICINE +SOLUVIT +SOMAKIT +SOMATOSTATINE +SOMATULINE +SOMAVERT +SOMNIDORON +SONDELBAY +SONOVUE +SOOLANTRA +SOPHIDONE +SORAFENIB +SORBITOL +SORIATANE +SOTALEX +SOTALOL +SOTYKTU +SOUFRE +SOURY +SOVALDI +SPACYR +SPAGULAX +SPANOR +SPASFON +SPASMAG +SPASMINE +SPASMOCALM +SPECIAFOLDINE +SPECIAL +SPECTRILA +SPEDIFEN +SPEDRA +SPEVIGO +SPEXOTRAS +SPEYWOOD +SPHONDYLIUM +SPICATA +SPIFEN +SPIGELIA +SPIKEVAX +SPINDLER +SPINOSA +SPINRAZA +SPIOLTO +SPIRAEA +SPIRAMYCINE +SPIRITUS +SPIRIVA +SPIROLEPT +SPIROMAX +SPIRONOLACTONE +SPLENINE +SPLENOCARBINE +SPONGIA +SPORANOX +SPORTENINE +SPOTOF +SPP +SPRAVATO +SPRYCEL +SQ-BET +SQ-HDM +SQ-T +STABILISE +STABILISEE +STABLON +STADA +STAGID +STALEVO +STAMARIL +STAMICIS +STAMINEUS +STANNEUX +STANNUM +STAPHYLOCOCCINUM +STAPHYLOTOXINUM +STAPHYSAGRIA +STELARA +STELLATUM +STEOVESS +STEQEYMA +STERDEX +STERIDOSE +STERILE +STERILENE +STERILISEE +STERILLIUM +STEROGYL +STIBINE +STICTA +STILLINGIA +STILNOX +STIMOL +STIMU +STIMU-ACTH +STIMUFEND +STIVARGA +STOBOCLO +STODAL +STODALINE +STORINYL +STRAGEN +STRAMONIUM +STREFEN +STRENSIQ +STREPSILS +STREPSILSPRAY +STREPTOCOCCINUM +STREPTOMYCINUM +STRESAM +STRESSDORON +STRIADYNE +STRIASCAN +STRIBILD +STRIE +STRIVERDI +STROMECTOL +STRONTIUM +STROPHANTHUS +STRUCTOCAL +STRUCTOFLEX +STRUCTUM +STRYCHNINUM +SUBOXONE +SUBSOL +SUBUTEX +SUCCICAPTAL +SUCCINICUM +SUCRE +SUFENTA +SUFENTANIL +SUGAMMADEX +SUI +SULFARLEM +SULFATE +SULFONATE +SULFUR +SULFURATUM +SULFURE +SULFURICA +SULFURICUM +SULFURIS +SULFURYL +SULPIRIDE +SUMATRIPTAN +SUMBUL +SUNITINIB +SUNLENCA +SUNOSI +SUPPLIVEN +SUPPOSITOIRES +SUPRANE +SURACTIVE +SURBRONC +SURFACE +SURGAM +SURMONTIL +SURRENAL +SURRENINE +SUSTIVA +SUTENT +SUVREZA +SUXAMETHONIUM +SYLVANT +SYLVATICA +SYLVESTRIS +SYMBICORT +SYMKEVI +SYMPATHIQUE +SYMPATHYL +SYMPHORICARPUS +SYMPHYTUM +SYNACTHENE +SYNAGIS +SYNALAR +SYNAREL +SYNAZE +SYNJARDY +SYNTHOL +SYNTOCINON +T.R.E +T.S.H +TABACUM +TACHOSIL +TADALAFIL +TADENAN +TADIM +TAFINLAR +TAGRISSO +TAHOR +TAKADOL +TAKHZYRO +TAKROZEM +TALMANCO +TALOXA +TALTZ +TALZENNA +TAMIFLU +TAMOXIFENE +TAMPONNE +TAMPONNEE +TAMRISA +TAMSULOSINE +TANACETUM +TANAKAN +TANGANIL +TANGANILPRO +TANOREN +TARAXACUM +TARCEVA +TARDYFERON +TAREG +TARENTULA +TARGOCID +TARGRETIN +TARKA +TARTARICUM +TARTRATE +TASIGNA +TASMAR +TAUMEA +TAVANIC +TAVLESSE +TAVNEOS +TAW +TAXOTERE +TAXUS +TAZOBACTAM +TAZOCILLINE +TCAPS +TECARTUS +TECENTRIQ +TECEOS +TECFIDERA +TECHNESCAN +TECTORUM +TECVAYLI +TEDRALAN +TEGELINE +TEGLUTIK +TEGRETOL +TEGSEDI +TEICOPLANINE +TEINTURE +TEKCIS +TEKTROTYD +TELEBRIX +TELFAST +TELLURIUM +TELMISARTAN +TELZIR +TEMERIT +TEMERITDUO +TEMESTA +TEMGESIC +TEMODAL +TEMOZOLOMIDE +TEMULENTUM +TENAX +TENDON +TENKASI +TENOFOVIR +TENORETIC +TENORMINE +TENSIONORME +TEPADINA +TEPEZZA +TEPKINLY +TERALITHE +TERAZOSINE +TERBINAFINE +TERBUTALINE +TERCIAN +TEREBINTHINA +TEREBYO +TERGYNAN +TERIFLUNOMIDE +TERIPARATIDE +TERLIPRESSINE +TERLOMEXIN +TERPINE +TERPONE +TERROSA +TERT-BUTYLAMINE +TEST +TESTAVAN +TESTOSTERONE +TETMODIS +TETRA +TETRACAINE +TETRACAÏNE +TETRALYSAL +TETRAVAC-ACELLULAIRE +TEUCRIUM +TEVAGRASTIM +TEZSPIRE +THAIS +THAISSEPT +THALAMUS +THALICTROIDES +THALIDOMIDE +THALLIUM +THAPSUS +THEA +THERACAP131 +THERALENE +THERAMEX +THERAPIE +THERASOLV +THERICA +THERIDION +THIOCOLCHICOSIDE +THIOPENTAL +THIOSINAMINUM +THIOTEPA +THIOVALONE +THORACALES +THUYA +THYMOGLOBULINE +THYMULINE +THYMUS +THYMUSINE +THYROFIX +THYROGEN +THYROIDEA +THYROZOL +TIADILON +TIANEPTINE +TIAPRIDAL +TIAPRIDE +TIAPROFENIQUE +TIBER +TIBERAL +TIBOLONE +TIBSOVO +TICAGRELOR +TICLOPIDINE +TICOVAC +TIENAM +TIGECYCLINE +TIGLIUM +TIGREAT +TIGRINUM +TILCOTIL +TILDIEM +TILIA +TILLOMED +TIMABAK +TIMACOR +TIMIFIT +TIMOFEROL +TIMOLOL +TIMOPTOL +TINCTORIA +TIORFAN +TIORFANOR +TIORFAST +TIOTROPIUM +TIPUREX +TIROFIBAN +TISANE +TISSEEL +TISSU +TISSUGEL +TITANOREINE +TIVICAY +TIXOCORTOL +TIXTAR +TOBI +TOBRABACT +TOBRADEX +TOBRAMYCINE +TOBREX +TOC +TOCO +TOCOLION +TOCTINO +TODEXAL +TOFRANIL +TOLAK +TOLEXINE +TOLVAPTAN +TOMENTOSA +TOMUDEX +TOPALGIC +TOPIRAMATE +TOPISCAB +TOPLEXIL +TOPOTECAN +TOPOTECANE +TOPREC +TORISEL +TORVA +TOSILATE +TOSTA +TOT'HEMA +TOTA +TOUJEO +TOURMALINE +TOUT +TOUX +TOVIAZ +TOWA +TOXICARB +TOXICODENDRON +TRABECTEDINE +TRACHYTE +TRACLEER +TRACRIUM +TRACTOCILE +TRACUTIL +TRAMADOL +TRANDATE +TRANDOLAPRIL +TRANEXAMIQUE +TRANQUITAL +TRANSACALM +TRANSCUTANEE +TRANSILANE +TRANSIPEG +TRANSIPEGLIB +TRANSLARNA +TRANSULOSE +TRANSVERCID +TRANXENE +TRASYLOL +TRAVATAN +TRAVOPROST +TRAZIMERA +TRECONDI +TRELEGY +TREMFYA +TREMULA +TREPOSUVI +TREPROSTINIL +TRESIBA +TREVICTA +TRH +TRIACEFAN +TRIAFEMI +TRIAMCINOLONE +TRIATEC +TRICOLOR +TRIDESONIT +TRIENTINE +TRIFLUCAN +TRIFOLIATA +TRIFOLIUM +TRIHEXY +TRIIODATUS +TRILEPTAL +TRILLIUM +TRILOBA +TRIMBOW +TRIMEBUTINE +TRIMETAZIDINE +TRIMETHYLPHLOROGLUCINOL +TRINARA +TRINIPATCH +TRINITRINE +TRINORDIOL +TRIOXIDE +TRIOXYDE +TRIPHYLLUM +TRIPLIXAM +TRIPUDIANS +TRISENOX +TRISEQUENS +TRITICUM +TRIUMEQ +TRIVALENT +TRIVASTAL +TRIVERAM +TRIXEO +TRIZIVIR +TRODELVY +TROLAMINE +TROLISE +TROLOVOL +TROMBOVAR +TRONOTHANE +TROPAEOLUM +TROPHICREME +TROPHIGIL +TROSPIPHARM +TROSPIUM +TROSYD +TROXERUTINE +TRUE +TRULICITY +TRUMENBA +TRUSOPT +TRUVADA +TRUXIMA +TSOLUDOSE +TTS +TUBERCULINUM +TUBEROSA +TUBEROSUM +TUBERTEST +TUKYSA +TULLE +TURBUHALER +TUSSIDANE +TUSSILAGO +TUSSIPAX +TUSSISEDAL +TWICOR +TWINRIX +TWISTHALER +TWYNSTA +TYAVAX +TYENNE +TYGACIL +TYPHIM +TYRUKO +TYSABRI +TYVERB +U.A.H +U.CEIP +U.I +U.L +UBISTESIN +UCEDANE +UIK +ULCAR +ULEXITE +ULIPRISTAL +ULMARIA +ULMUS +ULTARCORLENE +ULTIBRO +ULTIVA +ULTOMIRIS +ULTRA-FLUIDE +ULTRA-LEVURE +ULTRAPROCT +ULTRATECHNEKOW +ULTRAVIST +UMATROPE +UMBELLATA +UMBELLATUM +UMULINE +UN-ALFA +UNACIM +UNEDO +UNIFLOX +UNIFLUID +UNILARM +UNIMEDIC +UNIPEXIL +UNITES +UNITÉS +UNIVAGIL +UPFEN +UPJOHN +UPLIZNA +UPSA +UPSTAZA +UPTRAVI +URANIUM +URAPIDIL +URARTHONE +URBANUM +URBANYL +UREE +URENS +URGO +URICUM +URINAIRE +URISPAS +UROMITEXAN +UROREC +URSI +URSINUM +URSODESOXYCHOLIQUE +URSOLVAN +URTICA +USITATISSIMUM +USNEA +UTERINE +UTROGESTAN +UVA +UVADEX +UVECAPS +UVEDOSE +UVESTEROL +UVIMAG +UZPRUVO +V.A.B +VABLYS +VABOREM +VABYSMO +VACCIN +VACCINOTOXINUM +VAGIRUX +VALACICLOVIR +VALDOXAN +VALEFLOR +VALERIANA +VALERIANE +VALERIANICUM +VALGANCICLOVIR +VALIUM +VALNEVA +VALPROATE +VALS +VALSARTAN +VAMINOLACT +VANADIUM +VANCOMYCINE +VANFLYTA +VANILLA +VANIQA +VANTIVE +VAPORUB +VAQTA +VARDENAFIL +VARESOL +VARILRIX +VARIVAX +VARNOLINE +VASCULOCIS +VASELINE +VASOCONSTRICTEUR +VASTAREL +VASTEN +VAXCHORA +VAXELIS +VAXIGRIP +VAXIGRIPTETRA +VAXNEUVANCE +VAXZEVRIA +VECALMYS +VECTARION +VECTEUR +VECTIBIX +VEDROP +VEGETABILIS +VEGETAL +VEGETOSERUM +VEGZELMA +VEINAMITOL +VEINE +VEKLURY +VELBE +VELCADE +VELETRI +VELITEN +VELMETIA +VELOTAB +VELPHORO +VELSIPITY +VELTASSA +VENACLAR +VENCLYXTO +VENENOSUM +VENIN +VENIPHARM +VENLAFAXINE +VENOFER +VENTAVIS +VENTILASTIN +VENTIZOLVE +VENTOLINE +VENUS +VEOPLORE +VEOZA +VERA +VERAPAMIL +VERASEAL +VERATRAN +VERATRUM +VERBASCUM +VERCYTE +VERKAZIA +VERNALIS +VERNIX +VERONICA +VERRUCIDE +VERRUFILM +VERRULIA +VERSATIS +VERSICOLOR +VERT +VERTE +VERTEBRA +VERTEBRAL +VERTEBRAUX +VERTEBRES +VERZENIOS +VESANOID +VESCA +VESICARE +VESICULE +VESICULOSUS +VESPA +VESPULA +VESSIE +VEYRON +VEYVONDI +VFEND +VIABORPAX +VIAFLO +VIAGRA +VIALEBEX +VIBRAVEINEUSE +VIBURNUM +VICKS +VICTAN +VICTOZA +VIDAZA +VIDPREVTYN +VIGNE +VILDAGLIPTINE +VILLOSA +VIMIZIM +VIMKUNYA +VIMPAT +VINCA +VINCETOXICUM +VINCRISTINE +VINIFERA +VINORELBINE +VINTENE +VIOLA +VIPERA +VIPERFAV +VIRAMUNE +VIREAD +VIRGA +VIRGAN +VIRGINIANA +VIRGINICUM +VIRGO +VIRIDE +VIRIDIS +VIROPHTA +VIROSA +VIRPAX +VISANNE +VISCUM +VISIPAQUE +VISKEN +VISNAGA +VISQUEUSE +VISTABEL +VISUDYNE +VITABACT +VITALBA +VITALIPIDE +VITALOGINK +VITAMINE +VITAMINEE +VITAROS +VITASCORBOL +VITIS +VITRAKVI +VIVANTA +VIVELLEDOT +VIVIANITE +VIVOTIF +VIVUS +VIZAMYL +VIZARSIN +VIZILATAN +VIZITRAV +VJ-PHARM +VOCABRIA +VOCADYS +VOGALENE +VOGALIB +VOLIBRIS +VOLTARENACTIGO +VOLTARENE +VOLTARENOPHTA +VOLTARENOPHTABAK +VOLTARENPLAST +VOLTARENSPE +VOLUMES +VOLUVEN +VOMICA +VONCENTO +VOQUILY +VORANIGO +VORAXAZE +VORICONAZOLE +VOSEVI +VOTRIENT +VOTUBIA +VOXPAX +VOXZOGO +VOYDEYA +VPRIV +VUAB +VUEWAY +VULGARE +VULGARIS +VUMERITY +VYDURA +VYEPTI +VYJUVEK +VYLOY +VYNDAQEL +VYVGART +VYXEOS +W146 +W149 +W164 +W169 +W171 +W221 +W244 +W253 +W270 +W278 +W282 +W301 +W306 +W313 +W314 +W329 +W344 +W350 +W358 +W366 +W374 +W390 +W410 +W418 +W434 +W436 +W462 +W464 +W472 +W518 +W524 +W538 +W580 +W582 +W584 +W586 +W616 +W642 +W721 +W724 +W746 +W770 +W771 +W776 +W788 +W796 +W858 +W876 +W882 +W904 +W926 +W932 +W962 +W964 +WAKIX +WAYLIVRA +WAYMADE +WEGOVY +WELEDA +WELIREG +WELLVONE +WEZENLA +WILFACTIN +WILSTART +WILZIN +WINREVAIR +WINTERI +WYOST +WYSTAMM +X.O +XADAGO +XAGRID +XALACOM +XALATAN +XALKORI +XALUPRINE +XAMIOL +XANAX +XARELTO +XATRAL +XBB.1.5 +XBRYK +XELEVIA +XELJANZ +XELLIA +XELODA +XEMBIFY +XENAZINE +XENETIX +XENICAL +XENPOZYME +XEOMIN +XEPLION +XERAVA +XEROQUEL +XEVUDY +XGEVA +XIGDUO +XILMAC +XIMEPEG +XIMLUCI +XIOP +XOFIGO +XOGEL +XOLAAM +XOLAIR +XONVEA +XOSPATA +XTANDI +XULTOPHY +XURTA +XUVENIOL +XYBILUN +XYDALBA +XYLLOMAC +XYLOCAINE +XYLOCARD +XYLOCONTACT +XYLONOR +XYLOROLLAND +XYREM +XYZALL +YARGESA +YAZ +YDRALBUM +YELLOX +YERBALAXA +YERSIN +YERVOY +YESCARTA +YESINTEK +YOCORAL +YONDELIS +YORVIPATH +YTRACIS +YTTRIGA +YUCCA +YUFLYMA +ZADITEN +ZAGRAPA +ZALASTA +ZALDIAR +ZALERG +ZALERGONIUM +ZALTRAP +ZALVISO +ZAMELINE +ZAMUDOL +ZANEA +ZANEXTRA +ZANIDIP +ZANOSAR +ZARONTIN +ZARZIO +ZAVEDOS +ZAVESCA +ZAVICEFTA +ZEA +ZEBINIX +ZECLAR +ZEFFIX +ZEJULA +ZELACEO +ZELBORAF +ZELFUSOR +ZELITREX +ZENALIA +ZENTEL +ZEPATIER +ZERBAXA +ZERCEPAC +ZESSLY +ZESTORETIC +ZESTRIL +ZEULIDE +ZEYLANICUM +ZIAGEN +ZIDOVUDINE +ZIEXTENZO +ZIIHERA +ZILBRYSQ +ZIMINO +ZINC +ZINC-CUIVRE +ZINC-NICKEL-COBALT +ZINCUM +ZINDACLINE +ZINFORO +ZINGIBER +ZINNAT +ZINPLAVA +ZIRABEV +ZITHROMAX +ZIZIA +ZOCOR +ZOELY +ZOFENIL +ZOFENILDUO +ZOFENOPRIL +ZOFORA +ZOKINVY +ZOLADEX +ZOLEDRONIQUE +ZOLGENSMA +ZOLMITRIPTAN +ZOLOFT +ZOLPIDEM +ZOLSKETIL +ZOLTUM +ZOMACTON +ZOMETA +ZOMIG +ZOMIGORO +ZONDAR +ZONEGRAN +ZONISAMIDE +ZOPHREN +ZOPICLONE +ZORYON +ZOSTAVAX +ZOVIRAX +ZUBSOLV +ZUMALGIC +ZUTECTRA +ZYBAN +ZYCLARA +ZYDELIG +ZYKADIA +ZYLORIC +ZYMAD +ZYMADUO +ZYMAFLUOR +ZYPADHERA +ZYPREXA +ZYRTEC +ZYRTECSET +ZYTIGA +ZYVOXID diff --git a/eds_pseudo_manager.py b/eds_pseudo_manager.py index 6bbbdda..87cd354 100644 --- a/eds_pseudo_manager.py +++ b/eds_pseudo_manager.py @@ -64,6 +64,12 @@ class EdsPseudoManager: self._nlp = edsnlp.load(path) else: self._nlp = edsnlp.load(model_id_or_path) + # Activer les scores de confiance NER (edsnlp >= 0.16) + try: + ner_pipe = self._nlp.get_pipe('ner') + ner_pipe.compute_confidence_score = True + except Exception: + pass # versions plus anciennes sans support confiance self._loaded = True def unload(self) -> None: @@ -100,12 +106,15 @@ class EdsPseudoManager: mapped = EDS_LABEL_MAP.get(label, None) if mapped is None: continue + # Score de confiance réel si disponible (edsnlp >= 0.16) + raw_score = getattr(ent._, 'ner_confidence_score', None) + conf = raw_score if isinstance(raw_score, float) else 1.0 ents.append({ "entity_group": label, "word": ent.text, "start": ent.start_char, "end": ent.end_char, - "score": 1.0, # edsnlp ne fournit pas de score de confiance + "score": conf, "eds_mapped_key": mapped, }) out.append(ents) diff --git a/gliner_manager.py b/gliner_manager.py new file mode 100644 index 0000000..bd52dae --- /dev/null +++ b/gliner_manager.py @@ -0,0 +1,180 @@ +#!/usr/bin/env python3 +# -*- coding: utf-8 -*- +""" +GLiNER Manager — NER zero-shot pour validation croisée des entités. +------------------------------------------------------------------- +Utilise GLiNER (< 500M params, CPU) comme 3e signal NER en vote majoritaire +avec CamemBERT ONNX + EDS-Pseudo. Réduit les faux positifs : une entité +flaggée par 1 seul modèle sur 3 est supprimée. + +Modèle : urchade/gliner_multi_pii-v1 (1.1 GB, ~95ms/inférence CPU) +Version compatible : gliner==0.2.18 (pas plus récent, casse optimum-onnx) +""" +from __future__ import annotations + +import logging +from typing import Any, Dict, List, Optional + +log = logging.getLogger(__name__) + +try: + from gliner import GLiNER + _GLINER_AVAILABLE = True +except ImportError: + GLiNER = None # type: ignore + _GLINER_AVAILABLE = False + +# Labels zero-shot pour la détection PII en contexte clinique français +GLINER_PII_LABELS = [ + "person_name", + "date_of_birth", + "phone_number", + "email_address", + "social_security_number", + "postal_address", + "hospital", + "city", +] + +# Labels pour identifier les termes médicaux (anti-PII : si classé ici → pas un nom) +GLINER_SAFE_LABELS = [ + "medication", + "medical_condition", + "medical_procedure", +] + +# Mapping GLiNER label → clé PLACEHOLDERS +GLINER_LABEL_MAP: Dict[str, str] = { + "person_name": "NOM", + "date_of_birth": "DATE_NAISSANCE", + "phone_number": "TEL", + "email_address": "EMAIL", + "social_security_number": "NIR", + "postal_address": "ADRESSE", + "hospital": "ETAB", + "city": "VILLE", +} + +DEFAULT_MODEL = "urchade/gliner_multi_pii-v1" + + +class GlinerManager: + """Gestionnaire GLiNER pour NER zero-shot. Utilisé en vote majoritaire.""" + + def __init__(self): + self._model = None + self._loaded = False + self.model_id: Optional[str] = None + + def is_loaded(self) -> bool: + return self._loaded and self._model is not None + + def load(self, model_id: str = DEFAULT_MODEL) -> None: + if not _GLINER_AVAILABLE: + raise RuntimeError("gliner non disponible. Installez : pip install 'gliner==0.2.18'") + self.unload() + self.model_id = model_id + self._model = GLiNER.from_pretrained(model_id) + self._loaded = True + log.info(f"GLiNER chargé: {model_id}") + + def unload(self) -> None: + self._model = None + self._loaded = False + self.model_id = None + + def predict( + self, + text: str, + labels: Optional[List[str]] = None, + threshold: float = 0.5, + ) -> List[Dict[str, Any]]: + """Prédit les entités dans un texte. + + Returns: + Liste de dicts avec: text, label, score, start, end + """ + if not self.is_loaded(): + return [] + if labels is None: + labels = GLINER_PII_LABELS + GLINER_SAFE_LABELS + try: + entities = self._model.predict_entities(text, labels, threshold=threshold) + return [ + { + "text": e["text"], + "label": e["label"], + "score": e["score"], + "start": e["start"], + "end": e["end"], + } + for e in entities + ] + except Exception as e: + log.warning(f"GLiNER predict error: {e}") + return [] + + def is_pii(self, text: str, entity_text: str, threshold: float = 0.5) -> Optional[str]: + """Vérifie si un token est un PII selon GLiNER. + + Returns: + La clé PLACEHOLDERS mappée si PII, None sinon. + """ + if not self.is_loaded(): + return None + entities = self.predict(text, threshold=threshold) + for e in entities: + if e["text"].strip().lower() == entity_text.strip().lower(): + if e["label"] in GLINER_LABEL_MAP: + return GLINER_LABEL_MAP[e["label"]] + if e["label"] in GLINER_SAFE_LABELS: + return None # Explicitement classé comme terme médical + return None # Pas trouvé → pas de vote + + def validate_entities( + self, + text: str, + eds_entities: List[Dict[str, Any]], + threshold: float = 0.4, + ) -> List[Dict[str, Any]]: + """Valide les entités EDS-Pseudo via GLiNER (vote croisé). + + Chaque entité EDS reçoit un champ 'gliner_confirmed': True/False/None. + - True : GLiNER aussi détecte ce span comme PII + - False : GLiNER classifie ce span comme terme médical (medication/condition/procedure) + - None : GLiNER ne détecte rien (neutre) + """ + if not self.is_loaded() or not eds_entities: + return eds_entities + + # Prédiction GLiNER sur tout le texte + all_labels = GLINER_PII_LABELS + GLINER_SAFE_LABELS + gliner_preds = self.predict(text, labels=all_labels, threshold=threshold) + + # Index rapide : pour chaque position de caractère, quelles entités GLiNER couvrent + for e in eds_entities: + e_start = e.get("start", -1) + e_end = e.get("end", -1) + e_word = (e.get("word") or "").lower() + + confirmed = None # par défaut: neutre + for g in gliner_preds: + g_text = g["text"].lower() + # Match par overlap ou par texte identique + overlap = ( + (g["start"] <= e_start < g["end"]) or + (g["start"] < e_end <= g["end"]) or + (e_start <= g["start"] and e_end >= g["end"]) + ) + text_match = g_text == e_word or e_word in g_text or g_text in e_word + + if overlap or text_match: + if g["label"] in GLINER_SAFE_LABELS: + confirmed = False # GLiNER dit: c'est médical, pas PII + break + elif g["label"] in GLINER_LABEL_MAP: + confirmed = True # GLiNER confirme: c'est PII + + e["gliner_confirmed"] = confirmed + + return eds_entities diff --git a/regression_tests/baseline/LETTRE DE SORTIE 23087212.pseudonymise.txt b/regression_tests/baseline/LETTRE DE SORTIE 23087212.pseudonymise.txt index f229605..4ca1493 100644 --- a/regression_tests/baseline/LETTRE DE SORTIE 23087212.pseudonymise.txt +++ b/regression_tests/baseline/LETTRE DE SORTIE 23087212.pseudonymise.txt @@ -1,4 +1,4 @@ -Courrier Epi - [NOM], [NOM] +Courrier Epi - RICHARD, [NOM] ___________________________________________________________________________________________________________________________ Courriers médicaux >>>A Lettre de sortie 05/07/23 14 : 17 (mod. le 07/07/23 12:19 par [NOM] [NOM] , statut : Résu non validés) @@ -38,7 +38,7 @@ J’ai proposé de le revoir dans quelques semaines, après essai de la situatio ___________________________________________________________________________________________________________________________ Information patient Page 1 -17/04/2025 09 : 17:42 Courrier Epi - [NOM], [NOM] +17/04/2025 09 : 17:42 Courrier Epi - RICHARD, [NOM] ___________________________________________________________________________________________________________________________ Courriers médicaux Bien confraternellement. diff --git a/regression_tests/baseline/trackare-07003136-23135847_07003136_23135847.pseudonymise.txt b/regression_tests/baseline/trackare-07003136-23135847_07003136_23135847.pseudonymise.txt index 3193a3f..47328c4 100644 --- a/regression_tests/baseline/trackare-07003136-23135847_07003136_23135847.pseudonymise.txt +++ b/regression_tests/baseline/trackare-07003136-23135847_07003136_23135847.pseudonymise.txt @@ -147,7 +147,7 @@ Date expiration Message Anticoagulant -Ss [NOM] +Ss Kard Antécédents (texte libre) Type de note Nom diff --git a/regression_tests/baseline/trackare-11004431-23124019_11004431_23124019.pseudonymise.txt b/regression_tests/baseline/trackare-11004431-23124019_11004431_23124019.pseudonymise.txt index a41d2ef..bf2c834 100644 --- a/regression_tests/baseline/trackare-11004431-23124019_11004431_23124019.pseudonymise.txt +++ b/regression_tests/baseline/trackare-11004431-23124019_11004431_23124019.pseudonymise.txt @@ -527,7 +527,7 @@ Note d'évolution [NOM] [NOM] 30/06/2023 11 : 01 -Attention, installation d'une thrombopénie et d'une anémie, à distance du dernier ttt d'[NOM], à +Attention, installation d'une thrombopénie et d'une anémie, à distance du dernier ttt d'Enhertu, à surveiller. Contrôle bio dimanche 02/07. appel du laboratoire : présence de pneumocystis jirovecii 638copies/ml dans le LBA d'hier. @@ -1080,7 +1080,7 @@ Page 7 de 20 Note IDE 12 : 53 Notes équipe sociale [NOM] [NOM]- -[NOM] +FAURE 28/06/2023 10 : 08 Note IDE diff --git a/regression_tests/baseline/trackare-14025311-23034958_14025311_23034958.pseudonymise.txt b/regression_tests/baseline/trackare-14025311-23034958_14025311_23034958.pseudonymise.txt index 5896518..4a53d9d 100644 --- a/regression_tests/baseline/trackare-14025311-23034958_14025311_23034958.pseudonymise.txt +++ b/regression_tests/baseline/trackare-14025311-23034958_14025311_23034958.pseudonymise.txt @@ -779,7 +779,7 @@ Gelule(s) [NOM] [NOM] [NOM] -[NOM] GEL +0,5 GEL - Matin soir (8h - 19h) Normal 27/02/2023 18 : 40 diff --git a/regression_tests/baseline/trackare-23000862-23018396_23000862_23018396.pseudonymise.txt b/regression_tests/baseline/trackare-23000862-23018396_23000862_23018396.pseudonymise.txt index 3bc2f84..33e6780 100644 --- a/regression_tests/baseline/trackare-23000862-23018396_23000862_23018396.pseudonymise.txt +++ b/regression_tests/baseline/trackare-23000862-23018396_23000862_23018396.pseudonymise.txt @@ -2847,7 +2847,7 @@ Signé — PARACETAMOL ARW 500MG GELULE - 500MG gelule - Dose 2 GEL - ORALE - Matin midi soir nuit - 1ère dose : 24/05/2023 @ 19 : 00 -Signé — RAMIPRIL [NOM] 2,5MG CPR - 2,5MG +Signé — RAMIPRIL ARL 2,5MG CPR - 2,5MG comprime - Dose 2 CPR - ORALE - Matin [8h] - 1ère dose : 25/05/2023 @ 08:00 Signé — LOVENOX 4000UI AXA/0,4ML diff --git a/regression_tests/baseline/trackare-99252128-23177582_99252128_23177582.pseudonymise.txt b/regression_tests/baseline/trackare-99252128-23177582_99252128_23177582.pseudonymise.txt index 235d911..1faeaf6 100644 --- a/regression_tests/baseline/trackare-99252128-23177582_99252128_23177582.pseudonymise.txt +++ b/regression_tests/baseline/trackare-99252128-23177582_99252128_23177582.pseudonymise.txt @@ -763,7 +763,7 @@ Page 4 de 18 Note IDE 21 : 22 Note IDE [NOM] [NOM] -[NOM] +SAULE 04/10/2023 09 : 56 Note IDE @@ -776,7 +776,7 @@ Note IDE 17 : 25 Note IDE [NOM] [NOM] -[NOM] +SAULE 03/10/2023 10 : 30 Note IDE diff --git a/regression_tests/baseline/trackare-BA067657-23076655_BA067657_23076655.pseudonymise.txt b/regression_tests/baseline/trackare-BA067657-23076655_BA067657_23076655.pseudonymise.txt index ea2d587..17e24c5 100644 --- a/regression_tests/baseline/trackare-BA067657-23076655_BA067657_23076655.pseudonymise.txt +++ b/regression_tests/baseline/trackare-BA067657-23076655_BA067657_23076655.pseudonymise.txt @@ -2158,7 +2158,7 @@ CLOZAPINE MYL 100MG CPR [28] COMPRIME(S) DUPHALAC 10G/15ML SOL BUV SACHET GF [20] -SAC(s) +[NOM](s) EDUCTYL AD SUPPO [12] Suppositoire(s) KARDEGIC 160MG PDR @@ -2288,7 +2288,7 @@ Sortie Révisé/Traité [NOM] [NOM] -1 SAC +1 [NOM] ORALE Réalisé - Midi [12h] Presc. @@ -3144,7 +3144,7 @@ Patient : [NOM] [NOM] [NOM] - [DATE_NAISSANCE] ([IPP] ) Episode N. : [NDA] ( MEDECINE PNEUMOLOGIE - PNEUMOLOGIE PHTISIOLOGIE HC ) Le 24/04/2023 14 : 35 Page 21 de 35 Signé — EDUCTYL AD SUPPO - 1,15G + 0,7G -suppositoire - Dose 1 [NOM] - RECTALE - Matin +suppositoire - Dose 1 SUP - RECTALE - Matin [8h] Si besoin - Début presc. : 20/04/2023 @ 10:32 Si pas de selles pendant 3 jours Signé — NORMACOL LAVEMENT AD SOL @@ -3208,7 +3208,7 @@ Fin le 20/05/2023 à Admin le 24/04/2023 à 08 : 00 08 : 00 * 1 -[NOM] +SUP [NOM] [NOM] Début le 20/04/2023 à 10 : 32 diff --git a/regression_tests/baseline/trackare-BA127127-23135726_BA127127_23135726.pseudonymise.txt b/regression_tests/baseline/trackare-BA127127-23135726_BA127127_23135726.pseudonymise.txt index 3d9b5c0..b5c8b3f 100644 --- a/regression_tests/baseline/trackare-BA127127-23135726_BA127127_23135726.pseudonymise.txt +++ b/regression_tests/baseline/trackare-BA127127-23135726_BA127127_23135726.pseudonymise.txt @@ -1392,7 +1392,7 @@ Oxygene Vrac 15/07/2023 13 : 42 DR. [NOM] [NOM] -[NOM] [NOM] +SPIOLTO RESPIMAT 2,5MCG SOL PR INHAL [1] DISPOSITIF INHALATEUR(s) @@ -1403,7 +1403,7 @@ DR. [NOM] - Matin [8h] Normal 16/07/2023 13 : 14 21/07/2023 08 : 21 -[NOM] [NOM] +SPIOLTO RESPIMAT 2,5MCG SOL PR INHAL [1] DISPOSITIF INHALATEUR(s) @@ -2264,7 +2264,7 @@ Fin le 24/07/2023 à Admin le 20/07/2023 à 18 : 09 19 : 00 * 28 UI -[NOM] GASC +[NOM] [NOM] [NOM] Début le 19/07/2023 à 08 : 00 @@ -2347,7 +2347,7 @@ Midi (12h-16h) Soir (16h-21h) Soir (21h-07h) Signé — SPIOLTO RESPIMAT 2,5MCG SOL PR -INHAL - 2,5MCG solution - Dose 2 [NOM] +INHAL - 2,5MCG solution - Dose 2 BOUFFEE - INHALEE Directe - Matin [8h] - 1ère dose : 17/07/2023 @ 08 : 00 Signé — PIPER/TAZOB VTS 4G/500MG PDR @@ -2404,7 +2404,7 @@ Fin le 15/08/2023 à Admin le 21/07/2023 à 08 : 21 08 : 00 * 2 -[NOM] +BOUFFEE [NOM] [NOM] Début le 17/07/2023 à 11 : 38 @@ -2793,7 +2793,7 @@ Fin le 24/07/2023 à Admin le 20/07/2023 à 18 : 09 19 : 00 * 28 UI -[NOM] GASC +[NOM] [NOM] [NOM] Début le 19/07/2023 à 08 : 00 diff --git a/regression_tests/baseline/trackare-BA171849-23214501_BA171849_23214501.pseudonymise.txt b/regression_tests/baseline/trackare-BA171849-23214501_BA171849_23214501.pseudonymise.txt index 81e5362..617df69 100644 --- a/regression_tests/baseline/trackare-BA171849-23214501_BA171849_23214501.pseudonymise.txt +++ b/regression_tests/baseline/trackare-BA171849-23214501_BA171849_23214501.pseudonymise.txt @@ -961,11 +961,11 @@ COMPRIME(S) 16/11/2023 21 : 00 DR. [NOM] [NOM] -VOGALENE [NOM] 7,5MG -LYOPHILISAT ORAL [16] -LYOPHILISAT(S) +VOGALENE LYOC 7,5MG +[NOM] ORAL [16] +[NOM](S) 1 -LYOPHILISAT(S) +[NOM](S) - Normal [DATE_NAISSANCE] 12 : 30 17/11/2023 04 : 30 @@ -991,7 +991,7 @@ Urgent DR. [NOM] Voie d`administration : SOUS-CUTANEE Statut des prescriptions : Signé -[NOM] FLEXPEN +LEVEMIR FLEXPEN 300U/3ML SOL INJ STY [5] Cartouche(s) 10 U @@ -1436,19 +1436,19 @@ Signé — SERESTA 10MG CPR - 10MG comprime - Dose 1 CPR - ORALE - Nuit [21h] Si besoin - Début presc. : 13/11/2023 @ 12:18 "si anxiete " -Signé — VOGALENE [NOM] 7,5MG +Signé — VOGALENE LYOC 7,5MG LYOPHILISAT ORAL - 7,5MG lyophilisat - Dose 1 LYOPHILISAT(S) - ORALE - Toutes les 8 Heure(s) Si besoin - Début presc. : 13/11/2023 @ 12 : 30 si nausée -Signé — VOGALENE [NOM] 7,5MG +Signé — VOGALENE LYOC 7,5MG LYOPHILISAT ORAL - 7,5MG lyophilisat - Dose 1 LYOPHILISAT(S) - ORALE - Toutes les 8 Heure(s) Si besoin - Début presc. : 13/11/2023 @ 12 : 30 si nausée -Signé — VOGALENE [NOM] 7,5MG +Signé — VOGALENE LYOC 7,5MG LYOPHILISAT ORAL - 7,5MG lyophilisat - Dose 1 LYOPHILISAT(S) - ORALE - Toutes les 8 Heure(s) Si besoin - Début presc. : 13/11/2023 @ @@ -2045,19 +2045,19 @@ Signé — SERESTA 10MG CPR - 10MG comprime - Dose 1 CPR - ORALE - Nuit [21h] Si besoin - Début presc. : 13/11/2023 @ 12:18 "si anxiete " -Signé — VOGALENE [NOM] 7,5MG +Signé — VOGALENE LYOC 7,5MG LYOPHILISAT ORAL - 7,5MG lyophilisat - Dose 1 LYOPHILISAT(S) - ORALE - Toutes les 8 Heure(s) Si besoin - Début presc. : 13/11/2023 @ 12 : 30 si nausée -Signé — VOGALENE [NOM] 7,5MG +Signé — VOGALENE LYOC 7,5MG LYOPHILISAT ORAL - 7,5MG lyophilisat - Dose 1 LYOPHILISAT(S) - ORALE - Toutes les 8 Heure(s) Si besoin - Début presc. : 13/11/2023 @ 12 : 30 si nausée -Signé — VOGALENE [NOM] 7,5MG +Signé — VOGALENE LYOC 7,5MG LYOPHILISAT ORAL - 7,5MG lyophilisat - Dose 1 LYOPHILISAT(S) - ORALE - Toutes les 8 Heure(s) Si besoin - Début presc. : 13/11/2023 @ diff --git a/run_batch_30_audit.py b/run_batch_30_audit.py index ee48a01..3b24772 100644 --- a/run_batch_30_audit.py +++ b/run_batch_30_audit.py @@ -11,6 +11,7 @@ sys.path.insert(0, str(Path(__file__).parent)) import anonymizer_core_refactored_onnx as core from eds_pseudo_manager import EdsPseudoManager from vlm_manager import VlmManager +from gliner_manager import GlinerManager SRC = Path("/home/dom/Téléchargements/II-1 Ctrl_T2A_2025_CHCB_DocJustificatifs (1)") OUTDIR = SRC / "anonymise_audit_30" @@ -57,6 +58,15 @@ def main(): assert ner.is_loaded(), "EDS-Pseudo non chargé" print("EDS-Pseudo chargé.", flush=True) + print("Chargement GLiNER (vote croisé NER)...", flush=True) + gliner = GlinerManager() + try: + gliner.load() + print("GLiNER chargé.", flush=True) + except Exception as e: + print(f"GLiNER indisponible ({e}), on continue sans.", flush=True) + gliner = None + print("Chargement VLM (Ollama qwen2.5vl:7b)...", flush=True) vlm = VlmManager() try: @@ -97,6 +107,7 @@ def main(): ner_thresholds=None, ogc_label=ogc, vlm_manager=vlm, + gliner_manager=gliner, ) audit_path = Path(outputs.get("audit", "")) if audit_path.exists(): diff --git a/scripts/export_silver_annotations.py b/scripts/export_silver_annotations.py new file mode 100644 index 0000000..7ca95db --- /dev/null +++ b/scripts/export_silver_annotations.py @@ -0,0 +1,145 @@ +#!/usr/bin/env python3 +""" +Export silver annotations — Génère des données d'entraînement BIO à partir du pipeline existant. +================================================================================================ +Utilise le pipeline regex+NER+VLM actuel pour produire des annotations "silver standard" +sur les 706 OGC. Ces annotations servent de base pour fine-tuner CamemBERT-bio. + +Usage: + python scripts/export_silver_annotations.py [--limit N] [--out-dir DIR] + +Output: data/silver_annotations/ avec un fichier .bio par document +Format BIO: TOKEN\tLABEL (un token par ligne, lignes vides entre phrases) +""" +import sys +import re +import json +import argparse +from pathlib import Path +from typing import List, Tuple + +sys.path.insert(0, str(Path(__file__).parent.parent)) + +# Regex pour détecter les placeholders et reconstruire l'alignement +PLACEHOLDER_RE = re.compile( + r"\[(NOM|TEL|EMAIL|NIR|IPP|DOSSIER|NDA|EPISODE|RPPS|DATE_NAISSANCE|" + r"ADRESSE|CODE_POSTAL|VILLE|MASK|FINESS|OGC|AGE|ETAB|IBAN)\]" +) + +# Mapping placeholder → label BIO +PH_TO_BIO = { + "NOM": "PER", + "TEL": "TEL", + "EMAIL": "EMAIL", + "NIR": "NIR", + "IPP": "IPP", + "DOSSIER": "NDA", + "NDA": "NDA", + "EPISODE": "NDA", + "RPPS": "RPPS", + "DATE_NAISSANCE": "DATE_NAISSANCE", + "ADRESSE": "ADRESSE", + "CODE_POSTAL": "ZIP", + "VILLE": "VILLE", + "ETAB": "HOPITAL", + "FINESS": "HOPITAL", + "IBAN": "IBAN", + "AGE": "AGE", + "OGC": "NDA", + "MASK": "O", # MASK générique = pas d'annotation spécifique +} + + +def text_to_bio(pseudonymised_text: str) -> List[Tuple[str, str]]: + """Convertit un texte pseudonymisé en séquence BIO. + + Les tokens [PLACEHOLDER] deviennent B-TYPE / I-TYPE. + Les tokens normaux deviennent O. + """ + bio_tokens: List[Tuple[str, str]] = [] + + # Split le texte en segments : alternance texte normal / placeholder + parts = PLACEHOLDER_RE.split(pseudonymised_text) + # parts = [texte, label, texte, label, texte, ...] + + i = 0 + while i < len(parts): + if i % 2 == 0: + # Texte normal + text_part = parts[i] + for word in text_part.split(): + word = word.strip() + if word: + bio_tokens.append((word, "O")) + else: + # Label de placeholder + label = parts[i] + bio_label = PH_TO_BIO.get(label, "O") + if bio_label != "O": + # Le placeholder remplace un ou plusieurs tokens + bio_tokens.append((f"[{label}]", f"B-{bio_label}")) + else: + bio_tokens.append((f"[{label}]", "O")) + i += 1 + + return bio_tokens + + +def export_document(pseudo_path: Path, out_dir: Path) -> int: + """Exporte un fichier pseudonymisé en format BIO. Retourne le nombre de tokens.""" + text = pseudo_path.read_text(encoding="utf-8", errors="replace") + + bio_tokens = text_to_bio(text) + if not bio_tokens: + return 0 + + # Écrire en format CoNLL (TOKEN\tLABEL) + out_path = out_dir / pseudo_path.name.replace(".pseudonymise.txt", ".bio") + lines = [] + for token, label in bio_tokens: + # Séparer les "phrases" par des lignes vides (heuristique: point final ou retour ligne) + if token in (".", "!", "?") and label == "O": + lines.append(f"{token}\t{label}") + lines.append("") # séparateur de phrase + else: + lines.append(f"{token}\t{label}") + + out_path.write_text("\n".join(lines), encoding="utf-8") + return len(bio_tokens) + + +def main(): + parser = argparse.ArgumentParser(description="Export silver annotations BIO") + parser.add_argument("--input-dir", type=Path, + default=Path("/home/dom/Téléchargements/II-1 Ctrl_T2A_2025_CHCB_DocJustificatifs (1)/anonymise_audit_30"), + help="Répertoire contenant les .pseudonymise.txt") + parser.add_argument("--out-dir", type=Path, + default=Path(__file__).parent.parent / "data" / "silver_annotations", + help="Répertoire de sortie") + parser.add_argument("--limit", type=int, default=0, help="Limiter à N fichiers (0=tous)") + args = parser.parse_args() + + args.out_dir.mkdir(parents=True, exist_ok=True) + + pseudo_files = sorted(args.input_dir.glob("*.pseudonymise.txt")) + if args.limit > 0: + pseudo_files = pseudo_files[:args.limit] + + print(f"Export silver annotations: {len(pseudo_files)} fichiers → {args.out_dir}") + + total_tokens = 0 + total_entities = 0 + for f in pseudo_files: + n = export_document(f, args.out_dir) + ent_count = sum(1 for line in (args.out_dir / f.name.replace(".pseudonymise.txt", ".bio")).read_text().splitlines() + if line and not line.endswith("\tO")) + total_tokens += n + total_entities += ent_count + print(f" {f.name}: {n} tokens, {ent_count} entités") + + print(f"\nTotal: {total_tokens} tokens, {total_entities} entités annotées") + print(f"Sortie: {args.out_dir}") + + +if __name__ == "__main__": + main() diff --git a/scripts/finetune_camembert_bio.py b/scripts/finetune_camembert_bio.py new file mode 100644 index 0000000..5f68a2e --- /dev/null +++ b/scripts/finetune_camembert_bio.py @@ -0,0 +1,256 @@ +#!/usr/bin/env python3 +""" +Fine-tune CamemBERT-bio pour la désidentification clinique française. +===================================================================== +Entraîne almanach/camembert-bio-base sur les annotations silver/gold +exportées par export_silver_annotations.py. + +Usage: + python scripts/finetune_camembert_bio.py [--epochs 5] [--batch-size 8] [--lr 2e-5] + +Prérequis: pip install transformers datasets seqeval accelerate +Export ONNX post-training: python scripts/export_onnx.py +""" +import sys +import argparse +from pathlib import Path +from typing import Dict, List + +import numpy as np + +# Vérifier les dépendances +try: + from transformers import ( + AutoTokenizer, + AutoModelForTokenClassification, + TrainingArguments, + Trainer, + DataCollatorForTokenClassification, + ) + from datasets import Dataset, DatasetDict + import evaluate +except ImportError as e: + print(f"Dépendance manquante: {e}") + print("Installez: pip install transformers datasets seqeval accelerate") + sys.exit(1) + + +# Labels BIO pour la désidentification +LABEL_LIST = [ + "O", + "B-PER", "I-PER", + "B-TEL", "I-TEL", + "B-EMAIL", "I-EMAIL", + "B-NIR", "I-NIR", + "B-IPP", "I-IPP", + "B-NDA", "I-NDA", + "B-RPPS", "I-RPPS", + "B-DATE_NAISSANCE", "I-DATE_NAISSANCE", + "B-ADRESSE", "I-ADRESSE", + "B-ZIP", "I-ZIP", + "B-VILLE", "I-VILLE", + "B-HOPITAL", "I-HOPITAL", + "B-IBAN", "I-IBAN", + "B-AGE", "I-AGE", +] +LABEL2ID = {l: i for i, l in enumerate(LABEL_LIST)} +ID2LABEL = {i: l for l, i in LABEL2ID.items()} + +MODEL_NAME = "almanach/camembert-bio-base" + + +def load_bio_files(data_dir: Path) -> Dict[str, List]: + """Charge les fichiers .bio en format HuggingFace datasets.""" + tokens_list: List[List[str]] = [] + labels_list: List[List[int]] = [] + + for bio_file in sorted(data_dir.glob("*.bio")): + text = bio_file.read_text(encoding="utf-8") + current_tokens: List[str] = [] + current_labels: List[int] = [] + + for line in text.splitlines(): + line = line.strip() + if not line: + # Fin de phrase + if current_tokens: + tokens_list.append(current_tokens) + labels_list.append(current_labels) + current_tokens = [] + current_labels = [] + continue + + parts = line.split("\t") + if len(parts) != 2: + continue + token, label = parts + label_id = LABEL2ID.get(label, LABEL2ID["O"]) + current_tokens.append(token) + current_labels.append(label_id) + + if current_tokens: + tokens_list.append(current_tokens) + labels_list.append(current_labels) + + return {"tokens": tokens_list, "ner_tags": labels_list} + + +def tokenize_and_align(examples, tokenizer): + """Tokenize et aligne les labels avec les sous-tokens.""" + tokenized = tokenizer( + examples["tokens"], + truncation=True, + is_split_into_words=True, + max_length=512, + padding=False, + ) + + all_labels = [] + for i, labels in enumerate(examples["ner_tags"]): + word_ids = tokenized.word_ids(batch_index=i) + label_ids = [] + prev_word_id = None + for word_id in word_ids: + if word_id is None: + label_ids.append(-100) + elif word_id != prev_word_id: + label_ids.append(labels[word_id]) + else: + # Sous-token : I- si le premier est B-, sinon même label + orig = labels[word_id] + if orig > 0 and LABEL_LIST[orig].startswith("B-"): + # Convertir B- en I- + i_label = LABEL_LIST[orig].replace("B-", "I-") + label_ids.append(LABEL2ID.get(i_label, orig)) + else: + label_ids.append(orig) + prev_word_id = word_id + all_labels.append(label_ids) + + tokenized["labels"] = all_labels + return tokenized + + +def main(): + parser = argparse.ArgumentParser(description="Fine-tune CamemBERT-bio pour désidentification") + parser.add_argument("--data-dir", type=Path, + default=Path(__file__).parent.parent / "data" / "silver_annotations", + help="Répertoire des fichiers .bio") + parser.add_argument("--output-dir", type=Path, + default=Path(__file__).parent.parent / "models" / "camembert-bio-deid", + help="Répertoire de sortie du modèle") + parser.add_argument("--epochs", type=int, default=5) + parser.add_argument("--batch-size", type=int, default=8) + parser.add_argument("--lr", type=float, default=2e-5) + parser.add_argument("--val-split", type=float, default=0.15, help="Fraction pour validation") + args = parser.parse_args() + + # Charger les données + print(f"Chargement des données depuis {args.data_dir}...") + raw_data = load_bio_files(args.data_dir) + n_sentences = len(raw_data["tokens"]) + n_entities = sum(1 for labels in raw_data["ner_tags"] for l in labels if l != 0) + print(f" {n_sentences} phrases, {n_entities} entités annotées") + + if n_sentences < 10: + print("ERREUR: pas assez de données. Lancez d'abord export_silver_annotations.py") + sys.exit(1) + + # Split train/val + dataset = Dataset.from_dict(raw_data) + split = dataset.train_test_split(test_size=args.val_split, seed=42) + datasets = DatasetDict({"train": split["train"], "validation": split["test"]}) + print(f" Train: {len(datasets['train'])}, Validation: {len(datasets['validation'])}") + + # Tokenizer + modèle + print(f"\nChargement du modèle {MODEL_NAME}...") + tokenizer = AutoTokenizer.from_pretrained(MODEL_NAME) + model = AutoModelForTokenClassification.from_pretrained( + MODEL_NAME, + num_labels=len(LABEL_LIST), + id2label=ID2LABEL, + label2id=LABEL2ID, + ) + + # Tokenization + tokenized = datasets.map( + lambda ex: tokenize_and_align(ex, tokenizer), + batched=True, + remove_columns=datasets["train"].column_names, + ) + + # Métriques + seqeval = evaluate.load("seqeval") + + def compute_metrics(eval_pred): + logits, labels = eval_pred + predictions = np.argmax(logits, axis=-1) + true_labels = [] + true_preds = [] + for pred_seq, label_seq in zip(predictions, labels): + t_labels = [] + t_preds = [] + for p, l in zip(pred_seq, label_seq): + if l != -100: + t_labels.append(LABEL_LIST[l]) + t_preds.append(LABEL_LIST[p]) + true_labels.append(t_labels) + true_preds.append(t_preds) + results = seqeval.compute(predictions=true_preds, references=true_labels) + return { + "precision": results["overall_precision"], + "recall": results["overall_recall"], + "f1": results["overall_f1"], + } + + # Training + args.output_dir.mkdir(parents=True, exist_ok=True) + training_args = TrainingArguments( + output_dir=str(args.output_dir), + num_train_epochs=args.epochs, + per_device_train_batch_size=args.batch_size, + per_device_eval_batch_size=args.batch_size * 2, + learning_rate=args.lr, + weight_decay=0.01, + warmup_ratio=0.1, + eval_strategy="epoch", + save_strategy="epoch", + load_best_model_at_end=True, + metric_for_best_model="f1", + logging_steps=50, + fp16=False, # CPU training + report_to="none", + save_total_limit=2, + ) + + data_collator = DataCollatorForTokenClassification(tokenizer) + trainer = Trainer( + model=model, + args=training_args, + train_dataset=tokenized["train"], + eval_dataset=tokenized["validation"], + data_collator=data_collator, + compute_metrics=compute_metrics, + tokenizer=tokenizer, + ) + + print(f"\nDémarrage du fine-tuning ({args.epochs} epochs, batch={args.batch_size}, lr={args.lr})...") + trainer.train() + + # Sauvegarder + trainer.save_model(str(args.output_dir / "best")) + tokenizer.save_pretrained(str(args.output_dir / "best")) + print(f"\nModèle sauvegardé: {args.output_dir / 'best'}") + + # Évaluation finale + results = trainer.evaluate() + print(f"\nRésultats finaux:") + print(f" Precision: {results['eval_precision']:.4f}") + print(f" Recall: {results['eval_recall']:.4f}") + print(f" F1: {results['eval_f1']:.4f}") + print(f"\nPour exporter en ONNX:") + print(f" python -m optimum.exporters.onnx --model {args.output_dir / 'best'} {args.output_dir / 'onnx'}") + + +if __name__ == "__main__": + main()