Monitoraggio dei dati non strutturati per LLM e NLP
Monitoraggio dati non strutturati LLM e NLP
Un tutorial sul codice sull’uso dei descrittori di testo

Una volta che hai implementato una soluzione basata su NLP o LLM, hai bisogno di un modo per tenere traccia di essa. Ma come monitori i dati non strutturati per dare un senso alla pila di testi?
Ci sono alcune approcci qui, dalla rilevazione di deviazioni nei dati di testo grezzi e l’incorporazione delle deviazioni all’uso delle espressioni regolari per eseguire controlli basati su regole.
In questo tutorial, approfondiremo un approccio particolare: il tracciamento di descrittori di testo interpretabili che aiutano ad assegnare proprietà specifiche ad ogni testo.
Prima, copriremo un po’ di teoria:
- Entità nominate e le notizie
- Aliasing Il tuo Time Series ti sta mentendo
- 4 semplici modifiche ad alto impatto facili da implementare per potenziare le prestazioni del tuo codice Python
- Cos’è un descrittore di testo e quando usarlo.
- Esempi di descrittori di testo.
- Come selezionare descrittori personalizzati.
Successivamente, passiamo al codice! Lavorerai con dati di recensioni di e-commerce e seguirai i seguenti passaggi:
- Ottieni una panoramica dei dati di testo.
- Valuta le deviazioni dei dati di testo utilizzando descrittori standard.
- Aggiungi un descrittore di testo personalizzato utilizzando un modello pre-allenato esterno.
- Implementa test di pipeline per monitorare i cambiamenti dei dati.
Utilizzeremo la libreria open-source Python Evidently per generare descrittori di testo e valutare i cambiamenti nei dati.
Esempio di codice: Se preferisci andare direttamente al codice, ecco il notebook di esempio.
Cos’è un descrittore di testo?
Un descrittore di testo è qualsiasi caratteristica o proprietà che descrive gli oggetti nel dataset di testo. Ad esempio, la lunghezza dei testi o il numero di simboli in essi.
Potresti già avere metadati utili che accompagnano i tuoi testi e che serviranno come descrittori. Ad esempio, le recensioni degli utenti di e-commerce potrebbero essere accompagnate da valutazioni assegnate dagli utenti o etichette di argomento.
In caso contrario, puoi generare i tuoi descrittori! Puoi farlo aggiungendo “feature virtuali” ai tuoi dati di testo. Ognuna di esse aiuta a descrivere o classificare i tuoi testi utilizzando criteri significativi.

Creando questi descrittori, in sostanza crei la tua semplice “incorporazione” e mappi ogni testo su diverse dimensioni interpretabili. Ciò aiuta a dare un senso ai dati altrimenti non strutturati.
Puoi quindi utilizzare questi descrittori di testo:
- Per monitorare modelli di produzione NLP. Puoi tenere traccia delle proprietà dei tuoi dati nel tempo e rilevare quando cambiano. Ad esempio, i descrittori aiutano a rilevare picchi nella lunghezza dei testi o deviazioni nel sentiment.
- Per testare modelli durante gli aggiornamenti. Quando iteri sui modelli, puoi confrontare le proprietà dei dataset di valutazione e le risposte dei modelli. Ad esempio, puoi verificare che le lunghezze delle risposte generate da LLM rimangano simili e includano costantemente le parole che ti aspetti di vedere.
- Per risolvere problemi di deviazione dei dati o decadimento del modello. Se rilevi deviazioni nell’incorporazione o osservi direttamente una diminuzione nella qualità del modello, puoi utilizzare i descrittori di testo per esplorare da dove proviene.
Esempi di descrittori di testo
Ecco alcuni buoni descrittori di testo che consideriamo predefiniti:
Lunghezza del testo

Un ottimo punto di partenza sono le statistiche di base sul testo. Ad esempio, puoi osservare la lunghezza dei testi misurata in parole, simboli o frasi. Puoi valutare la lunghezza media e minima-massima e osservare le distribuzioni.
Puoi stabilire aspettative in base al tuo caso d’uso. Ad esempio, le recensioni dei prodotti tendono ad avere tra 5 e 100 parole. Se sono più brevi o più lunghe, potrebbe indicare un cambio di contesto. Se c’è un picco nelle recensioni di lunghezza fissa, potrebbe indicare un attacco di spam. Se sai che le recensioni negative sono spesso più lunghe, puoi tenere traccia della percentuale di recensioni superiori a una certa lunghezza.
Ci sono anche dei rapidi controlli di sanità: se esegui un chatbot, potresti aspettarti risposte diverse da zero o che ci sia una lunghezza minima per l’output significativo.
Parole fuori vocabolario

