Du kanske undrar om termen Zipf-distribution. För att förstå vad vi menar med denna term, måste vi definiera Zipfs lag först. Oroa dig inte, jag kommer att hålla allt enkelt.
Zipfs lag säger helt enkelt att med tanke på en del corpus (stor och strukturerad uppsättning texter) av naturliga språkuttalanden kommer förekomsten av det vanligaste ordet att vara ungefär dubbelt så ofta som det näst vanligaste ordet, tre gånger det tredje vanligaste ordet, fyra gånger som det fjärde vanligaste ordet och så vidare.
Låt oss titta på ett exempel på det. Om du tittar på Brown English Corpus Brown, märker du att det vanligaste ordet är de (69 971 förekomster). Om vi tittar på det näst vanligaste ordet, så är det av, vi kommer märka att det uppstår 36.411 gånger.
Ordet de står för cirka 7% av Brown Corpus-orden (69.971 av drygt 1 miljon ord). Om vi kommer till ordet av, vi kommer att märka att det står för cirka 3,6% av corpus (cirka hälften av de). Således kan vi märka att Zipfs lag gäller för denna situation.
Således försöker Zipfs lag att berätta för oss att ett litet antal saker oftast står för de flesta aktiviteter vi observerar. Till exempel utgör ett litet antal sjukdomar (cancer, hjärt-kärlsjukdomar) huvuddelen av dödsfallet. Detta gäller också ord som står för huvuddelen av alla ordsituationer i litteraturen och många andra exempel i våra liv.
Innan jag går framåt, låt mig hänvisa dig till de data vi ska använda för att experimentera med i vår handledning. Våra data denna gång kommer att vara från National Library of Medicine. Vi laddar ner det som heter ASCII-filen från MeSH (Medical Subject Heading), härifrån. I synnerhet d2016.bin (28 MB).
Jag kommer inte att gå in i detalj med att beskriva den här filen eftersom den ligger utanför handledningen och vi behöver bara experimentera med vår kod.
När du har laddat ned data i ovanstående avsnitt, låt oss nu börja bygga vårt Python-skript som kommer att hitta Zipfs distribution av data i d2016.bin
.
Det första normala steget att utföra är att öppna
filen:
open_file = open ('d2016.bin', 'r')
För att kunna utföra de nödvändiga operationerna på bin
fil måste vi ladda filen i en strängvariabel. Detta kan enkelt uppnås med hjälp av läsa()
funktion, enligt följande:
file_to_string = open_file.read ()
Eftersom vi kommer att leta efter ett visst mönster (dvs ord), kommer reguljära uttryck till spel. Vi kommer sålunda att använda Python re
modul.
Vid denna tidpunkt har vi redan läst bin
fil och laddade innehållet i en strängvariabel. Att hitta Zipfs distribution betyder att man hittar frekvensen för att ord uppträder i bin
fil. Det reguljära uttrycket används sålunda för att lokalisera orden i filen.
Metoden vi ska använda för att göra en sådan match är hitta alla()
metod. Som nämnts i re
moduldokumentation om hitta alla()
, metoden kommer att
Återvänd alla överlappande matcher av mönster i sträng, som en lista över strängar. De sträng skannas åt vänster åt höger och matchningar returneras i den hittade ordningen. Om en eller flera grupper är närvarande i mönstret, returnera en lista med grupper; Detta kommer att vara en lista med tuples om mönstret har mer än en grupp. Tomma träffar ingår i resultatet om de inte berör början av en annan match.
Vad vi vill göra är att skriva ett regelbundet uttryck som hittar alla enskilda ord i textsträngvariabeln. Det reguljära uttrycket som kan utföra denna uppgift är:
\ B [A-Za-z] [a-z] 2,10 \ b
var \ b
är ett ankare för ordgränser. I Python kan detta representeras enligt följande:
ord = re.findall (r '(\ b [A-Za-z] [a-z] 2,9 \ b)', file_to_string)
Detta regelbundna uttryck säger i princip att vi hittar alla ord som börjar med ett brev (stor eller liten) och följt av en sekvens bokstäver som består av minst 2
tecken och inte mer än 9
tecken. Med andra ord, storleken på orden som kommer att ingå i produktionen kommer att sträcka sig från 3
till 10
tecken långa.
Vi kan nu köra en slinga som syftar till att beräkna frekvensen av varje ords förekomst:
för ord i ord: count = frequency.get (word, 0) frequency [word] = count + 1
Här, om ordet inte hittas ännu i listan med ord, istället för att höja en KeyError
, standardvärdet 0
returneras. Annars ökas räkningen med 1
, vilket motsvarar hur många gånger ordet har uppstått i listan hittills.
Slutligen kommer vi att skriva ut ordbokens nyckelvärdespar, som visar ordet (nyckeln) och hur många gånger det visades i listan (värde):
för nyckel, värde i omvänd (sorterat (frequency.items (), key = itemgetter (1))): skrivnyckel, värde
Den här delen sorterade (frequency.items (), key = itemgetter (1))
sorterar produktionen efter värde i stigande ordning, det vill säga det visar orden från den minst frekventa förekomsten till den vanligaste förekomsten. För att lista de vanligaste orden i början använder vi reverseras ()
metod.
Efter att ha gått igenom programmets olika byggstenar, låt oss se hur allt ser ut tillsammans:
import re från operatör 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) för ord i ord: count = frequency.get (word, 0) frekvens [word] = count + 1 för nyckel, värde i omvänd (sorterat (frequency.items ), nyckel = itemgetter (1))): utskriftsknapp, värde
Här kommer jag att visa de första tio orden och deras frekvenser som returneras av programmet:
42602 abcdef 31913 och 30699 abbcdef 27016 var 17430 se 16189 med 14380 under 13127 för 9767 abcdefv 8694
Från denna Zipf-distribution kan vi validera Zipfs lag genom att vissa ord (högfrekventa ord) representerar huvuddelen av orden, som vi kan se ovan de
, och
, var
, för
. Detta gäller också för sekvenserna abcdef
, abbcdef
, och abcdefv
vilka är mycket frekventa brev sekvenser som har viss betydelse för denna fil.
I denna handledning har vi sett hur Python gör det enkelt att arbeta med statistiska begrepp som Zipfs lag. Python kommer särskilt användbart när man arbetar med stora textfiler, vilket skulle kräva mycket tid och ansträngning om vi skulle hitta Zipfs distribution manuellt. Som vi såg kunde vi snabbt ladda, analysera och hitta Zipfs distribution av en fil med storlek 28 MB. Äntligen är det enkelt att sortera produktionen tack vare Pythons ordböcker.