Implementering af Word2Vec med Gensim-biblioteket i Python

Indledning

Mennesker har en naturlig evne til at forstå, hvad andre mennesker siger, og hvad de skal sige som svar. Denne evne er udviklet ved konsekvent at interagere med andre mennesker og samfundet gennem mange år. Sproget spiller en meget vigtig rolle i den måde, hvorpå mennesker interagerer. Sprog, som mennesker bruger til interaktion, kaldes naturlige sprog.

Reglerne for forskellige naturlige sprog er forskellige. Der er dog én ting, der er fælles for naturlige sprog: fleksibilitet og udvikling.

Naturlige sprog er meget meget fleksible. Lad os antage, at du kører bil, og din ven siger en af disse tre ytringer: “Kør ind til siden”, “Stop bilen”, “Stop”, “Stop”. Du forstår straks, at han beder dig om at stoppe bilen. Det skyldes, at naturlige sprog er ekstremt fleksible. Der er flere måder at sige én ting på.

Et andet vigtigt aspekt ved naturlige sprog er, at de hele tiden udvikler sig. For nogle få år siden fandtes der f.eks. ikke et udtryk som “Google it”, der henviser til at søge efter noget på søgemaskinen Google. Naturlige sprog er hele tiden under udvikling.

Det modsatte er, at computersprog følger en streng syntaks. Hvis man ønsker at bede en computer om at udskrive noget på skærmen, findes der en særlig kommando til det. Opgaven med Natural Language Processing er at få computere til at forstå og generere menneskesprog på en måde, der ligner menneskers.

Dette er en enorm opgave, og der er mange forhindringer forbundet hermed. Denne videoforelæsning fra University of Michigan indeholder en meget god forklaring på, hvorfor NLP er så svært.

I denne artikel vil vi implementere Word2Vec-ordindlejringsteknikken Word2Vec, der bruges til at skabe ordvektorer med Pythons Gensim-bibliotek. Men før vi springer direkte til kodningsafsnittet, vil vi først kort gennemgå nogle af de mest almindeligt anvendte word embedding-teknikker sammen med deres fordele og ulemper.

Word Embedding Approaches

En af grundene til, at Natural Language Processing er et vanskeligt problem at løse, er det faktum, at computere i modsætning til mennesker kun kan forstå tal. Vi er nødt til at repræsentere ord i et numerisk format, der kan forstås af computerne. Word embedding henviser til de numeriske repræsentationer af ord.

Der findes i øjeblikket flere metoder til word embedding, og de har alle deres fordele og ulemper. Vi vil diskutere tre af dem her:

  1. Bag of Words
  2. TF-IDF Scheme
  3. Word2Vec

Bag of Words

Bag of Words-tilgangen er en af de enkleste metoder til ordindlejring af ord. Følgende er trin til at generere ordindlejringer ved hjælp af metoden bag of words.

Vi vil se de ordindlejringer, der genereres ved hjælp af metoden bag of words, ved hjælp af et eksempel. Antag, at du har et korpus med tre sætninger.

  • S1 = jeg elsker regn
  • S2 = regn regn regn gå væk
  • S3 = jeg er væk

For at konvertere ovenstående sætninger til deres tilsvarende ordindlejringsrepræsentationer ved hjælp af metoden bag of words skal vi udføre følgende trin:

Bemærk, at vi for S2 har tilføjet 2 i stedet for “rain” i ordbogen; det skyldes, at S2 indeholder “rain” to gange.

For- og ulemper ved ordposer

Omgangen med ordposer har både fordele og ulemper. Den største fordel ved bag of words-tilgangen er, at man ikke har brug for et meget stort korpus af ord for at få gode resultater. Du kan se, at vi opbygger en meget grundlæggende bag of words-model med tre sætninger. Rent beregningsteknisk er en bag of words-model ikke særlig kompleks.

En stor ulempe ved bag of words-tilgangen er, at vi skal oprette enorme vektorer med tomme pladser for at repræsentere et tal (sparse matrix), hvilket bruger hukommelse og plads. I det foregående eksempel havde vi kun 3 sætninger. Alligevel kan du se tre nuller i hver vektor.

