TextRank算法

article/2025/8/28 16:47:39

TextRank算法理解


TextRank算法

TextRank算法基于PageRank,用于为文本生成关键字和摘要。其论文是:
Mihalcea R, Tarau P. TextRank: Bringing order into texts[C]. Association for Computational Linguistics, 2004.

先从PageRank讲起
在浅入浅出:PageRank算法这篇博客中我做过简要的介绍,这里再补充一下。
PageRank最开始用来计算网页的重要性。整个www可以看作一张有向图图,节点是网页。如果网页A存在到网页B的链接,那么有一条从网页A指向网页B的有向边。
构造完图后,使用下面的公式:

S(Vi)是网页i的中重要性(PR值)。d是阻尼系数,一般设置为0.85。In(Vi)是存在指向网页i的链接的网页集合。Out(Vj)是网页j中的链接存在的链接指向的网页的集合。|Out(Vj)|是集合中元素的个数。
也就是说:
对于一篇网页来说,可以这么理解:它的重要性,取决于到他的每个链接页面的重要性之和来决定的。每个链接到该页面的页面的重要性 S(Vj) 还需要对所有它所出去的页面所评分。所以除以了OUT(Vj)。同时,该页面 S(Vj) 的重要性不能单单由其他的链接页面决定,还包含一定的概率来决定要不要接受由其他页面来决定,这也就是d的作用。

PageRank需要使用上面的公式多次迭代才能得到结果。初始时,可以设置每个网页的重要性为1。上面公式等号左边计算的结果是迭代后网页i的PR值,等号右边用到的PR值全是迭代前的。
举个例子:

上图表示了三张网页之间的链接关系,直觉上网页A最重要。

依然能判断出A、B、C的重要性。
使用TextRank提取关键字
将原文本拆分为句子,在每个句子中过滤掉停用词(可选),并只保留指定词性的单词(可选)。由此可以得到句子的集合和单词的集合。
每个单词作为pagerank中的一个节点。设定窗口大小为k,假设一个句子依次由下面的单词组成:
w1,w2,w3,w4,w5,…,wn
[w1,w2,…,wk]、[w2,w3,…,wk+1]、[w3,w4,…,wk+2]等都是一个窗口。在一个窗口中的任两个单词对应的节点之间存在一个无向无权的边。
基于上面构成图,可以计算出每个单词节点的重要性。最重要的若干单词可以作为关键词。
使用TextRank提取关键短语
参照“使用TextRank提取关键词”提取出若干关键词。若原文本中存在若干个关键词相邻的情况,那么这些关键词可以构成一个关键短语。
例如,在一篇介绍“支持向量机”的文章中,可以找到三个关键词支持、向量、机,通过关键短语提取,可以得到支持向量机。 使用TextRank提取摘要
将每个句子看成图中的一个节点,若两个句子之间有相似性,认为对应的两个节点之间有一个无向有权边,权值是相似度。
通过pagerank算法计算得到的重要性最高的若干句子可以当作摘要。
论文中使用下面的公式计算两个句子Si和Sj的相似度:

分子是在两个句子中都出现的单词的数量。|Si|是句子i的单词数。
由于是有权图,PageRank公式略做修改:

但是很明显我只想计算关键字,如果把一个单词视为一个句子的话,那么所有句子(单词)构成的边的权重都是0(没有交集,没有相似性),所以分子分母的权值w约掉了,算法退化为PageRank。所以说,这里称关键字提取算法为PageRank也不为过。

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)

http://chatgpt.dhexx.cn/article/JteoP8vZ.shtml

相关文章

TextRank

TextRank与PageRank TextRank的灵感来源于大名鼎鼎的PageRank算法&#xff0c;这是一个用作网页重要度排序的算法。 这个算法是基于图的&#xff0c;每个网页可以看作是一个图中的结点&#xff0c;如果网页A能够跳转到网页B&#xff0c;那么则有一条A->B的有向边。这样&am…

TextRank算法介绍及实现

目录 1、PageRank算法 2、TextRank算法 &#xff08;1&#xff09;关键词抽取&#xff08;keyword extraction&#xff09; &#xff08;2&#xff09;关键短语抽取&#xff08;keyphrase extration&#xff09; &#xff08;3&#xff09;关键句抽取&#xff08;sentence…

TextRank原理解释

目录 1. PageRank原理 2. TextRank &#xff08;1&#xff09;TextRank需要满足的条件 &#xff08;2&#xff09;TextRank思想的简要理解 &#xff08;3&#xff09;TextRank原理及例子讲解 1. PageRank原理 在这里可以看我转载的PageRank原理链接&#xff0c;比较详细h…

TextRank算法原理简析、代码实现

前言—PageRank 注&#xff1a;PageRank原理另行查询 在介绍TextRank前&#xff0c;我想先给大家介绍下PageRank&#xff0c;实质上个人认为可以把TextRank当做PageRank2.0。   谷歌的两位创始人的佩奇和布林&#xff0c;借鉴了学术界评判学术论文重要性的通用方法&#xff0…

NLP学习笔记——TextRank算法

一、算法简介 TextRank算法是一种基于图的排序算法&#xff0c;由谷歌的网页重要性排序算法PageRank算法改进而来&#xff0c;主要应用有关键词提取、文本摘要抽取等。该算法的主要思想是&#xff1a;把文档中的词&#xff08;句&#xff09;看成一个网络&#xff0c;词&#…

机器学习——逻辑回归常见面试题整理

逻辑回归 1.介绍 逻辑回归假设数据服从伯努利分布&#xff0c;通过极大化似然函数的方法&#xff0c;运用梯队下降来求解参数&#xff0c;来达到将数据二分类的目的。 2.逻辑回归的损失函数和梯度下降参数迭代方法 逻辑回归的损失函数是它的极大似然函数 参数迭代方法 3.逻…

