Modèle de sac de mots Python : Un guide complet

Le Bag of Words (BoW) est une technique dans le traitement du langage naturel (NLP). Elle est largement utilisée pour transformer les données textuelles en format lisible par machine, spécifiquement en valeurs numériques, sans considérer la grammaire et l’ordre des mots. Comprendre le BoW est important pour quiconque travaille avec des données textuelles. Python fournit plusieurs outils et bibliothèques pour implémenter efficacement le Bag of Words.

Dans ce tutoriel, nous plongerons dans le BoW, présenterons ses concepts, couvrirons ses utilisations et détaillerons une implémentation en Python. À la fin de ce tutoriel, vous serez capable d’appliquer le modèle Bag of Words à des problèmes du monde réel. Si vous êtes nouveau dans le NLP, jetez un œil à notre voie de compétences en traitement du langage naturel en Python pour en savoir plus.

Qu’est-ce que le Bag of Words ?

Le Bag of Words est une technique d’extraction de caractéristiques à partir de données textuelles pour des tâches d’apprentissage automatique, telles que la classification de texte et l’analyse des sentiments. Cela est important car les algorithmes d’apprentissage automatique ne peuvent pas traiter les données textuelles. Le processus de conversion du texte en nombres est connu sous le nom d’extraction de caractéristiques ou d’encodage des caractéristiques.

Un Bag of Words est basé sur l’occurrence des mots dans un document. Le processus commence par trouver le vocabulaire dans le texte et mesurer leur occurrence. Il est appelé un « bag » parce que l’ordre et la structure des mots ne sont pas pris en compte, seulement leur occurrence.

Le modèle Bag of Words est différent du modèle Continuous Bag of Words (CBOW), qui apprend des embeddings de mots denses en utilisant les mots environnants pour prédire un mot cible, capturant ainsi les relations sémantiques entre les mots. Le CBOW nécessite un entraînement sur un grand corpus et produit des vecteurs à faible dimension qui sont précieux pour des applications complexes de NLP où le contexte du mot est important.

Aspect

BOW

CBOW

Objectif

Compte le nombre d’occurrences de chaque mot

Prédit le mot cible basé sur le contexte

Type de sortie

Vecteur à haute dimension, sparse

Représentation dense à faible dimension

Prend en compte le contexte

Non (ignore l’ordre des mots)

Oui (utilise les mots environnants)

Représentation

Vecteur de fréquence sparse

Vecteur dense capturant la sémantique

Complexité

Bas (pas de formation requise)

Élevé (nécessite une formation sur un grand corpus)

Applications typiques

Classification de texte, analyse de sentiment

Embeddings de mots, tâches de NLP nécessitant un contexte

Pourquoi utiliser le Bag of Words?

Le Bag of Words est utile dans de tâches de NLP, quelques raisons pour son utilisation incluent :

  • Extraction de caractéristiques: Elle convertit les données textuelles non structurées en données structurées, qui peuvent être utilisées comme entrée pour divers algorithmes d’apprentissage automatique.
  • Simplicité et efficacité: Le BoW est simple à mettre en œuvre du point de vue informatique et fonctionne bien pour des corpus de texte de petite à moyenne taille.
  • Similitude entre documents: Elle peut être utilisée pour calculer la similitude entre des documents textuels en utilisant des techniques telles que la similarité cosinus.
  • Classification de texte : Lorsqu’il est combiné à des techniques telles que Naive Bayes, BoW est efficace pour des tâches de classification de texte telles que la classification du spam, et analyse de sentiment.

Cependant, il existe également des inconvénients, tels que le non-consideration de la sémantique, de la structure des mots ou de l’ordre des mots.

Étapes pour mettre en œuvre le Bag of Words en Python

Pour créer un modèle de « bag of words », nous prenons tous les mots dans un corpus et créons une colonne avec chaque mot. Les lignes représentent les phrases. Si un certain mot existe dans la phrase, il est représenté par un 1, et si le mot n’existe pas, il est représenté par un 0. Chaque mot dans la colonne représente une seule caractéristique.

