文档章节

使用TextRank算法为文本生成关键字和摘要

樂天
 樂天
发布于 2014/12/01 21:31
字数 1562
阅读 37297
收藏 157

本文同时发布在我的 博客 : http://www.letiantian.me/2014-12-01-text-rank/

 

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)|是集合中元素的个数。

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

举个例子:


上图表示了三张网页之间的链接关系,直觉上网页A最重要。可以得到下面的表:

   结束\起始 A B C
A 0 1 1
B 0 0 0
C 0 0 0


横栏代表其实的节点,纵栏代表结束的节点。若两个节点间有链接关系,对应的值为1。

根据公式,需要将每一竖栏归一化(每个元素/元素之和),归一化的结果是:

 

 

   结束\起始 A B C
A 0 1 1
B 0 0 0
C 0 0 0


上面的结果构成矩阵M。我们用matlab迭代100次看看最后每个网页的重要性:

 

 

M = [0 1 1 
    0 0 0
    0 0 0];

PR = [1; 1 ; 1];

for iter = 1:100
    PR = 0.15 + 0.85*M*PR;
    disp(iter);
    disp(PR);
end

运行结果(省略部分):
 

......

    95

    0.4050
    0.1500
    0.1500

    96

    0.4050
    0.1500
    0.1500

    97

    0.4050
    0.1500
    0.1500

    98

    0.4050
    0.1500
    0.1500

    99

    0.4050
    0.1500
    0.1500

   100

    0.4050
    0.1500
    0.1500

最终A的PR值为0.4050,B和C的PR值为0.1500。

如果把上面的有向边看作无向的(其实就是双向的),那么:

M = [0 1 1 
    0.5 0 0
    0.5 0 0];

PR = [1; 1 ; 1];

for iter = 1:100
    PR = 0.15 + 0.85*M*PR;
    disp(iter);
    disp(PR);
end

运行结果(省略部分):
 

.....

    98

    1.4595
    0.7703
    0.7703

    99

    1.4595
    0.7703
    0.7703

   100

    1.4595
    0.7703
    0.7703

依然能判断出A、B、C的重要性。

 

使用TextRank提取关键字

 

将原文本拆分为句子,在每个句子中过滤掉停用词(可选),并只保留指定词性的单词(可选)。由此可以得到句子的集合和单词的集合。

每个单词作为pagerank中的一个节点。设定窗口大小为k,假设一个句子依次由下面的单词组成:

w1, w2, w3, w4, w5, ..., wn

w1, w2, ..., wkw2, w3, ...,wk+1w3, w4, ...,wk+2等都是一个窗口。在一个窗口中的任两个单词对应的节点之间存在一个无向无权的边。

基于上面构成图,可以计算出每个单词节点的重要性。最重要的若干单词可以作为关键词。

 

使用TextRank提取关键短语


参照“使用TextRank提取关键词”提取出若干关键词。若原文本中存在若干个关键词相邻的情况,那么这些关键词可以构成一个关键短语。

例如,在一篇介绍“支持向量机”的文章中,可以找到三个关键词支持、向量、机,通过关键短语提取,可以得到支持向量机

使用TextRank提取摘要

 

将每个句子看成图中的一个节点,若两个句子之间有相似性,认为对应的两个节点之间有一个无向有权边,权值是相似度。

通过pagerank算法计算得到的重要性最高的若干句子可以当作摘要。

论文中使用下面的公式计算两个句子Si和Sj的相似度:



分子是在两个句子中都出现的单词的数量。|Si|是句子i的单词数。

由于是有权图,PageRank公式略做修改:

 

实现TextRank


因为要用测试多种情况,所以自己实现了一个基于Python 2.7的TextRank针对中文文本的库TextRank4ZH。位于:

https://github.com/someus/TextRank4ZH

下面是一个例子:

#-*- encoding:utf-8 -*-

import codecs
from textrank4zh import TextRank4Keyword, TextRank4Sentence

text = codecs.open('./text/01.txt', 'r', 'utf-8').read()
tr4w = TextRank4Keyword(stop_words_file='./stopword.data')  # 导入停止词

#使用词性过滤,文本小写,窗口为2
tr4w.train(text=text, speech_tag_filter=True, lower=True, window=2)  