Valutare la percentuale di parole al di fuori del vocabolario definito è una buona misura “grezza” della qualità dei dati. I tuoi utenti hanno iniziato a scrivere recensioni in una nuova lingua? Gli utenti stanno parlando con il tuo chatbot in Python, non in inglese? Gli utenti stanno riempiendo le risposte con “ggg” invece di parole effettive?
Questa è una singola misura pratica per rilevare tutti i tipi di cambiamenti. Una volta individuato uno spostamento, puoi quindi eseguire il debug in modo più approfondito.
Puoi creare aspettative sulla percentuale di parole fuori vocabolario basate sugli esempi dei dati di produzione “buoni” accumulati nel tempo. Ad esempio, se guardi il corpus delle precedenti recensioni dei prodotti, potresti aspettarti che le parole fuori vocabolario siano inferiori al 10% e monitorare se il valore supera questa soglia.
Caratteri non alfabetici
Correlato, ma con una variante: questo descrittore conterà tutti i tipi di simboli speciali che non sono lettere o numeri, inclusi virgole, parentesi, hashtag, ecc.
A volte ti aspetti una buona quantità di simboli speciali: i tuoi testi potrebbero contenere codice o essere strutturati come JSON. A volte, ti aspetti solo segni di punteggiatura in testo leggibile dall’uomo.
Rilevare uno spostamento nei caratteri non alfabetici può evidenziare problemi di qualità dei dati, come codici HTML che si infiltrano nei testi delle recensioni, attacchi di spam, casi d’uso imprevisti, ecc.
Sentimento

Il sentimento del testo è un altro indicatore utile in vari scenari: dalle conversazioni con chatbot alle recensioni degli utenti e alla scrittura di testi di marketing. Di solito puoi stabilire un’aspettativa sul sentimento dei testi con cui hai a che fare.
Anche se il sentimento “non si applica”, ciò potrebbe tradursi nell’aspettativa di un tono principalmente neutro. La comparsa potenziale di un tono negativo o positivo merita di essere monitorata e approfondita. Potrebbe indicare scenari d’uso imprevisti: l’utente sta usando il tuo consulente virtuale per ipoteche come canale di lamentela?
Potresti anche aspettarti un certo equilibrio: ad esempio, c’è sempre una quota di conversazioni o recensioni con un tono negativo, ma ti aspetti che non superino una certa soglia o che la distribuzione complessiva del sentimento delle recensioni rimanga stabile.
Parole trigger

Puoi anche verificare se i testi contengono parole da una o più liste specifiche e considerare ciò come una caratteristica binaria.
Questa è un modo potente per codificare molte aspettative sui tuoi testi. Hai bisogno di un certo sforzo per curare manualmente le liste, ma puoi progettare molti utili controlli in questo modo. Ad esempio, puoi creare liste di parole trigger come:
- Menzioni di prodotti o marchi.
- Menzioni di concorrenti.
- Menzioni di luoghi, città, posti, ecc.
- Menzioni di parole che rappresentano argomenti particolari.
Puoi curare (e continuamente estendere) liste come queste che sono specifiche per il tuo caso d’uso.
Ad esempio, se un chatbot consulente aiuta a scegliere tra i prodotti offerti dall’azienda, potresti aspettarti che la maggior parte delle risposte contenga i nomi di uno dei prodotti dalla lista.
Corrispondenze RegExp
L’inclusione di parole specifiche dalla lista è solo un esempio di un pattern che puoi formulare come espressione regolare. Puoi pensarne altri: ti aspetti che i tuoi testi inizino con “ciao” e finiscano con “grazie”? Includono indirizzi email? Contengono elementi nominati noti?
Se si prevede che gli input o gli output del modello corrispondano a un formato specifico, è possibile utilizzare la corrispondenza delle espressioni regolari come ulteriore descrizione.
Descrittori personalizzati
È possibile estendere ulteriormente questa idea. Ad esempio:
- Valutare altre proprietà del testo: tossicità, soggettività, formalità del tono, punteggio di leggibilità, ecc. Spesso è possibile trovare modelli pre-addestrati aperti per fare il trucco.
- Contare componenti specifici: email, URL, emoji, date e parti del discorso. È possibile utilizzare modelli esterni o semplici espressioni regolari.
- Ottenere dettagli statistici: è possibile monitorare statistiche molto dettagliate sul testo se sono significative per il caso d’uso, ad esempio, monitorare le lunghezze medie delle parole, se sono in maiuscolo o minuscolo, il rapporto di parole uniche, ecc.
- Monitorare le informazioni personalmente identificabili: ad esempio, quando non ci si aspetta che compaiano nelle conversazioni con i chatbot.
- Utilizzare il riconoscimento delle entità nominate: per estrarre entità specifiche e trattarle come tag.
- Utilizzare la modellazione degli argomenti per costruire un sistema di monitoraggio degli argomenti. Questo è l’approccio più laborioso ma potente quando viene fatto correttamente. È utile quando ci si aspetta che i testi rimangano principalmente sul tema e si ha un corpus di esempi precedenti per addestrare il modello. È possibile utilizzare il clustering degli argomenti non supervisionato e creare un modello per assegnare nuovi testi a cluster noti. È quindi possibile trattare le classi assegnate come descrittori per monitorare le modifiche nella distribuzione degli argomenti nei nuovi dati.