À la fin, nous obtenons une matrice creuse. Une matrice creuse est une matrice avec beaucoup de zéros.

Prétraitement des données

Pour créer un modèle de « Bag of Words » en Python, nous devons suivre quelques étapes de prétraitement. Ces étapes incluent la tokenisation et la suppression des stopwords.

La tokenisation est le processus de division d’un morceau de texte en unités plus petites, généralement des mots. Vous pouvez effectuer une tokenisation en utilisant NLTK.

Les mots vedettes sont des mots courants en anglais, tels que « the », « that » et « a », qui ne contribuent pas à la polarité d’une phrase.

import nltk from nltk.corpus import stopwords from nltk.tokenize import word_tokenize # Télécharger les mots vedettes et le tokenizer si vous ne l'avez pas déjà fait nltk.download("punkt") nltk.download("stopwords") # Phrase d'exemple sentence = "This is an example showing how to remove stop words from a sentence." # Tokeniser la phrase en mots words = word_tokenize(sentence) # Obtenir la liste des mots vedettes en anglais stop_words = set(stopwords.words("english")) # Supprimer les mots vedettes de la phrase filtered_sentence = [word for word in words if word.lower() not in stop_words] # Rejoindre les mots pour reformer une phrase filtered_sentence = " ".join(filtered_sentence) print(filtered_sentence)

Output :

example showing remove stop words sentence.

Créer un vocabulaire

Un vocabulaire est une collection de mots uniques trouvés dans un corpus de texte. Construire un vocabulaire consiste à rassembler tous les mots uniques du corpus et à compter leurs occurrences. Ce vocabulaire est utile pour diverses tâches de PLN comme le modélisation de langage, l’embedding de mots et la classification de texte.

Ce code ci-dessous crée une simple distribution de fréquence des mots dans le corpus, utile pour des tâches de PLN de base telles que la construction d’un vocabulaire ou la compréhension du contenu textuel :

  • La variable corpus contient quelques phrases d’exemple. Dans des applications réelles, elle contenirait des données textuelles plus grandes et plus variées.
  • vocab = defaultdict(int) simplifie le comptage de la fréquence des mots, en initialisant automatiquement tout nouveau mot avec un décompte de 0, permettant une incrémentation directe sans vérifications.
  • Chaque phrase est tokenisée en la convertissant en minuscules et en extrayant des mots à l’aide d’expressions régulières. Le motif \b\w+\b identifie des mots composés uniquement de caractères alphanumériques, en ignorant les ponctuations et autres symboles.
  • Le décompte de chaque mot est mis à jour dans le dictionnaire vocab.
  • Le vocabulaire est trié par fréquence en ordre décroissant, ce qui permet de voir les mots les plus courants en haut, et est affiché à titre de référence.
import re Importez le module d'expressions régulières pour aider dans le traitement du texte from collections import ( defaultdict, ) Importez defaultdict pour gérer facilement le comptage de la fréquence des mots Corpus d'exemple de texte - un petit ensemble de phrases à analyser 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.", ] Initialisez un defaultdict avec des valeurs entières pour stocker les fréquences des mots defaultdict(int) Initialise chaque nouvelle clé avec une valeur entière par défaut de 0 vocab = defaultdict(int) Bouclez sur chaque phrase du corpus pour tokeniser et normaliser for sentence in corpus: Convertissez la phrase en minuscules pour assurer une cohérence dans le comptage (par exemple, 'Tokenization' et 'tokenization' sont traités comme le même mot) Utilisez des expressions régulières pour trouver des mots composés uniquement de caractères alphanumériques words = re.findall(r"\b\w+\b", sentence.lower()) Pour chaque mot trouvé, incrémentez son compteur dans le dictionnaire vocab for word in words: vocab[word] += 1 Convertissez le defaultdict vocab en un dictionnaire régulier pour une gestion et un tri plus faciles Triez le dictionnaire par fréquence des mots en ordre décroissant et convertissez-le en un nouveau dictionnaire sorted_vocab = dict(sorted(vocab.items(), key=lambda x: x[1], reverse=True)) Affichez le vocabulaire trié avec chaque mot et son compteur de fréquence print("Vocabulary with Frequencies:", sorted_vocab)

