Come usare Python per trovare la distribuzione Zipf di un file di testo

Potresti starmi chiedendo il termine Distribuzione Zipf. Per capire cosa intendiamo con questo termine, dobbiamo definire La legge di Zipf primo. Non preoccuparti, terrò tutto semplice. 

La legge di Zipf

La legge di Zipf afferma semplicemente che dato un corpus (grande e strutturato insieme di testi) di espressioni del linguaggio naturale, l'occorrenza della parola più frequente sarà circa il doppio della frequenza della seconda parola più frequente, tre volte la terza più frequente, quattro volte come la quarta parola più frequente, e così via.  

Diamo un'occhiata a un esempio di questo. Se osservi il Brown Corpus dell'inglese americano, noterai che la parola più frequente è il (69.971 occorrenze). Se guardiamo alla seconda parola più frequente, cioè di, noteremo che si verifica 36.411 volte.

La parola il rappresenta circa il 7% delle parole di Brown Corpus (69.971 di poco più di 1 milione di parole). Se veniamo alla parola di, noteremo che rappresenta circa il 3,6% del corpus (circa la metà di il). Quindi, possiamo notare che la legge di Zipf si applica a questa situazione.

Quindi, la legge di Zipf sta cercando di dirci che un piccolo numero di articoli di solito rappresenta la maggior parte delle attività che osserviamo. Ad esempio, un numero limitato di malattie (cancro, malattie cardiovascolari) rappresenta la maggior parte dei decessi. Questo vale anche per le parole che rappresentano la maggior parte di tutte le occorrenze di parole nella letteratura e molti altri esempi nelle nostre vite.

Preparazione dei dati

Prima di andare avanti, lascia che ti rimandi ai dati che useremo per sperimentare nel nostro tutorial. I nostri dati questa volta saranno dalla National Library of Medicine. Scaricheremo quello che viene chiamato un file ASCII MeSH (Medical Subject Heading), da qui. In particolare, d2016.bin (28 MB).

Non entrerò nei dettagli nella descrizione di questo file poiché è oltre lo scopo di questo tutorial, e abbiamo solo bisogno di sperimentare con il nostro codice.

Costruire il programma

Dopo aver scaricato i dati nella sezione precedente, iniziamo ora a creare il nostro script Python che troverà la distribuzione dei dati di Zipf in d2016.bin.

Il primo passo normale da eseguire è quello di Aperto il file:

open_file = open ('d2016.bin', 'r')

Al fine di effettuare le operazioni necessarie sul bidone file, dobbiamo caricare il file in una variabile stringa. Questo può essere semplicemente ottenuto usando il leggere() funzione, come segue:

file_to_string = open_file.read ()

Dato che cercheremo qualche schema (cioè parole), entrano in gioco le espressioni regolari. Faremo quindi uso di Python ri modulo.

A questo punto abbiamo già letto il bidone file e caricato il suo contenuto in una variabile stringa. Trovare la distribuzione di Zipf significa trovare la frequenza di occorrenza delle parole nel file bidone file. L'espressione regolare verrà quindi utilizzata per individuare le parole nel file.

Il metodo che useremo per creare una simile corrispondenza è il trova tutto() metodo. Come menzionato nel ri documentazione del modulo trova tutto(), il metodo:

Restituisce tutte le corrispondenze non sovrapposte di modello nel stringa, come una lista di stringhe. Il stringa viene scansionato da sinistra a destra e le corrispondenze vengono restituite nell'ordine trovato. Se uno o più gruppi sono presenti nel modello, restituisce un elenco di gruppi; questo sarà un elenco di tuple se il modello ha più di un gruppo. Le partite vuote sono incluse nel risultato a meno che non tocchino l'inizio di un'altra partita.

Quello che vogliamo fare è scrivere un'espressione regolare che localizzerà tutte le singole parole nella variabile stringa di testo. L'espressione regolare che può eseguire questa attività è:

\ B [A-Za-z] [a-z] 2,10 \ b

dove \ b è un'ancora per confini di parole. In Python, questo può essere rappresentato come segue:

words = re.findall (r '(\ b [A-Za-z] [a-z] 2,9 \ b)', file_to_string)

Questa espressione regolare ci sta essenzialmente dicendo di trovare tutte le parole che iniziano con una lettera (maiuscole o minuscole) e seguite da una sequenza di lettere che consistono almeno di 2 personaggi e non più di 9 personaggi. In altre parole, la dimensione delle parole che saranno incluse nell'output andrà da 3 a 10 personaggi lunghi.

Ora possiamo eseguire un ciclo che mira a calcolare la frequenza di occorrenza di ogni parola:

per parole in parole: count = frequency.get (word, 0) frequency [word] = count + 1

Qui, se la parola non viene ancora trovata nella lista delle parole, invece di aumentare a KeyError, il valore predefinito 0 viene restituito. Altrimenti, il conteggio viene incrementato di 1, fino ad ora rappresenta il numero di volte in cui la parola si è verificata nella lista.

Infine, stamperemo la coppia chiave-valore del dizionario, mostrando la parola (chiave) e il numero di volte in cui è apparso nella lista (valore):

per chiave, valore in ordine inverso (ordinato (frequency.items (), key = itemgetter (1))): chiave di stampa, valore

Questa parte ordinato (frequency.items (), key = itemgetter (1)) ordina l'output in base al valore in ordine crescente, ovvero mostra le parole dall'evento meno frequente all'evento più frequente. Per elencare le parole più frequenti all'inizio, usiamo il invertita () metodo.

Mettere tutto insieme

Dopo aver esaminato i diversi elementi costitutivi del programma, vediamo come tutto sembra insieme:

import re dall'operatore import itemgetter frequency =  open_file = open ('d2016.bin', 'r') file_to_string = open_file.read () words = re.findall (r '(\ b [A-Za-z] [ az] 2,9 \ b) ', file_to_string) per parola in parole: count = frequency.get (word, 0) frequency [word] = count + 1 per key, valore in reverse (ordinato (frequency.items ( ), key = itemgetter (1))): tasto di stampa, valore

Mostrerò qui le prime dieci parole e le loro frequenze restituite dal programma:

il 42602 abcdef 31913 e 30699 abbcdef 27016 era 17430 vedere 16189 con 14380 sotto 13127 per 9767 abcdefv 8694

Da questa distribuzione Zipf, possiamo convalidare la legge di Zipf in quanto alcune parole (parole ad alta frequenza) rappresentano la maggior parte delle parole, come possiamo vedere sopra il, e, era, per. Questo vale anche per le sequenze a B c D e F, abbcdef, e abcdefv che sono sequenze di lettere molto frequenti che hanno un significato particolare per questo file.

Conclusione

In questo tutorial, abbiamo visto come Python rende facile lavorare con concetti statistici come la legge di Zipf. Python è molto utile in particolare quando si lavora con file di testo di grandi dimensioni, il che richiederebbe molto tempo e fatica se dovessimo trovare manualmente la distribuzione di Zipf. Come abbiamo visto, siamo stati in grado di caricare, analizzare e trovare rapidamente la distribuzione Zipf di un file di dimensioni 28 MB. Per non parlare della semplicità nell'ordinamento dell'output grazie ai dizionari Python.