创作目的

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

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

本项目旨在抛砖引玉,实现一个基本的相似度计算工具,为汉字 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>() {
@Override
public 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();

    @Override
public List<String> similarList(String word) {
if(MapUtil.isEmpty(map)) {
initDataMap();
} return map.get(word);
} private void initDataMap() {
if(MapUtil.isNotEmpty(map)) {
return;
} //DLC
synchronized (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. KMP算法番外篇--求解next数组

    KMP算法实现字符串的模式匹配的时间复杂度比朴素的模式匹配好很多,但是它时间效率的提高是有前提的,那就是:模式串的重复率很高,不然它的效率也不会凸显出来.在实际的应用中,KMP算法不算是使用率很高的一 ...

  3. 数据结构和算法 – 番外篇.时间测试类Timing

    public class Timing { //startingTime--用来存储正在测试的代码的开始时间. TimeSpan startingTime; //duration--用来存储正在测试的 ...

  4. CWMP开源代码研究番外篇——博通方案

    声明:本篇文章来自于某公司Cable Modem产品的文档资料,源码来自于博通公司,只提供参考(为保护产权,本人没有源码). 前文曾提到会写一篇关于博通的tr069,那么福利来了.福利,福利,福利,重 ...

  5. 痞子衡嵌入式:超级下载算法(RT-UFL)开发笔记番外(1) - JLinkScript妙用

    大家好,我是痞子衡,是正经搞技术的痞子.今天痞子衡给大家介绍的是超级下载算法开发笔记番外篇之JLinkScript妙用. JLinkScript 文件是配套 J-Link 调试器使用的脚本,这个脚本适 ...

  6. Java实现 蓝桥杯 算法提高 周期字串

    算法提高 周期字串 时间限制:1.0s 内存限制:256.0MB 问题描述 右右喜欢听故事,但是右右的妈妈总是讲一些"从前有座山,山里有座庙,庙里有个老和尚给小和尚讲故事,讲的什么呢?从前有 ...

  7. zz【清华NLP】图神经网络GNN论文分门别类,16大应用200+篇论文最新推荐

    [清华NLP]图神经网络GNN论文分门别类,16大应用200+篇论文最新推荐 图神经网络研究成为当前深度学习领域的热点.最近,清华大学NLP课题组Jie Zhou, Ganqu Cui, Zhengy ...

  8. Duang的成长——使用造字程序输入生僻字

    使用造字程序输入生僻字 最近,一个字突然间火了起来,那就是——duang! (图片来自网络) 那么,问题来了!造字程序哪家强?(此处有掌声) 其实,微软早就考虑到各国文字的博大精深,在系统中集成了一个 ...

  9. 【开源.NET】轻量级内容管理框架Grissom.CMS(第三篇解析配置文件和数据以转换成 sql)

    该篇是 Grissom.CMS 框架系列文章的第三篇, 主要介绍框架用到的核心库 EasyJsonToSql, 把标准的配置文件和数据结构解析成可执行的 sql. 该框架能实现自动化增删改查得益于 E ...

  10. 顶级开源项目 Sentry 20.x JS-SDK 设计艺术(Unified API篇)

    SDK 开发 顶级开源项目 Sentry 20.x JS-SDK 设计艺术(理念与设计原则篇) 顶级开源项目 Sentry 20.x JS-SDK 设计艺术(开发基础篇) 顶级开源项目 Sentry ...

随机推荐

  1. python机器学习——线性回归方法

    背景与原理: 线性回归是机器学习建模中最为简单的模型,也是计算起来最为直观的模型 所谓线性回归,我们要建立的是这样的模型:对一组数据,每组数据形如$(x_{1},...,x_{n},y)$,我们希望构 ...

  2. HDFS、Ceph、GFS、GPFS、Swift、Lustre……容器云选择哪种分布式存储更好?

    HDFS.Ceph.GFS.GPFS.Swift.Lustre--容器云选择哪种分布式存储更好?-51CTO.COM 容器云在使用分布式存储时,HDFS.CEPH.GFS.GPFS.Swift等分布式 ...

  3. Rancher 快速构建k8s容器管理平台解决方案(图片见原文链接)

    转载自Rancher 快速构建k8s容器管理平台解决方案_IT干货的博客-CSDN博客_k8s容器管理平台 一.Rancher 概述 Rancher 是企业级多集群Kubernetes管理平台,一个为 ...

  4. 在CentOS7中安装Redis

    一.检查操作系统中是否安装gcc依赖 [root@192 bin]# yum list installed gcc 如果出现上面图片内容则是已经安装.(由于我是安装了的,所以会存在) 二.安装gcc- ...

  5. 关于LAB2中的assert

    在LAB2中,测试类里会看到这样一句话 注释的意思是确保VM参数启用 -ea,这是个新东西,平时也没写过,我们来了解一下. assert不同于assertEquals这样的函数,是Java中的一个关键 ...

  6. Vue组件template中html代码自动补齐设置

    1.vscode设置==>扩展==>JSON==>在settings.json中编辑 2.在最后 } 前添加如下代码保存文件即可 // 自动补全模板字符串 "emmet.t ...

  7. 前端上传获取excel文件后,如何读取excel文件的内容

    1.安装xlsx npm install xlsx --save-dev 2.引入xlsx并封装读取excel方法 import * as XLSX from "xlsx"; /* ...

  8. 理解 Shell

    理解 Shell shell 的父子关系 用于登录的某个虚拟控制器终端,或在 GUI 中运行终端仿真器时所启动的默认的交互 shell,是一个父 shell.本书到目前为止都是父 shell 提供 C ...

  9. echarts属性大全

    // 全图默认背景  // backgroundColor: 'rgba(0,0,0,0)', // 默认色板 color: ['#ff7f50','#87cefa','#da70d6','#32cd ...

  10. 基础篇二:Linux常用系统命令

    Linux常用系统命令 pwd 打印当前目录 cd /目录 切换目录 cd ..   切换上一级目录 ls 显示目录 ls -a  包括隐藏文件 ls -l 以长格式列出 alias 当前系统所有别名 ...