Forestil dig et korpus med tusindvis af artikler. I et sådant tilfælde kan antallet af unikke ord i en ordbog være tusindvis. Hvis et dokument indeholder 10 % af de unikke ord, vil den tilsvarende indlejringsvektor stadig indeholde 90 % nuller.

Et andet stort problem med bag of words-tilgangen er, at den ikke vedligeholder nogen kontekstinformation. Den er ligeglad med den rækkefølge, i hvilken ordene forekommer i en sætning. Den behandler f.eks. sætningerne “Flasken er i bilen” og “Bilen er i flasken” på samme måde, hvilket er helt forskellige sætninger.

En type tilgang med en pose ord, kendt som n-grammer, kan hjælpe med at bevare forholdet mellem ord. N-gram henviser til en sammenhængende sekvens af n ord. F.eks. er 2-grammer for sætningen “Du er ikke glad”, “Du er”, “er ikke” og “ikke glad”. Selv om n-grammer-tilgangen er i stand til at indfange relationer mellem ord, vokser størrelsen af funktionssættet eksponentielt med for mange n-grammer.

TF-IDF-ordningen

TF-IDF-ordningen er en type tilgang med sækkeord, hvor man i stedet for at tilføje nuller og ettaller i indlejringsvektoren tilføjer flydende tal, der indeholder mere nyttige oplysninger end nuller og ettaller. Ideen bag TF-IDF-ordningen er, at ord, der har en høj forekomsthyppighed i ét dokument og en mindre forekomsthyppighed i alle de andre dokumenter, er mere afgørende for klassificeringen.

TF-IDF er et produkt af to værdier: Term Frequency (TF) og Inverse Document Frequency (IDF).

Term Frequency refererer til antallet af gange et ord forekommer i dokumentet og kan beregnes som:

Term frequence = (Number of Occurences of a word)/(Total words in the document)

For eksempel, hvis vi ser på sætning S1 fra det foregående afsnit, dvs. “I love rain”, forekommer hvert ord i sætningen én gang og har derfor en frekvens på 1. I modsætning hertil for S2, dvs. “rain rain go away”, er frekvensen af “rain” to, mens den for resten af ordene er 1.

IDF refererer til logaritmen af det samlede antal dokumenter divideret med antallet af dokumenter, hvori ordet forekommer, og kan beregnes som:

IDF(word) = Log((Total number of documents)/(Number of documents containing the word))

For eksempel er IDF-værdien for ordet “rain” 0,1760, da det samlede antal dokumenter er 3, og rain forekommer i 2 af dem, og log(3/2) er derfor 0,1760. Hvis man på den anden side ser på ordet “love” i den første sætning, optræder det i et af de tre dokumenter, og derfor er dets IDF-værdi log(3), hvilket er 0,4771.

For- og ulemper ved TF-IDF

Og selv om TF-IDF er en forbedring i forhold til den simple “bag of words”-tilgang og giver bedre resultater for almindelige NLP-opgaver, er de overordnede fordele og ulemper stadig de samme. Vi skal stadig oprette en enorm sparsom matrix, hvilket også kræver meget mere beregning end den simple bag of words-tilgang.

Word2Vec

Den <a target=”_blank rel=”nofollow””” href=”https://en.wikipedia.org/wiki/Word2vec”>Word2Vec-indlejringstilgang, der er udviklet af Tomas Mikolov, anses for at være state of the art. Word2Vec-tilgangen anvender dybe indlærings- og neurale netværksbaserede teknikker til at konvertere ord til tilsvarende vektorer på en sådan måde, at de semantisk lignende vektorer ligger tæt på hinanden i et N-dimensionelt rum, hvor N henviser til vektorens dimensioner.

Word2Vec giver nogle forbløffende resultater. Word2Vec’s evne til at bevare den semantiske relation afspejles af et klassisk eksempel, hvor hvis man har en vektor for ordet “konge”, og man fjerner den vektor, der repræsenteres af ordet “mand” fra “konge” og tilføjer “kvinder” til den, får man en vektor, der ligger tæt på vektoren “dronning”. Denne relation repræsenteres almindeligvis som:

King - Man + Women = Queen

