转载:码农场 » TextRank算法提取关键词的Java实现

谈起自动摘要算法,常见的并且最易实现的当属TF-IDF,但是感觉TF-IDF效果一般,不如TextRank好。

TextRank是在 Google的PageRank算法启发下,针对文本里的句子设计的权重算法,目标是自动摘要。它利用投票的原理,让每一个单词给它的邻居(术语称窗口) 投赞成票,票的权重取决于自己的票数。这是一个“先有鸡还是先有蛋”的悖论,PageRank采用矩阵迭代收敛的方式解决了这个悖论。TextRank也 不例外:

PageRank的计算公式:

正规的TextRank公式

正规的TextRank公式在PageRank的公式的基础上,引入了边的权值的概念,代表两个句子的相似度。

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

另外,如果你想提取关键句(自动摘要)的话,请参考姊妹篇《TextRank算法自动摘要的Java实现》。

TextRank的Java实现

先看看测试数据:

程序员(英文Programmer)是从事程序开发、维护的专业人员。一般将程序员分为程序设计人员和程序编码人员,但两者的界限并不非常清楚,特别是在中国。软件从业人员分为初级程序员、高级程序员、系统分析员和项目经理四大类。

我取出了百度百科关于“程序员”的定义作为测试用例,很明显,这段定义的关键字应当是“程序员”并且“程序员”的得分应当最高。

首先对这句话分词,这里可以借助各种分词项目,比如Ansj分词,得出分词结果:

