NLP 中文形近字相似度算法开源实现
項(xiàng)目簡介
nlp-hanzi-similar 為漢字提供相似性的計(jì)算。
創(chuàng)作目的
有一個(gè)小伙伴說自己在做語言認(rèn)知科學(xué)方向的課題研究,看了我以前寫的 NLP 中文形近字相似度計(jì)算思路
就想問下有沒有源碼或者相關(guān)資料。
國內(nèi)對于文本的相似度計(jì)算,開源的工具是比較豐富的。
但是對于兩個(gè)漢字之間的相似度計(jì)算,國內(nèi)基本一片空白。國內(nèi)的參考的資料少的可憐,國外相關(guān)文檔也是如此。
于是將以前寫的相似度算法整理開源,希望能幫到這位小伙伴。
本項(xiàng)目旨在拋磚引玉,實(shí)現(xiàn)一個(gè)基本的相似度計(jì)算工具,為漢字 NLP 貢獻(xiàn)一點(diǎn)綿薄之力。
特性
-
fluent 方法,一行代碼搞定一切
-
高度自定義,允許用戶定義自己的實(shí)現(xiàn)
-
詞庫自定義,適應(yīng)各種應(yīng)用場景
-
豐富的實(shí)現(xiàn)策略
默認(rèn)實(shí)現(xiàn)了基于 四角編碼+拼音+漢字結(jié)構(gòu)+漢字偏旁+筆畫數(shù) 的相似度比較。
變更日志
變更日志
快速開始
需要
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 獲取兩個(gè)漢字的相似度。
double rate1 = HanziSimilarHelper.similar('末', '未');結(jié)果為:
0.9629629629629629自定義權(quán)重
默認(rèn)是根據(jù) 四角編碼+拼音+漢字結(jié)構(gòu)+漢字偏旁+筆畫數(shù) 進(jìn)行相似度比較。
如果默認(rèn)的系統(tǒng)權(quán)重?zé)o法滿足你的需求,你可以通過自定義權(quán)重調(diào)整:
double rate = HanziSimilarBs.newInstance().jiegouRate(10).sijiaoRate(8).bushouRate(6).bihuashuRate(2).pinyinRate(1).similar('末', '未');自定義相似度
有些情況下,系統(tǒng)的計(jì)算是無法滿足的。
用戶可以在根目錄下 hanzi_similar_define.txt 進(jìn)行自定義。
入人 0.9 人入 0.9這樣在計(jì)算 人 和 入 的相似度時(shí),會優(yōu)先以用戶自定義的為準(zhǔn)。
double rate = HanziSimilarHelper.similar('人', '入');此時(shí)的結(jié)果為用戶自定義的值。
引導(dǎo)類
說明
為了便于用戶自定義,HanziSimilarBs 支持用戶進(jìn)行自定義配。
HanziSimilarBs 中允許自定義的配置列表如下:
| 1 | bihuashuRate | 筆畫數(shù)權(quán)重 |
| 2 | bihuashuData | 筆畫數(shù)數(shù)據(jù) |
| 3 | bihuashuSimilar | 筆畫數(shù)相似度策略 |
| 4 | jiegouRate | 結(jié)構(gòu)權(quán)重 |
| 5 | jiegouData | 結(jié)構(gòu)數(shù)據(jù) |
| 6 | jiegouSimilar | 結(jié)構(gòu)相似度策略 |
| 7 | bushouRate | 部首權(quán)重 |
| 8 | bushouData | 部首數(shù)據(jù) |
| 9 | bushouSimilar | 部首相似度策略 |
| 10 | sijiaoRate | 四角編碼權(quán)重 |
| 12 | sijiaoData | 四角編碼數(shù)據(jù) |
| 13 | sijiaoSimilar | 四角編碼相似度策略 |
| 14 | pinyinRate | 拼音權(quán)重 |
| 15 | pinyinData | 拼音數(shù)據(jù) |
| 16 | pinyinSimilar | 拼音相似度策略 |
| 17 | hanziSimilar | 漢字相似度核心策略 |
| 18 | userDefineData | 用戶自定義數(shù)據(jù) |
所有的配置都可以基于接口,用戶進(jìn)行自定義。
快速體驗(yàn)
說明
如果 java 語言不是你的主要開發(fā)語言,你可以通過下面的 exe 文件快速體驗(yàn)一下。
下載地址
https://github.com/houbb/nlp-hanzi-similar/releases/download/exe/hanzi-similar.zip
下載后直接解壓得到 hanzi-similar.exe 免安裝的可執(zhí)行文件。
執(zhí)行效果
界面是使用 java swing 實(shí)現(xiàn)的,所以美觀什么的,已經(jīng)完全放棄治療 T_T。
使用 exe4j 打包。
字符一輸入一個(gè)漢字,字符二輸入另一個(gè)漢字,點(diǎn)擊計(jì)算,則可以獲取對應(yīng)的相似度。
[外鏈圖片轉(zhuǎn)存失敗,源站可能有防盜鏈機(jī)制,建議將圖片保存下來直接上傳(img-Co86EgTm-1637587412203)(similar-execute.png)]
字典的弊端
這個(gè)項(xiàng)目開源,是因?yàn)橛幸晃恍』锇橛邢嚓P(guān)的需求,但是他不懂 java。
一開始想把項(xiàng)目設(shè)計(jì)成為字典的形式,兩個(gè)字對應(yīng)一個(gè)相似度。
但是有一個(gè)問題,2W 漢字,和 2W 漢字的相似度字典,數(shù)量已經(jīng)是近億的數(shù)據(jù)量。
空間復(fù)雜度過高,同時(shí)會導(dǎo)致時(shí)間復(fù)雜度問題。
所以目前采用的是實(shí)時(shí)計(jì)算,有時(shí)間做一下其他語言的遷移 😃
實(shí)現(xiàn)原理
實(shí)現(xiàn)思路
不同于文本相似度,漢字相似度的單位是漢字。
所以相似度是對于漢字的拆解,比如筆畫,拼音,部首,結(jié)構(gòu)等。
推薦閱讀:
NLP 中文形近字相似度計(jì)算思路
計(jì)算思路描述了實(shí)現(xiàn)的原理,但是小伙伴反應(yīng)不會實(shí)現(xiàn),于是才有了本項(xiàng)目。
核心代碼
核心實(shí)現(xiàn)如下,就是各種相似度,進(jìn)行加權(quán)計(jì)算。
/*** 相似度** @param context 上下文* @return 結(jié)果* @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. 通過權(quán)重計(jì)算獲取//3.1 四角編碼IHanziSimilar sijiaoSimilar = context.sijiaoSimilar();double sijiaoScore = sijiaoSimilar.similar(context);//3.2 結(jié)構(gòu)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. 計(jì)算總分double totalScore = sijiaoScore + jiegouScore + bushouScore + bihuashuScore + pinyinScore;//4.1 避免浮點(diǎn)數(shù)比較問題if(totalScore <= 0) {return 0;}//4.2 正則化double limitScore = context.sijiaoRate() + context.jiegouRate()+ context.bushouRate() + context.bihuashuRate() + context.pinyinRate();return totalScore / limitScore; }具體的細(xì)節(jié),如果感興趣,可以自行閱讀源碼。
開源地址
為了便于大家的學(xué)習(xí)和使用,本項(xiàng)目已開源。
開源地址:
https://github.com/houbb/nlp-hanzi-similar
歡迎大家,fork&star 鼓勵(lì)一下老馬~
算法的優(yōu)缺點(diǎn)
優(yōu)點(diǎn)
為數(shù)不多的幾篇 paper 是從漢字的結(jié)構(gòu)入手的。
本算法引入了四角編碼+結(jié)構(gòu)+部首+筆畫+拼音的方式,使其更加符合國內(nèi)的使用直覺。
缺點(diǎn)
部首這部分因?yàn)楫?dāng)時(shí)數(shù)據(jù)問題,實(shí)際上是有缺憾的。
后續(xù)準(zhǔn)備引入拆字字典,對漢字的所有組成部分進(jìn)行對比,而不是目前一個(gè)簡單的部首。
后期 Road-MAP
-
豐富相似度策略
-
優(yōu)化默認(rèn)權(quán)重
-
優(yōu)化 exe 界面
總結(jié)
以上是生活随笔為你收集整理的NLP 中文形近字相似度算法开源实现的全部內(nèi)容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: Partial-Function
- 下一篇: 解决微软newbing chat的Sor