面试精选逻辑推理题总结

类似的杀人游戏 1、500张骨牌整齐地排成一行&#xff0c;按顺序编号为1、2、3、……、499、500。第一次拿走所有奇数位置上的骨牌&#xff0c;第二次再从剩余骨牌中拿走奇数位置上的骨牌&#xff0c;以此类推。请问最后剩下的一张骨牌的编号是&#xff1f;&#xff08;256&…

IT科技企业逻辑思维面试题

逻辑思维面试题 一、假设有一个池塘&#xff0c;里面有无穷多的水。现有2个空水壶&#xff0c;容积分别为5升和6升。问题是如何只用这2个水壶从池塘里取得3升的水。【请描述操作过程】 答&#xff1a;&#xff08;1&#xff09;先用容积为6升的水壶装满水&#xff1b; &#…

面试逻辑题分享--字母数字映射关系推算题

越来越多的朋友可能会发现&#xff0c;在现在找工作的时候&#xff0c;经常会遇到一些笔试题&#xff0c;而且其中不乏有逻辑题&#xff0c;企业希望通过一些逻辑题的测试&#xff0c;来判断求职者的一个逻辑思维能力。今晚在群里看到有小伙伴发了一个题&#xff0c;一时兴起&a…

前端_逻辑题 1

题目一 5只鸡5天能下5个蛋&#xff0c;100天下100个蛋需要多少只鸡&#xff1f; 1只鸡5天能下1个蛋&#xff0c;1只鸡100天能下20个蛋&#xff0c;所以100天下100个蛋需要5只鸡。 题目二 两个盲人都各自买了一对黑袜和一对白袜&#xff0c;四对袜子的布质、大小完全相同&#…

华为软件测试笔试真题之变态逻辑推理题【二】华为爆火面试题

“一头牛重800公斤&#xff0c;一座桥承重700公斤&#xff0c;问牛怎么过桥&#xff1f;” 这个问题在知乎上被浏览过13672927次&#xff0c;火热程度可见一斑。 据说这是华为的面试题&#xff0c;看似不合理的题目和国际闻名的大厂&#xff0c;极大的勾起了人们的兴趣。 不像面…

二、逻辑回归LR面试题总结

1. 简单介绍一下逻辑回归&#xff1f; 逻辑回归主要用来解决分类问题&#xff0c;线性回归的结果 Y Y Y带入一个非线性变换的Sigmoid函数中&#xff0c;得到 [ 0 , 1 ] [0,1] [0,1]之间取值范围的数 S S S&#xff0c; S S S可以把它看成是一个概率值&#xff0c;如果我们设置…

互联网面试——.Net 面试题

提供了最常见的 .Net 面试问题和许多公司提出的答案。让我们看看顶级 Dot Net 面试问题列表。 1. 什么是.NET&#xff1f; .NET 是一种软件开发框架。它就像其他软件开发框架&#xff08;J2EE&#xff09;一样。它以类库和 API 的形式提供运行时功能和一组丰富的预构建功能。此…

程序员面试逻辑题解析

《程序员面试逻辑题解析》 基本信息 原书名&#xff1a;Puzzles for Programmers and Pro 作者&#xff1a; (美)Dennis E. Shasha [作译者介绍] 译者&#xff1a; 费若愚 朱学武 出版社&#xff1a;人民邮电出版社 ISBN&#xff1a;9787115301956 上架时间&#xff1a;2012…

程序员面试必看32道经典逻辑推理题

写在前面&#xff1a; 此文档由一位学长整理&#xff0c;转载请附上原文出处链接 32道经典逻辑推理题包括有关二进制、水桶、钱、蓝眼、时间、重量、数学、其他等问题 Click here 有秘密哦&#xff01;&#xff01;&#xff01; 点击浏览 文章目录 一、数字的魅力二、分而治之…

面试逻辑题

逻辑题目 逻辑题目现在也是面试中常考的题目,也不清楚面试出这种题目的意义,可能就是考察面试人员是否逻辑清晰. 这种题目没有什么好的方法,除非你见过原题,否则,只能根据所给出的条件慢慢分析,尽量不要用常规思路,希望大家要跳跃思维. 如果实在不行就给出一种解法,可能不是最…

面试常见逻辑题小整理

题一、 1 1 1 2 1 1 2 1 1 1 1 1 2 2 1 下一行是什么&#xff1f; 答案&#xff1a; 312211 题二、 &#xff08;1&#xff09;烧一根不均匀的绳要用一个小时&#xff0c;如何用它来判断半个小时&#xff1f; &#xff08;2&#xff09;烧一根不均匀的绳&#xff0c;从头烧…

二维vector数组初始化方法

在用devcpp编译程序时发现&#xff0c;二维vector数组如果只定义的话&#xff0c;不指定元素个数也不进行初始化的时候会导致编译出错。 通常情况下&#xff0c;可以只提供vector对象容纳的元素数量而略去初始值。此时库会创建一个值初始化的元素初值&#xff0c;并把它赋给容器…

【vector常用的6种初始化方法】

文章目录 一二三四五六 一 最常用&#xff0c;此时&#xff0c;vector为空&#xff0c; size为0&#xff0c;表明容器中没有元素&#xff0c;而且 capacity 也返回 0&#xff0c;意味着还没有分配内存空间。这种初始化方式适用于元素个数未知&#xff0c;需要在程序中动态添加…

vector的初始化和遍历

这里只说明常用的vector初始化的方式。一般vector的初始化我还是比较习惯于像数组一样的初始化方式。一个一个赋值&#xff0c;或者用花括号的初始化。下面用一个程序来说明&#xff1a; #include "stdafx.h"#include <vector>#include <iostream.h>usi…