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 打包。
字符一輸入一個漢字,字符二輸入另一個漢字,點擊計算,則可以獲取對應的相似度。
[外鏈圖片轉存失敗,源站可能有防盜鏈機制,建議將圖片保存下來直接上傳(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 界面 
總結
以上是生活随笔為你收集整理的NLP 中文形近字相似度算法开源实现的全部內容,希望文章能夠幫你解決所遇到的問題。
 
                            
                        - 上一篇: Partial-Function
- 下一篇: 解决微软newbing chat的Sor
