同义词相似度可以怎样计算

news/2025/3/22 0:33:39

前言

词语的相似性的计算方法有很多,比如字面相似度计算方法、基于语义词典的计算方法、基于统计的相似度(向量空间模型)计算方法和基于神经网络的相似度计算方法。

本篇文章讲讲基于词林的语义相似性。

词林

《同义词词林》是上世纪80年代出版的对汉语词汇进行语义分类的义类词典,共收录64223条词目。随后发展,哈尔滨工业大学信息检索实验室对其进行修正完善,《哈工大社会计算与信息检索研究中心同义词词林扩展版》。

格式

举个例子一般的格式如下,一共包含了五个级别和一个标记位,看下面第一行从左到右,A为一级、a为二级、01为三级、A为四级、02为五级、=为标记位。标记位主要是用于区分常规同义词、相关词和只有词语本身,分别用= # @三个符号表示。其中 = 表示常规同义词,# 表示相关词,@ 则表示独立性质,既没有同义词也没有相关词。

Aa01A02= 人类 生人 全人类
Aa01B03# 良民 顺民
Aa01D01@ 角色
Aa02A08= 奴 妾 妾身 民女
复制代码
编码位12345678
类别级别一级二级三级四级五级标记位
类别含义大类中类小类词群原子词群词语关系

词语相似度

词林的格式可以看成是一共有6个级,那么可以给每个级分配一定的权重,比如分配为 1.2, 1.2, 1.0, 1.0, 0.8, 0.4,总和为5.6。那么计算相似度时其实就是先获取两个单词对应的编码,然后再逐一对比编码每个级是否相等,将所有相等的级的权重加起来,除以总和得到的值即为相似性值。实现如下:

public static double sumWeight(String code1, String code2) {double weight = 0.0;for (int i = 1; i <= 6; i++) {String c1 = getLevelCode(code1, i);String c2 = getLevelCode(code2, i);if (c1.equals(c2)) {weight += WEIGHT[i - 1];} else {break;}}return weight;}public static String getLevelCode(String code, int level) {switch (level) {case 1:return code.substring(0, 1);case 2:return code.substring(1, 2);case 3:return code.substring(2, 4);case 4:return code.substring(4, 5);case 5:return code.substring(5, 7);case 6:return code.substring(7);}return "";}
复制代码

另外,由于每个词可能有多个编码,所以处理时取最高相似值的那个。

public double getSimilarity(String s1, String s2) {if (s1 == null && s2 == null) {return 1.0;} else if (s1 == null || s2 == null) {return 0.0;} else if (s1.equalsIgnoreCase(s2)) {return 1.0;}Set<String> codeSet1 = CilinDictionary.getInstance().getCilinCoding(s1);Set<String> codeSet2 = CilinDictionary.getInstance().getCilinCoding(s2);if (codeSet1 == null || codeSet2 == null) {return 0.0;}double similarity = 0.0;for (String code1 : codeSet1) {for (String code2 : codeSet2) {double s = sumWeight(code1, code2) / TOTAL_WEIGHT;logger.debug(code1 + "-" + code2 + "-" + sumWeight(code1, code2));if (similarity < s)similarity = s;}}return similarity;}
复制代码

测试

public void test() {String s1 = "中国人";String s2 = "炎黄子孙";CilinSimilarity cs = new CilinSimilarity();System.out.println(cs.getSimilarity(s1, s2));s1 = "汽车";s2 = "摩托";System.out.println(cs.getSimilarity(s1, s2));s1 = "人";s2 = "动物";System.out.println(cs.getSimilarity(s1, s2));s1 = "猫";s2 = "狗";System.out.println(cs.getSimilarity(s1, s2));s1 = "今天";s2 = "明天";System.out.println(cs.getSimilarity(s1, s2));}
复制代码
 1.00000000000000020.42857142857142860.00.42857142857142860.7857142857142858
复制代码

github

https://github.com/sea-boat/TextAnalyzer/blob/master/src/main/java/com/seaboat/text/analyzer/similarity/CilinSimilarity.java

-------------推荐阅读------------

我的2017文章汇总——机器学习篇

我的2017文章汇总——Java及中间件

我的2017文章汇总——深度学习篇

我的2017文章汇总——JDK源码篇

我的2017文章汇总——自然语言处理篇

我的2017文章汇总——Java并发篇


跟我交流,向我提问:

