Bag of Words (BoW) is een techniek binnen Natural Language Processing (NLP). Het wordt veel gebruikt om tekstgegevens om te zetten naar een machineleesbaar formaat, specifiek numerieke waarden, zonder rekening te houden met grammatica en woordvolgorde. BoW begrijpen is belangrijk voor iedereen die met tekstdata werkt. Python biedt meerdere tools en bibliotheken om Bag of Words effectief te implementeren.
In deze tutorial duiken we in BoW, introduceren we de concepten, behandelen we de toepassingen en lopen we stap voor stap door een implementatie in Python. Aan het einde kun je het Bag-of-Words-model toepassen op realistische problemen. Ben je nieuw in NLP? Bekijk dan onze Natural Language Processing in Python skill track om meer te leren.
Wat is Bag of Words?
Bag of Words is een techniek om features uit tekstdata te halen voor machinelearning-taken, zoals tekstclassificatie en sentimentanalyse. Dit is belangrijk omdat machinelearning-algoritmen geen ruwe tekst kunnen verwerken. Het proces waarbij tekst naar getallen wordt omgezet, heet feature-extractie of feature-encoding.
Een Bag of Words is gebaseerd op het voorkomen van woorden in een document. Het proces begint met het bepalen van de woordenschat in de tekst en het tellen van hun voorkomen. Het heet een "zak" omdat de volgorde en structuur van woorden niet worden meegenomen, alleen hun frequentie.
Het Bag-of-Words-model verschilt van het Continuous Bag of Words Model (CBOW), dat dichte woordembeddings leert door omringende woorden te gebruiken om een doelwoord te voorspellen en zo semantische relaties tussen woorden vast te leggen. CBOW vereist training op een grote corpus en produceert laag-dimensionale vectoren die waardevol zijn voor complexe NLP-toepassingen waarbij context belangrijk is.
Aspect
BOW
CBOW
Doel
Telt het aantal voorkomens van elk woord
Voorspelt doelwoord op basis van context
Type output
Hoog-dimensionale, spaarzame vector
Laag-dimensionale, dichte embedding
Neemt context mee
Nee (negeert woordvolgorde)
Ja (gebruikt omringende woorden)
Representatie
Spaarzame frequentievector
Dichte vector die semantiek vangt
Complexiteit
Laag (geen training nodig)
Hoog (training op grote corpus vereist)
Typische toepassingen
Tekstclassificatie, sentimentanalyse
Woordembeddings, NLP-taken met context
Waarom Bag of Words gebruiken?
Bag of Words is nuttig in veel NLP-taken. Enkele redenen om het te gebruiken:
Feature-extractie: Het zet ongestructureerde tekst om in gestructureerde data die je als input kunt gebruiken voor diverse machinelearning-algoritmen.
Eenvoud en efficiëntie: BoW is computationeel eenvoudig te implementeren en werkt goed voor kleine tot middelgrote corpora.
Documentsimilariteit: Je kunt de vergelijkbaarheid tussen documenten berekenen met technieken zoals cosinus-similariteit.
Tekstclassificatie: In combinatie met technieken zoals Naive Bayes is BoW effectief voor taken als spamclassificatie en sentimentanalyse.
Er zijn echter ook nadelen, zoals het niet meenemen van semantiek, woordstructuur of woordvolgorde.
Stappen om Bag of Words in Python te implementeren
Om een bag-of-words-model te maken, nemen we alle woorden in een corpus en maken we voor elk woord een kolom. De rijen stellen de zinnen voor. Als een bepaald woord in de zin voorkomt, krijgt het een 1; als het niet voorkomt, krijgt het een 0. Elk woord in de kolom vertegenwoordigt één feature.
Uiteindelijk krijgen we een spaarzame matrix. Een spaarzame matrix is een matrix met veel nullen.
Datapreprocessing
Om een Bag-of-Words-model in Python te maken, moeten we een paar preprocessing-stappen uitvoeren. Deze stappen omvatten tokenisatie en het verwijderen van stopwoorden.
Tokenisatie is het opsplitsen van tekst in kleinere eenheden, meestal woorden. Je kunt tokenisatie uitvoeren met NLTK.
Stopwoorden zijn veelvoorkomende woorden in het Engels, zoals "the", "that" en "a", die niet bijdragen aan de polariteit van een zin.
import nltk
from nltk.corpus import stopwords
from nltk.tokenize import word_tokenize
# Download stopwords and tokenizer if you haven't already
nltk.download("punkt")
nltk.download("stopwords")# Example sentence
sentence ="This is an example showing how to remove stop words from a sentence."# Tokenize the sentence into words
words = word_tokenize(sentence)# Get the list of stop words in English
stop_words =set(stopwords.words("english"))# Remove stop words from the sentence
filtered_sentence =[word for word in words if word.lower()notin stop_words]# Join the words back into a sentence
filtered_sentence =" ".join(filtered_sentence)print(filtered_sentence)Mogelijk gemaakt door
Een vocabulaire is een verzameling unieke woorden die in een tekstcorpus voorkomen. Een vocabulaire opbouwen houdt in dat je alle unieke woorden uit het corpus verzamelt en hun frequentie telt. Deze woordenschat is nuttig voor verschillende NLP-taken zoals language modeling, woordembeddings en tekstclassificatie.
Onderstaande code maakt een eenvoudige frequentieverdeling van woorden in het corpus, handig voor basistaken zoals het bouwen van een vocabulaire of het begrijpen van de tekstinhoud:
De variabele corpus bevat enkele voorbeeldzinnen. In echte toepassingen zou dit grotere en gevarieerdere tekstdata bevatten.
vocab = defaultdict(int) vereenvoudigt het tellen van woordfrequenties: nieuwe woorden krijgen automatisch een startwaarde 0, waardoor je direct kunt ophogen zonder extra checks.
Elke zin wordt getokeniseerd door deze naar lowercase te zetten en woorden met reguliere expressies te extraheren. Het patroon \b\w+\bherkent woorden met alleen alfanumerieke tekens en negeert leestekens en andere symbolen.
De telling van elk woord wordt bijgewerkt in het vocab-woordenboek.
De woordenschat wordt op frequentie in aflopende volgorde gesorteerd, zodat de meest voorkomende woorden bovenaan staan, en wordt ter referentie getoond.
import re
# Import the regular expressions module to help with text processingfrom collections import(
defaultdict,)# Import defaultdict to easily handle word frequency counting# Sample corpus of text - a small dataset of sentences to analyze
corpus =["Tokenization is the process of breaking text into words.","Vocabulary is the collection of unique words.","The process of tokenizing is essential in NLP.",]# Initialize a defaultdict with integer values to store word frequencies# defaultdict(int) initializes each new key with a default integer value of 0
vocab = defaultdict(int)# Loop through each sentence in the corpus to tokenize and normalizefor sentence in corpus:# Convert the sentence to lowercase to ensure consistency in counting (e.g., 'Tokenization' and 'tokenization' are treated as the same word)# Use regular expressions to find words composed of alphanumeric characters only
words = re.findall(r"\b\w+\b", sentence.lower())# For each word found, increment its count in the vocab dictionaryfor word in words:
vocab[word]+=1# Convert the defaultdict vocab to a regular dictionary for easier handling and sorting# Sort the dictionary by word frequency in descending order and convert it to a new dictionary
sorted_vocab =dict(sorted(vocab.items(), key=lambda x: x[1], reverse=True))# Display the sorted vocabulary with each word and its frequency countprint("Vocabulary with Frequencies:", sorted_vocab)Mogelijk gemaakt door
Handmatig een vocabulaire opbouwen kan tijdrovend zijn, zeker voor grote corpora. CountVectorizer van Scikit-learn automatiseert dit proces en biedt flexibelere tekstanalyse, zoals we later zullen zien.
Bag of Words implementeren in Python (from scratch)
Laten we beginnen met een eenvoudige implementatie van Bag of Words from scratch in Python. Dit helpt je de bouwstenen en de werking onder de motorkap te begrijpen.
Handmatige implementatie
Stap 1: De tekstdata pre-processen
We beginnen met een eenvoudige functie om tekst te verwerken: tokeniseren, naar lowercase omzetten en leestekens verwijderen.
from collections import defaultdict
import string
# Sample text data: sentences
corpus =["Python is amazing and fun.","Python is not just fun but also powerful.","Learning Python is fun!",]# Function to preprocess textdefpreprocess(text):# Convert to lowercase
text = text.lower()# Remove punctuation
text = text.translate(str.maketrans("","", string.punctuation))# Tokenize: split the text into words
tokens = text.split()return tokens
# Apply preprocessing to the sample corpus
processed_corpus =[preprocess(sentence)for sentence in corpus]print(processed_corpus)Mogelijk gemaakt door
Output:
[['python','is','amazing','and','fun'],['python','is','not','just','fun','but','also','powerful'],['learning','python','is','fun']]Mogelijk gemaakt door
Stap 2: Vocabulaire bouwen
Nu moeten we alle documenten doorlopen en een volledige lijst met unieke woorden opbouwen: dat is onze woordenschat.
# Initialize an empty set for the vocabulary
vocabulary =set()# Build the vocabularyfor sentence in processed_corpus:
vocabulary.update(sentence)# Convert to a sorted list
vocabulary =sorted(list(vocabulary))print("Vocabulary:", vocabulary)Mogelijk gemaakt door
Stap 3: Woordfrequenties berekenen en vectoriseren
We berekenen nu de frequentie van elk woord in de woordenschat voor elk document in het verwerkte corpus.
defcreate_bow_vector(sentence, vocab):
vector =[0]*len(vocab)# Initialize a vector of zerosfor word in sentence:if word in vocab:
idx = vocab.index(word)# Find the index of the word in the vocabulary
vector[idx]+=1# Increment the count at that indexreturn vector
Mogelijk gemaakt door
Op dit punt heb je voor elk document in je corpus een Bag-of-Words-representatie gemaakt.
# Create BoW vector for each sentence in the processed corpus
bow_vectors =[create_bow_vector(sentence, vocabulary)for sentence in processed_corpus]print("Bag of Words Vectors:")for vector in bow_vectors:print(vector)Mogelijk gemaakt door
Output:
Bag of Words Vectors:
[0, 1, 1, 0, 1, 1, 0, 0, 0, 0, 1]
[1, 0, 0, 1, 1, 1, 1, 0, 1, 1, 1]
[0, 0, 0, 0, 1, 1, 0, 1, 0, 0, 1]Mogelijk gemaakt door
Scikit-learn’s CountVectorizer gebruiken
Een Bag-of-Words-model handmatig bouwen is goed om te leren, maar voor productieomgevingen wil je efficiënte, geoptimaliseerde bibliotheken zoals Scikit-learn gebruiken.
De Python-functie die we gebruiken voor tokenisatie is CountVectorizer, geïmporteerd uit sklearn.feature_extraction.text. Een van de features van CountVectorizer is max_features, het maximale aantal woorden dat je in het bag-of-words-model wilt opnemen. In dit geval gebruiken we None, wat betekent dat alle features worden gebruikt.
Na het aanmaken van een instantie van CountVectorizer gebruik je de methode .fit_transform() om het bag-of-words-model te maken. Gebruik vervolgens .toarray() om het model om te zetten naar numpy-arrays die je aan een machinelearning-model kunt voeren.
Na het fitten heeft CountVectorizer een woordenboek met feature-indexen opgebouwd. De indexwaarde van een woord in het vocabulaire is gekoppeld aan de frequentie ervan in het hele trainingscorpus.
from sklearn.feature_extraction.text import CountVectorizer
# Original corpus
corpus =["Python is amazing and fun.","Python is not just fun but also powerful.","Learning Python is fun!",]# Create a CountVectorizer Object
vectorizer = CountVectorizer()# Fit and transform the corpus
X = vectorizer.fit_transform(corpus)# Print the generated vocabularyprint("Vocabulary:", vectorizer.get_feature_names_out())# Print the Bag-of-Words matrixprint("BoW Representation:")print(X.toarray())Mogelijk gemaakt door
Output:
markdownVocabulary:['also''amazing''and''but''fun''is''just''learning''not''powerful''python']
BoW Representation:[[01101100001][10011110111][00001101001]]Mogelijk gemaakt door
Voorbeeld: Bag of Words toepassen
Laten we het BoW-model nu toepassen op een klein tekstcorpus met drie filmrecensies om het hele proces te illustreren.
We gebruiken CountVectorizer van Scikit-learn om het BoW-model op dit kleine corpus toe te passen.
Dit zijn de stappen die we nemen:
CountVectorizer tokeniseert de tekst, verwijdert leestekens en zet de woorden automatisch naar lowercase.
.fit_transform(corpus) zet het corpus om in een document-termmatrix, waarbij elke rij een document en elke kolom een woord uit de woordenschat voorstelt.
X_dense is de dichte matrix die de frequentie van elk woord in elk document weergeeft.
from sklearn.feature_extraction.text import CountVectorizer
# Sample corpus of movie reviews
corpus =["I loved the movie, it was fantastic!","The movie was okay, but not great.","I hated the movie, it was terrible.",]# Initialize the CountVectorizer
vectorizer = CountVectorizer()# Fit and transform the corpus to a document-term matrix
X = vectorizer.fit_transform(corpus)# Convert the document-term matrix into a dense format (optional for visualization)
X_dense = X.toarray()# Get the vocabulary (mapping of words to index positions)
vocab = vectorizer.get_feature_names_out()# Print the vocabulary and document-term matrixprint("Vocabulary:", vocab)print("Document-Term Matrix:\n", X_dense)Mogelijk gemaakt door
Output:
Vocabulary:['but''fantastic''great''hated''it''loved''movie''not''okay''terrible''the''was']
Document-Term Matrix:[[010011100011]# First review: "I loved the movie, it was fantastic!"[101010111011]# Second review: "The movie was okay, but not great."[000110100111]]# Third review: "I hated the movie, it was terrible."Mogelijk gemaakt door
Zo kun je de bovenstaande output interpreteren:
Elk uniek woord in het corpus krijgt een index en de woorden zijn alfabetisch geordend. Bijvoorbeeld: "but" staat op index 0, "fantastic" op index 1, "movie" op index 6, enzovoort.
Elke rij in de documentmatrix vertegenwoordigt een filmrecensie en elke kolom correspondeert met een woord uit de woordenschat. De waarden in de matrix geven de frequentie van elk woord in dat specifieke document weer.
Eerste recensie: [0 1 0 0 1 1 1 0 0 0 1 1] geeft aan dat:
Het woord "fantastic" één keer voorkomt (1 op index 1),
Het woord "loved" één keer voorkomt (1 op index 5),
Het woord "movie" één keer voorkomt (1 op index 6),
Het woord "it" één keer voorkomt (1 op index 4),
Enzovoort.
De BoW-vector kun je als volgt interpreteren:
Elk document is een vector met aantallen woorden. Het aantal dimensies is gelijk aan de grootte van de woordenschat. In dit geval bevat de woordenschat 12 woorden, dus elke recensie wordt omgezet naar een 12-dimensionale vector.
De meeste woorden per rij zijn nullen, omdat niet elk document elk woord uit de woordenschat bevat. Daarom zijn BoW-modellen vaak spaarzaam, met veel nullen.
Voordelen en beperkingen van Bag of Words
Laten we nu enkele voordelen en beperkingen van het Bag-of-Words-model bespreken.
Voordelen
Eenvoudig te implementeren en te interpreteren: Het Bag-of-Words-model is een van de meest rechttoe rechtaan tekstrepresentaties, ideaal voor beginners. De eenvoud maakt snelle implementatie mogelijk zonder complexe preprocessing of gespecialiseerde modellen.
Eenvoudig te gebruiken voor tekstclassificatie: Bag of Words is geschikt voor basistaken zoals tekstclassificatie, sentimentanalyse en spamdetectie. Deze taken vereisen vaak geen geavanceerde taalmodellen, waardoor een BOW-representatie volstaat en efficiënt is.
Beperkingen
Woordenschatgrootte beïnvloedt spaarzaamheid: Hoe groter de woordenschat, hoe spaarzamer en hoog-dimensionaal de representatie wordt. Deze spaarzaamheid kan het leren voor modellen bemoeilijken en vereist zorgvuldige afstemming van de woordenschatgrootte om excessieve rekenkosten te vermijden.
Levert spaarzame matrices op die rekenintensief zijn: Omdat elk document wordt gerepresenteerd door de frequentie van elk woord in een mogelijk grote woordenschat, zijn de resulterende matrices vaak grotendeels nullen. Dat kan inefficiënt zijn om op te slaan en te verwerken in ML-pipelines. Spaarzame matrices vergen veel geheugen en vaak gespecialiseerde tools en bibliotheken voor efficiënte opslag en berekening, vooral bij grote datasets.
Verliest betekenis en context: BOW negeert woordvolgorde en zinsstructuur, waardoor grammaticale relaties en betekenis verloren gaan. Dit maakt het minder geschikt voor taken waarbij context, nuance en woordvolgorde ertoe doen, zoals vertaling of sentimentdetectie in complexe zinnen.
De volgende strategieën kunnen helpen om de grootte van de woordenschat in Bag of Words te verkleinen:
Hoofdlettergebruik negeren.
Leestekens verwijderen.
Stopwoorden verwijderen, dus veelvoorkomende woorden zoals the en a.
Zorgen dat alle woorden correct gespeld zijn.
Stemming toepassen om woorden tot hun stam te reduceren.
Volgende stappen: voorbij Bag of Words
Een beperking van het Bag-of-Words-model is dat het alle woorden gelijk behandelt. Daardoor kunnen sommige woorden te veel gewicht krijgen, simpelweg omdat ze vaak voorkomen.
TF-IDF (Term Frequency–Inverse Document Frequency) lost dit deels op door het gewicht van woorden aan te passen op basis van hoe vaak ze in alle documenten voorkomen.
TF-IDF: een uitbreiding op Bag of Words
Term Frequency (TF) is de frequentie van een term in een document. Inverse Document Frequency (IDF) verkleint de impact van woorden die in veel documenten voorkomen. De TF-IDF-score wordt berekend door deze twee maten te vermenigvuldigen.
Stel, een document bevat 200 woorden en het woord love komt 5 keer voor. De TF voor love is dan (5 / 200) = 0,025. Stel dat we een miljoen documenten hebben en het woord love komt in duizend daarvan voor, dan is de inverse documentfrequentie (IDF) log(1000000 / 1000) = 3. Het TF-IDF-gewicht is het product van deze waarden: 0,025 * 3 = 0,075.
In Scikit-learn is dit relatief eenvoudig te berekenen met de klasse TfidfVectorizer.
from sklearn.feature_extraction.text import TfidfVectorizer
# Sample corpus
corpus =["Python is amazing and fun.","Python is not just fun but also powerful.","Learning Python is fun!",]# Create the Tf-idf vectorizer
tfidf_vectorizer = TfidfVectorizer()# Fit and transform the corpus
X_tfidf = tfidf_vectorizer.fit_transform(corpus)# Show the Vocabularyprint("Vocabulary:", tfidf_vectorizer.get_feature_names_out())# Show the TF-IDF Matrixprint("TF-IDF Representation:")print(X_tfidf.toarray())Mogelijk gemaakt door
Output:
Vocabulary:['also''amazing''and''but''fun''is''just''learning''not''powerful''python']
TF-IDF Representation:[[0.0.572928830.572928830.0.3383810.3383810.0.0.0.0.338381][0.406676060.0.0.406676060.240189430.240189430.406676060.0.406676060.406676060.24018943][0.0.0.0.0.412858570.412858570.0.699030330.0.0.41285857]]Mogelijk gemaakt door
De hierboven geïmplementeerde TF-IDF-matrix geeft een gewogen maat in plaats van ruwe frequenties.
Hoewel het Bag-of-Words-model beperkingen heeft, zeker bij grotere en complexere datasets, blijft het een essentiële bouwsteen in veel NLP-toepassingen. Het begrijpen ervan helpt je bij het verkennen van meer geavanceerde modellen zoals woordembeddings en Transformers.
Vanaf hier kun je met BoW experimenteren in je eigen projecten, zoals spamdetectie, sentimentanalyse, documentclustering en meer.
Wil je verder verbeteren voorbij Bag of Words? Verken dan methoden als Word2Vec en GloVe, of deep learning-modellen zoals BERT.
Tot slot
De Bag-of-Words-techniek is een fundamentele techniek binnen Natural Language Processing. Het biedt een eenvoudige maar effectieve manier om ongestructureerde tekst om te zetten naar numerieke features die bruikbaar zijn voor machinelearning-algoritmen. In deze tutorial hebben we behandeld:
Wat is het Bag-of-Words (BoW)-model?
De voordelen van het Bag-of-Words-model bij het bouwen van ML-modellen.
Hoe je het Bag-of-Words-model in Python implementeert.
Voordelen en beperkingen van Bag of Words.
De theorie en motivatie achter het Bag-of-Words-model.
Introductie van TF-IDF als verbetering op de traditionele Bag-of-Words-aanpak.
Leer hoe je met Natural Language Processing (NLP) in Python teksten kunt transcriberen en interessante inzichten kunt halen uit boeken, beoordelingssites en online artikelen.
Bag of Words (BoW) is een techniek binnen Natural Language Processing (NLP). Het wordt veel gebruikt om tekstgegevens om te zetten naar een machineleesbaar formaat, specifiek numerieke waarden, zonder rekening te houden met grammatica en woordvolgorde. BoW begrijpen is belangrijk voor iedereen die met tekstdata werkt. Python biedt meerdere tools en bibliotheken om Bag of Words effectief te implementeren.
In deze tutorial duiken we in BoW, introduceren we de concepten, behandelen we de toepassingen en lopen we stap voor stap door een implementatie in Python. Aan het einde kun je het Bag-of-Words-model toepassen op realistische problemen. Ben je nieuw in NLP? Bekijk dan onze Natural Language Processing in Python skill track om meer te leren.
Wat is Bag of Words?
Bag of Words is een techniek om features uit tekstdata te halen voor machinelearning-taken, zoals tekstclassificatie en sentimentanalyse. Dit is belangrijk omdat machinelearning-algoritmen geen ruwe tekst kunnen verwerken. Het proces waarbij tekst naar getallen wordt omgezet, heet feature-extractie of feature-encoding.
Een Bag of Words is gebaseerd op het voorkomen van woorden in een document. Het proces begint met het bepalen van de woordenschat in de tekst en het tellen van hun voorkomen. Het heet een "zak" omdat de volgorde en structuur van woorden niet worden meegenomen, alleen hun frequentie.
Het Bag-of-Words-model verschilt van het Continuous Bag of Words Model (CBOW), dat dichte woordembeddings leert door omringende woorden te gebruiken om een doelwoord te voorspellen en zo semantische relaties tussen woorden vast te leggen. CBOW vereist training op een grote corpus en produceert laag-dimensionale vectoren die waardevol zijn voor complexe NLP-toepassingen waarbij context belangrijk is.
Aspect
BOW
CBOW
Doel
Telt het aantal voorkomens van elk woord
Voorspelt doelwoord op basis van context
Type output
Hoog-dimensionale, spaarzame vector
Laag-dimensionale, dichte embedding
Neemt context mee
Nee (negeert woordvolgorde)
Ja (gebruikt omringende woorden)
Representatie
Spaarzame frequentievector
Dichte vector die semantiek vangt
Complexiteit
Laag (geen training nodig)
Hoog (training op grote corpus vereist)
Typische toepassingen
Tekstclassificatie, sentimentanalyse
Woordembeddings, NLP-taken met context
Waarom Bag of Words gebruiken?
Bag of Words is nuttig in veel NLP-taken. Enkele redenen om het te gebruiken:
Er zijn echter ook nadelen, zoals het niet meenemen van semantiek, woordstructuur of woordvolgorde.
Stappen om Bag of Words in Python te implementeren
Om een bag-of-words-model te maken, nemen we alle woorden in een corpus en maken we voor elk woord een kolom. De rijen stellen de zinnen voor. Als een bepaald woord in de zin voorkomt, krijgt het een 1; als het niet voorkomt, krijgt het een 0. Elk woord in de kolom vertegenwoordigt één feature.
Uiteindelijk krijgen we een spaarzame matrix. Een spaarzame matrix is een matrix met veel nullen.
Datapreprocessing
Om een Bag-of-Words-model in Python te maken, moeten we een paar preprocessing-stappen uitvoeren. Deze stappen omvatten tokenisatie en het verwijderen van stopwoorden.
Tokenisatie is het opsplitsen van tekst in kleinere eenheden, meestal woorden. Je kunt tokenisatie uitvoeren met NLTK.
Stopwoorden zijn veelvoorkomende woorden in het Engels, zoals "the", "that" en "a", die niet bijdragen aan de polariteit van een zin.
Output:
Een vocabulaire maken
Een vocabulaire is een verzameling unieke woorden die in een tekstcorpus voorkomen. Een vocabulaire opbouwen houdt in dat je alle unieke woorden uit het corpus verzamelt en hun frequentie telt. Deze woordenschat is nuttig voor verschillende NLP-taken zoals language modeling, woordembeddings en tekstclassificatie.
Onderstaande code maakt een eenvoudige frequentieverdeling van woorden in het corpus, handig voor basistaken zoals het bouwen van een vocabulaire of het begrijpen van de tekstinhoud:
defaultdict(int)vereenvoudigt het tellen van woordfrequenties: nieuwe woorden krijgen automatisch een startwaarde 0, waardoor je direct kunt ophogen zonder extra checks.\b\w+\bherkent woorden met alleen alfanumerieke tekens en negeert leestekens en andere symbolen.Output:
Handmatig een vocabulaire opbouwen kan tijdrovend zijn, zeker voor grote corpora. CountVectorizer van Scikit-learn automatiseert dit proces en biedt flexibelere tekstanalyse, zoals we later zullen zien.
Bag of Words implementeren in Python (from scratch)
Laten we beginnen met een eenvoudige implementatie van Bag of Words from scratch in Python. Dit helpt je de bouwstenen en de werking onder de motorkap te begrijpen.
Handmatige implementatie
Stap 1: De tekstdata pre-processen
We beginnen met een eenvoudige functie om tekst te verwerken: tokeniseren, naar lowercase omzetten en leestekens verwijderen.
Output:
Stap 2: Vocabulaire bouwen
Nu moeten we alle documenten doorlopen en een volledige lijst met unieke woorden opbouwen: dat is onze woordenschat.
Stap 3: Woordfrequenties berekenen en vectoriseren
We berekenen nu de frequentie van elk woord in de woordenschat voor elk document in het verwerkte corpus.
Op dit punt heb je voor elk document in je corpus een Bag-of-Words-representatie gemaakt.
Output:
Scikit-learn’s CountVectorizer gebruiken
Een Bag-of-Words-model handmatig bouwen is goed om te leren, maar voor productieomgevingen wil je efficiënte, geoptimaliseerde bibliotheken zoals Scikit-learn gebruiken.
De Python-functie die we gebruiken voor tokenisatie is CountVectorizer, geïmporteerd uit
sklearn.feature_extraction.text. Een van de features vanCountVectorizerismax_features, het maximale aantal woorden dat je in het bag-of-words-model wilt opnemen. In dit geval gebruiken we None, wat betekent dat alle features worden gebruikt.Na het aanmaken van een instantie van
CountVectorizergebruik je de methode.fit_transform() om het bag-of-words-model te maken. Gebruik vervolgens.toarray()om het model om te zetten naar numpy-arrays die je aan een machinelearning-model kunt voeren.Na het fitten heeft CountVectorizer een woordenboek met feature-indexen opgebouwd. De indexwaarde van een woord in het vocabulaire is gekoppeld aan de frequentie ervan in het hele trainingscorpus.
Output:
Voorbeeld: Bag of Words toepassen
Laten we het BoW-model nu toepassen op een klein tekstcorpus met drie filmrecensies om het hele proces te illustreren.
We gebruiken CountVectorizer van Scikit-learn om het BoW-model op dit kleine corpus toe te passen.
Dit zijn de stappen die we nemen:
CountVectorizertokeniseert de tekst, verwijdert leestekens en zet de woorden automatisch naar lowercase..fit_transform(corpus)zet het corpus om in een document-termmatrix, waarbij elke rij een document en elke kolom een woord uit de woordenschat voorstelt.X_denseis de dichte matrix die de frequentie van elk woord in elk document weergeeft.Output:
Zo kun je de bovenstaande output interpreteren:
De BoW-vector kun je als volgt interpreteren:
Voordelen en beperkingen van Bag of Words
Laten we nu enkele voordelen en beperkingen van het Bag-of-Words-model bespreken.
Voordelen
Beperkingen
De volgende strategieën kunnen helpen om de grootte van de woordenschat in Bag of Words te verkleinen:
Volgende stappen: voorbij Bag of Words
Een beperking van het Bag-of-Words-model is dat het alle woorden gelijk behandelt. Daardoor kunnen sommige woorden te veel gewicht krijgen, simpelweg omdat ze vaak voorkomen.
TF-IDF (Term Frequency–Inverse Document Frequency) lost dit deels op door het gewicht van woorden aan te passen op basis van hoe vaak ze in alle documenten voorkomen.
TF-IDF: een uitbreiding op Bag of Words
Term Frequency (TF) is de frequentie van een term in een document. Inverse Document Frequency (IDF) verkleint de impact van woorden die in veel documenten voorkomen. De TF-IDF-score wordt berekend door deze twee maten te vermenigvuldigen.
Stel, een document bevat 200 woorden en het woord love komt 5 keer voor. De TF voor love is dan (5 / 200) = 0,025. Stel dat we een miljoen documenten hebben en het woord love komt in duizend daarvan voor, dan is de inverse documentfrequentie (IDF) log(1000000 / 1000) = 3. Het TF-IDF-gewicht is het product van deze waarden: 0,025 * 3 = 0,075.
In Scikit-learn is dit relatief eenvoudig te berekenen met de klasse TfidfVectorizer.
Output:
De hierboven geïmplementeerde TF-IDF-matrix geeft een gewogen maat in plaats van ruwe frequenties.
Hoewel het Bag-of-Words-model beperkingen heeft, zeker bij grotere en complexere datasets, blijft het een essentiële bouwsteen in veel NLP-toepassingen. Het begrijpen ervan helpt je bij het verkennen van meer geavanceerde modellen zoals woordembeddings en Transformers.
Vanaf hier kun je met BoW experimenteren in je eigen projecten, zoals spamdetectie, sentimentanalyse, documentclustering en meer.
Wil je verder verbeteren voorbij Bag of Words? Verken dan methoden als Word2Vec en GloVe, of deep learning-modellen zoals BERT.
Tot slot
De Bag-of-Words-techniek is een fundamentele techniek binnen Natural Language Processing. Het biedt een eenvoudige maar effectieve manier om ongestructureerde tekst om te zetten naar numerieke features die bruikbaar zijn voor machinelearning-algoritmen. In deze tutorial hebben we behandeld:
Bekijk onze Natural Language Processing in Python skill track om dieper in NLP te duiken.