Output:

Vocabulary with Frequencies: {'is': 3, 'the': 3, 'of': 3, 'process': 2, 'words': 2, 'tokenization': 1, 'breaking': 1, 'text': 1, 'into': 1, 'vocabulary': 1, 'collection': 1, 'unique': 1, 'tokenizing': 1, 'essential': 1, 'in': 1, 'nlp': 1}

Construire manuellement un vocabulaire peut être fastidieux, en particulier pour de grands corpus. Le CountVectorizer de Scikit-learn automatise ce processus et permet une traitement de texte plus flexible, comme nous le verrons plus tard.

Implémentation du Bag of Words en Python (de zéro)

Commençons par une implémentation simple du Bag of Words de zéro en Python. Cela vous aidera à comprendre les composants de base et le mécanisme de fonctionnement sous le capot.

Implémentation manuelle

Étape 1 : Prétraitement des données textuelles

Nous commencerons par définir une fonction simple pour traiter le texte, incluant la tokenisation, la conversion en minuscules et la suppression de la ponctuation.

from collections import defaultdict import string # Exemple de données textuelles : phrases corpus = [ "Python is amazing and fun.", "Python is not just fun but also powerful.", "Learning Python is fun!", ] # Fonction pour prétraiter le texte def preprocess(text): # Convertir en minuscules text = text.lower() # Supprimer la ponctuation text = text.translate(str.maketrans("", "", string.punctuation)) # Tokeniser : diviser le texte en mots tokens = text.split() return tokens # Appliquer le prétraitement au corpus d'exemple processed_corpus = [preprocess(sentence) for sentence in corpus] print(processed_corpus)

Sortie :

[['python', 'is', 'amazing', 'and', 'fun'], ['python', 'is', 'not', 'just', 'fun', 'but', 'also', 'powerful'], ['learning', 'python', 'is', 'fun']]

Étape 2 : Construire le vocabulaire

Maintenant, nous devons parcourir tous les documents et construire une liste complète de mots uniques, c’est notre vocabulaire.

# Initialiser un ensemble vide pour le vocabulaire vocabulary = set() # Construire le vocabulaire for sentence in processed_corpus: vocabulary.update(sentence) # Convertir en une liste triée vocabulary = sorted(list(vocabulary)) print("Vocabulary:", vocabulary)

Étape 3 : Calculer les Fréquences des Mots et Vectoriser

Nous allons maintenant calculer la fréquence de chaque mot dans le vocabulaire pour chaque document du corpus traité.

def create_bow_vector(sentence, vocab): vector = [0] * len(vocab) # Initialiser un vecteur de zéros for word in sentence: if word in vocab: idx = vocab.index(word) # Trouver l'index du mot dans le vocabulaire vector[idx] += 1 # Incrémenter le compteur à cet index return vector

À ce stade, vous aurez créé une représentation Sac de Mots pour chaque document de votre corpus.

# Créer un vecteur BoW pour chaque phrase du corpus traité bow_vectors = [create_bow_vector(sentence, vocabulary) for sentence in processed_corpus] print("Bag of Words Vectors:") for vector in bow_vectors: print(vector)

Sortie :

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]

Utilisation du CountVectorizer de Scikit-learn

Construire un modèle de sac de mots manuellement est bon pour l’apprentissage, mais pour des applications de production, vous voudrez utiliser des bibliothèques efficaces et optimisées comme Scikit-learn.

