北大開源的 Python 分詞工具 pkuseg

後臺回覆【入門資料】

送你十本Python電子書

北大开源的 Python 分词工具 pkuseg

文 | 皮乾東 推薦 | 編程派(微信號:codingpy)

本部分內容部分來自:https://github.com/lancopku/PKUSeg-python

1.前言

最近看到一些博文介紹了北大的一個開源的中文分詞工具包pkuseg。其中說到,它在多個分詞數據集上都有非常高的分詞準確率。我們所知道的,也經常使用的結巴分詞誤差率高達 18.55% 和 20.42,而北大的 pkuseg 只有 3.25% 與 4.32%。

當然還有其他的分詞工具,如:清華大學的THULAC,HanLp,pynlpir等工具。分詞的重要性不言而喻,在看到相關介紹後也在第一時間去嘗試一下,以下根據github開源信息做出實驗,其使用的語言是python。github地址為:https://github.com/lancopku/PKUSeg-python。

2.簡介

pkuseg是由北京大學語言計算與機器學習研究組研製推出的一套全新的中文分詞工具包。pkuseg具有如下幾個特點:

  1. 高分詞準確率。相比於其他的分詞工具包,該工具包在不同領域的數據上都大幅提高了分詞的準確度。根據測試結果,pkuseg分別在示例數據集(MSRA和CTB8)上降低了79.33%和63.67%的分詞錯誤率。

  2. 多領域分詞。該分詞包訓練了多種不同領域的分詞模型。根據待分詞的領域特點,用戶可以自由地選擇不同的模型。

  3. 支持用戶自訓練模型。支持用戶使用全新的標註數據進行訓練。

3.工具使用

3.1安裝

方式1.程序包下載安裝

  1. <code>pip install pkuseg/<code>

  2. <code>之後通過importpkuseg來引用/<code>

方式2.從github下載(需要下載模型文件)

  1. <code>將pkuseg文件放到目錄下,通過importpkuseg使用/<code>

  2. <code>模型需要下載或自己訓練。/<code>

3.2代碼示例

1.使用默認模型及默認詞典分詞

在實際測試中,第一次加載模型時間比較長,並且分詞的結果也沒有給出各個詞語的詞性,如下圖:

北大开源的 Python 分词工具 pkuseg

2.設置用戶自定義詞典

在實際測試中,可以看出,自定義詞典確實起到作用,但是這個處理時間似乎有點小長,默認詞典與自定義詞典比較,代碼如下

  1. <code>importpkuseg/<code>


  2. <code>lexicon = ['北京大學', '北京天安門'] #希望分詞時用戶詞典中的詞固定不分開/<code>

  3. <code>segDefault = pkuseg.pkuseg #默認分詞類型/<code>

  4. <code>seg = pkuseg.pkuseg(user_dict=lexicon) #加載模型,給定用戶詞典/<code>

  5. <code>textDefault = segDefault.cut('我愛北京天安門') #進行分詞/<code>

  6. <code>text = seg.cut('我愛北京天安門') #進行分詞/<code>

  7. <code>print(textDefault)/<code>

  8. <code>print(text)/<code>

運行結果如下:

  1. <code>loading model/<code>

  2. <code>finish/<code>

  3. <code>loading model/<code>

  4. <code>finish/<code>

  5. <code>['我', '愛', '北京', '天安門']/<code>

  6. <code>['我', '愛', '北京天安門']/<code>

  7. <code>[Finishedin40.2s]/<code>

3.模型訓練

訓練模型是需要解壓的,具體內容可參考github上的內容,其中代碼如下:

  1. <code>importpkuseg/<code>


  2. <code>seg = pkuseg.pkuseg(model_name='ctb8') #假設用戶已經下載好了ctb8的模型並放在了'ctb8'目錄下,通過設置model_name加載該模型/<code>

  3. <code>text = seg.cut('我愛北京天安門') #進行分詞/<code>

  4. <code>print(text)/<code>

運行結果:

  1. <code>loading model/<code>

  2. <code>finish/<code>

  3. <code>['我', '愛', '北京', '天安門']/<code>

  4. <code>[Finishedin24.6s]/<code>