Vord2Vec-modellen findes i to varianter: Skip Gram-modellen og Continuous Bag of Words-modellen (CBOW).

I Skip Gram-modellen forudsiges kontekstordene ved hjælp af basisordet. Hvis man f.eks. får en sætning “Jeg elsker at danse i regnen”, vil Skip Gram-modellen forudsige “love” og “dance” med ordet “to” som input.

CBOW-modellen vil derimod forudsige “to”, hvis kontekstordene “love” og “dance” indlæses som input til modellen. Modellen lærer disse relationer ved hjælp af dybe neurale netværk.

For- og ulemper ved Word2Vec

Word2Vec har flere fordele i forhold til bag of words og IF-IDF-ordningen. Word2Vec bevarer den semantiske betydning af forskellige ord i et dokument. Kontekstoplysningerne går ikke tabt. En anden stor fordel ved Word2Vec-tilgangen er, at størrelsen af indlejringsvektoren er meget lille. Hver dimension i indlejringsvektoren indeholder oplysninger om ét aspekt af ordet. Vi har ikke brug for enorme sparsomme vektorer i modsætning til bag of words- og TF-IDF-tilgangen.

Note: De matematiske detaljer om, hvordan Word2Vec fungerer, indebærer en forklaring af neurale netværk og softmax-sandsynlighed, som ligger uden for rammerne af denne artikel. Hvis du ønsker at forstå det matematiske grundlag for Word2Vec, bedes du læse denne artikel: https://arxiv.org/abs/1301.3781

Word2Vec i Python med Gensim-biblioteket

I dette afsnit vil vi implementere Word2Vec-modellen ved hjælp af Pythons Gensim-bibliotek. Følg disse trin:

Skabelse af korpus

Vi har tidligere diskuteret, at for at skabe en Word2Vec-model har vi brug for et korpus. I virkelige applikationer oprettes Word2Vec-modeller ved hjælp af milliarder af dokumenter. Googles Word2Vec-model er f.eks. trænet ved hjælp af 3 millioner ord og sætninger. For enkelhedens skyld vil vi imidlertid oprette en Word2Vec-model ved hjælp af en enkelt Wikipedia-artikel. Vores model vil ikke være lige så god som Googles. Selv om den er god nok til at forklare, hvordan Word2Vec-modellen kan implementeres ved hjælp af Gensim-biblioteket.

Hvor vi kunne opsummere Wikipedia-artikler, skal vi hente dem. For at gøre det vil vi bruge et par biblioteker. Det første bibliotek, som vi skal downloade, er Beautiful Soup-biblioteket, som er et meget nyttigt Python-værktøj til webscraping. Udfør følgende kommando i kommandoprompten for at downloade hjælpeprogrammet Beautiful Soup.

$ pip install beautifulsoup4

Et andet vigtigt bibliotek, som vi skal bruge til at analysere XML og HTML, er biblioteket lxml. Udfør følgende kommando i kommandoprompten for at downloade lxml:

$ pip install lxml

Artiklen, som vi skal skrabe, er Wikipedia-artiklen om kunstig intelligens. Lad os skrive et Python-script til at skrabe artiklen fra Wikipedia:

I ovenstående script henter vi først Wikipedia-artiklen ved hjælp af urlopen-metoden i request-klassen i urllib-biblioteket. Derefter læser vi artiklens indhold og analyserer det ved hjælp af et objekt af BeautifulSoup-klassen. Wikipedia gemmer tekstindholdet i artiklen inden for p-tags. Vi bruger find_all-funktionen i BeautifulSoup-objektet til at hente alt indholdet fra artiklens afsnitstags.

Slutteligt samler vi alle afsnit og gemmer den skrabede artikel i article_text-variablen til senere brug.

Forbehandling

På dette tidspunkt har vi nu importeret artiklen. Det næste skridt er at forbehandle indholdet til Word2Vec-modellen. Følgende script forbehandler teksten:

I ovenstående script konverterer vi al teksten til små bogstaver og fjerner derefter alle cifre, specialtegn og ekstra mellemrum fra teksten. Efter forbehandlingen er vi kun tilbage med ordene.

