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)技术支持
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)技术支持
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)技术支持
# 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)技术支持
步骤 3:计算词频并向量化
现在我们计算处理后语料中每个文档对词汇表中每个词的出现频次。
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
技术支持
至此,您已为语料中的每个文档构建了词袋表示。
# 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)技术支持
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())技术支持
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)技术支持
输出:
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."技术支持
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())技术支持
词袋(Bag of Words,BoW)是自然语言处理(NLP)中的一种技术。它被广泛用于将文本数据转换为机器可读的格式,特别是数值形式,而不考虑语法和词序。对于处理文本数据的人来说,理解 BoW 非常重要。Python 提供了多种工具和库来高效实现词袋模型。
在本教程中,我们将深入介绍 BoW,讲解其概念、使用场景,并带您一步步用 Python 实现。完成本教程后,您将能够将词袋模型应用于实际问题。如果您是 NLP 新手,欢迎查看我们的Python 自然语言处理技能路线了解更多。
什么是词袋模型?
词袋是一种从文本数据中提取特征以用于机器学习任务(如文本分类和情感分析)的技术。这很重要,因为机器学习算法无法直接处理原始文本。将文本转换为数字的过程称为特征提取或特征编码。
词袋模型基于文档中词语的出现情况。该过程从在文本中找出词汇表并统计其出现次数开始。之所以称为“袋”,是因为不考虑词语的顺序和结构,只关心其是否出现。
词袋模型不同于连续词袋模型(CBOW)。CBOW 通过使用上下文词来预测目标词来学习稠密的词向量,从而捕捉词语之间的语义关系。CBOW 需要在大型语料库上训练,并生成低维向量,适用于那些重视词语上下文的复杂 NLP 应用。
方面
BOW
CBOW
目的
统计每个词的出现次数
基于上下文预测目标词
输出类型
高维、稀疏向量
低维、稠密嵌入
是否考虑上下文
否(忽略词序)
是(使用周围词语)
表示方式
稀疏的频次向量
捕捉语义的稠密向量
复杂度
低(无需训练)
高(需在大型语料上训练)
典型应用
文本分类、情感分析
词向量、需要上下文的 NLP 任务
为什么使用词袋模型?
词袋在许多NLP 任务中很有用,其原因包括:
不过,它也有不足之处,例如不考虑语义、词形结构或词序等。
在 Python 中实现词袋模型的步骤
要创建词袋模型,我们将语料库中的所有词汇取出,并为每个词创建一列。每一行代表一个句子。若某个词出现在句子中,则用 1 表示;未出现则用 0 表示。列中的每个词即代表一个特征。
最终我们得到的是稀疏矩阵。稀疏矩阵是包含大量零值的矩阵。
数据预处理
要在 Python 中创建词袋模型,需要进行一些预处理步骤。这些步骤包括分词和去除停用词。
分词是将一段文本拆分为更小的单元,通常是词。您可以使用NLTK进行分词。
停用词是英语中常见的词,如 "the"、"that" 和 "a",这些词对句子的极性贡献不大。
输出:
创建词汇表
词汇表是语料库中出现的唯一词的集合。构建词汇表需要收集语料中的所有唯一词并统计其出现次数。该词汇表可用于语言建模、词向量、文本分类等多种 NLP 任务。
下面的代码创建了一个简单的词频分布,适用于构建词汇表或理解文本内容等基础 NLP 任务:
defaultdict(int)简化了词频统计,对新词自动初始化为 0,从而可直接自增而无需额外检查。\b\w+\b仅识别由字母数字构成的单词,忽略标点符号等。输出:
手动构建词汇表对大型语料而言很耗时。Scikit-learn 的 CountVectorizer 可以自动完成此流程,并提供更灵活的文本处理能力,我们稍后会看到。
使用 Python(从零开始)实现词袋模型
我们先在Python 中从零实现一个简单的词袋模型。这将帮助您理解其底层的构建模块和工作机制。
手动实现
步骤 1:预处理文本数据
我们先定义一个简单的函数来处理文本,包括分词、小写化和去除标点。
输出:
步骤 2:构建词汇表
接下来我们需要遍历所有文档,构建完整的唯一词清单,也就是词汇表。
步骤 3:计算词频并向量化
现在我们计算处理后语料中每个文档对词汇表中每个词的出现频次。
至此,您已为语料中的每个文档构建了词袋表示。
输出:
使用 Scikit-learn 的 CountVectorizer
手动构建词袋模型有助于学习,但在生产应用中,您会更希望使用高效、优化的库,如Scikit-learn。
我们用于分词的 Python 函数是CountVectorizer,它从
sklearn.feature_extraction.text导入。CountVectorizer的一个参数是max_features,表示您希望词袋模型中包含的最大词数。本例中使用 None,表示使用所有特征。创建
CountVectorizer的实例后,使用.fit_transform() 方法构建词袋模型。接着使用.toarray()将词袋模型转换为可输入机器学习模型的 numpy 数组。拟合完成后,CountVectorizer 会建立一个特征索引字典。词汇表中词的索引值与其在整个训练语料中的频次相关联。
输出:
示例:应用词袋模型
现在我们将词袋模型应用到一个由三条影评组成的小型文本语料库,以展示完整流程。
我们将使用 Scikit-learn 的 CountVectorizer 将词袋模型应用于这个小语料库。
我们将按以下步骤进行:
CountVectorizer会自动进行分词、去除标点并将词小写化。.fit_transform(corpus)将语料转换为文档-词项矩阵,其中每行代表一个文档,每列代表词汇表中的一个词。X_dense是稠密矩阵,表示每个文档中各词的出现频次。输出:
我们可以这样解读上述输出:
BoW 向量可以这样理解:
词袋模型的优缺点
下面我们来介绍词袋模型的一些优势与局限。
优势
局限
可采用以下策略来缩小词袋中的词汇表规模:
下一步:超越词袋模型
词袋模型的一个局限是将所有词一视同仁。这可能导致某些词因为出现频繁而被赋予过高的重要性。
TF-IDF(词频-逆文档频率)可以缓解这个问题,它根据词在所有文档中的出现频率来调整词的权重。
TF-IDF:词袋模型的扩展
词频(TF)表示某个词在文档中的出现频次;逆文档频率(IDF)会降低在多个文档中频繁出现的词的影响。TF-IDF 分数通过二者相乘得到。
例如,一个包含 200 个词的文档中,词 love 出现 5 次,则 love 的 TF 为 (5 / 200) = 0.025。假设共有一百万份文档,其中 love 出现在一千份文档中,则逆文档频率(IDF)为 log(1000000 / 1000) = 3。TF-IDF 权重为二者乘积:0.025 * 3 = 0.075。
在 Scikit-learn 中,可以使用 TfidfVectorizer 类相对容易地进行计算。
输出:
上述 TF-IDF 矩阵提供的是加权度量,而非原始频次。
尽管词袋模型在处理更大、更复杂的数据集时存在局限,但它仍是许多 NLP 应用中的基础构件。理解它将有助于您进一步探索更高级的模型,如词嵌入和Transformer。
接下来,您可以在项目中实践 BoW,例如垃圾邮件检测、情感分析、文档聚类等。
如果您希望在词袋模型之上进一步提升,可以探索如 Word2Vec、GloVe 等方法,或基于深度学习的 BERT。
结语
词袋技术是自然语言处理中的基础方法。它以一种简洁而有效的方式将非结构化文本转换为可被机器学习算法使用的数值特征。在本教程中,我们介绍了:
欢迎查看我们的Python 自然语言处理技能路线,深入学习自然语言处理。