4.對於大型文本數據集,如果需要快速分詞的話,我們也可以採用多線程的方式

讀取文件,並將分詞結果輸出到一個文件中,在進行測試的時候,幾經報錯,也可沒出結果,獲取我的系統配置有問題,或者輸入文件有問題,或者…這裡就拋磚引玉,希望大牛能夠調出來,代碼如下:

 
  1. <code>importpkuseg/<code>


  2. <code>#對input.txt的文件分詞輸出到output.txt中,使用默認模型和詞典,開20個進程/<code>

  3. <code>pkuseg.test('input.txt', 'output.txt', nthread=20)/<code>

運行結果:

  1. <code>loading model/<code>

  2. <code>finish/<code>

  3. <code>Traceback(most recent calllast):/<code>

  4. <code>File"<string>", line1

    ,in<module>/<string>/<code>

  5. <code>File"C:\\Development\\Python\\Anaconda3\\lib\\multiprocessing\\spawn.py", line105,inspawn_main/<code>

  6. <code>exitcode = _main(fd)/<code>

  7. <code>File"C:\\Development\\Python\\Anaconda3\\lib\\multiprocessing\\spawn.py", line114,in_main/<code>

  8. <code>prepare(preparation_data)/<code>

  9. <code>File"C:\\Development\\Python\\Anaconda3\\lib\\multiprocessing\\spawn.py", line225,inprepare/<code>

  10. <code>_fixup_main_from_path(data['init_main_from_path'])/<code>

  11. <code>File"C:\\Development\\Python\\Anaconda3\\lib\\multiprocessing\\spawn.py", line277,in_fixup_main_from_path/<code>

  12. <code>run_name="__mp_main__")/<code>

  13. <code>File"C:\\Development\\Python\\Anaconda3\\lib\\runpy.py", line263,inrun_path/<code>

  14. <code>pkg_name=pkg_name,>

  15. <code>File"C:\\Development\\Python\\Anaconda3\\lib\\runpy.py", line96,in_run_module_code/<code>

  16. <code>mod_name, mod_spec, pkg_name,>

  17. <code>File"C:\\Development\\Python\\Anaconda3\\lib\\runpy.py", line85,in_run_code/<code>

  18. <code>exec(code, run_globals)/<code>

  19. <code>File"C:\\Users\\JackPi\\Desktop\\test\\pkusegtest\\test.py", line10,in<module>/<code>

  20. <code>pkuseg.test('input.txt', 'output.txt', nthread=20)/<code>

  21. <code>File"C:\\Development\\Python\\Anaconda3\\lib\\site-packages\\pkuseg\\__init__.py", line263,intest/<code>

  22. <code>p.start/<code>

  23. <code>File"C:\\Development\\Python\\Anaconda3\\lib\\multiprocessing\\process.py", line105,instart/<code>

  24. <code>self

    ._popen =self._Popen(self)/<code>

  25. <code>File"C:\\Development\\Python\\Anaconda3\\lib\\multiprocessing\\context.py", line223,in_Popen/<code>

  26. <code>return_default_context.get_context.Process._Popen(process_obj)/<code>

  27. <code>File"C:\\Development\\Python\\Anaconda3\\lib\\multiprocessing\\context.py", line322,in_Popen/<code>

  28. <code>returnPopen(process_obj)/<code>

  29. <code>File"C:\\Development\\Python\\Anaconda3\\lib\\multiprocessing\\popen_spawn_win32.py", line33,in__init__/<code>

  30. <code>prep_data = spawn.get_preparation_data(process_obj._name)/<code>

  31. <code>File"C:\\Development\\Python\\Anaconda3\\lib\\multiprocessing\\spawn.py", line143,inget_preparation_data/<code>

  32. <code>_check_not_importing_main/<code>

  33. <code>File"C:\\Development\\Python\\Anaconda3\\lib\\multiprocessing\\spawn.py", line136,in_check_not_importing_main/<code>

  34. <code>isnotgoing to be frozen to produce an executable.''')/<code>

  35. <code>RuntimeError:/<code>

  36. <code>An attempt has been made to start a new process before the/<code>

  37. <code>current process has finished its bootstrapping phase./<code>


  38. <code>This probably means that you are not using fork to start your/<code>

  39. <code>child processes and you have forgotten to use the proper idiom/<code>

  40. <code>in the main module:/<code>


  41. <code>if __name__ == '__main__':/<code>

  42. <code>freeze_support/<code>

  43. <code>.../<code>


  44. <code>The "freeze_support" line can be omitted if the program/<code>

  45. <code>is not going to be frozen to produce an executable./<code>

  46. <code>loading model/<code>

  47. <code>finish/<code>

  48. <code>Traceback (most recent call last):/<code>

  49. <code>File "C:\\Users\\JackPi\\Desktop\\test\\pkusegtest\\test.py", line 10, in <module>/<code>

  50. <code>pkuseg.test('input.txt', 'output.txt', nthread=20)/<code>

  51. <code>File "C:\\Development\\Python\\Anaconda3\\lib\\site-packages\\pkuseg\\__init__.py", line 263, in test/<code>

  52. <code>p.start/<code>

  53. <code>File "C:\\Development\\Python\\Anaconda3\\lib\\multiprocessing\\process.py", line 105, in start/<code>

  54. <code>self._popen = self._Popen(self)/<code>

  55. <code>File "C:\\Development\\Python\\Anaconda3\\lib\\multiprocessing\\context.py", line 223, in _Popen/<code>

  56. <code>return _default_context.get_context.Process._Popen(process_obj)/<code>

  57. <code>File "C:\\Development\\Python\\Anaconda3\\lib\\multiprocessing\\context.py", line 322, in _Popen/<code>

  58. <code>return Popen(process_obj)/<code>

  59. <code>File "C:\\Development\\Python\\Anaconda3\\lib\\multiprocessing\\popen_spawn_win32.py", line 65, in __init__/<code>

  60. <code>reduction.dump(process_obj, to_child)/<code>

  61. <code>File "C:\\Development\\Python\\Anaconda3\\lib\\multiprocessing\\reduction.py", line 60, in dump/<code>

  62. <code>ForkingPickler(file, protocol).dump(obj)/<code>

  63. <code>BrokenPipeError: [Errno 32] Broken pipe/<code>

  64. <code>[Finished in 42.5s]/<code>

其中的input.txt中的內容為:

  1. <code>外星文明探索是一個很特殊的學科,它對研究者的人生觀影響很大。夜深人靜的時候,從耳機中聽著來自宇宙沒有生命的噪音,這噪音隱隱約約的,好像比那些星星還永恆;有時又覺得那聲音像大興安嶺的冬天裡沒完沒了的寒風,讓我感到很冷,那種孤獨真是沒法形容。地球生命真的是宇宙中偶然裡的偶然,人類是這空蕩蕩的大殿裡唯一一螞蟻。有時覺得生命真珍貴,一切都重如泰山;有時又覺得人是那麼渺小,什麼都不值一提。/<code>

5.重新訓練一個分詞模型

  1. <code>importpkuseg/<code>

  2. <code>#訓練文件為'msr_training.utf8',測試文件為'msr_test_gold.utf8',模型存到'./models'目錄下,開20個進程訓練模型/<code>

  3. <code>pkuseg.train('msr_training.utf8', 'msr_test_gold.utf8', './models', nthread=20)/<code>

這裡我就沒有去測試,感興趣的可以去嘗試一下。

6.參數說明

  1. <code>pkuseg.pkuseg(model_name='msra', user_dict='safe_lexicon')/<code>

  2. <code>model_name 模型路徑。默認是'msra'表示我們預訓練好的模型(僅對pip下載的用戶)。用戶可以填自己下載或訓練的模型所在的路徑如model_name='./models'。/<code>

  3. <code>user_dict 設置用戶詞典。默認為'safe_lexicon'表示我們提供的一箇中文詞典(僅pip)。用戶可以傳入一個包含若干自定義單詞的迭代器。/<code>


  4. <code>pkuseg.test(readFile, outputFile, model_name='msra', user_dict='safe_lexicon', nthread=10)/<code>

  5. <code>readFile 輸入文件路徑/<code>

  6. <code>outputFile 輸出文件路徑/<code>

  7. <code>model_name 同pkuseg.pkuseg/<code>

  8. <code>user_dict 同pkuseg.pkuseg/<code>

  9. <code>nthread 測試時開的進程數/<code>


  10. <code>pkuseg.train(trainFile, testFile, savedir, nthread=10)/<code>

  11. <code>trainFile 訓練文件路徑/<code>

  12. <code>testFile 測試文件路徑/<code>

  13. <code>savedir 訓練模型的保存路徑/<code>

  14. <code>nthread 訓練時開的進程數/<code>

4 各類分詞工具包性能比較

在進行比較之前需要說明以下預訓練模型

分詞模式下,用戶需要加載預訓練好的模型。這裡提供了三種在不同類型數據上訓練得到的模型,根據具體需要,用戶可以選擇不同的預訓練模型。以下是對預訓練模型的說明:

MSRA: 在MSRA(新聞語料)上訓練的模型。新版本代碼採用的是此模型。

CTB8: 在CTB8(新聞文本及網絡文本的混合型語料)上訓練的模型。

WEIBO: 在微博(網絡文本語料)上訓練的模型。

其中,MSRA數據由第二屆國際漢語分詞評測比賽提供,CTB8數據由LDC提供,WEIBO數據由NLPCC分詞比賽提供。

具體比較

官方數據中:在比較中選擇THULAC、結巴分詞等國內代表分詞工具包與pkuseg做性能比較,測試環境選擇Linux,在新聞數據(MSRA)和混合型文本(CTB8)數據上對不同工具包進行了準確率測試(數據在github上,可下載)。該比較使用了第二屆國際漢語分詞評測比賽提供的分詞評價腳本。評測結果如下:

北大开源的 Python 分词工具 pkuseg

通過上面的數據,可以說明jieba分詞的準確率最低,清華大學的THULAC的準確率也沒有pkuseg高。但是,我們需要注意的是:北大的這個分詞工具是經過這些數據訓練出來的,準確率高也是情理之中的事情。真正的好不好,就看使用者的反饋了。

5 相關論文及作者

1.論文

  • Xu Sun, Houfeng Wang, Wenjie Li. Fast Online Training with Frequency-Adaptive Learning Rates for Chinese Word Segmentation and New Word Detection. ACL. 253–262. 2012

  • Jingjing Xu, Xu Sun. Dependency-based Gated Recursive Neural Network for Chinese Word Segmentation. ACL 2016: 567-572

2.作者

Ruixuan Luo (羅睿軒), Jingjing Xu(許晶晶), Xu Sun (孫栩)

6 總結

從客觀來看,該工具還是存在缺點的,雖然官方給出的準確率很高,但是在實際分詞過程中,花費時間長,系統穩定性低,分詞結果也不可以顯示分詞的詞性,綜合來講與當前成熟的開源的分詞工具還是有一定的差距,但是也不否定該工具具有的亮點,以及其非常高的準確性。

分詞是自然語言處理中底層並且非常重要的一環,當前做得也是比較成熟了,但是也存在很多缺陷,也是一個研究的方向。個人認為,真正做自然語言處理,到最後依然是需要回歸到語言到底是什麼,語言是如何發出的,語言的發展等等,當今基於統計的自然語言處理不容置疑也確實做出不錯的成績,但基本上都是基於語料的,模型訓練的等等。在自然語言處理這一交叉學科上,其發展依然任重而道遠,不能一味地崇拜機器學習,深度學習,迴歸語言本質,用數學的方式進行處理也將會是未來研究的方向。

本文鏈接:https://blog.csdn.net/meiqi0538/article/details/86181846

回覆下方「關鍵詞」,獲取優質資源

回覆關鍵詞「 pybook03」,立即獲取主頁君與小夥伴一起翻譯的《Think Python 2e》電子版

回覆關鍵詞「入門資料」,立即獲取主頁君整理的 10 本 Python 入門書的電子版

回覆關鍵詞「

m」,立即獲取Python精選優質文章合集

回覆關鍵詞「book 數字」,將數字替換成 0 及以上數字,有驚喜好禮哦~


分享到:


相關文章: