Description
This model maps drug entities extracted from clinical text to their corresponding National Drug Codes (NDC). It uses ner_posology_greedy for drug entity recognition and provides fast code mapping without requiring embeddings at inference time. Trained on the openFDA NDC Directory (release 2026-07-22).
Live Demo Open in Colab Copy S3 URI
How to use
document_assembler = DocumentAssembler()\
.setInputCol("text")\
.setOutputCol("document")
sentence_detector = SentenceDetector()\
.setInputCols(["document"])\
.setOutputCol("sentence")
tokenizer = Tokenizer()\
.setInputCols(["sentence"])\
.setOutputCol("token")
word_embeddings = WordEmbeddingsModel.pretrained("embeddings_clinical", "en", "clinical/models")\
.setInputCols(["sentence", "token"])\
.setOutputCol("embeddings")
ner_posology = MedicalNerModel.pretrained("ner_posology_greedy", "en", "clinical/models")\
.setInputCols(["sentence", "token", "embeddings"])\
.setOutputCol("posology_ner")
ner_posology_converter = NerConverterInternal()\
.setInputCols(["sentence", "token", "posology_ner"])\
.setOutputCol("ner_chunk")\
.setWhiteList(["DRUG"])
ndc_mapper = ChunkMapperModel.pretrained("ndc_mapper", "en", "clinical/models")\
.setInputCols(["ner_chunk"])\
.setOutputCol("mappings")\
.setRels(["ndc_code"])
pipeline = Pipeline(stages=[
document_assembler, sentence_detector, tokenizer, word_embeddings,
ner_posology, ner_posology_converter, ndc_mapper
])
data = spark.createDataFrame([["She was started on amoxicillin 500 mg three times daily for a bacterial sinus infection, continues aspirin 81 mg once daily for cardiovascular prophylaxis, takes acetaminophen 500 mg as needed for pain, and was also prescribed cetirizine hydrochloride 10 mg once daily for seasonal allergies."]]).toDF("text")
result = pipeline.fit(data).transform(data)
document_assembler = nlp.DocumentAssembler()\
.setInputCol("text")\
.setOutputCol("document")
sentence_detector = nlp.SentenceDetector()\
.setInputCols(["document"])\
.setOutputCol("sentence")
tokenizer = nlp.Tokenizer()\
.setInputCols(["sentence"])\
.setOutputCol("token")
word_embeddings = nlp.WordEmbeddingsModel.pretrained("embeddings_clinical", "en", "clinical/models")\
.setInputCols(["sentence", "token"])\
.setOutputCol("embeddings")
ner_posology = medical.NerModel.pretrained("ner_posology_greedy", "en", "clinical/models")\
.setInputCols(["sentence", "token", "embeddings"])\
.setOutputCol("posology_ner")
ner_posology_converter = medical.NerConverterInternal()\
.setInputCols(["sentence", "token", "posology_ner"])\
.setOutputCol("ner_chunk")\
.setWhiteList(["DRUG"])
ndc_mapper = medical.ChunkMapperModel.pretrained("ndc_mapper", "en", "clinical/models")\
.setInputCols(["ner_chunk"])\
.setOutputCol("mappings")\
.setRels(["ndc_code"])
pipeline = nlp.Pipeline(stages=[
document_assembler, sentence_detector, tokenizer, word_embeddings,
ner_posology, ner_posology_converter, ndc_mapper
])
data = spark.createDataFrame([["She was started on amoxicillin 500 mg three times daily for a bacterial sinus infection, continues aspirin 81 mg once daily for cardiovascular prophylaxis, takes acetaminophen 500 mg as needed for pain, and was also prescribed cetirizine hydrochloride 10 mg once daily for seasonal allergies."]]).toDF("text")
result = pipeline.fit(data).transform(data)
val documentAssembler = new DocumentAssembler()
.setInputCol("text")
.setOutputCol("document")
val sentenceDetector = new SentenceDetector()
.setInputCols("document")
.setOutputCol("sentence")
val tokenizer = new Tokenizer()
.setInputCols("sentence")
.setOutputCol("token")
val wordEmbeddings = WordEmbeddingsModel.pretrained("embeddings_clinical", "en", "clinical/models")
.setInputCols(Array("sentence", "token"))
.setOutputCol("embeddings")
val nerPosology = MedicalNerModel.pretrained("ner_posology_greedy", "en", "clinical/models")
.setInputCols(Array("sentence", "token", "embeddings"))
.setOutputCol("posology_ner")
val nerPosologyConverter = new NerConverterInternal()
.setInputCols(Array("sentence", "token", "posology_ner"))
.setOutputCol("ner_chunk")
.setWhiteList(Array("DRUG"))
val ndcMapper = ChunkMapperModel.pretrained("ndc_mapper", "en", "clinical/models")
.setInputCols(Array("ner_chunk"))
.setOutputCol("mappings")
.setRels(Array("ndc_code"))
val pipeline = new Pipeline().setStages(Array(
documentAssembler, sentenceDetector, tokenizer, wordEmbeddings,
nerPosology, nerPosologyConverter, ndcMapper
))
val data = Seq("She was started on amoxicillin 500 mg three times daily for a bacterial sinus infection, continues aspirin 81 mg once daily for cardiovascular prophylaxis, takes acetaminophen 500 mg as needed for pain, and was also prescribed cetirizine hydrochloride 10 mg once daily for seasonal allergies.").toDF("text")
val result = pipeline.fit(data).transform(data)
Results
| ner_chunk | ndc_code |
|:-------------------------------|:-----------|
| amoxicillin 500 mg | 83112-0500 |
| aspirin 81 mg | 41250-0780 |
| acetaminophen 500 mg | 69618-0011 |
| cetirizine hydrochloride 10 mg | 66424-0564 |
Model Information
| Model Name: | ndc_mapper |
| Compatibility: | Healthcare NLP 6.4.0+ |
| License: | Licensed |
| Edition: | Official |
| Input Labels: | [ner_chunk] |
| Output Labels: | [mappings] |
| Language: | en |
| Size: | 8.3 MB |