Ecco alcune cose da tenere a mente durante la progettazione dei descrittori da monitorare:
- È meglio rimanere concentrati e cercare un piccolo numero di indicatori di qualità adatti che corrispondano al caso d’uso anziché monitorare tutte le possibili dimensioni. Pensate ai descrittori come a caratteristiche del modello. Volete trovare quelli forti anziché generare molte caratteristiche deboli o inutili. Molte di esse sono destinate a essere correlate: lingua e percentuale di parole sconosciute, lunghezza in frasi e simboli, ecc. Scegliete i vostri preferiti!
- Utilizzare l’analisi esplorativa dei dati per valutare le proprietà del testo nei dati esistenti (ad esempio, registri di conversazioni precedenti) per testare le vostre ipotesi prima di aggiungerle al monitoraggio del modello.
- Imparare dai fallimenti del modello. Ogni volta che si affronta un problema di qualità del modello di produzione che si prevede di ripresentarsi (ad esempio, testi in una lingua straniera), considerare come sviluppare un caso di test o un descrittore da aggiungere per rilevarlo in futuro.
- Attenzione al costo di calcolo. Utilizzare modelli esterni per valutare i vostri testi per ogni possibile dimensione è allettante, ma ciò comporta un costo. Consideratelo quando lavorate con set di dati più grandi: ogni classificatore esterno è un modello aggiuntivo da eseguire. Spesso è possibile ottenere risultati con meno controlli o controlli più semplici.
Tutorial passo passo
Per illustrare l’idea, seguiremo il seguente scenario: si sta costruendo un modello di classificazione per valutare le recensioni che gli utenti lasciano su un sito di e-commerce e assegnarle per argomento. Una volta che il modello è in produzione, si desidera rilevare eventuali cambiamenti nei dati e nell’ambiente del modello, ma non si hanno le etichette corrette. È necessario eseguire un processo di etichettatura separato per ottenerle.
Come è possibile tenere traccia dei cambiamenti senza le etichette?
Prendiamo un dataset di esempio e seguiamo i seguenti passaggi:
Esempio di codice: vai al notebook di esempio per seguire tutti i passaggi.
💻 1. Installa Evidently
Prima di tutto, installa Evidently. Utilizza il gestore dei pacchetti di Python per installarlo nel tuo ambiente. Se stai lavorando in Colab, esegui !pip install. Nel notebook di Jupyter, dovresti anche installare nbextension. Consulta le istruzioni per il tuo ambiente.
Dovrai anche importare alcune altre librerie come pandas e specifici componenti di Evidently. Segui le istruzioni nel notebook.
🔡 2. Prepara i dati
Una volta impostato tutto, diamo un’occhiata ai dati! Lavorerai con un dataset aperto di recensioni di e-commerce.
Ecco come appare il dataset:

