我要把人生变成科学的梦,然后再把梦变成现实。——居里夫人
概述
关键词是代表文章重要内容的一组词,在文献检索、自动文摘、文本聚类/分类等方面有着重要的应用。现实中大量的文本不包含关键词,这使得便捷获取文本信息更困难,所以自动提取关键词技术具有重要的价值和意义。
关键词提取分类
- 有监督
- 无监督
有监督虽然精度高,但需要维护一个内容丰富的词表,需要大量的标注数据,人工成本过高。
无监督不需要标注数据,因此这类算法在关键词提取领域应用更多。比如TF-IDF算法、TextRank算法和主题模型LDA算法等。
TF-IDF算法
TF-IDF(Term Frequency - Inverse Document Frequency)是一种基于统计的计算方法,常用于反映一个词对于语料中某篇文档的重要性。
TF是词频(Term Frequency),IDF是逆文本频率指数(Inverse Document Frequency)。TF-IDF 的主要思想就是:如果某个词在一篇文档中出现的频率高,也即 TF 高;并且在语料库中其他文档中很少出现,即DF低,也即IDF高,则认为这个词具有很好的类别区分能力。
TF 为词频(Term Frequency),表示词 t 在文档 d 中出现的频率,计算公式:
其中,分子是该词在文件中的出现次数,而分母则是在文件中所有字词的出现次数之和。
IDF 为逆文档频率(Inverse Document Frequency),表示语料库中包含词 t 的文档的数目的倒数,计算公式:
其中,|D|:语料库中的文件总数,|{j:ti∈dj}| 包含词 ti 的文件数目,如果该词语不在语料库中,就会导致被除数为零,因此一般情况下使用 1 |{j:ti∈dj}|。
然后再计算TF与IDF的乘积:
因此,TF-IDF倾向于过滤掉常见的词语,保留重要的词语。比如:有些词“的”,“了”,“地”等出现在每篇文章中都比较多,但是不具有区分文章类别的能力。
TextRank算法
TextRank算法脱离语料库,仅对单篇文档进行分析就可以提取该文档的关键词,此算法最早应用于文档的自动摘要,基于句子维度的分析,利用TextRank对每个句子进行打分,挑选出分数最高的n个句子作为文档的关键句,以达到自动摘要的效果。
TextRank基本思想来源于Google创始人拉里·佩奇和谢尔盖·布林1997年构建的PageRank算法。核心思想将文本中的词看作图中的节点,通过边相互连接,这里就形成了图,不同的节点会有不同的权重,权重高的节点可以作为关键词。
PageRank思想:
- 链接数量。一个网页被越多的其他网页链接,说明这个网页越重要。
- 链接质量。一个网页被一个越高权重的网页链接,也能表明这个网页越重要。
TextRank用PageRank的思想来解释它:
- 一个单词被很多单词指向的话,则说明这个单词比较重要。
- 一个单词被很高TextRank值的单词指向,则这个单词的TextRank值会相应地提高。
公式如下:
TextRank中一个单词i的权重取决于在i相连的各个点j组成的(j,i)这条边的权重,以及j这个点到其他边的权重之和,阻尼系数 d 一般取 0.85。
TextRank关键词提取步骤:
- 把给定的文本按照完整句子进行分割。
- 对每个句子,进行分词和词性标注处理,并过滤掉停用词,只保留指定词性的单词,如名词、动词等。
- 构建关键词图 G = (V,E),其中V 为节点集,由步骤2中生成的候选关键词组成,然后采用共现关系构造任两点之间的边,两个节点之间存在边仅当它们对应的词汇在长度为 K 的窗口中共现,K 表示窗口大小。
- 根据TextRank公式,迭代收敛,选出权重topK个词为关键词。
- 由步骤4得到最重要的k个单词,在原始文本中进行标记,若形成相邻词组,则组合成多词关键词。
基于 LDA 主题模型进行关键词提取
大多数情况,TF-IDF算法和TextRank算法就能满足,但某些场景不能从字面意思提取出关键词,比如:一篇讲健康饮食的,里面介绍了各种水果、蔬菜等对身体的好处,但全篇未显式的出现健康二字,这种情况前面的两种算法显然不能提取出健康这个隐含的主题信息,这时候主题模型就派上用场了。
LDA(隐含狄利克雷分布)是由David Blei等人在2003年提出的,理论基础为贝叶斯理论,LDA根据词的共现信息的分析,拟合出词——文档——主题的分布,进而将词、文本都映射到一个语义空间中。
实战
- jieba 已经实现了基于 TF-IDF 算法的关键词抽取,如下:
import jieba.analyse
text = '城市绿化是栽种植物以改善城市环境的活动。 城市绿化作为城市生态系统中的还原组织 城市生态系统具有受到外来干扰和破坏而恢复原状的能力,就是通常所说的城市生态系统的还原功能。'
#获取关键词
tags = jieba.analyse.extract_tags(text, topK=3)
print(u"关键词:")
print(" ".join(tags))
执行结果:
代码语言:javascript复制关键词:
生态系统 城市绿化 城市
- jieba也已经实现了基于 TextRank算法的关键词抽取,如下:
import jieba.analyse
text = '城市绿化是栽种植物以改善城市环境的活动。 城市绿化作为城市生态系统中的还原组织 城市生态系统具有受到外来干扰和破坏而恢复原状的能力,就是通常所说的城市生态系统的还原功能。'
result = " ".join(jieba.analyse.textrank(text, topK=3, withWeight=False, allowPOS=('ns', 'n', 'vn', 'v')))
print(u"关键词:")
print(result)
执行结果:
代码语言:javascript复制关键词:
城市 破坏 还原
- 通过 Gensim 库完成基于 LDA 的关键字提取,如下:
import jieba
import jieba.analyse as analyse
import gensim
from gensim import corpora, models, similarities
text = '城市绿化是栽种植物以改善城市环境的活动。 城市绿化作为城市生态系统中的还原组织 城市生态系统具有受到外来干扰和破坏而恢复原状的能力,就是通常所说的城市生态系统的还原功能。'
# 停用词
stop_word = ['的', '。', '是', ' ']
# 分词
sentences=[]
segs=jieba.lcut(text)
segs = list(filter(lambda x:x not in stop_word, segs))
sentences.append(segs)
# 构建词袋模型
dictionary = corpora.Dictionary(sentences)
corpus = [dictionary.doc2bow(sentence) for sentence in sentences]
# lda模型,num_topics是主题的个数
lda = gensim.models.ldamodel.LdaModel(corpus=corpus, id2word=dictionary, num_topics=8)
print(lda.print_topic(1, topn=3))
执行结果:
代码语言:javascript复制0.037*"城市" 0.037*"城市绿化" 0.037*"生态系统"