乐趣区

关于nlp:NLP-中文形近字相似度算法开源实现

我的项目简介

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

创作目标

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

就想问下有没有源码或者相干材料。

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

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

于是将以前写的类似度算法整顿开源,心愿能帮到这位小伙伴。

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

个性

  • 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 界面

退出移动版