Простое пошаговое руководство о том, как связать RxNorm с извлеченными лекарствами, используя TF-IDF и косинусное сходство.

https://bioportal.bioontology.org/ontologies/RXNORM

Для скачивания NIH — RxNorm Files требуется лицензия (бесплатная).

см. Эластичный поиск, чтобы узнать, как реализовать это в масштабируемом поисковом приложении.

Данные

import re
import pandas as pd

def parse_rxnorm_identifier(cls_id: str) -> str:
    return re.search(r'(?<=\/)(\w+)$', cls_id).group(0)

df = pd.read_csv('./RXNORM.csv')
df['Label'] = df['Preferred Label'].str.lower()
df['ID'] = df['Class ID'].map(parse_rxnorm_identifier)

df = df[['ID', 'Label', 'Class ID']]
df.tail(n=5)

Векторизатор TF-IDF

Vectorizer использует анализатор границ слов с различными шагами ngram.

from sklearn.feature_extraction.text import TfidfVectorizer

tfidf_vectorizer = TfidfVectorizer(
    analyzer='char_wb',
    ngram_range=(3,5)
)

vectors = tfidf_vectorizer.fit_transform(
    df['Label'].unique().tolist()
)

Способ поиска лекарств

Простой метод поиска, который использует косинусное сходство для возврата первых (n) ближайших лекарств.

import numpy as np
from sklearn.metrics import pairwise
from typing import List, Tuple


Medications = { i: row.to_dict() for i, row in df.iterrows() }

def query_medications(query_term: str, n=1) -> List[Tuple[dict, float]]:
    query_as_vector = tfidf_vectorizer.transform([
        query_term.strip()
    ])

    cosine_similarities = pairwise.pairwise_distances(
        vectors,
        query_as_vector,
        metric='cosine'
    ).flatten()

    return [
        (
            Medications[row_id],
            cosine_similarities[row_id]
        ) for row_id in np.argsort(cosine_similarities)[:n]
    ]
    
query_medications('tylenol', n=5)

Свяжите извлеченные объекты лекарств с RxNorm

Простой метод ссылки для запроса ближайшего лекарства и возврата его идентификатора RxNorm.

def link_medication(query_term: str) -> str:
    med, _ = query_medications(query_term, n=1)[0]
    return med['ID']

medication = {
    'text': 'Tylenol PM',
    'label': 'MEDICATION',
    'start': 5,
    'end': 11
}

medication['rx_id'] = link_medication(medication['text'])

## {
##    'text': 'Tylenol PM',
##    'label': 'MEDICATION',
##    'start': 5,
##    'end': 11,
##    'rx_id': '220581'
## }