Μια εισαγωγή στο Bag of Words και πώς να τον κωδικοποιήσετε στο Python για NLP

Το Bag of Words (BOW) είναι μια μέθοδος εξαγωγής χαρακτηριστικών από έγγραφα κειμένου. Αυτά τα χαρακτηριστικά μπορούν να χρησιμοποιηθούν για την κατάρτιση αλγορίθμων μηχανικής μάθησης. Δημιουργεί ένα λεξιλόγιο με όλες τις μοναδικές λέξεις που εμφανίζονται σε όλα τα έγγραφα του εκπαιδευτικού συνόλου.

Με απλά λόγια, είναι μια συλλογή λέξεων που αντιπροσωπεύουν μια πρόταση με πλήθος λέξεων και συνήθως αγνοούν τη σειρά με την οποία εμφανίζονται.

Το BOW είναι μια προσέγγιση που χρησιμοποιείται ευρέως με:

  1. Επεξεργασία φυσικής γλώσσας
  2. Ανάκτηση πληροφοριών από έγγραφα
  3. Ταξινομήσεις εγγράφων

Σε υψηλό επίπεδο, περιλαμβάνει τα ακόλουθα βήματα.

Τα παραγόμενα διανύσματα μπορούν να εισαχθούν στον αλγόριθμο μηχανικής μάθησης.

Ας ξεκινήσουμε με ένα παράδειγμα για να καταλάβουμε, λαμβάνοντας μερικές προτάσεις και δημιουργώντας διανύσματα για αυτά.

Εξετάστε τις παρακάτω δύο προτάσεις.

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

Αυτές οι δύο προτάσεις μπορούν επίσης να αναπαρασταθούν με μια συλλογή λέξεων.

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

Επιπλέον, για κάθε πρόταση, αφαιρέστε πολλές εμφανίσεις της λέξης και χρησιμοποιήστε τον αριθμό λέξεων για να το αντιπροσωπεύσετε.

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}

Υποθέτοντας ότι αυτές οι προτάσεις αποτελούν μέρος ενός εγγράφου, παρακάτω είναι η συνδυασμένη συχνότητα λέξεων για ολόκληρο το έγγραφό μας. Και οι δύο προτάσεις λαμβάνονται υπόψη.

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

Το παραπάνω λεξιλόγιο από όλες τις λέξεις σε ένα έγγραφο, με τον αντίστοιχο αριθμό λέξεων, θα χρησιμοποιηθεί για τη δημιουργία διανυσμάτων για κάθε μία από τις προτάσεις.

Το μήκος του διανύσματος θα είναι πάντα ίσο με το μέγεθος του λεξιλογίου. Σε αυτήν την περίπτωση το μήκος του διανύσματος είναι 11.

Προκειμένου να αναπαριστούν τις αρχικές προτάσεις μας σε ένα διάνυσμα, κάθε διάνυσμα αρχικοποιείται με όλα τα μηδενικά - [0, 0, 0, 0, 0, 0, 0, 0, 0, 0]

Ακολουθεί επανάληψη και σύγκριση με κάθε λέξη στο λεξιλόγιό μας και αύξηση της διανυσματικής τιμής εάν η πρόταση έχει αυτή τη λέξη.

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]

Για παράδειγμα, στην πρόταση 1 η λέξη likesεμφανίζεται στη δεύτερη θέση και εμφανίζεται δύο φορές. Έτσι, το δεύτερο στοιχείο του διανύσματος μας για την πρόταση 1 θα είναι 2: [1, 2, 1, 1, 2, 1, 1, 0, 0, 0]

Ο φορέας είναι πάντα ανάλογος με το μέγεθος του λεξιλογίου μας.