La fonction Python que nous utilisons pour la tokenisation est CountVectorizer, qui est importée depuis sklearn.feature_extraction.text. Une des caractéristiques de CountVectorizer est max_features, qui représente le nombre maximum de mots que vous souhaitez avoir dans le modèle de sac de mots. Dans ce cas, nous utilisons None, ce qui signifie que toutes les caractéristiques seront utilisées.

Après avoir créé une instance de CountVectorizer, utilisez la méthode .fit_transform() pour créer le modèle de sac de mots. Ensuite, utilisez .toarray() pour convertir le modèle de sac de mots en tableaux numpy qui peuvent être utilisés par un modèle d’apprentissage automatique.

Une fois installé, CountVectorizer a construit un dictionnaire des indices de caractéristiques. La valeur d’index d’un mot dans le vocabulaire est liée à sa fréquence dans tout le corpus d’entraînement.

from sklearn.feature_extraction.text import CountVectorizer # Corpus original corpus = [ "Python is amazing and fun.", "Python is not just fun but also powerful.", "Learning Python is fun!", ] # Créer un objet CountVectorizer vectorizer = CountVectorizer() # Ajuster et transformer le corpus X = vectorizer.fit_transform(corpus) # Afficher le vocabulaire généré print("Vocabulary:", vectorizer.get_feature_names_out()) # Afficher la matrice de sac de mots print("BoW Representation:") print(X.toarray())

Sortie :

markdownVocabulary: ['also' 'amazing' 'and' 'but' 'fun' 'is' 'just' 'learning' 'not' 'powerful' 'python'] BoW Representation: [[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]]

Exemple : Application du Bag of Words

Appliquons maintenant le modèle BoW à un petit corpus de textes composé de trois critiques de films pour illustrer tout le processus.

Nous utiliserons le CountVectorizer de Scikit-learn pour appliquer le modèle BoW à ce petit corpus de textes.

Voici les étapes que nous allons suivre :

  • CountVectorizer tokenize le texte, enlève la ponctuation et met les mots en minuscules automatiquement.
  • .fit_transform(corpus) convertit le corpus en une matrice document-termes, où chaque ligne représente un document et chaque colonne un mot du vocabulaire.
  • X_dense est la matrice dense qui représente la fréquence de chaque mot dans chaque document.
from sklearn.feature_extraction.text import CountVectorizer # Corpus d'exemple de critiques de films corpus = [ "I loved the movie, it was fantastic!", "The movie was okay, but not great.", "I hated the movie, it was terrible.", ] # Initialiser le CountVectorizer vectorizer = CountVectorizer() # Ajuster et transformer le corpus en une matrice document-termes X = vectorizer.fit_transform(corpus) # Convertir la matrice document-termes en un format dense (optionnel pour la visualisation) X_dense = X.toarray() # Obtenir le vocabulaire (cartographie des mots vers les positions d'index) vocab = vectorizer.get_feature_names_out() # Afficher le vocabulaire et la matrice document-termes print("Vocabulary:", vocab) print("Document-Term Matrix:\n", X_dense)

Output:

