【自然语言处理】TextRank 算法提取关键词(Python实现)

文章目录

  • 前言
  • PageRank 实现
  • TextRank 简单版源码实现
  • jieba工具包实现TextRank


前言

  TextRank 算法是一种基于图的排序算法,主要用于文本处理中的关键词提取和文本摘要。它基于图中节点之间的关系来评估节点的重要性,类似于 Google 的 PageRank 算法。TextRank 算法的关键思想是,一个词语在文本中的重要性可以通过与其他词语的关系来评估,而这些关系可以表示为图中的边。
  图构建(Graph Construction): 将文本中的词语或短语表示为图的节点,词语之间的关系可以是共现关系、语义相似度等。通常,可以使用共现矩阵或者基于词向量的相似度来构建图。
边权重计算(Edge Weighting): 计算图中边的权重,反映节点之间的关系强度。例如,可以使用共现词频、词向量相似度等作为边的权重。
  节点权重计算(Node Weighting): 利用图中节点之间的关系以及边的权重来计算节点的权重。通常采用迭代方法,类似于 PageRank 算法,根据节点之间的相互影响来计算节点的权重。
  排名(Ranking): 根据节点的权重对节点进行排名,排名较高的节点被认为是重要的词语或短语。
  TextRank 算法的节点得分更新公式:

PageRank 实现

初始化时,每个网页的重要性为 1。

我们可以用一个矩阵来表示图中 a、b、e、f 之间的入站和出站链接。

一行中的每个节点表示来自其他节点的入站链接。例如,对于 e 行,节点 a 和 b 具有指向节点 e 的出站链接。本演示文稿将简化更新权重的计算。

根据 1/|out(vi)|​,从函数中,我们应该规范化每一列。

我们使用这个矩阵乘以所有节点的权重。这只是一次没有阻尼系数 d 的迭代。 我们可以使用 Python 进行多次迭代。
import numpy as np
g = [[0, 0, 0, 0],
     [0, 0, 0, 0],
     [1, 0.5, 0, 0],
     [0, 0.5, 0, 0]]
     
g = np.array(g)
pr = np.array([1, 1, 1, 1]) # initialization for a, b, e, f is 1
d = 0.85

for iter in range(10):
    pr = 0.15 + 0.85 * np.dot(g, pr)
    print(iter)
    print(pr)

0
[0.15 0.15 1.425 0.575]
1
[0.15 0.15 0.34125 0.21375]
2
[0.15 0.15 0.34125 0.21375]
3
[0.15 0.15 0.34125 0.21375]
4
[0.15 0.15 0.34125 0.21375]
5
[0.15 0.15 0.34125 0.21375]
6
[0.15 0.15 0.34125 0.21375]
7
[0.15 0.15 0.34125 0.21375]
8
[0.15 0.15 0.34125 0.21375]
9
[0.15 0.15 0.34125 0.21375]
10
[0.15 0.15 0.34125 0.21375]

所以 e 的权重(PageRank值)为 0.34125。

如果我们把有向边变成无向边,我们就可以相应地改变矩阵。

规范化。

我们应该相应地更改代码。

import numpy as np
g = [[0, 0, 0.5, 0],
     [0, 0, 0.5, 1],
     [1, 0.5, 0, 0],
     [0, 0.5, 0, 0]]
     
g = np.array(g)
pr = np.array([1, 1, 1, 1]) # initialization for a, b, e, f is 1
d = 0.85

for iter in range(10):
    pr = 0.15 + 0.85 * np.dot(g, pr)
    print(iter)
    print(pr)

0
[0.575 1.425 1.425 0.575]
1
[0.755625 1.244375 1.244375 0.755625]
2
[0.67885937 1.32114062 1.32114062 0.67885937]
3
[0.71148477 1.28851523 1.28851523 0.71148477]
4
[0.69761897 1.30238103 1.30238103 0.69761897]
5
[0.70351194 1.29648806 1.29648806 0.70351194]
6
[0.70100743 1.29899257 1.29899257 0.70100743]
7
[0.70207184 1.29792816 1.29792816 0.70207184]
8
[0.70161947 1.29838053 1.29838053 0.70161947]
9
[0.70181173 1.29818827 1.29818827 0.70181173]

