探索文本的隐秘主题 —— 使用NLTK进行主题建模
学习目标
本课程将带领学员深入了解主题建模的概念,掌握如何使用NLTK库中的LDA算法对文本数据进行主题建模。通过本课程的学习,学员将能够独立完成从数据预处理到模型训练,再到结果分析的整个流程。
相关知识点
- 使用NLTK进行主题建模
学习内容
1 使用NLTK进行主题建模
1.1 主题建模的基本概念
主题建模是一种统计模型,用于在文档集合中发现抽象主题。这些主题由文档中频繁出现的词汇组成,每个文档可以由多个主题以不同的比例组合而成。主题建模的主要目的是从大量文本数据中提取出潜在的主题结构,帮助人们更好地理解和分析文本数据。
在实际应用中,主题建模可以用于新闻分类、市场趋势分析、用户兴趣挖掘等多个领域。例如,通过分析社交媒体上的帖子,可以发现人们对特定产品的兴趣点,从而为营销策略提供数据支持。
在进行主题建模之前,文本数据需要经过预处理,以去除噪声和标准化文本。NLTK库提供了丰富的工具和函数,可以方便地完成文本预处理工作。以下是一些常见的预处理步骤:
- 分词:将文本分割成单词或短语。在NLTK中,可以使用
word_tokenize函数实现。 - 去除停用词:停用词是指在文本中频繁出现但对主题分析没有帮助的词汇,如“的”、“是”、“在”等。NLTK提供了一个停用词列表,可以使用
stopwords.words('language')获取。 - 词干提取:将单词还原为其词根形式,以减少词汇的多样性。NLTK中的
PorterStemmer和LancasterStemmer是常用的词干提取器。 - 词形还原:将单词还原为其基本形式,如将“running”还原为“run”。NLTK中的
WordNetLemmatizer可以实现词形还原。
1.2 使用NLTK进行文本预处理
下面是一个简单的文本预处理示例代码。
1.2.1 环境安装与NLTK数据包下载
首先安装实验必须的python库。nltk是一个用于自然语言处理的库。gensim是一个用于主题建模和文档相似性分析的库。
环境安装如果出现以下错误信息可忽略,不影响运行。
ERROR: pip's dependency resolver does not currently take into account all the packages that are installed. This behaviour is the source of the following dependency conflicts.
catboost 1.2.7 requires plotly, which is not installed.
%pip install wheel==0.44.0
%pip install gensim==4.3.3 nltk==3.9.1
接下来下载几个NLTK数据包。本课程使用了三个NLTK的数据包:
- punkt:这是一个用于分词(Tokenization)的模型,能够将文本分割成单词和标点符号。在自然语言处理(NLP)中,分词是文本预处理的第一步。它将连续的文本字符串分割成单词、标点符号等离散的单元,以便后续处理。
- stopwords:这是一个停用词列表,包含了在文本中出现频率较高但通常对语义贡献较小的单词,如“的”、“了”、“和”等中文停用词,或者“is”、“a”、“the”等英文停用词。在文本预处理中,去除停用词可以减少数据量,提高模型的效率和准确性,同时使模型更加关注于有意义的词汇。
- wordnet:这是一个语义词典,提供了单词的同义词、反义词、上下位关系等语义信息。在词形还原(Lemmatization)中,wordnet 可以将单词还原为其基本形态(词典形式),这有助于统一不同形态的单词,减少词汇的多样性,提高模型的性能。
安装nltk库后可以使用代码自动安装(不推荐),代码下载数据的地址是外网极容易下载失败。
nltk.download('punkt')
nltk.download('stopwords')
nltk.download('wordnet')
本课程使用手动安装方式,学员下载数据包后解压即可使用。
!wget https://model-community-picture.obs.cn-north-4.myhuaweicloud.com/ascend-zone/notebook_datasets/94528ace2fa811f08c88fa163edcddae/nltk_data.zip
!unzip nltk_data.zip
1.2.2 文本预处理
准备完毕,接下来就可以使用NLTK进行文本预处理。示例中展示了四种文本预处理的方式及结果,分别是原始分词、去除停用词、词干提取、词形还原。
因为是手动安装,需要将nltk_data文件夹添加到NLTK的数据路径中,以便NLTK能够找到数据包。
import nltk
from nltk.tokenize import word_tokenize
from nltk.corpus import stopwords
from nltk.stem import PorterStemmer, WordNetLemmatizer
import os
# 添加nltk_data文件夹到NLTK的数据路径中
nltk.data.path.append(os.path.join(os.getcwd(), 'nltk_data'))
# 示例文本,用于后续的处理
text = "Natural language processing (NLP) is a field of computer science, artificial intelligence, and linguistics concerned with the interactions between computers and human (natural) languages."
- word_tokenize 用于将文本分割成单词。
- stopwords 用于获取停用词列表。
- PorterStemmer 和 WordNetLemmatizer 分别用于词干提取和词形还原。
- os 用于操作文件系统。
# 原始分词
tokens = word_tokenize(text)
print("原始分词结果:", tokens)
- 解释:word_tokenize函数将输入文本分割成单词和标点符号的列表。这里包括了所有单词和标点符号,如括号
(和),以及逗号,和句号.。 - 特点:这个结果保留了文本中的所有信息,但包含了停用词和标点符号。
# 去除停用词
stop_words = set(stopwords.words('english'))
filtered_tokens = [token for token in tokens if token.lower() not in stop_words]
print("去除停用词后的结果:", filtered_tokens)
- 解释:通过过滤掉英语中的停用词(如
is、a、of、and、with、the等),得到了一个更简洁的单词列表。停用词通常是那些在文本中出现频率较高但对语义贡献较小的词。 - 特点:这个结果更加聚焦于文本中的关键信息,减少了冗余。
# 词干提取
stemmer = PorterStemmer()
stemmed_tokens = [stemmer.stem(token) for token in filtered_tokens]
print("词干提取后的结果:", stemmed_tokens)
- 解释:使用 PorterStemmer 对单词进行了词干提取。词干提取是一种将单词缩减到其词根形式的技术,通常通过裁剪单词的末尾来实现。例如,Natural 被提取为 natur,language 被提取为 languag。
- 特点:词干提取后的单词可能不是有效的单词,但它有助于统一不同形态的单词,使其共享相同的词干。
# 词形还原
lemmatizer = WordNetLemmatizer()
lemmatized_tokens = [lemmatizer.lemmatize(token) for token in filtered_tokens]
print("词形还原后的结果:", lemmatized_tokens)
- 解释:使用 WordNetLemmatizer 对单词进行了词形还原。词形还原是将单词还原为其基本形态(词典形式)的过程。例如,languages 被还原为 language。
- 特点:与词干提取不同,词形还原后的单词通常是有效的单词,且更符合语言规范。
1.3 LDA算法及其在NLTK中的应用
LDA(Latent Dirichlet Allocation)是一种广泛使用的主题建模算法。LDA假设每个文档是由多个主题以不同的比例组合而成,每个主题又由多个词汇以不同的概率分布组成。通过LDA算法,可以从文档集合中推断出潜在的主题结构。使用主题建模生成主题总览可以快速了解文本集主要内容或趋势。实际中可以辅助文档搜索、聚类、自动推荐、知识发现等。
在NLTK中,虽然没有直接提供LDA算法的实现,但可以通过Gensim库来实现LDA。Gensim是一个强大的自然语言处理库,与NLTK可以很好地结合使用。
以下是一个使用Gensim进行LDA主题建模的示例代码:
import gensim
from gensim import corpora
from nltk.tokenize import word_tokenize
from nltk.tokenize import RegexpTokenizer
from nltk.corpus import stopwords
# 示例文档集合
documents = [
"Natural language processing is a field of computer science, artificial intelligence, and linguistics.",
"It is concerned with the interactions between computers and human (natural) languages.",
"LDA is a popular algorithm for topic modeling.",
"It can be used to discover hidden topics in a collection of documents."
]
# 文本预处理
stop_words = set(stopwords.words('english'))
tokenizer = RegexpTokenizer(r'\w+') # 只保留"单词"字符,去掉所有标点
tokenized_docs = [tokenizer.tokenize(doc.lower()) for doc in documents]
filtered_docs = [[token for token in doc if token not in stop_words] for doc in tokenized_docs]
# 创建词典
dictionary = corpora.Dictionary(filtered_docs)
# 将文档转换为词袋模型
corpus = [dictionary.doc2bow(doc) for doc in filtered_docs]
# 训练LDA模型
lda_model = gensim.models.LdaModel(
corpus,
num_topics=2, # 指定主题数!这个可根据实际调整
id2word=dictionary,
passes=10, # 迭代次数
random_state=42 # 固定随机种子,保证结果一致。需要不同结果可去除
)
# 输出主题
for idx, topic in lda_model.print_topics(-1):
print(f"Topic: {idx} \nWords: {topic}\n")
通过上述代码,可以从文档集合中提取出两个主题,并输出每个主题的关键词及其概率分布。这有助于人们理解文档集合中的潜在主题结构。
Topic 0
关键词:natural, processing, language, linguistics, artificial, intelligence, 等。这说明这一组文本主要在讨论“自然语言处理”“人工智能”等相关话题。
Topic 1
关键词:documents, topics, modeling, algorithm, lda 等。这些词主要和“主题建模方法本身”“算法和模型”相关。
这里的每个“Topic”就是LDA算法“自动总结归纳”出来的一个主题类别。
每个主题下面列出了若干单词(“natural”、“language”……),它们是这个主题里出现得多、对主题意义大的词——可把它理解成这个主题的“标签”。
0.071*"natural" 里的这个数字是这个词在该主题的“贡献度”或“重要性权重”,数字大代表更典型。
这些主题不是手动分类的,全靠算法自己分析数据统计得出的。
简单说:LDA就是帮我们把一堆文档归成若干主要类别,每个类别自动总结出一批描述它的关键词。
虽然主题词列表是自动化得到的,但是主题的实际“意义”要结合人工理解(比如“Topic 0是人工智能,Topic 1是算法技术”)。

被折叠的 条评论
为什么被折叠?



