Sissejuhatus sõnade koti ja kuidas seda NLP jaoks Pythonis kodeerida

Sõnade kott (BOW) on meetod tekstidokumentidest funktsioonide eraldamiseks. Neid funktsioone saab kasutada masinõppe algoritmide koolitamiseks. See loob sõnavara kõigist ainulaadsetest sõnadest, mis esinevad kõigis koolituskomplekti kuuluvates dokumentides.

Lihtsamalt öeldes on see sõnade kogum, mis esindab lausearvestusega lauset ja enamasti eirates nende esitamise järjekorda.

BOW on lähenemine, mida kasutatakse laialdaselt koos:

  1. Loomuliku keele töötlemine
  2. Teabe otsimine dokumentidest
  3. Dokumendi klassifikatsioonid

Kõrgel tasemel hõlmab see järgmisi samme.

Loodud vektoreid saab sisestada teie masinõppe algoritmi.

Alustame mõistmiseks mõeldud näitest, võttes mõned laused ja genereerides neile vektorid.

Vaatleme kahte allpool olevat lauset.

1. "John likes to watch movies. Mary likes movies too."
2. "John also likes to watch football games."

Neid kahte lauset saab esindada ka sõnade kogumikuga.

1. ['John', 'likes', 'to', 'watch', 'movies.', 'Mary', 'likes', 'movies', 'too.']
2. ['John', 'also', 'likes', 'to', 'watch', 'football', 'games']

Lisaks eemaldage iga lause kohta mitu sõna esinemist ja kasutage selle tähistamiseks sõnade arvu.

1. {"John":1,"likes":2,"to":1,"watch":1,"movies":2,"Mary":1,"too":1}
2. {"John":1,"also":1,"likes":1,"to":1,"watch":1,"football":1, "games":1}

Eeldades, et need laused on dokumendi osa, on allpool kogu meie dokumendi kombineeritud sõnade sagedus. Mõlemat lauset võetakse arvesse.

 {"John":2,"likes":3,"to":2,"watch":2,"movies":2,"Mary":1,"too":1, "also":1,"football":1,"games":1}

Kõigi lausete vektorite loomiseks kasutatakse ülaltoodud sõnavara kõigi dokumendis sisalduvate sõnade ja nende vastavate sõnade arvu järgi.

Vektori pikkus on alati võrdne sõnavara suurusega. Sel juhul on vektori pikkus 11.

Meie algsete lausete esitamiseks vektoris initsialiseeritakse kõik vektorid kõigi nullidega - [0, 0, 0, 0, 0, 0, 0, 0, 0, 0]

Sellele järgneb iteratsioon ja võrdlus meie sõnavara iga sõnaga ning vektorväärtuse suurendamine, kui lauses seda sõna on.

John likes to watch movies. Mary likes movies too.[1, 2, 1, 1, 2, 1, 1, 0, 0, 0]
John also likes to watch football games.[1, 1, 1, 1, 0, 0, 0, 1, 1, 1]

Näiteks lauses 1 on sõna likesteisel kohal ja kaks korda. Seega on lause 1 meie vektori teine ​​element 2: [1, 2, 1, 1, 2, 1, 1, 0, 0, 0]

Vektor on alati proportsionaalne meie sõnavara suurusega.

Suur dokument, kus loodud sõnavara on tohutu, võib põhjustada vektori, millel on palju 0 väärtust. Seda nimetatakse hõredaks vektoriks .Hõredad vektorid vajavad modelleerimisel rohkem mälu ja arvutuslikke ressursse. Suur positsioonide või mõõtmete arv võib muuta modelleerimisprotsessi traditsiooniliste algoritmide jaoks väga keeruliseks.

Meie BOW algoritmi kodeerimine

Meie koodi sisendiks on mitu lauset ja väljundiks vektorid.

Sisendimassiiv on järgmine:

["Joe waited for the train", "The train was late", "Mary and Samantha took the bus",
"I looked for Mary and Samantha at the bus station",
"Mary and Samantha arrived at the bus station early but waited until noon for the bus"]

1. samm: lause tokeniseerimine

Alustame lauseist märksõnade eemaldamisega.

Stopwords on sõnad, mis ei sisalda piisavalt tähtsust, mida kasutatakse ilma meie algoritm. Me ei taha, et need sõnad võtaksid meie andmebaasis ruumi või võtaksid väärtuslikku töötlemisaega. Selleks saame need hõlpsalt eemaldada, salvestades loendi sõnadest, mida peate stoppsõnadeks.

Tokeniseerimine on stringide jada osadeks jaotamine, näiteks sõnad, märksõnad, fraasid, sümbolid ja muud elemendid, mida nimetatakse märgideks . Märgid võivad olla üksikud sõnad, fraasid või isegi terved laused. Tokeniseerimise käigus loobutakse mõnest tähemärgist, näiteks kirjavahemärkidest.