print '关键词:'
# 20个关键词且每个的长度最小为1
print '/'.join(tr4w.get_keywords(20, word_min_len=1))  

print '关键短语:'
# 20个关键词去构造短语,短语在原文本中出现次数最少为2
print '/'.join(tr4w.get_keyphrases(keywords_num=20, min_occur_num= 2))  
    
tr4s = TextRank4Sentence(stop_words_file='./stopword.data')

# 使用词性过滤,文本小写,使用words_all_filters生成句子之间的相似性
tr4s.train(text=text, speech_tag_filter=True, lower=True, source = 'all_filters')

print '摘要:'
print '\n'.join(tr4s.get_key_sentences(num=3)) # 重要性最高的三个句子

 

 

运行结果如下:

关键词:
媒体/高圆圆/微/宾客/赵又廷/答谢/谢娜/现身/记者/新人/北京/博/展示/捧场/礼物/张杰/当晚/戴/酒店/外套
关键短语:
微博
摘要:
中新网北京12月1日电(记者 张曦) 30日晚,高圆圆和赵又廷在京举行答谢宴,诸多明星现身捧场,其中包括张杰(微博)、谢娜(微博)夫妇、何炅(微博)、蔡康永(微博)、徐克、张凯丽、黄轩(微博)等
高圆圆身穿粉色外套,看到大批记者在场露出娇羞神色,赵又廷则戴着鸭舌帽,十分淡定,两人快步走进电梯,未接受媒体采访
记者了解到,出席高圆圆、赵又廷答谢宴的宾客近百人,其中不少都是女方的高中同学

 

 

另外, jieba分词提供的基于TextRank的关键词提取工具。 snownlp也实现了关键词提取和摘要生成。
 

© 著作权归作者所有

樂天
粉丝 138
博文 680
码字总数 153018
作品 3
深圳
程序员
私信 提问
加载中

评论(28)

隔壁小狼
很不错的感觉,收下
m
m110501588

引用来自“m110501588”的评论

博主你好,麻烦问下,关键字提取的时候,如果窗口k=2,一个句子分词后有4个以上的词,那么构建图的时候只取前边4个关键词吗?

引用来自“樂天”的评论

不是这样子的。你再看一下: http://my.oschina.net/letiantian/blog/351154?p=2#OSC_h2_2

引用来自“m110501588”的评论

假设窗口k=2,那么{w1,w2}为一个窗口;{w2,w3}为一个窗口;{w3,w4}为一个窗口?总共有三个窗口?还是怎么样?

引用来自“樂天”的评论

恩,是这样理解的

引用来自“m110501588”的评论

那就是说一个句子如果K=2,就只取w1,w2,w3,w4四个词喽?也就是前边四个么?

引用来自“樂天”的评论

抱歉,之前没仔细看你的评论。不知道是不是我文章里有地方写的不合适让你以为只取4个词。实际上有多少取多少。有4个取4个,有10个取10个~

引用来自“m110501588”的评论

不好意思,还是想问下,假设k=2之后,怎么取关键词呢?我之前评论里讲的窗口的定义是否正确呢?能否举个例子呀?还是没理解,表示抱歉

引用来自“樂天”的评论

建议多读几篇pagerank的内容,也可以找些其他讲pagerank的文章。窗口大小所导致的结果没有对错,只能看效果是否满意。
好的,谢谢博主耐心讲解
樂天
樂天 博主

引用来自“m110501588”的评论

博主你好,麻烦问下,关键字提取的时候,如果窗口k=2,一个句子分词后有4个以上的词,那么构建图的时候只取前边4个关键词吗?

引用来自“樂天”的评论

不是这样子的。你再看一下: http://my.oschina.net/letiantian/blog/351154?p=2#OSC_h2_2

引用来自“m110501588”的评论

假设窗口k=2,那么{w1,w2}为一个窗口;{w2,w3}为一个窗口;{w3,w4}为一个窗口?总共有三个窗口?还是怎么样?

引用来自“樂天”的评论

恩,是这样理解的

引用来自“m110501588”的评论

那就是说一个句子如果K=2,就只取w1,w2,w3,w4四个词喽?也就是前边四个么?

引用来自“樂天”的评论

抱歉,之前没仔细看你的评论。不知道是不是我文章里有地方写的不合适让你以为只取4个词。实际上有多少取多少。有4个取4个,有10个取10个~

