Du lurer kanskje på begrepet Zipf distribusjon. For å forstå hva vi mener med dette begrepet, må vi definere Zipfs lov først. Ikke bekymre deg, jeg vil holde alt enkelt.
Zipfs lov sier ganske enkelt at gitt et korpus (stort og strukturert sett med tekster) av naturlige språkuttalelser, forekomsten av det hyppigste ordet vil være omtrent dobbelt så ofte som det nest vanligste ordet, tre ganger det tredje hyppigste ordet, fire ganger som det fjerde hyppigste ordet og så videre.
La oss se på et eksempel på det. Hvis du ser på Brown Corpus of American English, vil du legge merke til at det hyppigste ordet er de (69 971 hendelser). Hvis vi ser på det nest vanligste ordet, så er det av, vi vil legge merke til at det skjer 36.411 ganger.
Ordet de står for rundt 7% av Brown Corpus-ordene (69.971 av litt over 1 million ord). Hvis vi kommer til ordet av, vi vil legge merke til at det står for rundt 3,6% av corpus (rundt halvparten av de). Dermed kan vi merke at Zipfs lov gjelder denne situasjonen.
Dermed prøver Zipfs lov å fortelle oss at et lite antall elementer vanligvis utgjør de fleste aktivitetene vi observerer. For eksempel utgjør et lite antall sykdommer (kreft, hjerte-og karsykdommer) størstedelen av dødsfall. Dette gjelder også ord som står for hovedparten av alle ordsituasjonene i litteraturen, og mange andre eksempler i våre liv.
Før du går videre, la meg referere deg til dataene vi skal bruke til å eksperimentere med i opplæringen vår. Våre data denne gangen kommer fra National Library of Medicine. Vi laster ned det som heter ASCII-fil fra MeSH (Medical Subject Heading), herfra. Spesielt d2016.bin (28 MB).
Jeg vil ikke gå i detalj med å beskrive denne filen siden den er utenfor omfanget av denne opplæringen, og vi trenger bare å eksperimentere med koden vår.
Etter at du har lastet ned dataene i avsnittet ovenfor, la oss nå begynne å bygge vårt Python-skript som vil finne Zipfs distribusjon av dataene i d2016.bin
.
Det første vanlige trinnet å utføre er å åpen
filen:
open_file = open ('d2016.bin', 'r')
For å utføre de nødvendige operasjonene på bin
fil, må vi laste filen i en strengvariabel. Dette kan enkelt oppnås ved hjelp av lese()
funksjon, som følger:
file_to_string = open_file.read ()
Siden vi skal lete etter noe mønster (dvs. ord), kommer regulære uttrykk inn i spill. Vi vil dermed bruke Python re
modul.
På dette punktet har vi allerede lest bin
fil og lastet innholdet i en strengvariabel. Finne Zipfs distribusjon betyr å finne hyppigheten av forekomst av ord i bin
fil. Det vanlige uttrykket vil dermed bli brukt til å finne ordene i filen.
Metoden vi skal bruke til å lage en slik kamp er findall ()
metode. Som nevnt i re
modul dokumentasjon om findall ()
, metoden vil:
Returner alle ikke-overlappende kamper av mønster i string, som en liste over strenger. De string skannes venstre til høyre, og kampene returneres i den funnet rekkefølgen. Hvis en eller flere grupper er til stede i mønsteret, returner du en liste over grupper; Dette vil være en liste over tuples hvis mønsteret har mer enn en gruppe. Tomme kamper er inkludert i resultatet, med mindre de berører begynnelsen av en annen kamp.
Det vi vil gjøre er å skrive et vanlig uttrykk som vil finne alle de enkelte ordene i tekststrengvariabelen. Det vanlige uttrykket som kan utføre denne oppgaven er:
\ B [A-Za-z] [a-z] 2,10 \ b
hvor \ b
er et anker for ordgrenser. I Python kan dette bli representert som følger:
ord = re.findall (r '(b [A-Za-z] [a-z] 2,9 \ b)', file_to_string)
Dette regulære uttrykket forklarer oss i utgangspunktet å finne alle ordene som begynner med et brev (store eller små bokstaver) og etterfulgt av en sekvens av bokstaver som består av minst 2
tegn og ikke mer enn 9
tegn. Med andre ord, størrelsen på ordene som vil bli inkludert i utgangen vil variere fra 3
til 10
tegn lang.
Vi kan nå kjøre en loop som har som mål å beregne hyppigheten av forekomsten av hvert ord:
for ord i ord: count = frequency.get (word, 0) frequency [word] = count + 1
Her, hvis ordet ikke er funnet ennå i ordlisten, i stedet for å heve en KeyError
, standardverdien 0
returneres. Ellers økes telling med 1
, som representerer antall ganger ordet har skjedd i listen hittil.
Endelig vil vi skrive ut nøkkelverdierparet i ordlisten, vise ordet (nøkkelen) og antall ganger det viste seg i listen (verdi):
for nøkkel, verdi i omvendt (sortert (frequency.items (), key = itemgetter (1))): utskriftstast, verdi
Denne delen sortert (frequency.items (), key = itemgetter (1))
sorterer utgangen etter verdi i stigende rekkefølge, det vil si at det viser ordene fra den minst hyppige forekomsten til den hyppigste forekomsten. For å liste de vanligste ordene i begynnelsen, bruker vi reversert ()
metode.
Etter å ha gått gjennom de forskjellige byggeblokkene i programmet, la oss se hvordan alt ser ut sammen:
import re fra operatør import itemgetter frequency = open_file = open ('d2016.bin', 'r') file_to_string = open_file.read () ord = re.findall (r '(\ b [A-Za-z] [ az] 2,9 \ b) ', file_to_string) for ord i ord: count = frequency.get (word, 0) frekvens [word] = count + 1 for nøkkel, verdi i omvendt (sortert (frequency.items ), nøkkel = itemgetter (1))): utskriftstast, verdi
Jeg vil vise de første ti ordene og deres frekvenser returnert av programmet:
42602 abcdef 31913 og 30699 abbcdef 27016 var 17430 se 16189 med 14380 under 13127 for 9767 abcdefv 8694
Fra denne Zipf-distribusjonen kan vi validere Zipfs lov ved at noen ord (høyfrekvente ord) representerer hovedparten av ordene, som vi kan se over de
, og
, var
, til
. Dette gjelder også sekvensene A B C D E F
, abbcdef
, og abcdefv
som er svært hyppige brev sekvenser som har noen betydning spesielt for denne filen.
I denne opplæringen har vi sett hvordan Python gjør det enkelt å arbeide med statistiske begreper som Zipfs lov. Python kommer veldig praktisk, spesielt når du arbeider med store tekstfiler, noe som ville kreve mye tid og krefter hvis vi skulle finne Zipfs distribusjon manuelt. Som vi så, kunne vi raskt laste, analysere og finne Zipfs distribusjon av en fil med størrelse 28 MB. Tenk på enkelheten ved å sortere utdata takket være Pythons ordbøker.