Vord2Vec-modellen trænes på en samling af ord. Først skal vi konvertere vores artikel til sætninger. Vi bruger nltk.sent_tokenize hjælpeprogrammet til at konvertere vores artikel til sætninger. For at konvertere sætninger til ord bruger vi nltk.word_tokenize utility til at konvertere sætninger til ord. Som et sidste forbehandlingstrin fjerner vi alle stopord fra teksten.

Når scriptet er færdig med at udføre scriptet, indeholder all_words-objektet en liste over alle ord i artiklen. Vi vil bruge denne liste til at oprette vores Word2Vec-model med Gensim-biblioteket.

Skabelse af Word2Vec-model

Med Gensim er det yderst ligetil at oprette Word2Vec-modellen. Ordlisten overføres til Word2Vec-klassen i gensim.models-pakken gensim.models. Vi skal angive værdien for parameteren min_count. En værdi på 2 for min_count angiver, at der kun skal medtages de ord i Word2Vec-modellen, som forekommer mindst to gange i korpus. Følgende script opretter Word2Vec-modellen ved hjælp af den Wikipedia-artikel, vi har skrabet.

from gensim.models import Word2Vecword2vec = Word2Vec(all_words, min_count=2)

For at se ordbogen over unikke ord, der forekommer mindst to gange i korpus, skal du udføre følgende script:

vocabulary = word2vec.wv.vocabprint(vocabulary)

Når ovenstående script udføres, vil du se en liste over alle de unikke ord, der forekommer mindst to gange.

Modelanalyse

Vi har med succes oprettet vores Word2Vec-model i det sidste afsnit. Nu er det tid til at undersøge, hvad vi har skabt.

Findelse af vektorer for et ord

Vi ved, at Word2Vec-modellen konverterer ord til deres tilsvarende vektorer. Lad os se, hvordan vi kan se vektorrepræsentationen for et bestemt ord.

v1 = word2vec.wv

Vektoren v1 indeholder vektorrepræsentationen for ordet “kunstig”. Som standard oprettes der en hundredimensionel vektor af Gensim Word2Vec. Dette er en meget, meget mindre vektor sammenlignet med den vektor, der ville være blevet produceret af bag of words. Hvis vi bruger metoden med en pose ord til at indlejre artiklen, vil længden af vektoren for hver enkelt være 1206, da der er 1206 unikke ord med en minimumsfrekvens på 2. Hvis minimumsfrekvensen for forekomst sættes til 1, vil størrelsen af vektoren med en pose ord blive yderligere forøget. På den anden side påvirkes vektorerne, der genereres ved hjælp af Word2Vec, ikke af størrelsen af ordforrådet.

Finding af lignende ord

Der blev tidligere sagt, at kontekstuelle oplysninger om ordene ikke går tabt ved hjælp af Word2Vec-tilgangen. Vi kan verificere dette ved at finde alle de ord, der ligner ordet “intelligence”.

Tag et kig på følgende script:

sim_words = word2vec.wv.most_similar('intelligence')

Hvis du udskriver sim_words-variablen til konsollen, vil du se de ord, der ligner “intelligence” mest, som vist nedenfor:

Fra output kan du se de ord, der ligner “intelligence”, sammen med deres lighedsindeks. Ordet “ai” er det ord, der ifølge modellen ligner “intelligence” mest, hvilket faktisk giver mening. På samme måde findes ord som “menneskelig” og “kunstig” ofte sammen med ordet “intelligens”. Vores model har med succes fanget disse relationer ved hjælp af blot en enkelt Wikipedia-artikel.

Konklusion

I denne artikel har vi implementeret en Word2Vec ordindlejringsmodel med Pythons Gensim-bibliotek. Vi gjorde dette ved at skrabe en Wikipedia-artikel og opbyggede vores Word2Vec-model ved hjælp af artiklen som et korpus. Vi gennemgik også kort de mest almindeligt anvendte word embedding-tilgange sammen med deres fordele og ulemper som en sammenligning med Word2Vec.

Jeg vil foreslå dig at oprette din egen Word2Vec-model ved hjælp af et tekstkorpus og se, om du kan få bedre resultater sammenlignet med bag of words-tilgangen.

Skriv et svar

Din e-mailadresse vil ikke blive publiceret.