- 文献:TextRank: Bringing Order into Texts (2004)
- 作者:Rada Mihalcea and Paul Tarau
- 地址: https://web.eecs.umich.edu/~mihalcea/papers/mihalcea.emnlp04.pdf
作者主要做了什么?
在这篇paper中,作者将PageRank算法整合到了TextRank模型中,并应用到两类跟排序相关的自然语言处理任务中,分别是:
1)关键词(keyword extraction)提取,即选择出能够表达输入文本含义的几个关键短语;
2)句子提取(sentence extraction),即确定输入文本中最“重要”的几个可以用来建立摘要(summary)的句子。
值得注意一点是,其他基于图的排序算法,如HITS、Positional Function等,也可以轻松的整合到TextRank模型中。
TextRank是什么?
TextRank是一个基于图排序的、用于文本处理的算法。使用TextRank算法,不需要有深入的语言学和专业领域知识,它是一个无监督的算法,这个特性使得它可以很方便的应用到其他领域和语言中。
在文本中使用基于图的排序算法需要构建一张关系图来表达文本、词语以及其他实体。从实践的角度出发,词语、词语集合、整个句子等都可以作为图中的顶点,在这些顶点之间建立联系,如:词序关系、语义关系、内容相似度等,就能够构建一张合适的关系图。
由于基于图的排序算法通过迭代计算整张图的信息来确定顶点(vertex)重要性,而不是仅仅依赖顶点的局部信息,因此,基于图的排序算法,如:HITS、PageRank,在引用分析(citation analysis)、社交网络(social network)以及网页排序等方面取得成功的应用。
TextRank的优点有哪些?
- 无监督学习,使用者不需要有深入的语言学或者专业领域知识;
- 使用基于图的排序算法,综合考虑文本整体的信息来确定哪些words或者sentences可以更好的表达文本
不考虑加入图中的元素的类型和特征,如何在文本处理中应用基于图的排序算法?
step 1. 确定最适合当前任务的文本单元集(text units),把它们作为顶点集(vertices)加入到图中;
step 2. 确定text units之间的关系,基于这些关系把边集(edges)画出来,edge可以是有向(directed)/无向(undirected)的,当然,也可以是加权(weighted)/不加权(unweighted)的;
step 3. 使用基于图的排序算法迭代计算,直到收敛,得到各顶点的重要性得分;
step 4. 根据各顶点得分对顶点集进行排序,将排序之后的结果作为输出。
使用TextRank对中文进行分析
基于这篇paper,letiantian实现了针对中文进行处理的TextRank算法,即TextRank4ZH。
由于英文中,词和短语的区别不是很明显,这篇paper的作者将英文的keyword extraction和keyphrase extraction统一在keyword extraction这节中,样例中也没有将keyword和keyphrase进行区分。
但是中文里面的词和短语区分非常明显,关键词提取和关键短语提取可以认为是两个不一样的任务,letiantian在实现这个算法的时候将关键词提取、关键短语提取进行了区分,分别封装了两个函数:get_keywords和get_keyphrases。
关键词提取(keyword extraction)
关键词提取是指从文本中确定一些能够描述文档含义的术语的过程。
对关键词提取而言,用于构建顶点集(vertices)的文本单元(text unit)可以是句子中的一个或多个字;根据这些字之间的关系(比如:在一个框中同时出现)构建边。根据任务的需要,可以使用语法过滤器(syntactic filters)对顶点集进行优化。语法过滤器的主要作用是将某一类或者某几类词性的字过滤出来作为顶点集。
step 1. 对文本进行词性标记,这是为了应用语法过滤器而进行的预处理
step 2. 构建图
step 3. 使用PageRank进行迭代计算,得到各顶点的重要性得分,按得分对顶点进行排序
step 4. 将top-N结果输出
下面是基于textrank4zh进行中文关键词提取的演示:
点击下载样本数据
from textrank4zh import TextRank4Keyword
lines = open('./keyword_extraction.data', 'r').readlines()
lines = [line.strip('\n') for line in lines]
text = ' '.join(lines)
tr4w = TextRank4Keyword(allow_speech_tags=['n', 'nr', 'nrfg', 'ns', 'nt', 'nz'])
# 将动词过滤掉
tr4w.analyze(text=text, window=2)
# text -- 文本内容,字符串。
# window -- 窗口大小,int,用来构造单词之间的边。默认值为2。
kws = tr4w.get_keywords(num=6, word_min_len=2)
# num -- 返回关键词数量
# word_min_len -- 词的最小长度,默认值为1
kws
输出结果如下:
[{'weight': 0.028586717054060257, 'word': '人工智能'},
{'weight': 0.026946002730704365, 'word': '人类'},
{'weight': 0.02410264096249914, 'word': '机器人'},
{'weight': 0.014908545336161625, 'word': '机器'},
{'weight': 0.01362202506014923, 'word': '电影'},
{'weight': 0.011395769681302775, 'word': '科幻'}]
关键短语提取(keyphrase extration)
关键词提取结束后,我们可以得到的N个关键词,在原始文本中相邻的关键词构成关键短语。因此,从get_keyphrases函数的源码中我们可以看到,它先调用get_keywords提取关键词,然后分析关键词是否存在相邻的情况,最后确定哪些是关键短语。
get_keyphrases源码如下:
def get_keyphrases(self, keywords_num = 12, min_occur_num = 2):
# 调用get_keywords提取关键词
# word_min_len默认值为1,get_keyphrases函数不支持修改该参数,实际使用时如果不希望出现一个字的关键词,
# 可根据需要直接修改源码中的参数
keywords_set = set([ item.word for item in self.get_keywords(num=keywords_num, word_min_len = 1)])
keyphrases = set()
for sentence in self.words_no_filter:
one = []
# 在句子中检查是否存在若干个相邻的关键词
for word in sentence:
if word in keywords_set:
one.append(word)
else:
# 如果存在若干个关键词相邻,就将他们组合成关键短语
if len(one) > 1:
keyphrases.add(''.join(one))
if len(one) == 0:
continue
else:
one = []
if len(one) > 1:
keyphrases.add(''.join(one))
# 判断phrase在文中出现的次数是否大于min_occur_num,输出结果
return [phrase for phrase in keyphrases
if self.text.count(phrase) >= min_occur_num]
下面是提取中文关键短语的演示:
kws = tr4w.get_keyphrases(keywords_num=20, min_occur_num= 1)
# keywords_num -- 抽取的关键词数量
# min_occur_num -- 关键短语在文中的最少出现次数
kws
输出结果如下:
['人类思维', '人类沙文主义', '机器人定律', '科幻作家', '人类社会', '人类智慧']
句子提取(sentence extraction)
这篇paper中的句子提取任务主要针对的是自动摘要这个场景。由于工作中不涉及这个场景,对这个任务的理解很浅。下面简单介绍一下paper中进行sentence extraction的主要思想中与keyword extration的不同之处:
将每一个sentence作为一个顶点;
不能再使用“同时出现”作为顶点之间的联系,“同时出现”在这个应用场景没有意义,作为替代,文中根据两个句子之间的内容重复程度来计算他们之间的“相似度”,以这个相似度作为联系;
由于不同句子之间相似度大小不一致,在这个场景下构建的是以相似度大小作为edge权重的有权图。
下面是提取句子的演示:
from textrank4zh import TextRank4Sentence
tr4s = TextRank4Sentence()
tr4s.analyze(text=text, lower=True, source = 'all_filters')
tr4s.get_key_sentences(num=6)
输出结果如下:
[{'index': 19,
'sentence': '直到《机械姬》(2015年)中,具有独立思考能力的智能机器人“夏娃”才以一个能通过“图灵测试”,让男人分辨不出是机器还是人类的形象,而且是以一个女性“她”的形象,开始呈现出人工智能未必都是男性,她也渴望成为人的诉求',
'weight': 0.01843663608214886},
{'index': 25,
'sentence': '人类沙文主义:机器人三定律只存在于贵圈 想要便成人,一个最主要的缘由是在文艺作品中有了独立思考能力的人工智能们渴望摆脱人类的奴役',
'weight': 0.016295422313582313},
{'index': 71,
'sentence': '而无论是机器人、人造人还是人工智能,处处透着一个“人”字烙印,标志着“非人”和“人造”的双重含义,亦在同时,让人类有了上帝造人之感',
'weight': 0.016030835354765443},
{'index': 38,
'sentence': '这一思维的集大成者,无疑是被科幻迷们奉为圭臬的机器人三定律,或者说是在科幻小说中理所当然的人工智能设定: 第一定律:机器人不得伤害人类,或因不作为使人类受到伤害',
'weight': 0.015822579189346337},
{'index': 47,
'sentence': '而另一位人工智能理论研究者本·格策尔给出的答案更加让人有颠覆之感:阿西莫夫的未来社会是光天化日的基质沙文主义,人类拥有的权利比人形机器人的权利更多',
'weight': 0.015683710871720248},
{'index': 100,
'sentence': '或者说,类似机器或西蒙妮这样的人工智能形象,更符合人类给予人工智能的设定,即他和她之外的第三人,配合、辅助、参与、完善和实现人类的最终幻想,或许也是觉醒后的人工智能的最终幻想,而非简单的以暴易暴式对抗',
'weight': 0.015327223889169753}]