NLP 中文形近字相似度算法開源實現 項目簡介 變更日誌 快速開始 引導類 快速體驗 字典的弊端 實現原理 算法的優缺點 後期 Road-MAP

項目簡介

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 打包。

字符一輸入一個漢字,字符二輸入另一個漢字,點擊計算,則可以獲取對應的相似度。

[外鏈圖片轉存失敗,源站可能有防盜鏈機制,建議將圖片保存下來直接上傳(img-Co86EgTm-1637587412203)(similar-execute.png)]

字典的弊端

這個項目開源,是因爲有一位小夥伴有相關的需求,但是他不懂 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 界面

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章