NLP学习笔记——TextRank算法

article/2025/8/28 16:42:01

一、算法简介

TextRank算法是一种基于图排序算法,由谷歌的网页重要性排序算法PageRank算法改进而来,主要应用有关键词提取、文本摘要抽取等。该算法的主要思想是:把文档中的词(句)看成一个网络,词(句)之间的语义关系为网络之间的链接。通过迭代计算获得权重值依旧依赖词频,通常词频越高计算的权重值越高,一般需要进行停用词处理)公式如下:

\mathbf{}W(v_{i})=(1-d)+d\sum_{v_{j}\in In(v_{i})}^{}\frac{W_{ij}}{\sum_{v_{k}\in Out(v_{j})}^{}W_{jk}}W(v_{j})

其中,W(v_{i})为节点i的权重值、d为学习率(一般为0.85)、v_{i}v_{j}分别表示节点i和节点jIn(v_{i})表示所有指向节点i的节点、W_{ij}表示节点i和节点j的链接的权重值。

也可以理解成无向图的形式:W_{ab}为两节点的边权重值,v为节点,W(v_{a})为节点权重值、\sum_{v_{k}\in Out(v_{j})}^{}W_{jk}为所有与节点j连接的边权值之和(主要是为了归一化操作,不理解的通过以下代码的运行去解读)。如下图所示:

优缺点: 

优:

  1. textrank只依赖文章本身,它认为一开始每个词的重要程度是一样的。
  2. 继承了PageRank的思想,效果相对较好,相对于TF-IDF方法,可以更充分的利用文本元 素之间的关系。
  3. 无监督方式,无需构造数据集训练。

缺:

  1. 结果受分词、文本清洗影响较大,即对于某些停用词的保留与否,直接影响最终结果。
  2. 虽然与TF-IDF比,不止利用了词频,但是仍然受高频词的影响,因此需要结合词性和词频进行筛选,以达到更好效果,但词性标注显然又是一个问题。

二、TextRank关键词提取步骤及实现

其实摘要抽取关键词提取原理一样的,无非就是文本细粒度的不同,通过句子的词权值相加(或者取平均值,记不清了,个人觉得取平均值比较靠谱)的结果为句子权重,再根据句子权重从大到小提取一定数量的句子为摘要。

关键词提取具体步骤如下:

1、把给定的文本T按照完整句子进行分割,即T=[S_{1},S_{2},...,S_{m}]

2、对于每个句子S; ∈T,进行分词和词性标注处理,并过滤掉停用词,只保留指定词性的单词,如名词、动词、形容词,即S =[t_{i1},t_{i2},...,t_{tn}],其中t_{ij}是保留后的候选关键词。

3、构建候选关键词图G=(V,E),其中V为节点集,由上步生成的候选关键词组成,然后采用共现关系构造任两点之间的边,两个节点之间存在边仅当它们对应的词汇在长度为k的窗口中共现,k表示窗口大小,即最多共现k个单词。

4、根据上面的公式,迭代传播各节点的权重,直至收敛。

5、对节点权重进行倒序排列,从而得到最重要的T个单词,作为候选关键词。

6、由上步得到最重要的T个单词,在原始文本中进行标记,若形成相邻词组,则组合成多词关键词

