Questo è il secondo post dedicato all'analisi quantitativa. Il motivo principale per cui ritorno sul tema è spudoratamente quello di pubblicizzare il mio corso online di analisi dei dati con R. Ci sono ancora 5 posti liberi, ed il costo, per gli iscritti alla newsletter, è di 350€ (200 per gli studenti). Il corso, interamente online, inizia martedì 29 giugno. Se sei interessata, contattami.
Questo post è focalizzato sulla possibilità di fare analisi quantitativa dei testi. Più in particolare voglio mostrare i passaggi ed i risultati di un processo di machine learning finalizzato ad estrarre delle parole chiave da un corpus di testi e ad utilizzare questi termini per classificare i testi in una clusterizzazione.
I testi su cui ho lavorato sono i pdf di articoli scientifici che ho scaricato negli ultimi 5 anni. Sono, grossomodo, 650 documenti. Ma prima di focalizzarmi su questo insieme, faccio una breve divagazione per introdurre la metodologia.
Indovina chi
Conosci il Project Gutenberg? È un progetto che raccoglie 60.000 ebook liberi, principalmente perché non più soggetti a copyright. Esiste un pacchetto in R, gutenbergr, che permette di cercare e scaricare in ambiente R i testi dei libri digitali.
Il primo esercizio che ho fatto è stato quello di estrarre le "parole chiave" dei libri di un autore piuttosto famoso ed applicare i passaggi descritti in questo post: Text classification with tidy data principles.
Queste sono i termini principali che ho estratto (ne ho tolti un paio per non rendere la cosa troppo facile):
sexual, psychic, libido, taboo, neuroses, neurosis, ego, infantile, totem, neurotic, dream, totemism, erogenous, dreams, sexuality, leonardo, normal, psychology, genital, genitals, dreamer, psychological, unconscious.
Riesci ad indovinare di che autore si tratta?
Estrarre le parole chiave dai pdf
Per poter applicare una procedura simile agli articoli della mia libreria, ho dovuto in primo luogo trasformare tutti i pdf in testo con uno script e la funzione pdftotext
.
Il secondo passaggio è stato di caricare tutti i testi in un data.frame
(una tabella di dati) in R, associandoli al nome del file corrispondente. Salvo poche eccezioni, da anni salvo gli articoli con il pattern anno(di pubblicazione)_autori_titolo. Ad esempio 2013_Friederici_Gierhan_The language network.pdf
. I file pdf sono però organizzati in una tassonomia - ovvero in una gerarchia di cartelle. Nello script di trasformazione ho fatto in modo di mantenere le etichette delle cartelle dove sono collocati. E dunque l'articolo di cui sopra è stato trasformato in cogsci_language_2013_Friederici_Gierhan_The language network.txt
, dove la cartella principale è cogsci
e quella secondaria language
.
Il terzo passaggio consiste nell'estrazione delle parole dai testi. Praticamente da una stringa che corrisponde al testo dell'intero articolo si ottiene un vettore che contiene tutte le parole di tutti gli articoli. Questo lunghissimo vettore (circa 10 milioni di token) viene pulito, togliendo tutti i token che contengono caratteri non alfabetici, togliendo le cosiddette stopwords (un elenco di parole estremamente comuni nella lingua di riferimento, in questo caso l'inglese) e togliendo tutte le parole che, nell'intero corpus, compaiono meno di 10 volte.
Quello che ne esce è una tabella come questa, ma con 8 milioni di termini.
"source" | "word" |
---|---|
da_classificare_2000_book_Dermot Moran_Introduction to Phenomenology.txt | hidden |
motivation_ncomms11793.txt | way |
cogsci_learning_2017_Gershman_Daw_Reinforcement Learning and Episodic Memory in Humans and Animals_ An Integrative Framework.txt | well |
statistica_ai_machine_learning_sentiment_analysis_2017_Bartov_al_Can Twitter help predict firm-level earnings and stock returns_.txt | societies |
statistica_methodology_qual_mixed_2011_book_Bernard_Research methods in anthropology_ Qualitative and quantitative approaches.txt | white |
motivation_interest_curiosity_attitude_2007_Petty_Persuasion_ From Single to Multiple to Meta-Cognitive Processes.txt | effect |
hci_design_experience_design_201x_Bevan_What is the difference between the purpose of usability and user experience evaluation methods.txt | tool |
hci_marketing_brand_2005_Ahuvia_Aaron_Beyond the extended self_ Loved objects and consumers_ identity narratives.txt | december |
cogsci_language_2013_Pickering_Garrod_An integrated theory of language production and comprehension.txt | b |
cogsci_semantic_thematic_2011_Estes__Golonka_Jones_Thematic Thinking_The Apprehension and Consequences of Thematic Relations.txt | thematic |
da_classificare_2010_Tse_Schema and Memory Consolidation.txt | retrieval |
statistica_methodology_qual_mixed_2005_Daymon_Holloway_Qualitative Research Methods in Public Relations and Marketing Communications.txt | reassurance |
da_classificare_2002_Kotler_Marketing_Management.txt | entities |
hci_action_network_theory_2014_Missonier_Fedida_Stakeholder analysis and engagement in projects_ From stakeholder relational perspective to stakeholder relational ontology.txt | comprised |
cogsci_language_2014_Gee_An introduction to discourse analysis_ Theory and method.txt | transcripts |
filosofia_retorica_2004_Rivkin_Ryan_Literary_Theory_-_An_Anthology_Blackwell.txt | character |
cogsci_planning_decision_2013_Friston_The anatomy of choice_ active inference and agency.txt | timescales |
cogsci_knowledge_2009_McNamara_Magliano_Toward a comprehensive model of comprehension.txt | text |
cogsci_planning_decision_2012_Diamond_Executive Functions.txt | et |
da_classificare_2012_Unger_Chandler_A project guide to ux design.txt | basic |
Questa tabella viene ulteriormente filtrata, togliendo tutte le parole con meno di 2 lettere. Inoltre, ho applicato la funzione di stemming, finalizzata ad uniformare le forme verbali diverse di uno stesso termine: wordStem function. Ad esempio
wordStem(c("win", "winning", "winner"))
[1] "win" "win" "winner"
winning
viene semplificato in win
.
Passaggio successivo: calcolo la frequenza delle parole in ogni documento e peso ogni parola di ogni documento in base alla inverse document frequency (tf–idf - Wikipedia). Attraverso questo calcolo posso pesare le parole in base a quanto sono comuni in quel corpus. Se una parola è usata in un documento ma è presente nella maggior parte dei documenti, è poco distintiva e dunque probabilmente non è una buona parola chiave. A questo punto, ho filtrato tutti i termini molto comuni all'interno del corpus. Contemporaneamente, ho tolto anche quei termini troppo specifici (presenti soltanto in uno, due, tre documenti) perché generalmente sono o nomi di autori citati o comunque termini poco interessanti.
Quello che ne esce è una lunga lista di parole chiave, che posso filtrare per documento. Ad esempio, le parole chiave del documento (estratto a sorte) cogsci_decision_2013_Evans Stanovich_Dual-process theories of higher cognition advancing the debate.txt
sono
distinct, system, believ, featur, theori, task, reflect, psycholog, attribut, tabl, defin, brain, argument, automat, reason, intellig, judgment, conflict, correl, rule, think, memori, oxford, mind, cognit, conscious, type, belief, bias, ration, intuit, west, disposit, england, kahneman, gigerenz, evan, dual, stanovich
Come potete vedere, alcuni termini sono troncati dallo stemming: theori
è la forma unificata di termini come theory o theories. Naturalmente se volessimo usare questi termini per creare delle parole chiave, dovremmo trovare il modo per rappresentare in forma comprensibile i termini troncati. A parte questo, una simile lista può costituire un utile punto di partenza per identificare le parole chiave. È però evidente che per essere usata dagli utenti la lista andrà pulita e valutata da un esperto.
Per la cronaca, l'articolo è questo: Dual-Process Theories of Higher Cognition: Advancing the Debate - Jonathan St. B. T. Evans, Keith E. Stanovich, 2013.
Classificare gli articoli
Dalla lista di termini divisa per documenti è possibile creare una matrice documenti*parole. E, su questa matrice, è possibile applicare dei metodi di clustering. Ad esempio, sulla matrice è possibile applicare la tecnica k-means, che crea una partizione: le n
voci sono divise in k<n
gruppi.
Considerato che abbiamo un insieme di circa 650 documenti dopo alcuni tentativi ho settato k=40
. I risultati del partizionamento sono piuttosto interessanti: il 50% circa degli articoli viene classificato in maniera piuttosto buona (pur con delle eccezioni). L'altra metà finisce in un calderone, un cluster di 300 e passa voci. Qual è la ragione di questo risultato? Utilizzando anche altre tecniche di analisi della matrice (ad esempio una variante della principal component analysis) ho notato che le voci che vengono classificate meglio sono quelle legate a temi meno presenti nel corpus. Ad esempio un piccolo gruppo di articoli dedicati al branding che si distanzia molto rispetto agli altri articoli. Un altro gruppo centrato sui concetti di empowerment e resilience, e così via. Rispetto ai 2-300 articoli più di confine gli articoli con un insieme di termini più comuni faticano a differenziarsi.
Un meccanismo per classificare anche questi articoli è quello di procedere iterativamente: si escludono tutti i documenti già classificati e si riavvia il processo utilizzando solo quelli del calderone. Anche in questo caso la clusterizzazione porta ad identificare delle categorie abbastanza buone per metà degli articoli (150 circa) mentre gli altri 150 finiscono di nuovo in un gruppo unico. Probabilmente (ma non ho provato) una nuova iterazione potrebbe portare alla classificazione anche di questi ultimi articoli.
Un metodo di clusterizzazione alternativo è la hierarchical cluster analysis. Nella classificazione del nostro corpus, i risultati della hca sembrano essere molto meno soggetti ai problemi riscontrati con le tecniche del k-means e della PCA. Dalla partizione di una cluster analysis gerarchica in 60 gruppi, ad esempio, ho ottenuto la classificazione che potete visualizzare in questo file csv.
Conclusioni
Il processo che ho adottato in questa analisi è esplorativo e ampiamente ottimizzabile: il mio scopo non è quello di arrivare alla clusterizzazione definitiva, ma di dimostrare le potenzialità di alcuni strumenti statistici di machine learning non supervisionato nel supportare la progettazione dell'architettura dell'informazione di un corpus di documenti abbastanza ampio da risultare oneroso con un approccio esclusivamente manuale.
Probabilmente se il calcolo della inverse document frequency si basasse sul confronto con un corpus di documenti più ampio ed eterogeneo dei documenti stessi da classificare potremmo ottenere una migliore selezione di parole chiave, e questo potrebbe avere una influenza positiva anche nel processo di clusterizzazione. Inoltre, sarebbe interessante sperimentare la classificazione non dei documenti ma delle parole chiave.
Credo che la machine learning non supervisionata possa essere applicata con profitto in un processo integrato dal lavoro di utenti ed esperti, attraverso i seguenti passaggi:
- Usare il metodo come analisi quantitativa preliminare
- Verificare a mano i risultati
- Confrontare con gli esperti
- Creare delle navigazioni a parole chiave
- Creare delle partizioni e delle tassonomie
Non ho pubblicato lo script in R utilizzato per fare i calcoli, perché è ancora in una versione spudoratamente spaghetti code. Se però sei interessata ad approfondire l'argomento o ti interessa il codice, non esitare a contattarmi.
Bibliografia
Ho affrontato il tema della possibilità di utilizzare strumenti di analisi dei dati nell'architettura dell'informazione già qualche anno fa: