天天看點

如何使用Hanlp加載大字典

如何使用Hanlp加載大字典
問題

因為需要加載一個 近 1G 的字典到Hanlp中,一開始使用了CustomDictionay.add() 方法來一條條的加載,果然到了中間,維護DoubleArraTre 的成本太高,添加一個節點,都會很長時間,本來時間長一點沒有關系,隻要訓練出.bin 的檔案,第二次加載就會很快,然而作為以空間換時間的DAT結構,記憶體消耗很大,預料之内的出現了

1   out of memory: heap size

的問題。後來嘗試直接加載了1G 的字典,顯然更不行。

思路

閱讀了Hanlp的部分源碼,也請教了原作者一部分問題,就打算從源碼入手。初步想法大概是将原始字典 split 成多份,然後分别将多份的小字典 訓練成 多個小的.bin 檔案,再完整的加載到記憶體中,基于的原則則是:加載兩個10M的字典的消耗比一個20M的要小。

然後又優化了一部分,現在加載一個大概1G的字典,占記憶體約3g+ ,已經可以使用了。

大概流程

1 修改 CustomDictionary.java 設定一個 hashmap 或者 一個 list 來存儲所有的小Dat

2 将所有的dat加載完,這裡就不再區分主副字典了。

3 修改Segment.java裡面的combineByCustomDictionary 函數,源碼中隻有一個dat, 這裡我們需要選擇我們容器中其中某一個dat作為要比對使用,之前使用的方案是,周遊所有的dat,知道有了比對,但是這樣缺陷很明顯,解決不了多個字典比對同一個詞的字串的情況,這裡我的考察方案是,字典中的同一個字開始的詞條映射到同一個檔案,這樣不會出現字串問題了。

以上就是個大概的修改,可以參考。