import numpy as np
import jieba.posseg as psegclass TextRank(object):def __init__(self, sentence, window, learn_rate, iterations):self.sentence = sentenceself.window = windowself.learn_rate = learn_rateself.edge_dict = {}  # 记录节点的边连接字典self.iterations = iterations  # 迭代次数def createNodes(self):# 对句子进行分词# jieba.load_userdict('user_dict.txt')# 这里进行了停用词处理,只保留的规定词性的词tag_filter = ['a', 'd', 'n', 'v']seg_result = pseg.cut(self.sentence)self.word_list = [s.word for s in seg_result if s.flag in tag_filter]print(self.word_list)# 根据窗口,构建每个节点的相邻节点,返回边的集合tmp_list = []word_list_len = len(self.word_list)for index, word in enumerate(self.word_list):  #遍历句子的词if word not in self.edge_dict.keys():  #判断该词(中心词)是否处理过tmp_list.append(word)tmp_set = set()left = index - self.window + 1  # 窗口左边界right = index + self.window  # 窗口右边界# 规范窗口边界if left < 0: left = 0if right >= word_list_len: right = word_list_len#查找窗口内除中心点意外的点for i in range(left, right):if i == index:  #判断该点是不是中心点,是就跳过continueelse:tmp_set.add(self.word_list[i])  #记录非中心点,集合可以去重self.edge_dict[word] = tmp_set #记录中心点周围点{'中心点1':{'周围点1','周围点2',...},'中心点2':{'周围点1','周围点2',...}}# 根据边的相连关系,构建矩阵def createMatrix(self):self.matrix = np.zeros([len(set(self.word_list)), len(set(self.word_list))])self.word_index = {}  # 记录词的indexself.index_dict = {}  # 记录节点index对应的词#构建点和边的双向索引for i, v in enumerate(set(self.word_list)):self.word_index[v] = iself.index_dict[i] = v#构建无向图for key in self.edge_dict.keys():   #查找中心点for w in self.edge_dict[key]:    #查找中心点对应的周围点self.matrix[self.word_index[key]][self.word_index[w]] = 1  #建立无向便,有边为1,反之为0self.matrix[self.word_index[w]][self.word_index[key]] = 1  #无相边的矩阵为对角矩阵# 根据textrank公式计算权重并输出结果def call(self):# 归一化(按公式里对j节点归一化)sum = np.sum(self.matrix, axis=0)  # 按列求和for j in range(self.matrix.shape[1]):for i in range(self.matrix.shape[0]):self.matrix[i][j] /= sum[j]  # 按列归一化self.nodeI = np.ones([len(set(self.word_list))])for i in range(self.iterations):  #公式self.nodeI = (1 - self.learn_rate) + self.learn_rate * np.dot(self.matrix, self.nodeI)# 输出词和相应的权重word_pr = {}for i in range(len(self.nodeI)):word_pr[self.index_dict[i]] = self.nodeI[i]#items()函数返回列表里嵌套(键,值)元组res = sorted(word_pr.items(), key=lambda x: x[1], reverse=True)  #对列表进行临时排序,reverse选择降序print(res)if __name__ == '__main__':s = '情感分析又称倾向性分析或观点挖掘,是一种重要的信息分析处理技术,其研究目的是自动挖掘文本中的立场、观点、看法、情绪和喜恶等。在情感状态的理论研究中,情感状态的主要表示方法有两种:离散类别型表示方法和维度连续型表示方法。'TextRank = TextRank(s, 3, 0.85, 700)TextRank.createNodes()TextRank.createMatrix()TextRank.call()

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

相关文章

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

逻辑回归 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…

c++ vector 初始化_C++--vector()的用法

vector()的用法 概念 vector 是向量类型&#xff0c;它可以容纳许多类型的数据&#xff0c;如若干个整数&#xff0c;所以称其为容器。vector 是C STL的一个重要成员&#xff0c;使用它时需要包含头文件&#xff1a; #include<vector>;一、vector的初始化 (1) vector&l…

C++中 std::vector 的6种初始化方法

1.vector<int> list1; 默认初始化&#xff0c;最常用 此时&#xff0c;vector为空&#xff0c; size为0&#xff0c;表明容器中没有元素&#xff0c;而且 capacity 也返回 0&#xff0c;意味着还没有分配内存空间。 这种初始化方式适用于元素个数未知&#xff0c;需要在…

怎样初始化二维vector

二维vector的初始化方法总结 初始化一个 二维vector,行M,列N学会用大括号初始化二维数组初始化一个 二维vector,行M,列不固定初始化一个二维vector,行列都不固定注意初始化二维vector为空时的情况leetcode例题1leetcode例题2 以定义一个二维整形数组并初始化为例&#xff1a; …

c++之vector 及 二维容器vector<vector<int>>初始化方法 及 三维数组初始化

C二维容器vector<vector>初始化方法解析 遇到的问题&#xff1a; 在解决“求最大字串”问题时想到了用二位数组vector<vector<int>> table&#xff0c;但是不知道怎么对其进行初始化&#xff08;初始化时指定二维容器的大小&#xff09;,于是网上搜索一番&a…

打算自学一些编程,想兼职程序员打零工,想问问现在哪个程序员兼职平台单子简单,不考察接单人学历?

兼职平台接单&#xff0c;都不查学历。 等你具备最基本的可以接单的技术能力时&#xff0c;找个技术工作&#xff0c;随随便便一份都能有2000以上。但是&#xff0c;自己接单&#xff1f;实不相瞒&#xff0c;会饿死的。没有什么钱是从一开始就坐在家里轻轻松松能赚到的。除非…