[程序员/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以内的单词:

{开发=[专业, 程序员, 维护, 英文, 程序, 人员],

软件=[程序员, 分为, 界限, 高级, 中国, 特别, 人员],

程序员=[开发, 软件, 分析员, 维护, 系统, 项目, 经理, 分为, 英文, 程序, 专业, 设计, 高级, 人员, 中国],

分析员=[程序员, 系统, 项目, 经理, 高级],

维护=[专业, 开发, 程序员, 分为, 英文, 程序, 人员],

系统=[程序员, 分析员, 项目, 经理, 分为, 高级],

项目=[程序员, 分析员, 系统, 经理, 高级],

经理=[程序员, 分析员, 系统, 项目],

分为=[专业, 软件, 设计, 程序员, 维护, 系统, 高级, 程序, 中国, 特别, 人员],

英文=[专业, 开发, 程序员, 维护, 程序],

程序=[专业, 开发, 设计, 程序员, 编码, 维护, 界限, 分为, 英文, 特别, 人员],

特别=[软件, 编码, 分为, 界限, 程序, 中国, 人员],

专业=[开发, 程序员, 维护, 分为, 英文, 程序, 人员],

设计=[程序员, 编码, 分为, 程序, 人员],

编码=[设计, 界限, 程序, 中国, 特别, 人员],

界限=[软件, 编码, 程序, 中国, 特别, 人员],

高级=[程序员, 软件, 分析员, 系统, 项目, 分为, 人员],

中国=[程序员, 软件, 编码, 分为, 界限, 特别, 人员],

人员=[开发, 程序员, 软件, 维护, 分为, 程序, 特别, 专业, 设计, 编码, 界限, 高级, 中国]}

然后开始迭代投票:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
        for (int i = 0; i < max_iter; ++i)
        {
            Map<String, Float> m = new HashMap<String, Float>();
            float max_diff = 0;
            for (Map.Entry<String, Set<String>> entry : words.entrySet())
            {
                String key = entry.getKey();
                Set<String> value = entry.getValue();
                m.put(key, 1 - d);
                for (String other : value)
                {
                    int size = words.get(other).size();
                    if (key.equals(other) || size == 0continue;
                    m.put(key, m.get(key) + d / size * (score.get(other) == null 0 : score.get(other)));
                }
                max_diff = Math.max(max_diff, Math.abs(m.get(key) - (score.get(key) == null 0 : score.get(key))));
            }
            score = m;
            if (max_diff <= min_diff) break;
        }

排序后的投票结果:

[程序员=1.9249977,

人员=1.6290349,

分为=1.4027836,

程序=1.4025855,

高级=0.9747374,

软件=0.93525416,

中国=0.93414587,

特别=0.93352026,

维护=0.9321688,

专业=0.9321688,

系统=0.885048,

编码=0.82671607,

界限=0.82206935,

开发=0.82074183,

分析员=0.77101076,

项目=0.77101076,

英文=0.7098714,

设计=0.6992446,

经理=0.64640945]

程序员果然荣登榜首,并且分数也有区分度,嗯,勉勉强强。

TextRank算法提取关键词的Java实现的更多相关文章

  1. 基于TextRank提取关键词、关键短语、摘要

    一.TextRank原理 TextRank是一种用来做关键词提取的算法,也可以用于提取短语和自动摘要.因为TextRank是基于PageRank的,所以首先简要介绍下PageRank算法. 1. Pa ...

  2. TextRank算法

    TextRank是一种用来做关键词提取的算法,也可以用于提取短语和自动摘要.因为TextRank是基于PageRank的,所以首先简要介绍下PageRank算法. (1)PageRank PageRa ...

  3. Textrank算法介绍

    先说一下自动文摘的方法.自动文摘(Automatic Summarization)的方法主要有两种:Extraction和Abstraction.其中Extraction是抽取式自动文摘方法,通过提取 ...

  4. TF-IDF与余弦类似性的应用(一):自己主动提取关键词

    作者: 阮一峰 日期: 2013年3月15日 原文链接:http://www.ruanyifeng.com/blog/2013/03/tf-idf.html 这个标题看上去好像非常复杂,事实上我要谈的 ...

  5. 基于TextRank算法的文本摘要

    本文介绍TextRank算法及其在多篇单领域文本数据中抽取句子组成摘要中的应用. TextRank 算法是一种用于文本的基于图的排序算法,通过把文本分割成若干组成单元(句子),构建节点连接图,用句子之 ...

  6. TextRank算法及生产文本摘要方法介绍

    TextRank 算法是一种用于文本的基于图的排序算法,其基本思想来源于谷歌的 PageRank算法,通过把文本分割成若干组成单元(句子),构建节点连接图,用句子之间的相似度作为边的权重,通过循环迭代 ...

  7. Java 需要记得、了解的关键词 (Java 学习中的小记录)

    Java 需要记得.了解的关键词 (Java 学习中的小记录)     作者:王可利(Star·星星) 总结:本次随笔,仅且拿来平时翻阅记忆用

  8. PageRank算法与TextRank算法详解

    PageRank算法: 该算法本质上属于有向带权图. 对于某个互联网网页A来说,该网页PageRank的计算基于以下两个基本假设: 数量假设:在Web图模型中,如果一个页面节点接收到的其他网页指向的入 ...

  9. 算法笔记_071:SPFA算法简单介绍(Java)

    目录 1 问题描述 2 解决方案 2.1 具体编码   1 问题描述 何为spfa(Shortest Path Faster Algorithm)算法? spfa算法功能:给定一个加权连通图,选取一个 ...

随机推荐

  1. mysql创建用户两次授权

    mysql> GRANT ALL PRIVILEGES ON *.* TO 'monty'@'localhost'     ->     IDENTIFIED BY 'some_pass' ...

  2. windows 7 获取SYSTEM权限

    当Adobe Reader 9.0卸载之后,你会发现原来的C:\Program Files\Adobe\Reader 9.0\Resource\CMap文件夹下的一些文件无法删除,提示你需要SYSTE ...

  3. 要后台控制前台的的CSS样式,我们可以加入ASP.NET Literal 控件

    ASP.NET Literal 控件,用于在页面上显示文本.此文本是可编程的. 我用它来制作了 ) { this.LtdMemberPromotion7.Text = "<style ...

  4. LRESULT与wParam和lParam的问题

    在微软vc提供的头文件中有定义在winnt.h中typedef long LONG;在windef.h中typedef LONG LRESULT; 所以LRESULT就是long,也就是长整形之所以取 ...

  5. gb2312和UTF-8的区别

    GB2312编码大约包含6000多汉字(不包括特殊字符),编码范围为第一位b0-f7,第二位编码范围为a1-fe(第一位为cf时,第二位为a1-d3),计算一下汉字个数为6762个汉字.当然还有其他的 ...

  6. xib上拖拽scrollview的自动布局方法

    http://www.cocoachina.com/ios/20150104/10810.html

  7. oracle 学习笔记--用户管理

    oracle 用户管理 创建用户(需要具有dba权限的用户) create user 用户名 identified by 密码 defaule tablespace users     //默认表空间 ...

  8. c++中从一段字符串中提取数字

    采用标准输入输出: 输入:12&3 34*133^3131   13031* 输出:12 3 34 133 3131 13031 思路,先将整个输入存进一个字符串,再解析字符串,这样运行速度会 ...

  9. 批处理脚本命令行方式关闭Windows服务

    对于一些不常用的Windows Services,可以通过设置其启动类型为"禁用"而将其关闭.这种关闭方式是长期性的,电脑重启之后仍然起作用. 有时候希望在批处理脚本里通过命令行方 ...

  10. 关于刘冬大侠Spring.NET系列学习笔记3的一点勘正

    诚如他第22楼“只因渴求等待”提出的疑问一样,他的下面那一段代码是存在一点点问题的, XElement root = XElement.Load(fileName); var objects = fr ...