引用来自“m110501588”的评论

不好意思,还是想问下,假设k=2之后,怎么取关键词呢?我之前评论里讲的窗口的定义是否正确呢?能否举个例子呀?还是没理解,表示抱歉
建议多读几篇pagerank的内容,也可以找些其他讲pagerank的文章。窗口大小所导致的结果没有对错,只能看效果是否满意。
m
m110501588

引用来自“m110501588”的评论

博主你好,麻烦问下,关键字提取的时候,如果窗口k=2,一个句子分词后有4个以上的词,那么构建图的时候只取前边4个关键词吗?

引用来自“樂天”的评论

不是这样子的。你再看一下: http://my.oschina.net/letiantian/blog/351154?p=2#OSC_h2_2

引用来自“m110501588”的评论

假设窗口k=2,那么{w1,w2}为一个窗口;{w2,w3}为一个窗口;{w3,w4}为一个窗口?总共有三个窗口?还是怎么样?

引用来自“樂天”的评论

恩,是这样理解的

引用来自“m110501588”的评论

那就是说一个句子如果K=2,就只取w1,w2,w3,w4四个词喽?也就是前边四个么?

引用来自“樂天”的评论

抱歉,之前没仔细看你的评论。不知道是不是我文章里有地方写的不合适让你以为只取4个词。实际上有多少取多少。有4个取4个,有10个取10个~
不好意思,还是想问下,假设k=2之后,怎么取关键词呢?我之前评论里讲的窗口的定义是否正确呢?能否举个例子呀?还是没理解,表示抱歉
樂天
樂天 博主

引用来自“m110501588”的评论

博主你好,麻烦问下,关键字提取的时候,如果窗口k=2,一个句子分词后有4个以上的词,那么构建图的时候只取前边4个关键词吗?

引用来自“樂天”的评论

不是这样子的。你再看一下: http://my.oschina.net/letiantian/blog/351154?p=2#OSC_h2_2

引用来自“m110501588”的评论

假设窗口k=2,那么{w1,w2}为一个窗口;{w2,w3}为一个窗口;{w3,w4}为一个窗口?总共有三个窗口?还是怎么样?

引用来自“樂天”的评论

恩,是这样理解的

引用来自“m110501588”的评论

那就是说一个句子如果K=2,就只取w1,w2,w3,w4四个词喽?也就是前边四个么?
抱歉,之前没仔细看你的评论。不知道是不是我文章里有地方写的不合适让你以为只取4个词。实际上有多少取多少。有4个取4个,有10个取10个~
m
m110501588

引用来自“m110501588”的评论

博主你好,麻烦问下,关键字提取的时候,如果窗口k=2,一个句子分词后有4个以上的词,那么构建图的时候只取前边4个关键词吗?

引用来自“樂天”的评论

不是这样子的。你再看一下: http://my.oschina.net/letiantian/blog/351154?p=2#OSC_h2_2

引用来自“m110501588”的评论

假设窗口k=2,那么{w1,w2}为一个窗口;{w2,w3}为一个窗口;{w3,w4}为一个窗口?总共有三个窗口?还是怎么样?

引用来自“樂天”的评论

恩,是这样理解的
那就是说一个句子如果K=2,就只取w1,w2,w3,w4四个词喽?也就是前边四个么?
樂天
樂天 博主

引用来自“m110501588”的评论

博主你好,麻烦问下,关键字提取的时候,如果窗口k=2,一个句子分词后有4个以上的词,那么构建图的时候只取前边4个关键词吗?

引用来自“樂天”的评论

不是这样子的。你再看一下: http://my.oschina.net/letiantian/blog/351154?p=2#OSC_h2_2

引用来自“m110501588”的评论

假设窗口k=2,那么{w1,w2}为一个窗口;{w2,w3}为一个窗口;{w3,w4}为一个窗口?总共有三个窗口?还是怎么样?
恩,是这样理解的
m
m110501588

引用来自“m110501588”的评论

博主你好,麻烦问下,关键字提取的时候,如果窗口k=2,一个句子分词后有4个以上的词,那么构建图的时候只取前边4个关键词吗?

引用来自“樂天”的评论