Ci concentreremo sulla colonna “Review_Text” a scopo dimostrativo. In produzione, vogliamo monitorare i cambiamenti nei testi delle recensioni.
Dovrai specificare la colonna che contiene i testi utilizzando il mapping delle colonne:
column_mapping = ColumnMapping( numerical_features=['Età', 'Conteggio_Feedback_Positivi'], categorical_features=['Nome_Divisione', 'Nome_Departimento', 'Nome_Classe'], text_features=['Testo_Recensione', 'Titolo'])
Dovresti anche suddividere i dati in due parti: riferimento e corrente. Immagina che i dati di “riferimento” siano i dati per un periodo passato rappresentativo (ad esempio, mese precedente) e “corrente” siano i dati di produzione attuali (ad esempio, questo mese). Questi sono i due dataset che confronti utilizzando i descrittori.
Nota: è importante stabilire una linea temporale storica adeguata. Scegli il periodo che riflette le tue aspettative su come i dati dovrebbero apparire in futuro.
Abbiamo selezionato 5000 esempi per ogni campione. Per rendere le cose interessanti, abbiamo introdotto uno spostamento artificiale selezionando le recensioni negative per il nostro dataset corrente.
recensioni_rif = recensioni[recensioni.Voto > 3].sample(n=5000, replace=True, ignore_index=True, random_state=42)recensioni_cor = recensioni[recensioni.Voto < 3].sample(n=5000, replace=True, ignore_index=True, random_state=42)
📊 3. Analisi esplorativa dei dati
Per comprendere meglio i dati, puoi generare un report visivo utilizzando Evidently. È disponibile un preset predefinito Panoramica testo che consente di confrontare rapidamente due dataset di testo. Combina vari controlli descrittivi e valuta la deriva complessiva dei dati (in questo caso, utilizzando un metodo di rilevamento della deriva basato su modello).
Questo report include anche alcuni descrittori standard e consente di aggiungere descrittori utilizzando liste di Trigger Words. Esamineremo i seguenti descrittori come parte del report:
- Lunghezza dei testi
- Percentuale di parole OOV
- Percentuale di simboli non alfabetici
- Il sentimento delle recensioni
- Recensioni che includono le parole “vestito” o “abito”
- Recensioni che includono le parole “blusa” o “camicia”
Consulta la documentazione di Evidently sui Descrittori per ulteriori dettagli.
Ecco il codice che devi eseguire per questo report. Puoi assegnare nomi personalizzati a ciascun descrittore.
report_panoramica_testo = Report(metrics=[ TextOverviewPreset(column_name="Testo_Recensione", descriptors={ "Testi delle recensioni - % OOV" : OOV(), "Testi delle recensioni - % Non Alfabetico" : PercentualeCaratteriNonAlfabetici(), "Testi delle recensioni - Lunghezza Simboli" : LunghezzaTesto(), "Testi delle recensioni - Numero Frasi" : ConteggioFrasi(), "Testi delle recensioni - Numero Parole" : ConteggioParole(), "Testi delle recensioni - Sentimento" : Sentimento(), "Recensioni su Vestiti" : PresenzaTriggerWords(words_list=['vestito', 'abito']), "Recensioni su Bluse" : PresenzaTriggerWords(words_list=['blusa', 'camicia']), }) ]) report_panoramica_testo.run(dati_riferimento=recensioni_rif, dati_correnti=recensioni_cor, mapping_colonne=column_mapping) report_panoramica_testo
Eseguendo un report come questo, è possibile esplorare i modelli e plasmare le aspettative su proprietà particolari, come la distribuzione della lunghezza del testo.
La distribuzione del descrittore “sentimento” mette rapidamente in evidenza il trucco che abbiamo fatto durante la suddivisione dei dati. Abbiamo inserito le recensioni con un punteggio superiore a 3 nel dataset di “riferimento” e recensioni più negative nel dataset “corrente”. I risultati sono visibili:

