创作目的

国内对于文本的相似度计算,开源的工具是比较丰富的。

但是对于两个汉字之间的相似度计算,国内基本一片空白。国内的参考的资料少的可怜,国外相关文档也是如此。

本项目旨在抛砖引玉,实现一个基本的相似度计算工具,为汉字 NLP 贡献一点绵薄之力。

推荐阅读:

NLP 中文形近字相似度计算思路

中文形近字相似度算法实现,为汉字 NLP 尽一点绵薄之力

当代中国最贵的汉字是什么?

NLP 开源形近字算法补完计划(完结篇)

NLP 开源形近字算法之形近字列表(番外篇)

开源项目在线化 中文繁简体转换/敏感词/拼音/分词/汉字相似度/markdown 目录

需求

有时候我们并不是需要返回两个字的相似,而是需要返回一个汉字的相似列表。

实现思路

我们可以分别计算所有的汉字之间的相似度,然后保留最大的前100个,放在字典中。

然后实时查询这个字典即可。

实现方式

bihuashu_2w.txt 中我们主要需要的是对应的 2W 常见汉字。

hanzi_similar_list.txt 用来存放汉字和相似字的映射关系。

数据初始化

public static void main(String[] args) {final String path = "D:\\code\\coin\\nlp-hanzi-similar\\src\\main\\resources\\hanzi_similar_list.txt";// 读取列表List<String> lines = FileUtil.readAllLines("D:\\code\\coin\\nlp-hanzi-similar\\src\\main\\resources\\nlp\\bihuashu_2w.txt");// 所有的单词Set<String> allWordSet = new HashSet<>();for(String line : lines) {String word = line.split(" ")[0];allWordSet.add(word);}// 循环对比for(String word : allWordSet) {List<String> list = getSimilarListData(word, allWordSet);String line = word +" " + StringUtil.join(list, "");FileUtil.append(path, line);}
}
  • 优先级队列取前 100 个

我们通过优先级队列存储:

