博客主页:真的睡不醒
系列专栏:深度学习环境搭建、环境配置问题解决、自然语言处理、语音信号处理、项目开发
每日语录:你要做冲出的黑马 而不是坠落的星星。
感谢大家点赞收藏⭐指正✍️
关键词提取是将文本中的关键信息、核心概念或重要主题抽取出来的过程。这些关键词可以帮助人们快速理解文本的主题,构建文本摘要,提高搜索引擎的效率,甚至用于文本分类和信息检索等应用领域。因此,关键词提取在文本分析和自然语言处理中具有广泛的应用前景。本文主要包括以下几个内容:
本博客将深入探讨自然语言处理中常用的TextRank算法,以多种方式展现TextRank算法的核心思想。
一般情况下我们拿到的文本是不规范的,需要我们进行一系列的预处理操作。
- 文本数据清洗:去除特殊符号、HTML标签、数字等无关字符。
- 分词:将文本拆分成单词或词组。
- 停用词去除:排除常见的停用词,如“的”、“在”等,以减少噪音。
在前边的准备工作中,你已经获得了停用词表,通过以下代码提取停用词。
# 获取停用词
def load_stopwords(stopwords_file):
stopwords = set()
with open(stopwords_file, 'r', encoding='utf-8') as f:
for line in f:
stopwords.add(line.strip())
return stopwords
在这里提一嘴,在编程中,set 是一种数据结构,它类似于列表(list)或字符串(string),但具有一些不同的特点。
- 列表(list)是一种有序的数据结构,可以包含多个元素,每个元素可以是不同类型的数据(例如数字、字符串、其他列表等)。列表中的元素可以重复。
- 字符串(string)是一种有序的字符序列,通常用于表示文本。字符串的每个字符都有一个索引位置。
- set 是一种无序的集合数据结构,它用于存储不重复的元素。集合中的元素不按顺序排列,并且每个元素在集合中只能出现一次。集合通常用于存储一组唯一的值。
# 加载文档集,对文档集过滤词性和停用词
def filter_documents(data_path, stopwords):
documents = []
with open(data_path, 'r', encoding='utf-8') as f:
for line in f:
document = []
words = pseg.cut(line.strip())
for word, flag in words:
if flag.startswith('n') and word not in stopwords and len(word) > 1:
document.append(word)
documents.append(document)
return documents
通过这一步,我们就得到一个包含精确分词、词性过滤和停用词去除的文本数据。
预处理完成,接下来就是算法详解和实现。
算法思想:TextRank算法是一种用于文本摘要和关键词提取的基于图的算法,它借鉴了PageRank算法的思想,用于自动提取文本中重要的句子或关键词。下面我将详细讲解TextRank算法的思想和工作原理。
前边我们已经完成了文本预处理的工作。
TextRank算法的核心思想是将文本表示为图,其中句子或词语是图中的节点,它们之间的关系是边。构建图的过程包括以下步骤:
2.1. 节点表示
每个句子或词语都被表示为图中的一个节点。通常,可以使用词向量(Word Embeddings)来表示词语,这些词向量可以通过预训练的词嵌入模型(如Word2Vec或GloVe)获取。对于句子,可以使用句向量来表示,通常是将句子中所有词语的词向量进行平均或加权平均。
2.2. 边的构建
接下来,需要确定节点之间的关系,即边。通常使用某种相似度度量来计算节点之间的相似性,例如余弦相似度。节点之间的相似度可以根据节点的词向量或其他特征来计算。如果相似度超过一个预定的阈值,则在两个节点之间建立一条边。
一旦构建了图,就可以使用类似PageRank的算法来计算每个节点(句子或词语)的重要性分数。TextRank算法使用迭代的方式计算这些分数,直到收敛为止。以下是计算节点重要性的步骤:
3.1. 初始化分数
为每个节点初始化一个初始重要性分数,通常可以设置为相等的值。
3.2. 迭代计算
重要性分数的计算通过多轮迭代进行,每一轮都根据与其相连接的节点的重要性来更新节点自身的重要性分数。更新公式如下:
Score(A) = (1 - d) + d * Σ (Score(B) / OutDegree(B))
A
是当前节点的重要性分数,需要更新的节点。B
是与节点A
有边相连的节点。d
是阻尼因子(damping factor),通常取一个介于0和1之间的值,用于平衡迭代过程中的随机浏览和节点之间的相互连接。Score(B)
是节点B
的当前重要性分数。OutDegree(B)
是节点B
的出度,表示与节点B
相连的边的数量。
3.3. 收敛
迭代计算会一直进行,直到重要性分数收敛,即分数的变化不再显著。
一旦计算出每个节点的重要性分数,就可以根据这些分数来选择最重要的句子或词语作为文本摘要或关键词。通常,可以根据分数排名来选择前N个句子或词语。
# 使用TextRank提取关键词
def extract_keywords_textrank(documents, top_n=10):
top_keywords_per_document = []
tr4w = TextRank4Keyword()
for document in documents:
text = ' '.join(document)
tr4w.analyze(text=text, lower=True, window=2)
keywords = tr4w.get_keywords(top_n, word_min_len=2)
top_keywords_per_document.append([keyword.word for keyword in keywords])
return top_keywords_per_document
为了使提取到的关键词更加直观,这里我们词云的形式展现。首先需要确保你的环境已经安装了词云可以通过以下命令安装wordcloud。
有的同学在生成词语的时候,会出现乱码的问题,为了避免乱码建议下载中文字体,这里我直接分享给大家。(提取码:peng)百度网盘 请输入提取码 (baidu.com)
def generate_wordcloud(keywords, title):
"""
生成词云图并显示
参数:
keywords (list): 包含关键词的列表。
title (str): 词云图的标题。
返回:
None
"""
# 将关键词列表转化为字符串
keywords_str = ' '.join(keywords)
# 指定中文字体文件路径(根据实际情况替换为合适的路径)
font_path = r'D:\my_homework\NLP_homework\NLP_test1\SimHei.ttf' # 替换为包含中文字符的字体文件路径
# 创建词云对象并指定字体
wordcloud = WordCloud(width=800, height=400, background_color='white', font_path=font_path).generate(keywords_str)
# 显示词云图
plt.figure(figsize=(10, 5))
plt.imshow(wordcloud, interpolation='bilinear')
plt.axis('off')
plt.title(f'wordcloud - {title}')
plt.show()
效果展示:
总的来说,TextRank算法是一种有效的自动化关键词提取方法,它不需要依赖领域知识或语法规则,只需要基于文本本身的统计信息就能得到关键词,因此在各种自然语言处理任务中都具有广泛的应用前景。
import jieba
import jieba.posseg as pseg
from sklearn.feature_extraction.text import TfidfVectorizer
from textrank4zh import TextRank4Keyword
import matplotlib.pyplot as plt
from wordcloud import WordCloud
# 获取停用词
def load_stopwords(stopwords_file):
stopwords = set()
with open(stopwords_file, 'r', encoding='utf-8') as f:
for line in f:
stopwords.add(line.strip())
return stopwords
# 加载文档集,对文档集过滤词性和停用词
def filter_documents(data_path, stopwords):
documents = []
with open(data_path, 'r', encoding='utf-8') as f:
for line in f:
document = []
words = pseg.cut(line.strip())
for word, flag in words:
if flag.startswith('n') and word not in stopwords and len(word) > 1:
document.append(word)
documents.append(document)
return documents
def generate_wordcloud(keywords, title):
"""
生成词云图并显示
参数:
keywords (list): 包含关键词的列表。
title (str): 词云图的标题。
返回:
None
"""
# 将关键词列表转化为字符串
keywords_str = ' '.join(keywords)
# 指定中文字体文件路径(根据实际情况替换为合适的路径)
font_path = r'D:\my_homework\NLP_homework\NLP_test1\SimHei.ttf' # 替换为包含中文字符的字体文件路径
# 创建词云对象并指定字体
wordcloud = WordCloud(width=800, height=400, background_color='white', font_path=font_path).generate(keywords_str)
# 显示词云图
plt.figure(figsize=(10, 5))
plt.imshow(wordcloud, interpolation='bilinear')
plt.axis('off')
plt.title(f'wordcloud - {title}')
plt.show()
# 使用TextRank提取关键词
def extract_keywords_textrank(documents, top_n=10):
top_keywords_per_document = []
tr4w = TextRank4Keyword()
for document in documents:
text = ' '.join(document)
tr4w.analyze(text=text, lower=True, window=2)
keywords = tr4w.get_keywords(top_n, word_min_len=2)
top_keywords_per_document.append([keyword.word for keyword in keywords])
return top_keywords_per_document
if __name__ == "__main__":
stopwords_file = r'D:\my_homework\NLP_homework\NLP_test1\stopword.txt' # 停用词文件路径
data_path = r'D:\my_homework\NLP_homework\NLP_test1\corpus4keyword.txt' # 文档集文件路径
stopwords = load_stopwords(stopwords_file)
documents = filter_documents(data_path, stopwords)
print('停用词表的大小为:', len(stopwords))
print('文档的数量为', len(documents))
top_keywords1 = extract_keywords_textrank(documents)
# 打印每个文档的前10个关键词
for doc_id, keywords in enumerate(top_keywords1):
print(f'文档 {doc_id + 1} 的前10个关键词: {", ".join(keywords)}')
document_keywords = top_keywords1[19] # 假设第20个文档的索引是19
generate_wordcloud(document_keywords, 'wordcloud')