关键词提取就是从文本里面把跟这篇文章意义最相关的一些词语抽取出来。这个可以追溯到文献检索初期,关键词是为了文献标引工作,从报告、论文中选取出来用以表示全文主题内容信息的单词或术语,在现在的报告和论文中,我们依然可以看到关键词这一项。因此,关键词在文献检索、自动文摘、文本聚类/分类等方面有着重要的应用,它不仅是进行这些工作不可或缺的基础和前提,也是互联网上信息建库的一项重要工作。
目前大多数应用领域的关键词抽取算法都是基于后者实现的,从逻辑上说,后者比前者在实际应用中更准确。
下面介绍一些关于关键词抽取的常用和经典的算法实现。
在信息检索理论中,TF-IDF 是 Term Frequency - Inverse Document Frequency 的简写。TF-IDF 是一种数值统计,用于反映一个词对于语料中某篇文档的重要性。在信息检索和文本挖掘领域,它经常用于因子加权。
因此,TF-IDF 倾向于过滤掉常见的词语,保留重要的词语。例如,某一特定文件内的高频率词语,以及该词语在整个文件集合中的低文件频率,可以产生出高权重的 TF-IDF。
好在 jieba 已经实现了基于 TF-IDF 算法的关键词抽取,通过命令 import jieba.analyse 引入,函数参数解释如下:
jieba.analyse.extract_tags(sentence, topK=20, withWeight=False, allowPOS=())
接下来看例子,我采用的语料来自于百度百科对自然语言处理的定义,获取 Top20 关键字,用空格隔开打印:
import jieba.analyse
sentence = "自然语言处理是计算机科学领域与人工智能领域中的一个重要方向。它研究能实现人与计算机之间用自然语言进行有效通信的各种理论和方法。自然语言处理是一门融语言学、计算机科学、数学于一体的科学。因此,这一领域的研究将涉及自然语言,即人们日常使用的语言,所以它与语言学的研究有着密切的联系,但又有重要的区别。自然语言处理并不是一般地研究自然语言,而在于研制能有效地实现自然语言通信的计算机系统,特别是其中的软件系统。因而它是计算机科学的一部分。"
keywords = " ".join(jieba.analyse.extract_tags(sentence , topK=20, withWeight=False, allowPOS=()))
print(keywords)
输出:
自然语言 计算机科学 语言学 研究 领域 处理 通信 有效 软件系统 人工智能 实现 计算机系统 重要 一体 一门 日常 计算机 密切 数学 研制
下面只获取 Top10 的关键字,并修改一下词性,只选择名词和动词,看看结果有何不同?
import jieba.analyse
sentence = "自然语言处理是计算机科学领域与人工智能领域中的一个重要方向。它研究能实现人与计算机之间用自然语言进行有效通信的各种理论和方法。自然语言处理是一门融语言学、计算机科学、数学于一体的科学。因此,这一领域的研究将涉及自然语言,即人们日常使用的语言,所以它与语言学的研究有着密切的联系,但又有重要的区别。自然语言处理并不是一般地研究自然语言,而在于研制能有效地实现自然语言通信的计算机系统,特别是其中的软件系统。因而它是计算机科学的一部分。"
keywords =(jieba.analyse.extract_tags(sentence , topK=10, withWeight=True, allowPOS=(['n','v'])))
print(keywords)
输出:
[('计算机科学', 0.944278347636774), ('语言学', 0.5780022728625807), ('领域', 0.5237705363622581), ('处理', 0.5236311926477419), ('人工智能', 0.30509762566096776), ('实现', 0.30172453397354837), ('计算机系统', 0.293973739006129), ('一体', 0.23797146276870967), ('计算机', 0.2195091751896774), ('数学', 0.21317227341290323)]
TextRank 是由 PageRank 改进而来,核心思想将文本中的词看作图中的节点,通过边相互连接,不同的节点会有不同的权重,权重高的节点可以作为关键词。这里给出 TextRank 的公式:
节点 i 的权重取决于节点 i 的邻居节点中 i-j 这条边的权重 / j 的所有出度的边的权重 * 节点 j 的权重,将这些邻居节点计算的权重相加,再乘上一定的阻尼系数,就是节点 i 的权重,阻尼系数 d 一般取 0.85。
TextRank 用于关键词提取的算法如下:
(1)把给定的文本 T 按照完整句子进行分割,即:
(2)对于每个句子,进行分词和词性标注处理,并过滤掉停用词,只保留指定词性的单词,如名词、动词、形容词,其中
ti,j 是保留后的候选关键词。
(3)构建候选关键词图 G = (V,E),其中 V 为节点集,由(2)生成的候选关键词组成,然后采用共现关系(Co-Occurrence)构造任两点之间的边,两个节点之间存在边仅当它们对应的词汇在长度为 K 的窗口中共现,K 表示窗口大小,即最多共现 K 个单词。
(4)根据 TextRank 的公式,迭代传播各节点的权重,直至收敛。
(5)对节点权重进行倒序排序,从而得到最重要的 T 个单词,作为候选关键词。
(6)由(5)得到最重要的 T 个单词,在原始文本中进行标记,若形成相邻词组,则组合成多词关键词。
同样 jieba 已经实现了基于 TextRank 算法的关键词抽取,通过命令 import jieba.analyse 引用,函数参数解释如下:
jieba.analyse.textrank(sentence, topK=20, withWeight=False, allowPOS=('ns', 'n', 'vn', 'v'))
直接使用,接口参数同 TF-IDF 相同,注意默认过滤词性。
接下来,我们继续看例子,语料继续使用上例中的句子。
import jieba.analyse
sentence = "自然语言处理是计算机科学领域与人工智能领域中的一个重要方向。它研究能实现人与计算机之间用自然语言进行有效通信的各种理论和方法。自然语言处理是一门融语言学、计算机科学、数学于一体的科学。因此,这一领域的研究将涉及自然语言,即人们日常使用的语言,所以它与语言学的研究有着密切的联系,但又有重要的区别。自然语言处理并不是一般地研究自然语言,而在于研制能有效地实现自然语言通信的计算机系统,特别是其中的软件系统。因而它是计算机科学的一部分。"
#tf-idf
keywords = " ".join(jieba.analyse.extract_tags(sentence , topK=20, withWeight=False, allowPOS=()))
print(keywords)
#textrank
print("-------")
result = " ".join(jieba.analyse.textrank(sentence, topK=20, withWeight=False, allowPOS=('ns', 'n', 'vn', 'v')))
print(result)
输出结果:
自然语言 计算机科学 语言学 研究 领域 处理 通信 有效 软件系统 人工智能 实现 计算机系统 重要 一体 一门 日常 计算机 密切 数学 研制
-------
研究 领域 计算机科学 实现 处理 语言学 数学 人们 计算机 涉及 有着 一体 方法 语言 研制 使用 人工 智能 在于 联系 科学