不是这样子的。你再看一下: http://my.oschina.net/letiantian/blog/351154?p=2#OSC_h2_2
假设窗口k=2,那么{w1,w2}为一个窗口;{w2,w3}为一个窗口;{w3,w4}为一个窗口?总共有三个窗口?还是怎么样?
樂天
樂天 博主

引用来自“m110501588”的评论

博主你好,麻烦问下,关键字提取的时候,如果窗口k=2,一个句子分词后有4个以上的词,那么构建图的时候只取前边4个关键词吗?
不是这样子的。你再看一下: http://my.oschina.net/letiantian/blog/351154?p=2#OSC_h2_2
m
m110501588
博主你好,麻烦问下,关键字提取的时候,如果窗口k=2,一个句子分词后有4个以上的词,那么构建图的时候只取前边4个关键词吗?
基于 Python 的自动文本提取:抽象法和生成法的比较

本文为 AI 研习社编译的技术博客,原标题 :Text Summarization in Python: Extractive vs. Abstractive techniques revisited 翻译 | 田栋文、二十六 整理 | 凡江 原文链接:https://rare-...

雷锋字幕组
2018/10/15
0
0
中文文本关键词和摘要提取库--TextRank4ZH

TextRank4ZH 用于自动从中文文本中提取关键词和摘要,基于 TextRank 算法,使用 Python 编写。 TextRank 算法可以用来从文本中提取关键词和摘要(重要的句子)。TextRank4ZH是针对中文文本的...

樂天
2014/12/02
6.5K
0
使用TextRank生成文本摘要

因为项目内容中涉及自动生成文本摘要的功能,因此学习了一下TextRank算法实现摘要提取。 1.介绍一下TextRank算法 TextRank算法的思想是,拟定一个通用的评分标准,给文本中的每一个句子打分,...

Airship
04/01
47
0
Byte Cup 2018机器学习大赛进入冲刺阶段,最全资料帮你快速上手!

2018 Byte Cup 国际机器学习竞赛(以下简称 Byte Cup)是一项面向全球的机器学习竞赛,旨在促进机器学习的学术研究和具体应用。 Byte Cup 2018 的主题是自动生成文本标题。自从互联网诞生以来...

Paper_weekly
2018/12/01
0
0
快速,准确的中文文本摘要实现方法

以前发布过一个Yaha库 ,里面有三种不同的摘要实现方法。它们都是基于关键字提取的,缺点很明显(测试地址): 基于关键字的摘要不够准确,会提供到不少关键字份量很大同时很垃圾的句子 基于...

余争
2013/12/16
3.5K
5

没有更多内容

加载失败,请刷新页面

加载更多

Phpstorm2018 永久激活

1、安装phpstorm,安装包请自行官网下载 http://www.jetbrains.com/phpstorm/download/ 2、下载JetbrainsCrack.jar文件,存放至你的phpstorm执行文件同级目录下 下载JetbrainsCrack.jar 提取...

happyfish319
33分钟前
6
0
谈一谈Android进程间通信的几种方式

###来看一下Android中除了AIDL还有哪些进程间通信的方式: 1、Bundle Bundle实现了Parcelable,所以在Android中我们可以通过Intent在不同进程间传递Bundle数据。 但是在Intent 传输数据的过程...

二营长的意大利炮手
34分钟前
7
0
互联网薪资“高开低走”,你的能力是否真的可以匹配高薪?

对于国内外主流互联网大厂,技术出身似乎已经成为各大掌门人的必备标签。谷歌 CEO 桑达尔·皮查伊、马克·扎克伯格、李彦宏、马化腾、雷军等等皆为技术人出身,都曾参与了公司内部重要产品的...

Java技术剑
36分钟前
10
0
java 多线程

线程声明周期 线程的五个状态:新建,就绪,运行,阻塞,死亡。 其中就绪和运行两个状态客户互相转换,但运行到阻塞,阻塞到就绪,只能单向转换。 刚new出的线程就是【新建】状态,调用start...

雷开你的门
37分钟前
12
0
构造器Constructor是否可被overrid

构造器不能被重写,不能用static修饰构造器,只能用public private protected这三个权限修饰符,且不能有返回语句。

无名氏的程序员
41分钟前
7
0

没有更多内容

加载失败,请刷新页面

加载更多

返回顶部
顶部