所以 e 的权重(PageRank值)为 1.29818827。

TextRank 简单版源码实现

#!/usr/bin/env python3
# -*- coding: utf-8 -*-
# @Author: yudengwu(余登武)
# @Date  : 2025/2/06
#@email:1344732766@qq.com

import numpy as np
import jieba
import jieba.posseg as pseg #posseg是Python中的一个分词工具,它可以将文本切割成词语,并且为每个词语标注词性

class TextRank(object):
    def __init__(self, sentence, window, alpha, iternum):
        self.sentence = sentence #文本
        self.window = window#窗口大小
        self.alpha = alpha#权重
        self.edge_dict = {}  # 记录节点的边连接字典
        self.iternum = iternum  # 迭代次数

    # 对句子进行分词
    def cutSentence(self):
        #jieba.load_userdict('user_dict.txt')
        #tag_filter = ['a', 'd', 'n', 'v'] #a形容词,d副词,n名称, v动词
        tag_filter = ['ns', 'n', 'vn', 'v']#地名、名词、动名词、动词
        seg_result = pseg.cut(self.sentence)
        self.word_list = [s.word for s in seg_result if s.flag in tag_filter and len(s.word)>1]
        #print(self.word_list)#['年度', '中国', '爱心', '城市', '公益活动', '新闻', '发布会'...]

    # 根据窗口,构建每个节点的相邻节点,返回边的集合
    def createNodes(self):
        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)
                #针对当前word取出左右边界词  word:{左边界词1,左边界词2...右边界词1,右边界词2}
                tmp_set = set()#当前word的
                left = index - self.window + 1  # 窗口左边界
                right = index + self.window  # 窗口右边界
                if left < 0: left = 0
                if right >= word_list_len: right = word_list_len
                for i in range(left, right):#左闭右开
                    if i == index:
                        continue
                    tmp_set.add(self.word_list[i])
                self.edge_dict[word] = tmp_set #{word:{左边界词1,左边界词2...右边界词1,右边界词2}}

    # 根据边的相连关系,构建矩阵
    def createMatrix(self):
        #self.word_list=['年度', '中国', '爱心', '城市', '公益活动', '新闻', '发布会'...]
        self.matrix = np.zeros([len(set(self.word_list)), len(set(self.word_list))])

        self.word_index = {}  # 记录词的index
        self.index_dict = {}  # 记录节点index对应的词
        for i, v in enumerate(set(self.word_list)):
            self.word_index[v] = i#{词:索引}
            self.index_dict[i] = v #{索引:词}
        for key in self.edge_dict.keys():#edge_dict {word:{左边界词1,左边界词2...右边界词1,右边界词2}|
            for w in self.edge_dict[key]:
                self.matrix[self.word_index[key]][self.word_index[w]] = 1
                self.matrix[self.word_index[w]][self.word_index[key]] = 1
        # 归一化
        for j in range(self.matrix.shape[1]):#列
            sum = 0
            for i in range(self.matrix.shape[0]):#行
                sum += self.matrix[i][j]#一列的和
            for i in range(self.matrix.shape[0]):
                self.matrix[i][j] /= sum

    # 根据textrank公式计算权重
    def calPR(self):
        self.PR = np.ones([len(set(self.word_list)), 1])#每个词语重要性初始化为1
        for i in range(self.iternum):
            self.PR = (1 - self.alpha) + self.alpha * np.dot(self.matrix, self.PR)#重要性迭代更新

    # 输出词和相应的权重
    def printResult(self):
        word_pr = {}
        for i in range(len(self.PR)):
            #self.index_dict[i] 得到位置索引i对应的词
            word_pr[self.index_dict[i]] = self.PR[i][0] #{词:重要性}
            res = sorted(word_pr.items(), key=lambda x: x[1], reverse=True)[:5]#前5个单词
        print(res)






