HanLP关键词提取。⼊门篇
前段时间,领导要求出⼀个关键字提取的微服务,要求轻量级。
对于没写过微服务的⼀个⼩⽩来讲。硬着头⽪上也不能说不会啊。
⾸先了解下公司⽬前的架构体系,发现并不是分布式开发,只能算是分模块部署。然后我需要写个Boot的服务,对外提供⼀个接⼝就⾏。
在上⽹浏览了下分词概念后,然后我选择了Gradle & HanLP & SpringBoot & JDK1.8 & tomcat8 & IDEA⼯具来实现。
然后准备就绪后,在idea⾥配置⼀下Gradle路径
HanLP分为词典 和模型,其中词典(dictionary)是词法分析必备,模型(model)是句法分析必需。解压好准备data的上级⽬录 的绝对路径 下⾯会提到⽤途。
这⾥为G:/kaipu/data-for-1.7.3
tomcat8 去官⽹⾃⾏下载,选择⾃⼰操作系统对应的。 jdk1.8 下载安装,环境变量配置不再描述。
⼀切准备就绪,开始创建项⽬
输⼊项⽬ID:keyWord,NEXT
选择本地的gradle
Next ,Finish
此刻项⽬就创建好了。
打开根⽬录下的
dependencies {
weight是什么词性compile 'org.springframework.boot:spring-boot:2.0.5.RELEASE'
compile 'org.springframework.boot:spring-boot-starter-web:2.0.5.RELEASE'
providedRuntime 'org.springframework.boot:spring-boot-starter-tomcat:2.0.5.RELEASE'
testCompile group: 'junit', name: 'junit', version: '4.11'
compile 'com.hankcs:hanlp:portable-1.7.3'
}
前三个jar 是集成springboot外部tomcat⽤的,第四个是junit单元测试依赖,第五个就是我们要⽤的hanlp依赖。
PS:这⾥我着重说下打包的事情,因为我没⽤过Gradle打包,项⽬时间紧,我就延⽤了war包格式,这⾥先记录下过程,这个项⽬后,再回头来研究Gradle打JAR包。
group 'keyword'
version '1.0-SNAPSHOT'
apply plugin: 'java'
apply plugin: 'war'
war {
archiveName 'key-word.war'
}
等待idea⾃动导包完成后,我们来加载hanlp
在resources下,出现⼀个hanlp.properties,打开编辑这个⽂件,更改root路径。这个路径就是上⾯我们提到的 data上级⽬录的绝对路径。
创建第⼀个测试类
@Test
public void test0(){
String text = "中国是世界上的经济⼤国,社会主义强国!";
List<Term> keyWords = HanLP.segment(text);
System.out.String());
}
说明词库引⼊成功。
接下来可以正常开发,按照需求,需要提取正⽂⾥的关键词,摘要。
分析如下:
关键词抽取⼯具:
思路:输⼊标题,正⽂⽂本,综合考虑词频、位置、词性、组合性短语长度等因素,计算权重得分;返回topN个关键词。在此基础上进⾏抽取式摘要,按句⼦包含的关键词数量和权重进⾏处理。
原理:分词后,将命名实体单独拿到,再合适的名词短语。依托HanLP的核⼼词典,根据TF*IDF算法计算每个命名实体和名词性短语的得分score,按score倒排返回前⾯若⼲关键词。
⾸先定义⼀个关键词类。可以是个单词,也可以是⼏个单词组成的短语。
public class Phrase implements Comparable<Phrase>{
private String word; //候选关键词
private boolean inDictionary; //是否在HanLP词典中
private String suffixWord; //中⼼词。对单词,中⼼词就是word。如果是短语,则是短语中最后⼀词
private String suffixWordPos; //中⼼词的词性
private String prefixWordPos; //⾸词的词性
private int freqOfDict = 1; //在词典中该词的词频
private boolean single; //true表⽰单词,false表⽰短语
private Location location; //该候选关键词出现的位置
private int offset; //该候选词在正⽂中位置
private boolean isCandidate; //是否候选关键词
*
*
*
/**
*这会在⽐较score时⽤到
*/
@Override
public int compareTo(Phrase o) {
Word()Word());
}
}
以下是核⼼算法的⼀部分,寻候选关键词
/**全局逻辑
先出关键词,再计算分数
⼀、
* 从分词Term中解析候选的关键词,
* 因为要计算每个句⼦的分数值需要句⼦⾥的所有词累加计算score,所以这⾥都需要打标分数。
* @param terms 分词列表
* @param title ⽂章标题
* @param firstParagraphEnd 对于正⽂处理,表⽰正⽂第⼀段结尾位置
* @param lastParagraphBegin 对于正⽂处理,表⽰正⽂最后⼀段开始位置
*/
int index= 0;
while (index < terms.size()) {
//当前词
Term current = (index);
//⾸先判断是否是命名实体⼈名开头包含地名动名词其他专名,或者团体名开头
if (current.nature.startsWith("nr")
|| current.nature.equals(Nature.ns)
|| current.nature.)
|| current.nature.equals(Nature.vn)
|| current.nature.startsWith("nt")) {
Phrase phrase = new Phrase(current.word,
current.word,
String(),
String(),
<(current.word) == null ? 100 : (current.word).totalFrequency,
true,
phrases.add(phrase);
index++;
}
⼆、
//计算候选关键词的权重
TreeMap<Phrase, Double> scoreMap = new TreeMap<>();
for (Phrase phrase : phrases) {
double score = ainsKey(phrase) ? (phrase) : 0.0;
int wordLength = Word().toString().length();
//排除单字符的关键字
if (score == 0.0 && wordLength != 1) {
//weight⽅法:根据词性、词频、位置、词语长度等因素计算权重
//这⾥依赖HanLp核⼼词典实现TF*IDF算法
版权声明:本站内容均来自互联网,仅供演示用,请勿用于商业和其他非法用途。如果侵犯了您的权益请与我们联系QQ:729038198,我们将在24小时内删除。
发表评论