def word_extraction(sentence): ignore = ['a', "the", "is"] words = re.sub("[^\w]", " ", sentence).split() cleaned_text = [w.lower() for w in words if w not in ignore] return cleaned_text

For more robust implementation of stopwords, you can use python nltk library. It has a set of predefined words per language. Here is an example:

import nltkfrom nltk.corpus import stopwords set(stopwords.words('english'))

Step 2: Apply tokenization to all sentences

def tokenize(sentences): words = [] for sentence in sentences: w = word_extraction(sentence) words.extend(w) words = sorted(list(set(words))) return words

The method iterates all the sentences and adds the extracted word into an array.

The output of this method will be:

['and', 'arrived', 'at', 'bus', 'but', 'early', 'for', 'i', 'joe', 'late', 'looked', 'mary', 'noon', 'samantha', 'station', 'the', 'took', 'train', 'until', 'waited', 'was']

Step 3: Build vocabulary and generate vectors

Use the methods defined in steps 1 and 2 to create the document vocabulary and extract the words from the sentences.

def generate_bow(allsentences): vocab = tokenize(allsentences) print("Word List for Document \n{0} \n".format(vocab));
for sentence in allsentences: words = word_extraction(sentence) bag_vector = numpy.zeros(len(vocab)) for w in words: for i,word in enumerate(vocab): if word == w: bag_vector[i] += 1 print("{0}\n{1}\n".format(sentence,numpy.array(bag_vector)))

Here is the defined input and execution of our code:

allsentences = ["Joe waited for the train train", "The train was late", "Mary and Samantha took the bus",
"I looked for Mary and Samantha at the bus station",
"Mary and Samantha arrived at the bus station early but waited until noon for the bus"]
generate_bow(allsentences)

The output vectors for each of the sentences are:

Output:
Joe waited for the train train[0. 0. 0. 0. 0. 0. 1. 0. 1. 0. 0. 0. 0. 0. 0. 0. 0. 2. 0. 1. 0.]
The train was late[0. 0. 0. 0. 0. 0. 0. 0. 0. 1. 0. 0. 0. 0. 0. 1. 0. 1. 0. 0. 1.]
Mary and Samantha took the bus[1. 0. 0. 1. 0. 0. 0. 0. 0. 0. 0. 1. 0. 1. 0. 0. 1. 0. 0. 0. 0.]
I looked for Mary and Samantha at the bus station[1. 0. 1. 1. 0. 0. 1. 1. 0. 0. 1. 1. 0. 1. 1. 0. 0. 0. 0. 0. 0.]
Mary and Samantha arrived at the bus station early but waited until noon for the bus[1. 1. 1. 2. 1. 1. 1. 0. 0. 0. 0. 1. 1. 1. 1. 0. 0. 0. 1. 1. 0.]

As you can see, each sentence was compared with our word list generated in Step 1. Based on the comparison, the vector element value may be incremented. These vectors can be used in ML algorithms for document classification and predictions.

We wrote our code and generated vectors, but now let’s understand bag of words a bit more.

Insights into bag of words

The BOW model only considers if a known word occurs in a document or not. It does not care about meaning, context, and order in which they appear.

This gives the insight that similar documents will have word counts similar to each other. In other words, the more similar the words in two documents, the more similar the documents can be.

Limitations of BOW

  1. Semantic meaning: the basic BOW approach does not consider the meaning of the word in the document. It completely ignores the context in which it’s used. The same word can be used in multiple places based on the context or nearby words.
  2. Vector size: For a large document, the vector size can be huge resulting in a lot of computation and time. You may need to ignore words based on relevance to your use case.

This was a small introduction to the BOW method. The code showed how it works at a low level. There is much more to understand about BOW. For example, instead of splitting our sentence in a single word (1-gram), you can split in the pair of two words (bi-gram or 2-gram). At times, bi-gram representation seems to be much better than using 1-gram. These can often be represented using N-gram notation. I have listed some research papers in the resources section for more in-depth knowledge.

You do not have to code BOW whenever you need it. It is already part of many available frameworks like CountVectorizer in sci-kit learn.

Our previous code can be replaced with:

from sklearn.feature_extraction.text import CountVectorizervectorizer = CountVectorizer()X = vectorizer.fit_transform(allsentences)print(X.toarray())

It’s always good to understand how the libraries in frameworks work, and understand the methods behind them. The better you understand the concepts, the better use you can make of frameworks.

Täname artikli lugemise eest. Kuvatud kood on saadaval minu GitHubis.

Võite mind jälgida meediumites, Twitteris ja LinkedInis. Kõigi küsimuste korral võite minuga ühendust võtta e-posti teel (praveend806 [at] gmail [dot] com).

Ressursid, et lugeda rohkem sõnakotist

  1. Vikipeedia-BOW
  2. Sõnade koti mudeli mõistmine: statistiline raamistik
  3. Semantikat säilitavad sõnade koti mudelid ja rakendused