Il report predefinito è molto completo e consente di esaminare molte proprietà del testo contemporaneamente. Fino a esplorare le correlazioni tra descrittori e altre colonne nel dataset!
Puoi usarlo durante la fase esplorativa, ma probabilmente non è qualcosa che devi fare tutto il tempo.
Felizmente, è facile personalizzare.
Chiaramente Impostazioni predefinite e metriche. Chiaramente ha preset di report che generano rapidamente i report pronti all’uso. Tuttavia, ci sono molte metriche individuali tra cui scegliere! Puoi combinarle per creare un report personalizzato. Sfoglia i preset e le metriche per capire cosa c’è.
📈 4. Monitora la variazione dei descrittori
Supponiamo che, in base all’analisi esplorativa e alla comprensione del problema aziendale, decidi di tenere traccia di un numero limitato di proprietà:
Vuoi accorgerti quando c’è un cambiamento statistico: le distribuzioni di queste proprietà differiscono dal periodo di riferimento. Per rilevarlo, puoi utilizzare i metodi di rilevamento della variazione implementati in Chiaramente. Ad esempio, per le caratteristiche numeriche come “sentiment”, per impostazione predefinita monitorerà lo spostamento utilizzando la distanza di Wasserstein. Puoi anche scegliere un metodo diverso.
Ecco come puoi creare un semplice rapporto di variazione per tenere traccia delle modifiche nei tre descrittori.
descriptors_report = Report(metrics=[ ColumnDriftMetric(WordCount().for_column("Review_Text")), ColumnDriftMetric(Sentiment().for_column("Review_Text")), ColumnDriftMetric(TriggerWordsPresence(words_list=['dress', 'gown']).for_column("Review_Text")), ]) descriptors_report.run(reference_data=reviews_ref, current_data=reviews_cur, column_mapping=column_mapping) descriptors_report
Una volta eseguito il report, otterrai visualizzazioni combinate per tutti i descrittori scelti. Ecco uno:

La linea verde scuro è il sentiment medio nel dataset di riferimento. L’area verde copre una deviazione standard dalla media. Puoi notare che la distribuzione attuale (in rosso) è visibilmente più negativa.
Nota: In questo scenario, ha senso monitorare anche la variazione dell’output: tenendo traccia delle variazioni nelle classi previste. Puoi utilizzare metodi di rilevamento della variazione dei dati categorici, come la divergenza JS. Non trattiamo questo nel tutorial, poiché ci concentriamo solo sugli input e non generiamo previsioni. Nella pratica, la variazione delle previsioni è spesso il primo segnale a cui reagire.
😍 5. Aggiungi un descrittore “emozione”
Supponiamo che tu abbia deciso di tenere traccia di un’altra proprietà significativa: l’emozione espressa nella recensione. Il sentiment generale è una cosa, ma aiuta anche a distinguere tra recensioni “tristi” e “arrabbiate”, ad esempio.
Aggiungi questo descrittore personalizzato! Puoi trovare un modello open-source esterno appropriato per valutare il tuo dataset. Quindi, lavorerai con questa proprietà come colonna aggiuntiva.
Prenderemo il modello Distilbert da Huggingface, che classifica il testo in base a cinque emozioni.
Puoi considerare l’utilizzo di qualsiasi altro modello per il tuo caso d’uso, come riconoscimento delle entità nominate, rilevamento della lingua, rilevamento della tossicità, ecc.
Devi installare transformers per poter eseguire il modello. Verifica le istruzioni per ulteriori dettagli. Quindi, applicalo al dataset delle recensioni:
from transformers import pipeline classifier = pipeline("text-classification", model='bhadresh-savani/distilbert-base-uncased-emotion', top_k=1) prediction = classifier("Amo usare Chiaramente! È facile da usare", ) print(prediction)
Nota: questa operazione valuterà il dataset utilizzando il modello esterno. Ci vorrà del tempo per eseguire, a seconda del tuo ambiente. Per capire il principio senza attendere, consulta la sezione “Esempio semplice” nel notebook di esempio.
Dopo aver aggiunto la nuova colonna “emozione” al dataset, devi riflettere questo nella Column Mapping. Dovresti specificare che si tratta di una nuova variabile categorica nel dataset.
column_mapping = ColumnMapping( numerical_features=['Age', 'Positive_Feedback_Count'], categorical_features=['Division_Name', 'Department_Name', 'Class_Name', 'emozione'], text_features=['Review_Text', 'Title'] )
Ora puoi aggiungere il monitoraggio della variazione nella distribuzione dell'”emozione” al Report.
descriptors_report = Report(metrics=[ ColumnDriftMetric(WordCount().for_column("Review_Text")), ColumnDriftMetric(Sentiment().for_column("Review_Text")), ColumnDriftMetric(TriggerWordsPresence(words_list=['dress', 'gown']).for_column("Review_Text")), ColumnDriftMetric('emozione'), ]) descriptors_report.run(reference_data=reviews_ref, current_data=reviews_cur, column_mapping=column_mapping) descriptors_report
Ecco cosa ottieni!

