Cum se utilizează Python pentru a găsi distribuția Zipf a unui fișier text

S-ar putea să te întrebi termenul Distribuția Zipf. Pentru a înțelege ce înțelegem prin acest termen, trebuie să definim Legea lui Zipf primul. Nu vă faceți griji, voi păstra totul simplu. 

Legea lui Zipf

Legea lui Zipf precizează pur și simplu că, dată fiind un corpus (textul larg și structurat de texte) al cuvântărilor limbajului natural, apariția celui mai frecvent cuvânt va fi de aproximativ două ori mai frecvent decât al doilea cuvânt cel mai frecvent, de trei ori cel de-al treilea cuvânt cel mai frecvent, de patru ori ca al patrulea cuvânt cel mai frecvent și așa mai departe.  

Să ne uităm la un exemplu. Dacă te uiți în Brown Corpus of American English, vei observa că cel mai frecvent cuvânt este (69.971 apariții). Dacă privim cel de-al doilea cuvânt cel mai frecvent, asta este de, vom observa că apare de 36.411 de ori.

Cuvantul reprezintă aproximativ 7% din cuvintele Brown Corpus (69,971 cu puțin peste 1 milion de cuvinte). Dacă venim la cuvânt de, vom observa că reprezintă aproximativ 3,6% din corpus (aproximativ jumătate din ). Astfel, putem observa că legea lui Zipf se aplică acestei situații.

Astfel, legea lui Zipf încearcă să ne spună că un număr mic de articole reprezintă, de obicei, cea mai mare parte a activităților pe care le observăm. De exemplu, un număr mic de boli (cancer, boli cardiovasculare) reprezintă cea mai mare parte a deceselor. Acest lucru se aplică și cuvintelor care reprezintă cea mai mare parte a tuturor aparițiilor de cuvinte din literatură și multe alte exemple din viața noastră.

Pregătirea datelor

Înainte de a merge mai departe, permiteți-mi să vă refer la datele pe care le vom folosi pentru a experimenta în tutorialul nostru. Datele noastre de data aceasta vor fi de la Biblioteca Națională de Medicină. Vom descărca ceea ce se numește un fișier ASCII MeSH (Subiect medical), de aici. În particular, d2016.bin (28 MB).

Nu voi intra în detaliu în descrierea acestui fișier, deoarece este dincolo de sfera de aplicare a acestui tutorial, și avem nevoie doar de el pentru a experimenta cu codul nostru.

Construirea programului

După ce ați descărcat datele din secțiunea de mai sus, începeți acum să construim scriptul Python care va găsi distribuția datelor Zipf în d2016.bin.

Primul pas normal pentru a efectua este de a deschis fișierul:

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

Pentru a efectua operațiunile necesare pe cos fișier, trebuie să încărcăm fișierul într-o variabilă de șir. Acest lucru poate fi realizat simplu folosind citit() funcție, după cum urmează:

file_to_string = open_file.read ()

Deoarece vom căuta un anumit tipar (adică cuvinte), vor intra în joc expresii regulate. Astfel vom folosi Python-ul re modul.

În acest moment am citit deja cos fișier și a încărcat conținutul său într-o variabilă de șir. Găsirea distribuției Zipf înseamnă găsirea frecvenței de apariție a cuvintelor în cos fişier. Expresia regulată va fi astfel utilizată pentru a localiza cuvintele din fișier.

Metoda pe care o vom folosi pentru a face o astfel de potrivire este Găsiți toate() metodă. După cum se menționează în re modulul despre module Găsiți toate(), metoda va:

Returnează toate meciurile care nu se suprapun model în şir, ca o listă de șiruri de caractere. şir este scanat de la stânga la dreapta și meciurile sunt returnate în ordinea găsită. Dacă unul sau mai multe grupuri sunt prezente în model, returnați o listă de grupuri; aceasta va fi o listă de tupluri dacă modelul are mai multe grupuri. Meciurile goale sunt incluse în rezultat, cu excepția cazului în care atinge începutul unui alt meci.

Ceea ce vrem să facem este să scriem o expresie regulată care să găsească toate cuvintele individuale din variabila șir de text. Expresia obișnuită care poate îndeplini această sarcină este:

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

Unde \ b este o ancoră pentru limitele cuvintelor. În Python, acesta poate fi reprezentat după cum urmează:

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

Această expresie regulată ne spune, în principiu, să găsim toate cuvintele care încep cu o literă (majuscule sau cu litere mici) și urmate de o succesiune de litere care constau cel puțin dintr- 2 personaje și nu mai mult de 9 de caractere. Cu alte cuvinte, mărimea cuvintelor care vor fi incluse în ieșire va varia de la 3 la 10 caractere lungi.

Acum putem rula o buclă care vizează calcularea frecvenței apariției fiecărui cuvânt:

pentru cuvânt în cuvinte: count = frequency.get (word, 0) frecvență [word] = count + 1

Aici, dacă cuvântul nu este găsit încă în lista de cuvinte, în loc de a ridica a KeyError, valoarea implicită 0 este returnat. În caz contrar, numărul este incrementat de 1, reprezentând de câte ori cuvântul a apărut în listă până în prezent.

În cele din urmă, vom imprima perechea cheie-valoare a dicționarului, afișând cuvântul (cheie) și numărul de apariții în listă (valoare):

pentru cheie, valoare în inversat (sortat (frecvență.geturi (), cheie = itemgetter (1))): cheie de imprimare, valoare

Această parte sortate (frecvența.geturi (), key = itemgetter (1)) sortează ieșirea în funcție de valoare în ordine ascendentă, adică arată cuvintele de la cea mai puțin frecventă până la cea mai frecventă apariție. Pentru a lista cele mai frecvente cuvinte de la început, folosim inversat () metodă.

Punându-le pe toți împreună

După ce ați trecut prin diferitele blocuri ale programului, să vedem cum arată împreună:

importul de la operator import itemgetter frequency =  open_file = deschide ('d2016.bin', 'r') file_to_string = open_file.read () words = re.findall (r '(\ b [A-Za-z] (numar) = frecvență (cuvânt, 0) frecvență [cuvânt] = număr + 1 pentru cheie, valoare în inversat ), key = itemgetter (1))): cheia de imprimare, valoare

Voi arăta aici primele zece cuvinte și frecvențele lor returnate de program:

42602 abcdef 31913 și 30699 abbcdef 27016 a fost 17430 a se vedea 16189 cu 14380 sub 13127 pentru 9767 abcdefv 8694

Din această distribuție Zipf, putem valida legea lui Zipf prin faptul că unele cuvinte (cuvintele de înaltă frecvență) reprezintă cea mai mare parte a cuvintelor, așa cum vedem mai sus , și, a fost, pentru. Acest lucru se aplică și secvențelor abcdef, abbcdef, și abcdefv care sunt secvențe de literă foarte frecvente, care au o anumită semnificație pentru acest fișier.

Concluzie

În acest tutorial, am văzut cum Python ușurează lucrul cu concepte statistice, cum ar fi legea lui Zipf. Python vine foarte util, în special, atunci când lucrăm cu fișiere text mari, ceea ce ar necesita mult timp și efort dacă am fi găsit distribuția manuală a lui Zipf. După cum am văzut, am reușit să încărcăm rapid, să analizăm și să găsim distribuția Zipf a unui fișier cu dimensiunea de 28 MB. Să nu mai vorbim de simplitatea în sortarea rezultatelor grație dicționarelor Python.

Cod