if __name__ == '__main__':
    text = '6月19日,《2012年度“中国爱心城市”公益活动新闻发布会》在京举行。' + \
           '中华社会救助基金会理事长许嘉璐到会讲话。基金会高级顾问朱发忠,全国老龄' + \
           '办副主任朱勇,民政部社会救助司助理巡视员周萍,中华社会救助基金会副理事长耿志远,' + \
           '重庆市民政局巡视员谭明政。晋江市人大常委会主任陈健倩,以及10余个省、市、自治区民政局' + \
           '领导及四十多家媒体参加了发布会。中华社会救助基金会秘书长时正新介绍本年度“中国爱心城' + \
           '市”公益活动将以“爱心城市宣传、孤老关爱救助项目及第二届中国爱心城市大会”为主要内容,重庆市' + \
           '、呼和浩特市、长沙市、太原市、蚌埠市、南昌市、汕头市、沧州市、晋江市及遵化市将会积极参加' + \
           '这一公益活动。中国雅虎副总编张银生和凤凰网城市频道总监赵耀分别以各自媒体优势介绍了活动' + \
           '的宣传方案。会上,中华社会救助基金会与“第二届中国爱心城市大会”承办方晋江市签约,许嘉璐理' + \
           '事长接受晋江市参与“百万孤老关爱行动”向国家重点扶贫地区捐赠的价值400万元的款物。晋江市人大' + \
           '常委会主任陈健倩介绍了大会的筹备情况。'

    tr = TextRank(text, 3, 0.85, 600)
    tr.cutSentence()
    tr.createNodes()
    tr.createMatrix()
    tr.calPR()
    tr.printResult()

jieba工具包实现TextRank

#!/usr/bin/env python3
# -*- coding: utf-8 -*-
# @Author: yudengwu(余登武)
# @Date  : 2025/2/06
#@email:1344732766@qq.com


import jieba
import jieba.posseg as psg
from jieba import analyse

def textrank_extract(text, pos=False, keyword_num=5):
    textrank = analyse.textrank
    keywords = textrank(text, allowPOS=('ns', 'n', 'vn', 'v'),topK=keyword_num,withWeight=
                        False,)
    # 输出抽取出的关键词
    for keyword in keywords:
        print(keyword + "/ ", end='')
    print()
if __name__ == '__main__':
    text = '6月19日,《2012年度“中国爱心城市”公益活动新闻发布会》在京举行。' + \
           '中华社会救助基金会理事长许嘉璐到会讲话。基金会高级顾问朱发忠,全国老龄' + \
           '办副主任朱勇,民政部社会救助司助理巡视员周萍,中华社会救助基金会副理事长耿志远,' + \
           '重庆市民政局巡视员谭明政。晋江市人大常委会主任陈健倩,以及10余个省、市、自治区民政局' + \
           '领导及四十多家媒体参加了发布会。中华社会救助基金会秘书长时正新介绍本年度“中国爱心城' + \
           '市”公益活动将以“爱心城市宣传、孤老关爱救助项目及第二届中国爱心城市大会”为主要内容,重庆市' + \
           '、呼和浩特市、长沙市、太原市、蚌埠市、南昌市、汕头市、沧州市、晋江市及遵化市将会积极参加' + \
           '这一公益活动。中国雅虎副总编张银生和凤凰网城市频道总监赵耀分别以各自媒体优势介绍了活动' + \
           '的宣传方案。会上,中华社会救助基金会与“第二届中国爱心城市大会”承办方晋江市签约,许嘉璐理' + \
           '事长接受晋江市参与“百万孤老关爱行动”向国家重点扶贫地区捐赠的价值400万元的款物。晋江市人大' + \
           '常委会主任陈健倩介绍了大会的筹备情况。'

    print('TextRank模型结果:')
    textrank_extract(text)

在这里插入图片描述

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:/a/965844.html

如若内容造成侵权/违法违规/事实不符,请联系我们进行投诉反馈qq邮箱809451989@qq.com,一经查实,立即删除!

相关文章

免费windows pdf编辑工具