Puoi vedere un aumento significativo delle recensioni “tristi” e una diminuzione delle recensioni “gioiose”.
Appare utile tracciare nel tempo? Puoi continuare ad eseguire questo controllo valutando i nuovi dati man mano che arrivano.
🏗️ 6. Esegui i test del processo
Per eseguire un’analisi regolare dei tuoi dati di input, ha senso raggruppare le valutazioni come test. In questo scenario, otterrai un risultato chiaro di “pass” o “fallito”. Probabilmente non hai bisogno di guardare i grafici se tutti i test passano. Sei interessato solo quando le cose cambiano!
Evidentemente ha un’interfaccia alternativa chiamata Test Suite che funziona in questo modo.
Ecco come creare un Test Suite per verificare la distribuzione statistica negli stessi quattro descrittori:
descriptors_test_suite = TestSuite(tests=[ TestColumnDrift(column_name = 'emotion'), TestColumnDrift(column_name = WordCount().for_column("Review_Text")), TestColumnDrift(column_name = Sentiment().for_column("Review_Text")), TestColumnDrift(column_name = TriggerWordsPresence(words_list=['dress', 'gown']).for_column("Review_Text")), ]) descriptors_test_suite.run(reference_data=reviews_ref, current_data=reviews_cur, column_mapping=column_mapping) descriptors_test_suite
Nota: abbiamo usato le impostazioni predefinite, ma puoi anche impostare metodi e condizioni di drift personalizzati.
Ecco il risultato. L’output è strutturato in modo ordinato in modo da poter vedere quali descrittori hanno subito drift.

Rilevare il drift della distribuzione statistica è uno dei modi per monitorare i cambiamenti nelle proprietà del testo. Ce ne sono altri! A volte, è comodo eseguire aspettative basate su regole sui valori minimi, massimi o medi del descrittore.
Diciamo che vuoi verificare che tutti i testi delle recensioni siano più lunghi di due parole. Se almeno una recensione è più corta di due parole, vuoi che il test fallisca e vedere il numero di testi brevi nella risposta.
Ecco come si fa! Puoi scegliere un controllo TestNumberOfOutRangeValues(). Questa volta, devi impostare un limite personalizzato: il lato “sinistro” dell’intervallo previsto sono due parole. Devi anche impostare una condizione di test: eq=0. Questo significa che ti aspetti che il numero di oggetti al di fuori di questo intervallo sia 0. Se è maggiore, vuoi che il test restituisca un fallimento.
descriptors_test_suite = TestSuite(tests=[ TestNumberOfOutRangeValues(column_name = WordCount().for_column("Review_Text"), left=2, eq=0), ]) descriptors_test_suite.run(reference_data=reviews_ref, current_data=reviews_cur, column_mapping=column_mapping) descriptors_test_suite
Ecco il risultato. Puoi anche vedere i dettagli del test che mostrano l’aspettativa definita.

Puoi seguire questo principio per progettare altri controlli.
Supporta Evidently
Ti è piaciuto il tutorial? Metti una stella a Evidently su GitHub per contribuire! Questo ci aiuta a continuare a creare strumenti e contenuti gratuiti e open-source per la comunità. ⭐️ Metti una stella su GitHub ⟶
Conclusione
I descrittori di testo mappano i dati di testo in dimensioni interpretabili che possono essere espresse come attributi numerici o categorici. Aiutano a descrivere, valutare e monitorare dati non strutturati.
In questo tutorial, hai imparato come monitorare i dati di testo utilizzando i descrittori.
Puoi utilizzare questo approccio per monitorare il comportamento dei modelli basati su NLP e LLM in produzione. Puoi personalizzare e combinare i tuoi descrittori con altri metodi, come il monitoraggio del drift dell’embedding.
Esistono altri descrittori che consideri universalmente utili? Fatecelo sapere! Unisciti alla nostra comunità Discord per condividere le tue opinioni.
Inizialmente pubblicato su https://www.evidentlyai.com il 27 giugno 2023. Grazie a Olga Filippova per aver co-scritto l’articolo.