NLP 中文形近字类似度算法开源实现

2021年11月23日 阅读数:8
这篇文章主要向大家介绍NLP 中文形近字类似度算法开源实现,主要内容包括基础应用、实用技巧、原理机制等方面,希望对大家有所帮助。

项目简介

nlp-hanzi-similar 为汉字提供类似性的计算。java

在这里插入图片描述

创做目的

有一个小伙伴说本身在作语言认知科学方向的课题研究,看了我之前写的 NLP 中文形近字类似度计算思路git

就想问下有没有源码或者相关资料。github

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

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

因而将之前写的类似度算法整理开源,但愿能帮到这位小伙伴。maven

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

特性

  • fluent 方法,一行代码搞定一切
  • 高度自定义,容许用户定义本身的实现
  • 词库自定义,适应各类应用场景
  • 丰富的实现策略

默认实现了基于 四角编码+拼音+汉字结构+汉字偏旁+笔画数 的类似度比较。工具

变动日志

变动日志

快速开始

须要

jdk1.7+学习

maven 3.x+优化

maven 引入

<dependency>
    <groupId>com.github.houbb</groupId>
    <artifactId>nlp-hanzi-similar</artifactId>
    <version>1.0.0</version>
</dependency>

快速开始

基本用法

HanziSimilarHelper.similar 获取两个汉字的类似度。

double rate1 = HanziSimilarHelper.similar('末', '未');

结果为:

0.9629629629629629

自定义权重

默认是根据 四角编码+拼音+汉字结构+汉字偏旁+笔画数 进行类似度比较。

若是默认的系统权重没法知足你的需求,你能够经过自定义权重调整:

double rate = HanziSimilarBs.newInstance()
                .jiegouRate(10)
                .sijiaoRate(8)
                .bushouRate(6)
                .bihuashuRate(2)
                .pinyinRate(1)
                .similar('末', '未');

自定义类似度

有些状况下,系统的计算是没法知足的。

用户能够在根目录下 hanzi_similar_define.txt 进行自定义。

入人 0.9
人入 0.9

这样在计算 的类似度时,会优先以用户自定义的为准。

double rate = HanziSimilarHelper.similar('人', '入');

此时的结果为用户自定义的值。

引导类

说明

为了便于用户自定义,HanziSimilarBs 支持用户进行自定义配。

HanziSimilarBs 中容许自定义的配置列表以下:

序号 属性 说明
1 bihuashuRate 笔画数权重
2 bihuashuData 笔画数数据
3 bihuashuSimilar 笔画数类似度策略
4 jiegouRate 结构权重
5 jiegouData 结构数据
6 jiegouSimilar 结构类似度策略
7 bushouRate 部首权重
8 bushouData 部首数据
9 bushouSimilar 部首类似度策略
10 sijiaoRate 四角编码权重
12 sijiaoData 四角编码数据
13 sijiaoSimilar 四角编码类似度策略
14 pinyinRate 拼音权重
15 pinyinData 拼音数据
16 pinyinSimilar 拼音类似度策略
17 hanziSimilar 汉字类似度核心策略
18 userDefineData 用户自定义数据

全部的配置均可以基于接口,用户进行自定义。

快速体验

说明

若是 java 语言不是你的主要开发语言,你能够经过下面的 exe 文件快速体验一下。

下载地址

https://github.com/houbb/nlp-hanzi-similar/releases/download/exe/hanzi-similar.zip

下载后直接解压获得 hanzi-similar.exe 免安装的可执行文件。

执行效果

界面是使用 java swing 实现的,因此美观什么的,已经彻底放弃治疗 T_T。

使用 exe4j 打包。

字符一输入一个汉字,字符二输入另外一个汉字,点击计算,则能够获取对应的类似度。

在这里插入图片描述

字典的弊端

这个项目开源,是由于有一位小伙伴有相关的需求,可是他不懂 java。

一开始想把项目设计成为字典的形式,两个字对应一个类似度。

可是有一个问题,2W 汉字,和 2W 汉字的类似度字典,数量已是近亿的数据量。

空间复杂度太高,同时会致使时间复杂度问题。

因此目前采用的是实时计算,有时间作一下其余语言的迁移 :)

实现原理

实现思路

不一样于文本类似度,汉字类似度的单位是汉字。

因此类似度是对于汉字的拆解,好比笔画,拼音,部首,结构等。

推荐阅读:

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

计算思路描述了实现的原理,可是小伙伴反应不会实现,因而才有了本项目。

核心代码

核心实现以下,就是各类类似度,进行加权计算。

/**
 * 类似度
 *
 * @param context 上下文
 * @return 结果
 * @since 1.0.0
 */
@Override
public double similar(final IHanziSimilarContext context) {
    final String charOne = context.charOne();
    final String charTwo = context.charTwo();

    //1. 是否相同
    if(charOne.equals(charTwo)) {
        return 1.0;
    }

    //2. 是否用户自定义
    Map<String, Double> defineMap = context.userDefineData().dataMap();
    String defineKey = charOne+charTwo;
    if(defineMap.containsKey(defineKey)) {
        return defineMap.get(defineKey);
    }

    //3. 经过权重计算获取
    //3.1 四角编码
    IHanziSimilar sijiaoSimilar = context.sijiaoSimilar();
    double sijiaoScore = sijiaoSimilar.similar(context);

    //3.2 结构
    IHanziSimilar jiegouSimilar = context.jiegouSimilar();
    double jiegouScore = jiegouSimilar.similar(context);

    //3.3 部首
    IHanziSimilar bushouSimilar = context.bushouSimilar();
    double bushouScore = bushouSimilar.similar(context);

    //3.4 笔画
    IHanziSimilar biahuashuSimilar = context.bihuashuSimilar();
    double bihuashuScore = biahuashuSimilar.similar(context);

    //3.5 拼音
    IHanziSimilar pinyinSimilar = context.pinyinSimilar();
    double pinyinScore = pinyinSimilar.similar(context);

    //4. 计算总分
    double totalScore = sijiaoScore + jiegouScore + bushouScore + bihuashuScore + pinyinScore;
    //4.1 避免浮点数比较问题
    if(totalScore <= 0) {
        return 0;
    }

    //4.2 正则化
    double limitScore = context.sijiaoRate() + context.jiegouRate()
            + context.bushouRate() + context.bihuashuRate() + context.pinyinRate();

    return totalScore / limitScore;
}

具体的细节,若是感兴趣,能够自行阅读源码。

开源地址

为了便于你们的学习和使用,本项目已开源。

开源地址:

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

欢迎你们,fork&star 鼓励一下老马~

算法的优缺点

优势

为数很少的几篇 paper 是从汉字的结构入手的。

本算法引入了四角编码+结构+部首+笔画+拼音的方式,使其更加符合国内的使用直觉。

缺点

部首这部分由于当时数据问题,其实是有缺憾的。

后续准备引入拆字字典,对汉字的全部组成部分进行对比,而不是目前一个简单的部首。

后期 Road-MAP

  • [ ] 丰富类似度策略
  • [ ] 优化默认权重
  • [ ] 优化 exe 界面

在这里插入图片描述