Epdf&#xff08;完全免费&#xff09; 作者&#xff1a;不染心 时间&#xff1a;2025/2/6 Github: https://github.com/dog-tired/Epdf Epdf Epdf 是一款使用 Rust 编写的 PDF 编辑器&#xff0c;目前仍在开发中。它提供了一系列实用的命令行选项&#xff0c;方便用户对 PDF …

星闪开发入门级教程之安装编译器与小项目烧录

系列文章目录 星闪开发入门级教程 好久不见&#xff0c;已经好几年没有发文章了&#xff0c;星闪-作为中国原生的新一代近距离无线联接技术品牌。我想着写点东西。为了适合新手&#xff0c;绝对小白文。 文章目录 系列文章目录前言一、Hispark Studio1.安装Hispark Studio2.安…

Caused by: org.springframework.beans.factory.UnsatisfiedDependencyException解决办法

1.问题描述 在编写完一个功能后,第一次启动这个模块的启动类时,报以下错误, 2.文件解决 检查了controller,service和mapper,均未发现有问题,核对了依赖也未发现依赖冲突 在网上也找了资料,有总结的比较好的: controller层service层dao层注解是否都使用正确&#xff1f;接口…

记录 | WPF基础学习Style局部和全局调用

目录 前言一、Style1.1 例子1.2 为样式起名字1.3 BasedOn 继承上一个样式 二、外部StyleStep1 创建资源字典BaseButtonStyle.xamlStep2 在资源字典中写入StyleStep3 App.xaml中写引用路径【全局】Step4 调用三、代码提供四、x:Key和x:Name区别 更新时间 前言 参考文章&#xff…

信创数据库使用问题汇总

笔者工作中需要使用多种信创数据库&#xff0c;在使用过程中发现一些问题&#xff0c;现记录如下。 1 OceanBase-Oracle租户的Python连接方式 用Python连接OB数据库的mysql租户可以使用连接mysql的包&#xff0c;但连接oracle租户是没有官方包的&#xff0c;必须使用基于jdbc…

多光谱成像技术在华为Mate70系列的应用

华为Mate70系列搭载了光谱技术的产物——红枫原色摄像头&#xff0c;这是一款150万像素的多光谱摄像头。 相较于普通摄像头&#xff0c;它具有以下优势&#xff1a; 色彩还原度高&#xff1a;色彩还原准确度提升约 120%&#xff0c;能捕捉更多光谱信息&#xff0c;使拍摄照片色…

Web3 与区块链:开启透明、安全的网络新时代

在这个信息爆炸的时代&#xff0c;我们对网络的透明性、安全性和隐私保护的需求日益增长。Web3&#xff0c;作为新一代互联网的代表&#xff0c;正携手区块链技术&#xff0c;引领我们走向一个更加透明、安全和去中心化的网络世界。本文将深入探讨 Web3 的基本概念、区块链技术…

[Android] 全球网测-版本号4.3.8

[Android] 全球网测 链接&#xff1a;https://pan.xunlei.com/s/VOIV5G3_UOFWnGuMQ_GlIW2OA1?pwdfrpe# 应用介绍 "全球网测"是由中国信通院产业与规划研究所自主研发的一款拥有宽带测速、上网体验和网络诊断等功能的综合测速软件。APP突出六大亮点优势&#xff1a…

AI智算-k8s部署DeepSeek Janus-Pro-7B 多模态大模型

文章目录 简介环境依赖模型下载下载Janus库GPU环境镜像模型manifest调用Janus多模态文生图 简介 DeepSeek Janus Pro 作为一款强大的多模态理解与生成框架&#xff0c;正在成为研究人员和开发者的热门选择。本文将详细介绍如何在云原生k8s环境中部署配置和使用 DeepSeek Janus…

windows 安装nvidaia驱动和cuda

安装nvidaia驱动和cuda 官网搜索下载驱动 https://www.nvidia.cn/drivers/lookup/ 这里查出来的都是最高支持什么版本的cuda 安装时候都默认精简就行 官网下载所需版本的cuda包 https://developer.nvidia.com/cuda-toolkit-archive 安装成功但是nvcc -V 失败 &#xff0c…