private static List<String> getSimilarListData(String word, Set<String> wordSet) {PriorityQueue<SimilarListDataItem> items = new PriorityQueue<>(new Comparator<SimilarListDataItem>() {@Overridepublic int compare(SimilarListDataItem o1, SimilarListDataItem o2) {// 相似度大的放在前面return -o1.getRate().compareTo(o2.getRate());}});for(String other : wordSet) {if(word.equals(other)) {continue;}// 对比double rate = HanziSimilarHelper.similar(word.charAt(0), other.charAt(0));SimilarListDataItem item = new SimilarListDataItem(other, rate);items.add(item);}final int limit = 100;List<String> wordList = new ArrayList<>();for(SimilarListDataItem item : items) {wordList.add(item.getWord());if(wordList.size() >= limit) {break;}}return wordList;
}

相似字的获取

初始化好数据之后,一切就变得非常简单:

  • 接口定义
/*** 数据接口-相似列表* @author binbin.hou* @since 1.3.0*/
public interface IHanziSimilarListData {/*** 返回数据信息* @param word 单词* @return 结果* @since 1.3.0*/List<String> similarList(String word);}
  • 数据获取
public class HanziSimilarListData implements IHanziSimilarListData {private static volatile Map<String, List<String>> map = Guavas.newHashMap();@Overridepublic List<String> similarList(String word) {if(MapUtil.isEmpty(map)) {initDataMap();}return map.get(word);}private void initDataMap() {if(MapUtil.isNotEmpty(map)) {return;}//DLCsynchronized (map) {if(MapUtil.isEmpty(map)) {List<String> lines = StreamUtil.readAllLines("/hanzi_similar_list.txt");for(String line : lines) {String[] words = line.split(" ");// 后面的100个相近词List<String> list = StringUtil.toCharStringList(words[1]);map.put(words[0], list);}}}}}

便利性

为了用户使用方便,我们在 HanziSimilarHelper 中添加 2 个工具类方法:

/*** 相似的列表* @param hanziOne 汉字一* @param limit 大小* @return 结果* @since 1.3.0*/
public static List<String> similarList(char hanziOne, int limit) {return HanziSimilarBs.newInstance().similarList(hanziOne, limit);
}
/*** 相似的列表* @param hanziOne 汉字一* @return 结果* @since 1.3.0*/
public static List<String> similarList(char hanziOne) {return similarList(hanziOne, 10);
}

测试效果

我们使用看一下效果:

我们来看一下【爱】的形近字。

List<String> list = HanziSimilarHelper.similarList('爱');
Assert.assertEquals("[爰, 爯, 受, 爭, 妥, 憂, 李, 爳, 叐, 雙]", list.toString());

开源地址

为了便于大家使用学习,项目已开源。

https://github.com/houbb/nlp-hanzi-similar

小结

一个字的形近字可以做很多有趣的事情,这个要看大家的想象力。

实现方式也不难,最核心的还是相似度的计算。

我是老马,期待与你的下次重逢。

NLP 开源形近字算法之相似字列表(番外篇)相关推荐

  1. NLP 开源形近字算法补完计划(完结篇)

    前言 所有的故事都有开始,也终将结束. 本文将作为 NLP 汉字相似度的完结篇,为该系列画上一个句号. 起-NLP 中文形近字相似度计算思路 承-中文形近字相似度算法实现,为汉字 NLP 尽一点绵薄之 ...

  2. NLP 中文形近字相似度算法开源实现

    项目简介 nlp-hanzi-similar 为汉字提供相似性的计算. 创作目的 有一个小伙伴说自己在做语言认知科学方向的课题研究,看了我以前写的 NLP 中文形近字相似度计算思路 就想问下有没有源码 ...

  3. 程序猿成长之路番外篇之前后端加解密(rsa+aes混合加解密算法)

    今年国庆前夕接手一个外部项目,说是要保障接口数据安全,数据安全相对容易些,接口安全嘛emmmmm, 这个要考虑加解密算法.白名单之类的问题了.于是打算今天搞一期接口安全为题的成长之路番外篇. 为什么要 ...

  4. OpenCV-Python实战(番外篇)——利用 SVM 算法识别手写数字

    OpenCV-Python实战(番外篇)--利用 SVM 算法识别手写数字 前言 使用 SVM 进行手写数字识别 参数 C 和 γ 对识别手写数字精确度的影响 完整代码 相关链接 前言 支持向量机 ( ...

  5. OpenCV-Python实战(番外篇)——利用 KNN 算法识别手写数字

    OpenCV-Python实战(番外篇)--利用 KNN 算法识别手写数字 前言 手写数字数据集 MNIST 介绍 基准模型--利用 KNN 算法识别手写数字 改进模型1--参数 K 对识别手写数字精 ...

  6. 白话机器学习算法理论+实战番外篇之LightGBM

    1. 写在前面 如果想从事数据挖掘或者机器学习的工作,掌握常用的机器学习算法是非常有必要的,在这简单的先捋一捋, 常见的机器学习算法: 监督学习算法:逻辑回归,线性回归,决策树,朴素贝叶斯,K近邻,支 ...

  7. 【番外篇】2W字诚意满满的新活:常见接口测试69道面试题,附带答案

    最近发现面试题热度 挺好的,不过大家博客都只有面试题,从来都不带答案,顺手就码了点收集到的博客问题的答案 共69道,2W字,耗时两天(疯狂暗示)欢迎催更吹水,来一个人就是一份催更动力点击并输入暗号:C ...

  8. 漫谈算法(番外篇) 符号标记以及基本数学公式

    Keywords:Big O: Little O:Big Omega:Little Omega:Theta:Mathematical Formula. 说到算法,大家最熟悉的恐怕就是这个大欧标记了,即 ...

  9. 番外篇(1)模块次序表、代数环及其检测算法

    文章目录 模块次序表 直通模块与端点模块 代数环简介 模块次序表需要注意的其它细节 缺少一次更新的加法器 直通模块交叉1:DFS的问题 直通模块交叉2:BFS的问题 重排算法与代数环检测 其它容易出错 ...

最新文章

  1. mysql 运行sql 编码_关于解决运行 sql 文件时, 找不到 MySQL 默认编码 utf8mb4 的问题...
  2. 很蛋疼的ORA-00911:无效的字符错误
  3. 如何解决文件明明存在nginx却提示404
  4. Applese 的QQ群
  5. 汉仪尚巍手书可以商用吗_【商用车维修】夏天修空调可以撑起全年修车收入的一半,你会了吗?...
  6. mac os和linux和安卓,在我的安卓手机里,安装Windows和macOS系统
  7. .NET的资源并不限于.resx文件,你可以采用任意存储形式[上篇] (转载)
  8. docker命令易错点整理
  9. 开课吧:浅析语音识别算法工程师能力要求
  10. 单应性变换、仿射变换、透视变换
  11. 简明python教程实例
  12. php huoqv 多选,镊噍虫刻蘖舌#joquycg
  13. 1 常见的HTTP股票数据接口整理 腾讯 新浪 网易 2019-08-02
  14. Linux-设置静态IP地址
  15. 一文读懂云计算、大数据、人工智能
  16. 强人工智能和弱人工智能
  17. ocr识别身份证护照阅读器
  18. 今年的第几天?(p16)模拟
  19. 大学英语精读第三版(第六册)学习笔记(原文及全文翻译)——6B - John Thomas’s Cube(约翰·托马斯的立方体)
  20. 一周总结——2020.7.26

热门文章

  1. 点云体素下采样 ❤️(体素质心 | 体素中心)
  2. 从零单刷数据结构(Java描述)——哈希表
  3. setCapture 和 releaseCapture
  4. 黑猴子的家:Ubuntu18.04.2 安装 QQ 就是这么简单
  5. 单纯形法以及对偶单纯形法的Matlab实现
  6. 操作系统1——引导扇区的理解
  7. 【安卓 R 源码】 bindService 源码分析
  8. fortran使用MKL函数库计算一个复数向量的共轭与另一个复数向量的内积
  9. 小程序实现即时语音聊天功能
  10. OMG!Python你竟然这么厉害,这么嚣张