NLP 开源形近字算法补完计划(完结篇)
前言
所有的故事都有开始,也终将结束。
本文将作为 NLP 汉字相似度的完结篇,为该系列画上一个句号。
起-NLP 中文形近字相似度计算思路
承-中文形近字相似度算法实现,为汉字 NLP 尽一点绵薄之力
转-当代中国最贵的汉字是什么?
不足之处
之所以有本篇,是因为上一次的算法实现存在一些不足。
巴别塔
《圣经》中有关于巴别塔建造,最终人们因为语言问题而停工的故事。
创11:6 “看哪!他们成为一样的人民,都是一样的言语,如今既作起这事来,以后他们所要作的事,就没有不成就的了。创11:7 我们下去,在那里变乱他们的口音,使他们的言语彼此不通。”创11:8 于是,耶和华使他们从那里分散在全地上;他们就停工不造那城了。
为了避免语言问题,我一开始就实现了一个 exe4j 打包的对比程序,自己跑的很顺畅。
小伙伴一跑,运行失败。各种环境配置一顿操作,最后还是报错。
于是,我写了一个 python 简易版本,便于做 NLP 研究的小伙伴们学习。
https://github.com/houbb/nlp-hanzi-similar/releases/tag/pythn
java 是一种语言,python 是一种语言。
编程语言,让人和机器之间可以沟通,却让人与人之间产生了隔阂。
拆字
在 当代中国最贵的汉字是什么? 一文中,我们首次说明了汉字的拆合。
汉字的拆分实现,核心目的之一就是为了完善汉字的相似度比较。
通过对比汉字的拆分部分,然后获取拆字的相似度,提高对比的准确性。
拆字相似度
简单的需求
为了便于小伙伴们理解,我们用产品经理的思维和大家介绍一下实现方式。
我的需求比较简单。你看,【明】可以拆分【日】【月】,【冐】也可以拆分为【日】【月】。对比一下,结果是显然的。怎么实现我不管,明天上线吧。
小伙伴们,应该已经知道怎么实现了吧?
使用体验
诚如产品所言,这个需求已经实现。
maven 引入
<dependency><groupId>com.github.houbb</groupId><artifactId>nlp-hanzi-similar</artifactId><version>1.2.0</version>
</dependency>
使用
double rate1 = HanziSimilarHelper.similar('末', '未');
对应的结果为:0.9696969696969697
更多使用细节,参考开源地址:
https://github.com/houbb/nlp-hanzi-similar
写在完结前
涉及的项目
汉字的相似度计算到这里算是告一段落。
主要涉及的资料及项目有:
拼音
拆字
四角编码词库
汉字结构词库
汉字偏旁词库
笔画数词库
当然,还可以结果 opencc4j 进行繁简体的处理,此处不再延伸。
之后的计划
NLP 的领域还有很多东西需要大家攻克,毕竟中文 NLP 才刚刚开始。
技术尚未成功,同志仍需努力。
据说最近鹅城的某位黄老爷惹得大家怨声载道。
很多小伙伴说,如果有一款软件可以实现【月丷夫马言卂彳山兀攴人言】的沟通功能,那么我肯定会用。
所谓说者无心,听者有意。
写一个通讯软件,主要是为了巩固下 netty 的学习,其他的都不重要。
虽然知道就算有,大家肯定也不太会改变,但是老马还是准备试试。
java 实现思路
警告,如果你头发已经所剩无几,或者对实现并不感兴趣。
那么就可以收藏+点赞+评论【不明觉厉】,然后离开了。
下面是枯燥的代码实现环节。
程序员的思维
下面是程序员的思维。
首先要解决几个问题:
(1)汉字的拆分实现
这个直接复用已经实现的汉字拆分实现。
List<String> stringList = ChaiziHelper.chai(charWord.charAt(0));
相同的一个汉字可以有多种拆分方式,简单起见,我们默认取第一个。
(2)相似的比较
假设我们对比 A B 两个汉字,可以拆分为如下的子集。
A = {A1, A2, …, Am}
B = {B1, B2, …, Bm}
/*** 获取拆分后对应的拆分字符* @param charWord 字符* @return 结果*/
private char[] getSplitChars(String charWord) {List<String> stringList = ChaiziHelper.chai(charWord.charAt(0));// 这里应该选择哪一个是有讲究的。此处为了简单,默认选择第一个。String string = stringList.get(0);return string.toCharArray();
}
拆分后的子集对比有多种实现方式,简单起见,我们直接遍历元素,判断另一个子集是否存在。
当然,遍历的时候要以拆分数量较少的的为基准。
int minLen = Math.min(charsOne.length, charsTwo.length);// 比较
double totalScore = 0.0;
for(int i = 0; i < minLen; i++) {char iChar = charsOne[i];String textChar = iChar+"";if(ArrayPrimitiveUtil.contains(charsTwo, iChar)) {//累加分数}
}
(3)拆分子集的权重
比如 一
月
两个汉字都是子集,但是因为笔画数不同,权重也不同。
我们用一个子集的笔画数占整体汉字的笔画数计算权重。
int textNumber = getNumber(textChar, similarContext);double scoreOne = textNumber*1.0 / numberOne * 1.0;
double scoreTwo = textNumber*1.0 / numberTwo * 1.0;totalScore += (scoreOne + scoreTwo) / 2.0;
ps: 这里的除以 2,是为了归一化。保证最后的结果在 0-1 之间。
(4)笔画数
获取笔画数的方式,我们可以直接复用以前的方法。
如果没有匹配的,默认笔画数为 1。
private int getNumber(String text, IHanziSimilarContext similarContext) {Map<String, Integer> map = similarContext.bihuashuData().dataMap();Integer number = map.get(text);if(number == null) {return 1;}return number;
}
java 完整实现
我们把所有的碎片拼接起来,就得到一个完整的实现。
/*** 拆字** @author 老马啸西风* @since 1.0.0*/
public class ChaiziSimilar implements IHanziSimilar {@Overridepublic double similar(IHanziSimilarContext similarContext) {String hanziOne = similarContext.charOne();String hanziTwo = similarContext.charTwo();int numberOne = getNumber(hanziOne, similarContext);int numberTwo = getNumber(hanziTwo, similarContext);// 拆分char[] charsOne = getSplitChars(hanziOne);char[] charsTwo = getSplitChars(hanziTwo);int minLen = Math.min(charsOne.length, charsTwo.length);// 比较double totalScore = 0.0;for(int i = 0; i < minLen; i++) {char iChar = charsOne[i];String textChar = iChar+"";if(ArrayPrimitiveUtil.contains(charsTwo, iChar)) {int textNumber = getNumber(textChar, similarContext);double scoreOne = textNumber*1.0 / numberOne * 1.0;double scoreTwo = textNumber*1.0 / numberTwo * 1.0;totalScore += (scoreOne + scoreTwo) / 2.0;}}return totalScore * similarContext.chaiziRate();}/*** 获取拆分后对应的拆分字符* @param charWord 字符* @return 结果*/private char[] getSplitChars(String charWord) {List<String> stringList = ChaiziHelper.chai(charWord.charAt(0));// 这里应该选择哪一个是有讲究的。此处为了简单,默认选择第一个。String string = stringList.get(0);return string.toCharArray();}/*** 获取笔画数* @param text 文本* @param similarContext 上下文* @return 结果*/private int getNumber(String text, IHanziSimilarContext similarContext) {Map<String, Integer> map = similarContext.bihuashuData().dataMap();Integer number = map.get(text);if(number == null) {return 1;}return number;}}
小结
本文引入了汉字拆字,进一步丰富了相似度的实现。
当然,实现本身依然有很多值得提升的地方,比如拆分后的选择,是否可以递归拆分等,这个还是留给后人研究吧。
我是老马,期待与你的下次重逢。
NLP 开源形近字算法补完计划(完结篇)相关推荐
- NLP 开源形近字算法之相似字列表(番外篇)
创作目的 国内对于文本的相似度计算,开源的工具是比较丰富的. 但是对于两个汉字之间的相似度计算,国内基本一片空白.国内的参考的资料少的可怜,国外相关文档也是如此. 本项目旨在抛砖引玉,实现一个基本的相 ...
- NLP 中文形近字相似度算法开源实现
项目简介 nlp-hanzi-similar 为汉字提供相似性的计算. 创作目的 有一个小伙伴说自己在做语言认知科学方向的课题研究,看了我以前写的 NLP 中文形近字相似度计算思路 就想问下有没有源码 ...
- 算法补完计划(五) 二分图匹配
二分图 如果一张图能被分为两部分,两部分之间存在边相连,而单个部分内的结点无边相连,那这张图叫做二分图 判断二分图 我们给图进行染色,从一个点开始染成红色,相邻点染蓝色,最后能全部染完,并且任意相邻点 ...
- NLP(四十七)文本纠错之获取形近字
简介 笔者最近在从事文本纠错的相关工作,颇有收获,因此记录于此. 文本纠错很大一部分工作在于纠正同音字.形近字,所谓形近字,是指字形相近的汉字.本文将介绍如何获取形近字. 获取形近字的算法 ...
- ctc center-loss在字符识别形近字分类中的使用
最近在处理字符识别形近字易识别错的问题,然后有大佬推荐了ctc center loss,该方法来源于阿里,据说效果不错 1.先介绍以下ctc center loss(ctc loss + center ...
- 阿里读光OCR原理介绍ppt之 crnn ctc + centerloss 提升形近字识别
此篇文章为阿里云栖大会的介绍自己读光OCR系统的pdf 已经通过crnn ctc + centerloss 实现对形近字的提升 github:https://github.com/tommyMessi ...
- macos模拟器_苹果芯补完计划,iOS终将回归mac OS?
在过去几年时间里,国内外有越来越多小道消息都在传苹果将为新款Mac改用定制设计的ARM处理器:<彭博社>曾报道,苹果可能于今年开始在 Mac 电脑上改用内部代号为Kalamata的自研处理 ...
- 【机器学习】补完计划
机器学习补完计划 发现之前的帖子太长了,拆了整理一下,理一理以前的笔记,其实代码实现和数学推导更加有助于理解 PS:任天堂特邀嘉宾来举例子 波克基斯.玛狃拉,比卡超 四个主要任务 分类(classif ...
- [TaskList] 省选前板子补完计划
省选前本子补完计划 [ ] 带权并查集 [ ] 树上莫队 - UOJ58 [WC2013]糖果公园 loj2485「CEOI2017」Chase 转载于:https://www.cnblogs.com ...
最新文章
- mysql随机查询 uuid_mysql实现随机查询经验谈
- 滴滴魅族手机人脸识别没有反应_手机UI颜值排名榜单,小米MIUI排到第九,魅族没有上榜...
- 恶意npm包收集用户IP等信息并在GitHub传播
- 高仿真的类-BeanDefinitionReader
- 二叉堆详解实现优先级队列
- linux系统支持uefi,支持UEFI启动的 Puppy Linux 7.5发布,Linux 4.4和4.9 LTS内核
- 移动web开发适配rem
- Centos6.4下zabbix的安装配置
- dataframe保存为txt_Word,PDF,PPT,TXT之间的相互转换方法
- 【转载】一个通过JSONP跨域调用WCF REST服务的例子(以jQuery为例)
- Ubuntu镜像源下载
- Cesium:去除原生自带绿色选择框
- 计算机网络学习笔记——操作
- Cartographer(二)使用思岚rplidar雷达进行cartographer建图
- 2015年ps计算机试题,2015年计算机一级考试《PS》模拟试题及答案(一)(2)
- 计算机研究生哪个子专业最容易考公务员
- 【AAE】【Keras】实现merge出错:TypeError: ‘module‘ object is not callable
- 注册微信小程序的操作步骤
- cad安装日志文件发生错误_CAD 2012 安装出错,错误log文件如下,该怎么修复 在线等。...
- 旅游路线定制APP开发是否具备发展前景呢?