一、背景
因为项目需要进行中文分词后,按关键词进行检索,为此小功能引入一个分词小模型占用GPU算力,不值得。
所以经过研究和测试,决定使用Han Language Processing (HanLP)进行免模型中文分词。它的分词效果和速度经过多方测试,表现都不错。
二、依赖引用
HanLP在2.0版本以上,只能使用在线版。我们内网中,必须离线使用,因此使用1.x版本。
首先引入pom依赖:
java
<dependency>
<groupId>com.hankcs</groupId>
<artifactId>hanlp</artifactId>
<version>portable-1.8.2</version>
</dependency>
注:如果想使用持久化的自定义词库,或者针对分词进行一些定制化操作,还需要下载数据包:
关于自定义配置和数据包的使用,请参考官网:
如果没有特殊自定义需求,就不用下载和处理这个数据包。
三、分词功能使用
- 标准分词
开箱即用"的静态分词器。
java
String inputStr = "windows系统的时钟服务怎么设置?";
List<Term> termList = StandardTokenizer.segment(inputStr);
for (Term t : StandardTokenizer.segment(inputStr)) {
System.out.println(t.word);
}
System.out.println(termList);
- NLP分词
基于NLPTokenizer(9970万字的大型综合语料库),执行词性标注和命名实体识别。
java
System.out.println(NLPTokenizer.segment("我新造一个词叫攻城狮,你能识别并标注正确词性吗?"));
- 极速分词
基于AhoCorasickDoubleArrayTrie实现的词典分词,适用于"高吞吐量""精度一般"的场合。
java
for (Term t : SpeedTokenizer.segment(inputStr)) {
System.out.println(t.word);
}
四、关键词提取功能使用
java
public static void test() {
String content = "程序员(英文Programmer)是从事程序开发、维护的专业人员。一般将程序员分为程序设计人员和程序编码人员,但两者的界限并不非常清楚,特别是在中国。软件从业人员分为初级程序员、高级程序员、系统分析员和项目经理四大类。";
//List<String> keywordList = HanLP.extractKeyword(content, 10);
List<String> keywordList = TextRankKeyword.getKeywordList(content, 10);
System.out.println(keywordList);
}
五、短语提取功能使用
java
public static void test2() {
String text = "算法工程师\n" +
"算法(Algorithm)是一系列解决问题的清晰指令,也就是说,能够对一定规范的输入,在有限时间内获得所要求的输出。如果一个算法有缺陷,或不适合于某个问题,执行这个算法将不会解决这个问题。不同的算法可能用不同的时间、空间或效率来完成同样的任务。一个算法的优劣可以用空间复杂度与时间复杂度来衡量。算法工程师就是利用算法处理事物的人。\n" +
"\n" +
"1职位简介\n" +
"算法工程师是一个非常高端的职位;\n" +
"专业要求:计算机、电子、通信、数学等相关专业;\n" +
"学历要求:本科及其以上的学历,大多数是硕士学历及其以上;\n" +
"语言要求:英语要求是熟练,基本上能阅读国外专业书刊;\n" +
"必须掌握计算机相关知识,熟练使用仿真工具MATLAB等,必须会一门编程语言。\n" +
"\n" +
"2研究方向\n" +
"视频算法工程师、图像处理算法工程师、音频算法工程师 通信基带算法工程师\n" +
"\n" +
"3目前国内外状况\n" +
"目前国内从事算法研究的工程师不少,但是高级算法工程师却很少,是一个非常紧缺的专业工程师。算法工程师根据研究领域来分主要有音频/视频算法处理、图像技术方面的二维信息算法处理和通信物理层、雷达信号处理、生物医学信号处理等领域的一维信息算法处理。\n" +
"在计算机音视频和图形图像技术等二维信息算法处理方面目前比较先进的视频处理算法:机器视觉成为此类算法研究的核心;另外还有2D转3D算法(2D-to-3D conversion),去隔行算法(de-interlacing),运动估计运动补偿算法(Motion estimation/Motion Compensation),去噪算法(Noise Reduction),缩放算法(scaling),锐化处理算法(Sharpness),超分辨率算法(Super Resolution),手势识别(gesture recognition),人脸识别(face recognition)。\n" +
"在通信物理层等一维信息领域目前常用的算法:无线领域的RRM、RTT,传送领域的调制解调、信道均衡、信号检测、网络优化、信号分解等。\n" +
"另外数据挖掘、互联网搜索算法也成为当今的热门方向。\n" +
"算法工程师逐渐往人工智能方向发展。";
//List<String> phraseList = HanLP.extractPhrase(text, 10);
IPhraseExtractor extractor = new MutualInformationEntropyPhraseExtractor();
List<String> phraseList = extractor.extractPhrase(text, 12);
System.out.println(phraseList);
}
六、向分词字典中动态添加自定义词汇
java
public static void addSeg() {
{
// 动态增加
CustomDictionary.add("攻城狮");
// 强行插入
CustomDictionary.insert("白富美", "nz 1024");
// 删除词语(注释掉试试)
// CustomDictionary.remove("攻城狮");
System.out.println(CustomDictionary.add("单身狗", "nz 1024 n 1"));
System.out.println(CustomDictionary.get("单身狗"));
String text = "攻城狮逆袭单身狗,迎娶白富美,走上人生巅峰"; // 怎么可能噗哈哈!
// AhoCorasickDoubleArrayTrie自动机扫描文本中出现的自定义词语
final char[] charArray = text.toCharArray();
CustomDictionary.parseText(charArray, new AhoCorasickDoubleArrayTrie.IHit<CoreDictionary.Attribute>()
{
@Override
public void hit(int begin, int end, CoreDictionary.Attribute value)
{
System.out.printf("[%d:%d]=%s %s\n", begin, end, new String(charArray, begin, end - begin), value);
}
});
// 自定义词典在所有分词器中都有效
System.out.println(HanLP.segment(text));
}
}