Ένα μεγάλο έγγραφο όπου το δημιουργημένο λεξιλόγιο είναι τεράστιο μπορεί να οδηγήσει σε ένα διάνυσμα με πολλές τιμές 0. Αυτό ονομάζεται αραιό διάνυσμα .Οι αραιοί φορείς απαιτούν περισσότερη μνήμη και υπολογιστικούς πόρους κατά τη μοντελοποίηση. Ο τεράστιος αριθμός θέσεων ή διαστάσεων μπορεί να κάνει τη διαδικασία μοντελοποίησης πολύ δύσκολη για τους παραδοσιακούς αλγόριθμους.

Κωδικοποίηση του αλγορίθμου BOW

Η εισαγωγή στον κώδικα θα είναι πολλές προτάσεις και η έξοδος θα είναι οι διανύσματα.

Ο πίνακας εισόδου είναι ο εξής:

["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: Διαγράψτε μια πρόταση

Θα ξεκινήσουμε με την αφαίρεση λέξεων-κλειδιών από τις προτάσεις.

Εξαιρούμενες λέξεις είναι λέξεις που δεν περιέχουν αρκετή σημασία που πρέπει να χρησιμοποιηθεί χωρίς αλγορίθμου μας. Δεν θα θέλαμε αυτές οι λέξεις να καταλαμβάνουν χώρο στη βάση δεδομένων μας ή να καταλαμβάνουν πολύτιμο χρόνο επεξεργασίας. Γι 'αυτό, μπορούμε να τις καταργήσουμε εύκολα αποθηκεύοντας μια λίστα λέξεων που θεωρείτε ως λέξεις διακοπής.

Tokenization είναι η πράξη της διάσπασης μιας ακολουθίας συμβολοσειρών σε κομμάτια όπως λέξεις, λέξεις-κλειδιά, φράσεις, σύμβολα και άλλα στοιχεία που ονομάζονται διακριτικά . Τα κουπόνια μπορεί να είναι μεμονωμένες λέξεις, φράσεις ή ακόμη και ολόκληρες προτάσεις. Κατά τη διαδικασία της κωδικοποίησης, απορρίπτονται ορισμένοι χαρακτήρες, όπως σημεία στίξης.

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

Για πιο ισχυρή εφαρμογή των λέξεων- κλειδιών , μπορείτε να χρησιμοποιήσετε τη βιβλιοθήκη python nltk . Έχει ένα σύνολο προκαθορισμένων λέξεων ανά γλώσσα. Εδώ είναι ένα παράδειγμα:

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

Βήμα 2: Εφαρμόστε διακριτικά σε όλες τις προτάσεις

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

Η μέθοδος επαναλαμβάνει όλες τις προτάσεις και προσθέτει την εξαγόμενη λέξη σε έναν πίνακα.

Το αποτέλεσμα αυτής της μεθόδου θα είναι:

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

Βήμα 3: Δημιουργήστε λεξιλόγιο και δημιουργήστε διανύσματα

Χρησιμοποιήστε τις μεθόδους που ορίζονται στα βήματα 1 και 2 για να δημιουργήσετε το λεξιλόγιο εγγράφων και να εξαγάγετε τις λέξεις από τις προτάσεις.

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)))

Εδώ είναι η καθορισμένη εισαγωγή και εκτέλεση του κώδικα μας:

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)

Τα διανύσματα εξόδου για καθεμία από τις προτάσεις είναι:

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.

Ευχαριστούμε που διαβάσατε το άρθρο. Ο κωδικός που εμφανίζεται είναι διαθέσιμος στο GitHub μου.

Μπορείτε να με ακολουθήσετε στο Medium, το Twitter και το LinkedIn. Για οποιεσδήποτε ερωτήσεις, μπορείτε να επικοινωνήσετε μαζί μου μέσω email (praveend806 [at] gmail [dot] com).

Πόροι για να διαβάσετε περισσότερα σχετικά με την τσάντα των λέξεων

  1. Wikipedia-BOW
  2. Κατανόηση του Bag-of-Words Model: Ένα στατιστικό πλαίσιο
  3. Σημασιολογία-Διατήρηση Bag-of-Words Μοντέλα και Εφαρμογές