公众号的菜单已分为“读书总结”、“分布式”、“机器学习”、“深度学习”、“NLP”、“Java深度”、“Java并发核心”、“JDK源码”、“Tomcat内核”等,可能有一款适合你的胃口。

为什么写《Tomcat内核设计剖析》

欢迎关注:


https://dhexx.cn/news/show-2612007.html

相关文章

制作一个Mac APP:XcodeExtension

作为一个iOS developer 突然想尝试Mac开发&#xff0c;这是我第一个Mac APP 这个软件目前包含以下功能 ConvertFromCase 把选择的下划线内容变为驼峰DeleteEmptyLines 删除选中的空行SortLines 排列选中的行JsonToModel 把Json数据转成Swift模型&#xff0c;会把下划线命名变为…

C# 递归获取 文件夹的 所有文件

public void Director(string dir, List<string> list) {DirectoryInfo d new DirectoryInfo(dir);FileInfo[] files d.GetFiles();//文件DirectoryInfo[] directs d.GetDirectories();//文件夹foreach (FileInfo f in files){list.Add(f.Name);//添加文件名到列表中 …

天台人满为患,不如来看下这个Ramnit蠕虫DesktopLayer.exe分析

今年的世界杯越来越看不懂&#xff0c;想去天台吹吹风都不一定有位置&#xff0c;心凉了&#xff0c;事儿还得做&#xff0c;先从网上抓个可疑样本压压惊&#xff01;上手分析才发现并没有我想得那么简单…… 一、基本信息 MD5ff5e1f27193ce51eec318714ef038bef 文件大小 55 KB…

软件架构设计2

中间件提高开发效率 提高复用性 安全性 降低难度 中间件代理机制 适配器 是进行接口转换 java架构体系里面 不同的名词对应的组件是有好处的 数据库规范程度越高 数据表拆的越散 避免数据的冗余&#xff0c;操作异常等一系列问题。表格拆的太散 会带来效率问题 负载均衡 做业…

TOMCAT源码分析-事件与监听

开篇 作为Tomcat生命周期的补充&#xff0c;解释下事件的触发。 源码部分 每个容器由于继承自LifecycleBase&#xff0c;当容器状态发生变化时都会调用fireLifecycleEvent方法生成LifecycleEvent&#xff0c;并且交由此容器的事件监听器处理。通过addLifecycleListener添加事件…

架构论文准备

数据库建模 概念模式关系模型 可靠性 冗余备份 安全性 安全技术 加密 信息摘要 数字证书 体系结构 就是 架构风格 架构的演化 就是考察架构风格 以前用什么架构 现在用什么架构架构优缺点 。 论面向服务的架构设计 就是SOA 摘要 背景 两段 过度段 回应题目子题目…

GMTC 大前端时代前端监控的最佳实践

摘要&#xff1a;今天我分享的内容分成三个部分&#xff1a; 第一部分是“大前端时代前端监控新的变化”, 讲述这些年来&#xff0c;前端监控一些新的视角以及最前沿的一些思考。 第二部分"前端监控的最佳实践"&#xff0c; 从使用的角度出发&#xff0c;介绍前端监控…

dubbo源码解析(三十一)远程调用——rmi协议

远程调用——rmi协议 目标&#xff1a;介绍rmi协议的设计和实现&#xff0c;介绍dubbo-rpc-rmi的源码。前言 dubbo支持rmi协议&#xff0c;主要基于spring封装的org.springframework.remoting.rmi包来实现&#xff0c;当然最原始还是依赖 JDK 标准的java.rmi.*包&#xff0c;采…

Spring Clould负载均衡重要组件:Ribbon中重要类的用法

Ribbon是Spring Cloud Netflix全家桶中负责负载均衡的组件&#xff0c;它是一组类库的集合。通过Ribbon&#xff0c;程序员能在不涉及到具体实现细节的基础上“透明”地用到负载均衡&#xff0c;而不必在项目里过多地编写实现负载均衡的代码。比如&#xff0c;在某个包含Eureka…

LOJ #6032 「雅礼集训 2017 Day2」水箱

题目链接 https://loj.ac/problem/6032 题解 扫描线&#xff0c;先将每个操作按照y轴排序&#xff0c;考虑水从下面淹到上面。 对于挡板被截断的情况&#xff1a;并查集合并左侧和右侧的格子。 对于要求没有水的情况&#xff1a;如果水不淹到上面&#xff0c;那么它一定会被满足…