Vocabulary: ['but' 'fantastic' 'great' 'hated' 'it' 'loved' 'movie' 'not' 'okay' 'terrible' 'the' 'was'] Document-Term Matrix: [[0 1 0 0 1 1 1 0 0 0 1 1] # Première critique : "J'ai adoré le film, c'était fantastique !" [1 0 1 0 1 0 1 1 1 0 1 1] # Deuxième critique : "Le film était correct, mais pas excellent." [0 0 0 1 1 0 1 0 0 1 1 1]] # Troisième critique : "J'ai détesté le film, c'était affreux."

Voici comment nous pouvons interpréter la sortie ci-dessus :

  • Chaque mot unique du corpus est affecté d’un index, et les mots sont ordonnés alphabétiquement. Par exemple, « but » est à l’index 0, « fantastic » est à l’index 1, « movie » est à l’index 6, et ainsi de suite.
  • Chaque ligne de la matrice de documents représente un avis sur un film, et chaque colonne correspond à un mot du vocabulaire. Les valeurs dans la matrice représentent la fréquence de chaque mot dans ce document particulier.
    • Première critique : [0 1 0 0 1 1 1 0 0 0 1 1] indique que :
      • Le mot « fantastic » apparaît une fois (1 à l’index 1),
      • Le mot « adoré » apparaît une fois (1 à l’index 5),
      • Le mot « film » apparaît une fois (1 à l’index 6),
      • Le mot « c’était » apparaît une fois (1 à l’index 4),
      • Et ainsi de suite.

Le vecteur BoW peut être interprété comme suit :

  • Chaque document est un vecteur de nombres représentant les compteurs de mots. Les dimensions du vecteur sont égales à la taille du vocabulaire. Dans ce cas, le vocabulaire contient 12 mots, donc chaque critique est transformée en un vecteur 12-dimensionnel.
  • La plupart des mots dans chaque ligne sont des zéros parce que chaque document ne contient pas chaque mot du vocabulaire. Par conséquent, les modèles BoW sont souvent sparses, c’est-à-dire qu’ils ont beaucoup de zéros.

Avantages et Limitations du Modèle Bag of Words

Passons maintenant en revue certains des avantages et limitations du modèle Bag of Words.

Avantages

  1. Facile à mettre en œuvre et à interpréter : Le modèle Bag of Words est l’une des techniques les plus simples de représentation du texte, ce qui le rend idéal pour les débutants. Sa simplicité permet une mise en œuvre rapide sans nécessiter un prétraitement complexe ou des modèles spécialisés.
  2. Facile à utiliser pour des tâches de classification de texte : Bag of Words est bien adapté aux tâches de base comme la classification de texte, l’analyse de sentiment et la détection de spam. Ces tâches n’ont souvent pas besoin de modèles de langage sophistiqués, donc une représentation BOW est suffisante et efficace.

Limitations

  1. La taille du vocabulaire affecte la sparsité des représentations : Plus le vocabulaire est grand, plus la représentation devient épaisse et à haute dimension. Cette sparsité peut rendre plus difficile l’apprentissage des modèles et nécessite un ajustement soigneux de la taille du vocabulaire pour éviter des coûts computationnels excessifs.
  2. Produit des matrices éparse qui sont coûteuses en termes computationnels : Puisque chaque document est représenté par la fréquence de chaque mot dans un vocabulaire potentiellement large, les matrices résultantes sont souvent majoritairement composées de zéros, ce qui peut être inefficient à stocker et à traiter dans les pipelines d’apprentissage automatique. Les matrices éparse consomment une mémoire significative et nécessitent souvent des outils et des bibliothèques spécialisés pour un stockage et une computation efficaces, en particulier avec de grands ensembles de données.
  3. Perte de sens et de contexte : BOW ignore l’ordre des mots et la structure de la phrase, ce qui entraîne la perte de relations grammaticales et de sens. Cette limitation le rend moins approprié pour des tâches où le contexte, la nuance et l’ordre des mots sont importants, telles que la traduction ou la détection de sentiment dans des phrases complexes.

Les stratégies suivantes peuvent être utilisées pour réduire la taille du vocabulaire dans le Bag of Words :

  • Ignorer la casse.
  • Supprimer les ponctuations.
  • Supprimer les stopwords, c’est-à-dire les mots communs tels que « le » et « un ».
  • Assurer que tous les mots sont correctement orthographiés.
  • Utiliser des techniques de stemming pour réduire les mots à leur forme racine.

Étapes suivantes : Au-delà du Bag of Words

Une limitation du modèle Bag of Words est qu’il traite tous les mots de manière égale. Malheureusement, cela peut entraîner des problèmes où certains mots sont considérés comme plus importants simplement parce qu’ils apparaissent fréquemment.

TF-IDF (Fréquence du terme-Inverse de la fréquence du document) est une solution à ce problème, car il ajuste le poids des mots en fonction de leur fréquence sur l’ensemble des documents.

TF-IDF : Une extension du Bag of Words

La fréquence du terme (TF) représente la fréquence d’un terme dans un document. La fréquence inverse du document (IDF) réduit l’impact des mots couramment utilisés sur plusieurs documents. Le score TF-IDF est calculé en multipliant les deux métriques.

Considérez un document contenant 200 mots, où le mot amour apparaît 5 fois. Le TF pour amour est alors (5 / 200) = 0,025. En supposant que nous avons un million de documents et que le mot amour occurs dans mille de ceux-ci, la fréquence inverse des documents (c’est-à-dire l’IDF) est calculée comme log(1000000 / 1000) = 3. Le poids TF-IDF est le produit de ces quantités : 0,025 * 3 = 0,075.

Dans Scikit-learn, c’est relativement facile à calculer en utilisant la classe TfidfVectorizer.

from sklearn.feature_extraction.text import TfidfVectorizer # Corpus d'exemple corpus = [ "Python is amazing and fun.", "Python is not just fun but also powerful.", "Learning Python is fun!", ] # Créer le vectoriseur Tf-idf tfidf_vectorizer = TfidfVectorizer() # Ajuster et transformer le corpus X_tfidf = tfidf_vectorizer.fit_transform(corpus) # Afficher le vocabulaire print("Vocabulary:", tfidf_vectorizer.get_feature_names_out()) # Afficher la matrice TF-IDF print("TF-IDF Representation:") print(X_tfidf.toarray())

Sortie :

Vocabulary: ['also' 'amazing' 'and' 'but' 'fun' 'is' 'just' 'learning' 'not' 'powerful' 'python'] TF-IDF Representation: [[0. 0.57292883 0.57292883 0. 0.338381 0.338381 0. 0. 0. 0. 0.338381 ] [0.40667606 0. 0. 0.40667606 0.24018943 0.24018943 0.40667606 0. 0.40667606 0.40667606 0.24018943] [0. 0. 0. 0. 0.41285857 0.41285857 0. 0.69903033 0. 0. 0.41285857]]

La matrice TF-IDF implémentée ci-dessus vous donne une mesure pondérée au lieu de fréquences brutes.

Bien que le modèle du Sac de Mots ait ses limites, en particulier pour des ensembles de données plus grands et plus complexes, il reste un élément essentiel dans de nombreuses applications de NLP. Comprendre cela vous aidera lorsque vous explorerez des modèles plus avancés comme les représentations de mots et les Transformers.

À partir de là, vous pourriez expérimenter avec le BoW dans vos projets, y compris la détection de spam, l’analyse de sentiment, le regroupement de documents, et plus.

Si vous souhaitez des améliorations supplémentaires au-delà du Sac de Mots, vous pouvez explorer des méthodes comme Word2Vec et GloVe, ou des modèles d’apprentissage profond comme BERT.

Reflections

La technique du Bag of Words est une technique fondamentale utilisée dans le traitement du langage naturel. Elle sert de moyen simple mais efficace pour convertir du texte non structuré en caractéristiques numériques utilisables par les algorithmes d’apprentissage automatique. Dans ce tutoriel, nous avons couvert:

  • Qu’est-ce que le modèle Bag of Words (BoW)?
  • Les avantages du modèle Bag of Words dans la construction de modèles d’apprentissage automatique.
  • Comment implémenter le modèle Bag of Words en Python.
  • Les avantages et limitations du Bag of Words.
  • La théorie et la motivation derrière le modèle Bag of Words.
  • La présentation du TF-IDF comme une amélioration de l’approche traditionnelle du Bag of Words.

Jetez un œil à notre parcours de compétences Natural Language Processing en Python, pour plonger profondément dans le traitement du langage naturel.

Source:
https://www.datacamp.com/tutorial/python-bag-of-words-model