HAL库外设宝典:基于CubeMX的STM32开发手册(持续更新)

目录 前言 GPIO&#xff08;通用输入输出引脚&#xff09; 推挽输出模式 浮空输入和上拉输入模式 GPIO其他模式以及内部电路原理 输出驱动器 输入驱动器 中断 外部中断&#xff08;EXTI&#xff09; 深入中断&#xff08;内部机制及原理&#xff09; 外部中断/事件控…

动态规划(01背包问题)

目录 题目内容题目分析未装满情况思路一思路二代码实现滚动数组优化优化代码 恰好装满情况代码实现滚动数组优化 题目内容 你有一个背包&#xff0c;最多能容纳的体积是V。 现在有n个物品&#xff0c;第i个物品的体积为Vi​,价值为Wi &#xff08;1&#xff09;求这个背包至多能…

力扣.270. 最接近的二叉搜索树值(中序遍历思想)

文章目录 题目描述思路复杂度Code 题目描述 思路 遍历思想(利用二叉树的中序遍历) 本题的难点在于可能存在多个答案&#xff0c;并且要返回最小的那一个&#xff0c;为了解决这个问题&#xff0c;我门则要利用上二叉搜索树中序遍历为有序序列的特性&#xff0c;具体到代码中&a…

高效协同,Tita 助力项目管理场景革新

在当今快节奏、高度竞争的商业环境中&#xff0c;企业面临着前所未有的挑战&#xff1a;如何在有限资源下迅速响应市场变化&#xff0c;确保多个项目的高效执行并达成战略目标&#xff1f;答案就在于优化项目集程管理。而在这个过程中&#xff0c;Tita项目管理产品以其独特的优…

Java使用aspose实现pdf转word

Java使用aspose实现pdf转word 一、下载aspose-pdf-21.6.jar包【下载地址】&#xff0c;存放目录结构如图&#xff1b;配置pom.xml。 <!--pdf to word--> <dependency><groupId>com.aspose</groupId><artifactId>aspose-pdf</artifactId>…

【数据结构-C语言】绪论

文章目录 一、前言二、基本概念和术语2.1 数据元素、数据项和数据对象2.2 数据结构2.2.1 逻辑结构2.2.2 存储结构 2.3 时间复杂度 一、前言 数据结构部分是根据严蔚敏老师的《数据结构-C语言版第2版》书中内容整理的。 二、基本概念和术语 2.1 数据元素、数据项和数据对象 …

anaconda中可以import cv2,但是notebook中cv2 module not found

一、问题 anaconda中成功import cv2 但是jupyter notebook中却无法导入cv2 二、排查 anaconda中使用python路径如下&#xff1a; jupyter notebook中使用python路径如下&#xff1a; 可以发现路径不一致。 三、解决 ①查看可用的kernel ②选中想要修改的kernel&#xff0c;打…

华北平原shp格式范围

华北平原是中国东部的重要地理区域&#xff0c;以下是对其的简要介绍&#xff1a; 此数据为付费数据&#xff0c;如有需求&#xff0c;请联系本人。 1. 地理位置与范围 位置&#xff1a;位于中国东部&#xff0c;西起太行山脉和伏牛山&#xff0c;东至黄海、渤海&#xff0c;北…

MySQL - 字段内分组

1、MySQL 5.7及之前版本 SELECT A.要显示的字段名称,FIRST_VALUE : A.分组字段名称,last :IF(FIRST_VALUE A.分组字段名称, last 1, 1 ) AS rn,FROM 表1 A,(SELECT last : 0, FIRST_VALUE : NULL ) BORDER BY A.排序字段例&#xff1a;SELECT A.DLR_CODE,A.VAILD_CARD_NO,A.L…

【FPGA】 MIPS 12条整数指令 【3】

实现乘除 修改框架 EX&#xff1a;实现带符号乘除法和无符号乘除法 HiLo寄存器&#xff1a;用于存放乘法和除法的运算结果。Hi、Lo为32bit寄存器。电路描述与实现RegFile思想一致 仿真 代码 DataMem.v include "define.v"; module DataMem(input wire clk,input…