Una libreria al giorno toglie il medico di torno
Published: 2023-10-03 14:23:27

---
title: Una libreria al giorno toglie il medico di torno
published: true
date: 2023-06-06 00:00:00 UTC
tags: 
canonical_url: 
---

# Intro

L’analisi del linguaggio naturale rappresenta un campo con una miriade di opportunità per casi d’uso nella vita di tutti i giorni: uno dei migliori esempi è il settore sanitario, dove la ricerca medica e la cura del paziente possono contare su diverse tecnologie che possono migliorare le informazioni che sono già state raccolte. Molte aziende sfruttano software proprietario o sotto licenza a pagamento, ma quali sono le alternative open source?

Scopriamo [MedSpaCy](https://github.com/medspacy/medspacy), una libreria di strumenti per eseguire delle attività di NLP sul dominio clinico sfruttando un caso d’uso reale!

# medspaCy

[MedSpaCy](https://github.com/medspacy/medspacy) è uno strumento di libreria per l’esecuzione di attività di NLP clinica e di elaborazione del testo.

Riunisce una serie di altri strumenti, ciascuno dei quali implementa funzionalità specifiche per l’ **elaborazione di testi clinici** comuni come la segmentazione delle frasi, l’analisi contestuale e la segmentazione del testo.

Questa libreria viene progettata per essere utilizzato come parte della pipeline di elaborazione [spaCy](https://spacy.io/), una delle più conosciute librerie di analisi del linguaggio naturale.

In questo post, ci concentriamo su un task in particolare, ossia quello del riconoscimento delle entità -in inglese _[Named Entity Recognition](https://en.wikipedia.org/wiki/Named-entity_recognition)_ (aka NER)- ossia un’attività che **contrassegna le entità nel testo con il tipo corrispondente.**

> Esempio: _ **pneumonia** _ potrebbe essere classificato come “problema”, così come _ **warfarin** _ come “medicinale”.

Si tratta di un’attività piuttosto semplice, anche se spesso non riesce a lavorare bene su un testo molto specifico, come quello relativo al campo della salute e della medicina.

# Installazione

Tramite _pip_, è super semplice:

```
pip install medspacy

```

Tieni presente, tuttavia, che hai bisogno di [https://spacy.io/](https://spacy.io/) versione 3 e _[pyrush](https://github.com/medspacy/PyRuSH)_ come requisiti per l’installazione di medspaCy.

# NER

Vediamo un esempio di come addestrare il modello giò presente usando il [TargetMatcher](https://github.com/medspacy/target_matcher), un componente che serve per fornire delle regole ulteriori alla pipeline che andremo a utilizzare.

L’obiettivo è quello di creare un piccolo sistema che <ins>estragga da un testo le entità cliniche e le evidenzi</ins>, come mostrato nella figura seguente, dove vengono etichettati problemi (intesi come problemi clinici), trattamenti ed eventuali problemi negati, quindi condizioni che il/la paziente non presenta.

![](https://theredcode.it/img/medspacy.png)

Andiamo per gradi: per prima cosa, importiamo le librerie necessarie

```
import medspacy
from medspacy.ner import TargetMatcher, TargetRule
from medspacy.visualization import visualize_ent
import pandas as pd

```

In questo caso, andiamo a importare [MedSpaCy](https://github.com/medspacy/medspacy) insieme al TargetRule, che ci permette di specificare delle regole o dei pattern per alimentare il modello già addestrato. Inoltre, andiamo a importare una libreria di utility, come _pandas_, per poter lavorare al meglio con i dati che abbiamo in input.

Nel prossimo passaggio, andiamo a caricare il modello di default dalla libreria e selezioniamo il componente TargetMatcher nella pipeline:

```
nlp = medspacy.load()
target_matcher = nlp.get_pipe("medspacy_target_matcher")

```

A questo punto, dobbiamo <ins>caricare il dataset</ins> che contiene i dati che vogliamo esaminare: nel caso di esempio, ne andremo a utilizzare uno presente su [Kaggle](https://www.kaggle.com/code/chaitanyakck/medical-text-classification/input)che contiene una serie di diagnosi più o meno specifiche. Il dataset è un file .dat composto da diverse righe, ognuna delle quali contiene una diagnosi diversa, e non ha alcuna intestazione: per questo, usiamo il metodo _read\_table_di _pandas_ per caricare queste informazioni, specificando che la prima riga è già un dato e non un’intestazione.

```
df = pd.read_table("./input/test.dat", header=None)

```

Ora è il momento di **specificare delle regole** per il riconoscimento delle entità: per esempio, vogliamo identificare_surgery_ come un trattamento, e _stroke_ come un problema: costruiamo una TargetRule e specifichiamo sia la categoria a cui appartiene, sia il termine da utilizzare:

```
target_rules = [
 TargetRule("surgery", "TREATMENT"),
 TargetRule("stroke", "PROBLEM")
]

```

Queste regole possono essere complesse a piacere: è possibile infatti specificare anche dei pattern da rispettare, piuttosto che l’opzionalità di uno o più termini: nel seguente esempio, riportiamo che la parola _tumor_ potrebbe essere preceduta da _infiltrative_ o _myofibroblastic_, termini che possono comparire 0 o una volta.

```
target_rules = [
 TargetRule("myofibroblastic tumor", category="CONDITION",
 pattern=[
 {"LOWER": {"IN": ["infiltrative", "myofibroblastic"]}, "OP": "?"},
 {"LOWER": "tumor"},
 ])
]

```

Una volta aggiunte le regole con le entità del dominio d’interesse, andiamo ad aggiungere queste regole al componente della pipeline che abbiamo caricato in precedenza:

```
target_matcher.add(target_rules)

```

L’ultimo step consiste nel **testare il modello** : è sufficiente utilizzare la funzione _nlp_ per recuperare il Document prodotto dalla libreria, che contiene le entità rilevate e le informazioni a esso associate.

Per il caso di esempio, andiamo a stampare il nome dell’entità e se questa fa parte di un contesto di negazione (un problema che il/la paziente non presenta), e poi utilizziamo la funzione _visualize\_ent_ per riportare il testo con le etichette evidenziate, rispetto al testo fornito come input: utilizzando un testo diverso da quello presente nel dataset, questo è quello che otteniamo:

```
text = ""The lesion could not be totally resected. Not an benign tumor, but a inflammatory myofibroblastic tumor was suspected, so steroid pulse therapy was not introduced, but it was ineffective.
 Two months after the referral to our department, endoscopic transsphenoidal surgery was performed. Gamma Knife radiosurgery (marginal dose 15 Gy, maximum dose 30.1 Gy)
 was performed, and chemotherapy with tamoxifen and sulindac was introduced..."
doc = nlp(text)
for ent in doc.ents:
 print(ent, ent._.is_negated)
 visualize_ent(doc)

```

![](https://theredcode.it/img/medspacy2.png)

L’esempio è banale, quanto efficace: con una persona esperta di dominio, è possibile personalizzare il modello per un contesto più specifico e riuscire a individuare le entità cliniche, così da utilizzare il sistema per molteplici obiettivi: un caso può essere quello di uno strumento per fornire un primo consulto rapido per uno strumento che consente una conversazione tra paziente e professionista, dove la persona curante può utilizzare questo sistema come_ausilio_ per le sue attività.

# Risorse utili

- [Documentazione ufficiale](https://github.com/medspacy/medspacy/)
- [Repo ufficiale](https://github.com/medspacy/medspacy/notebooks)
- [Esempio completo](https://github.com/serenasensini/medspaCy-tutorial)
- [Dataset di esempio](https://www.kaggle.com/code/chaitanyakck/medical-text-classification/input)