【自然语言处理】TextRank算法
TextRank算法
TextRank算法基于PageRank,用于为文本生成关键字和摘要。其论文是:
Mihalcea R, Tarau P. TextRank: Bringing order into texts[C]. Association for Computational Linguistics, 2004.
先从PageRank讲起
首先介绍原理与概念
TextRank 算法是一种用于文本的基于图的排序算法。其基本思想来源于谷歌的 PageRank算法(其原理在本文在下面), 通过把文本分割成若干组成单元(单词、句子)并建立图模型, 利用投票机制对文本中的重要成分进行排序, 仅利用单篇文档本身的信息即可实现关键词提取、文摘。和 LDA、HMM 等模型不同, TextRank不需要事先对多篇文档进行学习训练, 因其简洁有效而得到广泛应用。
TextRank 一般模型可以表示为一个有向有权图 G =(V, E), 由点集合 V和边集合 E 组成, E 是V ×V的子集。图中任两点 Vi , Vj 之间边的权重为 wji , 对于一个给定的点 Vi, In(Vi) 为 指 向 该 点 的 点 集 合 , Out(Vi) 为点 Vi 指向的点集合。点 Vi 的得分定义如下:
其中, d 为阻尼系数, 取值范围为 0 到 1, 代表从图中某一特定点指向其他任意点的概率, 一般取值为 0.85。使用TextRank 算法计算图中各点的得分时, 需要给图中的点指定任意的初值, 并递归计算直到收敛, 即图中任意一点的误差率小于给定的极限值时就可以达到收敛, 一般该极限值取 0.0001。
举个例子:
上图表示了三张网页之间的链接关系,直觉上网页A最重要。可以得到下面的表:
横栏代表其实的节点,纵栏代表结束的节点。若两个节点间有链接关系,对应的值为1。根据公式,需要将每一竖栏归一化(每个元素/元素之和),归一化的结果是:
上面的结果构成矩阵M。我们用matlab迭代100次看看最后每个网页的重要性:
M = [0 1 1 0 0 00 0 0];
PR = [1; 1 ; 1];
for iter = 1:100PR = 0.15 + 0.85*M*PR;disp(iter);disp(PR);
end
运行结果(省略部分
97---0.40500.15000.150098---0.40500.15000.150099---0.40500.15000.1500100---0.40500.15000.1500
最终A的PR值为0.4050,B和C的PR值为0.1500
如果把上面的有向边看作无向的(其实就是双向的),那么:
M = [0 1 1 0.5 0 00.5 0 0];PR = [1; 1 ; 1];for iter = 1:100PR = 0.15 + 0.85*M*PR;disp(iter);disp(PR);
end
运行结果(省略部分):
.....981.45950.77030.7703991.45950.77030.77031001.45950.77030.7703
依然能判断出A、B、C的重要性。
使用TextRank提取关键字
关键词抽取的任务就是从一段给定的文本中自动抽取出若干有意义的词语或词组。TextRank算法是利用局部词汇之间关系(共现窗口)对后续关键词进行排序,直接从文本本身抽取。其主要步骤如下:
(1)把给定的文本T按照完整句子进行分割,即
(2)对于每个句子,进行分词和词性标注处理,并过滤掉停用词,只保留指定词性的单词,如名词、动词、形容词,即,其中是保留后的候选关键词。
(3)构建候选关键词图G = (V,E),其中V为节点集,由(2)生成的候选关键词组成,然后采用共现关系(co-occurrence)构造任两点之间的边,两个节点之间存在边仅当它们对应的词汇在长度为K的窗口中共现,K表示窗口大小,即最多共现K个单词。
(4)根据上面公式,迭代传播各节点的权重,直至收敛。
(5)对节点权重进行倒序排序,从而得到最重要的T个单词,作为候选关键词。
(6)由(5)得到最重要的T个单词,在原始文本中进行标记,若形成相邻词组,则组合成多词关键词。例如,文本中有句子“Matlab code for plotting ambiguity function”,如果“Matlab”和“code”均属于候选关键词,则组合成“Matlab code”加入关键词序列。
原理思路整理:程序员(英文Programmer)是从事程序开发、维护的专业人员。一般将程序员分为程序设计人员和程序编码人员,但两者的界限并不非常清楚,特别是在中国。软件从业人员分为初级程序员、高级程序员、系统分析员和项目经理四大类。
我取出了百度百科关于“程序员”的定义作为测试用例,很明显,这段定义的关键字应当是“程序员”并且“程序员”的得分应当最高。首先对这句话分词,这里可以借助各种分词项目,比如HanLP分词,得出分词结果:[程序员/n, (, 英文/nz, programmer/en, ), 是/v, 从事/v, 程序/n, 开发/v, 、/w, 维护/v, 的/uj, 专业/n, 人员/n, 。/w, 一般/a, 将/d, 程序员/n, 分为/v, 程序/n, 设计/vn, 人员/n, 和/c, 程序/n, 编码/n, 人员/n, ,/w, 但/c, 两者/r, 的/uj, 界限/n, 并/c, 不/d, 非常/d, 清楚/a, ,/w, 特别/d, 是/v, 在/p, 中国/ns, 。/w, 软件/n, 从业/b, 人员/n, 分为/v, 初级/b, 程序员/n, 、/w, 高级/a, 程序员/n, 、/w, 系统/n, 分析员/n, 和/c, 项目/n, 经理/n, 四/m, 大/a, 类/q, 。/w]
然后去掉里面的停用词,这里我去掉了标点符号、常用词、以及“名词、动词、形容词、副词之外的词”。得出实际有用的词语:[程序员, 英文, 程序, 开发, 维护, 专业, 人员, 程序员, 分为, 程序, 设计, 人员, 程序, 编码, 人员, 界限, 特别, 中国, 软件, 人员, 分为, 程序员, 高级, 程序员, 系统, 分析员, 项目, 经理]
之后建立两个大小为5的窗口,每个单词将票投给它身前身后距离5以内的单词:{开发=[专业, 程序员, 维护, 英文, 程序, 人员],软件=[程序员, 分为, 界限, 高级, 中国, 特别, 人员],程序员=[开发, 软件, 分析员, 维护, 系统, 项目, 经理, 分为, 英文, 程序, 专业, 设计, 高级, 人员, 中国],分析员=[程序员, 系统, 项目, 经理, 高级],维护=[专业, 开发, 程序员, 分为, 英文, 程序, 人员],系统=[程序员, 分析员, 项目, 经理, 分为, 高级],项目=[程序员, 分析员, 系统, 经理, 高级],经理=[程序员, 分析员, 系统, 项目],分为=[专业, 软件, 设计, 程序员, 维护, 系统, 高级, 程序, 中国, 特别, 人员],英文=[专业, 开发, 程序员, 维护, 程序],程序=[专业, 开发, 设计, 程序员, 编码, 维护, 界限, 分为, 英文, 特别, 人员],特别=[软件, 编码, 分为, 界限, 程序, 中国, 人员],专业=[开发, 程序员, 维护, 分为, 英文, 程序, 人员],设计=[程序员, 编码, 分为, 程序, 人员],编码=[设计, 界限, 程序, 中国, 特别, 人员],界限=[软件, 编码, 程序, 中国, 特别, 人员],高级=[程序员, 软件, 分析员, 系统, 项目, 分为, 人员],中国=[程序员, 软件, 编码, 分为, 界限, 特别, 人员],人员=[开发, 程序员, 软件, 维护, 分为, 程序, 特别, 专业, 设计, 编码, 界限, 高级, 中国]}
TextRank的打分思想依然是从PageRank的迭代思想衍生过来的,如下公式所示:
等式左边表示一个句子的权重(WS是weight_sum的缩写),右侧的求和表示每个相邻句子对本句子的贡献程度。与提取关键字的时候不同,一般认为全部句子都是相邻的,不再提取窗口。
求和的分母wji表示两个句子的相似程度,分母又是一个weight_sum,而WS(Vj)代表上次迭代j的权重。整个公式是一个迭代的过程。
相似程度的计算
而相似程度wji的计算,推荐使用BM25
BM25算法,通常用来作搜索相关性平分。一句话概况其主要思想:对Query进行语素解析,生成语素qi;然后,对于每个搜索结果D,计算每个语素qi与D的相关性得分,最后,将qi相对于D的相关性得分进行加权求和,从而得到Query与D的相关性得分。
BM25算法.pdf
测试用例
文字:
算法可大致分为基本算法、数据结构的算法、数论算法、计算几何的算法、图的算法、动态规划以及数值分析、加密算法、排序算法、检索算法、随机化算法、并行算法、厄米变形模型、随机森林算法。
算法可以宽泛的分为三类,
一,有限的确定性算法,这类算法在有限的一段时间内终止。他们可能要花很长时间来执行指定的任务,但仍将在一定的时间内终止。这类算法得出的结果常取决于输入值。
二,有限的非确定算法,这类算法在有限的时间内终止。然而,对于一个(或一些)给定的数值,算法的结果并不是唯一的或确定的。
三,无限的算法,是那些由于没有定义终止定义条件,或定义的条件无法由输入的数据满足而不终止运行的算法。通常,无限算法的产生是由于未能确定的定义终止条件。
断句
算法可大致分为基本算法、数据结构的算法、数论算法、计算几何的算法、图的算法、动态规划以及数值分析、加密算法、排序算法、检索算法、随机化算法、并行算法、厄米变形模型、随机森林算法
算法可以宽泛的分为三类
一
有限的确定性算法
这类算法在有限的一段时间内终止
他们可能要花很长时间来执行指定的任务
但仍将在一定的时间内终止
这类算法得出的结果常取决于输入值
二
有限的非确定算法
这类算法在有限的时间内终止
然而
对于一个(或一些)给定的数值
算法的结果并不是唯一的或确定的
三
无限的算法
是那些由于没有定义终止定义条件
或定义的条件无法由输入的数据满足而不终止运行的算法
通常
无限算法的产生是由于未能确定的定义终止条件
分词并过滤停用词
[算法, 大致, 分, 基本, 算法, 数据, 结构, 算法, 数论, 算法, 计算, 几何, 算法, 图, 算法, 动态, 规划, 数值, 分析, 加密, 算法, 排序, 算法, 检索, 算法, 随机, 化, 算法, 并行, 算法, 厄, 米, 变形, 模型, 随机, 森林, 算法]
[算法, 宽泛, 分为, 三类]
[]
[有限, 确定性, 算法]
[类, 算法, 有限, 一段, 时间, 终止]
[可能, 花, 长, 时间, 执行, 指定, 任务]
[一定, 时间, 终止]
[类, 算法, 得出, 常, 取决, 输入, 值]
[二]
[有限, 非, 确定, 算法]
[类, 算法, 有限, 时间, 终止]
[]
[一个, 定, 数值]
[算法, 唯一, 确定]
[三]
[无限, 算法]
[没有, 定义, 终止, 定义, 条件]
[定义, 条件, 无法, 输入, 数据, 满足, 终止, 运行, 算法]
[通常]
[无限, 算法, 产生, 未, 确定, 定义, 终止, 条件]
迭代投票
for (int _ = 0; _ < max_iter; ++_){double[] m = new double[D];double max_diff = 0;for (int i = 0; i < D; ++i){m[i] = 1 - d;for (int j = 0; j < D; ++j){if (j == i || weight_sum[j] == 0) continue;m[i] += (d * weight[j][i] / weight_sum[j] * vertex[j]);}double diff = Math.abs(m[i] - vertex[i]);if (diff > max_diff){max_diff = diff;}}vertex = m;if (max_diff <= min_diff) break;}
排序输出结果
这类算法在有限的时间内终止
这类算法在有限的一段时间内终止
无限算法的产生是由于未能确定的定义终止条件
分别对应于原文
算法可大致分为基本算法、数据结构的算法、数论算法、计算几何的算法、图的算法、动态规划以及数值分析、加密算法、排序算法、检索算法、随机化算法、并行算法、厄米变形模型、随机森林算法。
算法可以宽泛的分为三类,
一,有限的确定性算法,这类算法在有限的一段时间内终止。他们可能要花很长时间来执行指定的任务,但仍将在一定的时间内终止。这类算法得出的结果常取决于输入值。
二,有限的非确定算法,这类算法在有限的时间内终止。然而,对于一个(或一些)给定的数值,算法的结果并不是唯一的或确定的。
三,无限的算法,是那些由于没有定义终止定义条件,或定义的条件无法由输入的数据满足而不终止运行的算法。通常,无限算法的产生是由于未能确定的定义终止条件。
TextRank代码
使用textrank源代码可以抽取摘要,也可以抽取关键词。
以snownlp的源代码为例,抽取摘要:
def solve(self): #针对抽关键句for cnt, doc in enumerate(self.docs):scores = self.bm25.simall(doc) #在本实现中,使用的不是前面提到的公式,而是使用的BM25算法,之前会有一个预处理(self.bm25 = BM25(docs)),然后求doc跟其他所有预料的相似程度。self.weight.append(scores)self.weight_sum.append(sum(scores)-scores[cnt])#需要减掉本身的权重。self.vertex.append(1.0)for _ in range(self.max_iter):m = []max_diff = 0for i in range(self.D):#每个文本都要计算与其他所有文档的链接,然后计算出重要程度。m.append(1-self.d)for j in range(self.D):if j == i or self.weight_sum[j] == 0:continuem[-1] += (self.d*self.weight[j][i]/ self.weight_sum[j]*self.vertex[j])#利用前面的公式求解if abs(m[-1] - self.vertex[i]) > max_diff:#找到该次迭代中,变化最大的一次情况。max_diff = abs(m[-1] - self.vertex[i])self.vertex = mif max_diff <= self.min_diff:#当变化最大的一次,仍然小于某个阈值时认为可以满足跳出条件,不用再循环指定的次数。breakself.top = list(enumerate(self.vertex))self.top = sorted(self.top, key=lambda x: x[1], reverse=True)def solve(self):#针对抽关键词for doc in self.docs:que = []for word in doc:if word not in self.words:self.words[word] = set()self.vertex[word] = 1.0que.append(word)if len(que) > 5:que.pop(0)for w1 in que:for w2 in que:if w1 == w2:continueself.words[w1].add(w2)self.words[w2].add(w1)for _ in range(self.max_iter):m = {}max_diff = 0tmp = filter(lambda x: len(self.words[x[0]]) > 0,self.vertex.items())tmp = sorted(tmp, key=lambda x: x[1] / len(self.words[x[0]]))for k, v in tmp:for j in self.words[k]:if k == j:continueif j not in m:m[j] = 1 - self.dm[j] += (self.d / len(self.words[k]) * self.vertex[k]) #利用之前提到的公式,简化的结果。for k in self.vertex:if k in m and k in self.vertex:if abs(m[k] - self.vertex[k]) > max_diff:max_diff = abs(m[k] - self.vertex[k])self.vertex = mif max_diff <= self.min_diff:breakself.top = list(self.vertex.items())self.top = sorted(self.top, key=lambda x: x[1], reverse=True)
转自:
https://blog.csdn.net/kamendula/article/details/51756552
http://www.hankcs.com/nlp/textrank-algorithm-java-implementation-of-automatic-abstract.html
https://blog.csdn.net/HHTNAN/article/details/78032712
【自然语言处理】TextRank算法相关推荐
- 独家 | 基于TextRank算法的文本摘要(附Python代码)
作者:Prateek Joshi 翻译:王威力 校对:丁楠雅 本文约3300字,建议阅读10分钟. 本文介绍TextRank算法及其在多篇单领域文本数据中抽取句子组成摘要中的应用. TextRank ...
- python nlp文本摘要实现_用TextRank算法实现自动文本摘要
[51CTO.com快译]1. 引言 文本摘要是自然语言处理(NLP)领域中的应用之一,它必将对我们的生活产生巨大影响.随着数字媒体和出 版业的不断发展,谁还有时间浏览整篇文章/文档/书籍来决定它们是 ...
- 使用TextRank算法进行文本摘要提取(python代码)
文本摘要是自然语言处理(NLP)的一种应用,随着人工智能的发展文本提取必将对我们的生活产生巨大的影响.随着网络的发展我们处在一个信息爆炸的时代,通读每天更新的海量文章/文档/书籍会占用我们大量的时间, ...
- TextRank算法学习及使用
文章目录 一.算法思想 二.python代码实现 三.TextRank算法使用 1.textrank4zh模块的安装 2.实例介绍 总结 参考资料: 文本关键词抽取.文本摘要生成是自然语言处理( ...
- TextRank算法介绍及实现
目录 1.PageRank算法 2.TextRank算法 (1)关键词抽取(keyword extraction) (2)关键短语抽取(keyphrase extration) (3)关键句抽取(se ...
- 使用TextRank算法为文本生成关键字和摘要
使用TextRank算法为文本生成关键字和摘要 发表于1年前(2014-12-01 21:31) 阅读(10282) | 评论(27) 155人收藏此文章, 我要收藏 赞15 摘要 TextRan ...
- 岗位推荐 | 微软AI Research Group招募自然语言处理AI算法研究实习生
PaperWeekly 致力于推荐最棒的工作机会,精准地为其找到最佳求职者,做连接优质企业和优质人才的桥梁. 如果你需要我们来帮助你推广实习机会或全职岗位,请添加微信号「pwbot02」. 微软 A ...
- 岗位推荐 | 微软AI Research Group招聘自然语言处理AI算法研究实习生
PaperWeekly 致力于推荐最棒的工作机会,精准地为其找到最佳求职者,做连接优质企业和优质人才的桥梁. 如果你需要我们来帮助你推广实习机会或全职岗位,请添加微信号「pwbot02」. 微软 A ...
- TextRank算法原理和提取关键词的主要过程详解 计算句子相似度 计算句子重要性公式
1.TextRank计算句子相似度和句子重要性的公式 2.TextRank算法提取关键词的过程 3.TextRank建立关键词无向图
最新文章
- C++类、函数、指针
- 普通程序员,光靠GitHub打赏就年入70万,要不你也试试
- C#开发笔记之04-如何用C#优雅的计算个人所得税?
- easyui tab 引用html,jQuery插件EasyUI获取当前Tab中iframe窗体对象的方法
- resnet 50 网络分析
- Python基础之初识类和对象
- 34.在排序数组中查找元素的第一个和最后一个位置(力扣leetcode) 博主可答疑该问题
- 关于IplImage的widthstep
- JAVA商城系统开发 VS PHP商城系统开发
- 获取谷歌浏览器缓存视频方法
- ACM/IOI 历年国家集训队论文集和论文算法分类整理
- 计算机桌面是快捷方式,我的电脑桌面上的图标都变成快捷方式了怎么处理?
- SL4A_API翻译贴镜像
- PDC10与最后的恐慌者
- 计算机存储单位的换算关系
- whoosh使用简介
- godaddy plesk mysql_» Godaddy的Plesk面板语言更改图文详细教程
- java 字符串中取消换行或添加换行
- MyBatis自定义自定义动态SQL解析方式
- Exp7 网络欺诈防范 Week10 - 20165201
热门文章
- 以太坊开发入门-开发环境准备
- 基于WINCE.NET4.2系统的PDA使用PPC2003软件全攻略
- latex中文,以及书签
- 电脑被格式化怎么恢复数据?电脑格式化后还能恢复数据吗?
- slot插槽以及directive自定义指令的使用
- IMPORT/EXPORT与SET PARAMETER/GET PARAMETER简单使用
- 百度SEO站群网站右下角悬浮圆形图标客服菜单代码
- 身份证识别在移动端和服务器端的应用与特点
- 项目名称:Bank Account Management System 银行账户管理系统 简称BAM
- hpe或hp与hp 3par的关系初识之一