1. 程式人生 > >Python中文分詞--jieba的基本使用

Python中文分詞--jieba的基本使用

中文分詞的原理

1、中文分詞(Chinese Word Segmentation) 

指的是將一個漢字序列切分成一個一個單獨的詞。

分詞就是將連續的字序列按照一定的規範重新組合成詞序列的過程

2、現有的分詞演算法可分為三大類:基於字串匹配的分詞方法、基於理解的分詞方法和基於統計的分詞方法

  1. 基於字串匹配的分詞方法:這種方法又叫做機械分詞方法,
  2. 它是按照一定的策略將待分析的漢字串與一個“充分大的”機器詞典中的詞條進行配,
  3. 若在詞典中找到某個字串,則匹配成功(識別出一個詞)
  4. 1)正向最大匹配法(由左到右的方向)
  5. 2)逆向最大匹配法(由右到左的方向):
  6. 3)最少切分(使每一句中切出的詞數最小)
  7. 4)雙向最大匹配法(進行由左到右、由右到左兩次掃描)
  8. 基於理解的分詞方法:這種分詞方法是通過讓計算機模擬人對句子的理解,達到識別詞的效果。
  9. 其基本思想就是在分詞的同時進行句法、語義分析,利用句法資訊和語義資訊來處理歧義現象。
  10. 它通常包括三個部分:分詞子系統、句法語義子系統、總控部分。
  11. 在總控部分的協調下,分詞子系統可以獲得有關詞、句子等的句法和語義資訊來對分詞歧義進行判斷,
  12. 即它模擬了人對句子的理解過程。這種分詞方法需要使用大量的語言知識和資訊。
  13. 由於漢語語言知識的籠統、複雜性,難以將各種語言資訊組織成機器可直接讀取的形式,
  14. 因此目前基於理解的分詞系統還處在試驗階段。
  15. 基於統計的分詞方法:給出大量已經分詞的文字,利用統計機器學習模型學習詞語切分的規律(稱為訓練),
  16. 從而實現對未知文字的切分。
  17. 例如最大概率分詞方法和最大熵分詞方法等。
  18. 隨著大規模語料庫的建立,統計機器學習方法的研究和發展,基於統計的中文分詞方法漸漸成為了主流方法。
  19. 主要統計模型:N元文法模型(N-gram),隱馬爾可夫模型(HiddenMarkovModelHMM),最大熵模型(ME),
  20. 條件隨機場模型(ConditionalRandomFieldsCRF)等。

結巴分詞:

  1. github:https://github.com/fxsjy/jieba
  2. 開源中國地址:http://www.oschina.net/p/jieba/?fromerr=LRXZzk9z

特點

  • 支援三種分詞模式:
    • 精確模式,試圖將句子最精確地切開,適合文字分析;
    • 全模式,把句子中所有的可以成詞的詞語都掃描出來, 速度非常快,但是不能解決歧義;
    • 搜尋引擎模式,在精確模式的基礎上,對長詞再次切分,提高召回率,適合用於搜尋引擎分詞。
  • 支援繁體分詞
  • 支援自定義詞典
  • MIT 授權協議

線上演示

  1. jiebademo
  2. (Powered by Appfog)
  3. 網站程式碼:https://github.com/fxsjy/jiebademo

安裝說明

程式碼對 Python 2/3 均相容

  • 全自動安裝:easy_install jieba 或者pip install jieba / pip3 install jieba
  • 手動安裝:將 jieba 目錄放置於當前目錄或者 site-packages 目錄
  • 通過 import jieba 來引用

演算法

  • 基於字首詞典實現高效的詞圖掃描,生成句子中漢字所有可能成詞情況所構成的有向無環圖 (DAG)
  • 採用了動態規劃查詢最大概率路徑, 找出基於詞頻的最大切分組合
  • 對於未登入詞,採用了基於漢字成詞能力的 HMM 模型,使用了 Viterbi 演算法

主要功能

1. 分詞

  • jieba.cut 
    1. 方法接收三個輸入引數:
    2. 需要分詞的字串;
    3. cut_all 引數用來控制是否採用全模式
    4. HMM 引數用來控制是否使用 HMM 模型
  • jieba.cut_for_search 
    1. 方法接收兩個引數:
    2. 需要分詞的字串;
    3. 是否使用 HMM 模型。
    4. 該方法適合用於搜尋引擎構建倒排索引的分詞,粒度比較細

待分詞的字串可以是 unicode UTF-8字串、GBK 字串。

注意:不建議直接輸入 GBK 字串,可能無法預料地錯誤解碼成 UTF-8

  1. jieba.cut以及 jieba.cut_for_search 返回的結構都是一個可迭代的 generator
  2. 可以使用for迴圈來獲得分詞後得到的每一個詞語(unicode),或者用
  • jieba.lcut 以及jieba.lcut_for_search 直接返回 list
  • jieba.Tokenizer(dictionary=DEFAULT_DICT) 
    1. 新建自定義分詞器,可用於同時使用不同詞典。
    2. jieba.dt 為預設分詞器,所有全域性分詞相關函式都是該分詞器的對映。

程式碼示例

  1. # encoding=utf-8
  2. import jieba
  3. seg_list = jieba.cut("我來到北京清華大學", cut_all=True)
  4. print("Full Mode: "+"/ ".join(seg_list))# 全模式
  5. seg_list = jieba.cut("我來到北京清華大學", cut_all=False)
  6. print("Default Mode: "+"/ ".join(seg_list))# 精確模式
  7. seg_list = jieba.cut("他來到了網易杭研大廈")# 預設是精確模式
  8. print(", ".join(seg_list))
  9. seg_list = jieba.cut_for_search("小明碩士畢業於中國科學院計算所,後在日本京都大學深造")# 搜尋引擎模式
  10. print(", ".join(seg_list))

輸出:

  1. 【全模式】:我/來到/北京/清華/清華大學/華大/大學
  2. 【精確模式】:我/來到/北京/清華大學
  3. 【新詞識別】:他,來到,了,網易,杭研,大廈(此處,“杭研”並沒有在詞典中,但是也被Viterbi演算法識別出來了)
  4. 【搜尋引擎模式】:小明,碩士,畢業,於,中國,科學,學院,科學院,中國科學院,計算,計算所,後,
  5. 在,日本,京都,大學,日本京都大學,深造

2. 新增自定義詞典

載入詞典

  • 開發者可以指定自己自定義的詞典,以便包含 jieba 詞庫裡沒有的詞。雖然 jieba 有新詞識別能力,但是自行新增新詞可以保證更高的正確率
  • 用法: jieba.load_userdict(file_name) # file_name 為檔案類物件或自定義詞典的路徑
  • 詞典格式和 dict.txt 一樣,一個詞佔一行;每一行分三部分:詞語、詞頻(可省略)、詞性(可省略),用空格隔開,順序不可顛倒。file_name 若為路徑或二進位制方式開啟的檔案,則檔案必須為 UTF-8 編碼
  • 詞頻省略時使用自動計算的能保證分出該詞的詞頻。

例如:

  1. 創新辦3 i
  2. 雲端計算5
  3. 凱特琳 nz
  4. 臺中

更改分詞器

調整詞典

  • 使用 add_word(word, freq=None, tag=None) del_word(word) 可在程式中動態修改詞典
  • 使用 suggest_freq(segment, tune=True) 可調節單個詞語的詞頻,使其能(或不能)被分出來。
  • 注意:自動計算的詞頻在使用 HMM 新詞發現功能時可能無效。

程式碼示例:

  1. >>>print('/'.join(jieba.cut('如果放到post中將出錯。', HMM=False)))
  2. 如果/放到/post/中將/出錯/。
  3. >>> jieba.suggest_freq(('中','將'),True)
  4. 494
  5. >>>print('/'.join(jieba.cut('如果放到post中將出錯。', HMM=False)))
  6. 如果/放到/post/中/將/出錯/。
  7. >>>print('/'.join(jieba.cut('「臺中」正確應該不會被切開', HMM=False)))
  8. 「/臺/中/」/正確/應該/不會/被/切開
  9. >>> jieba.suggest_freq('臺中',True)
  10. 69
  11. >>>print('/'.join(jieba.cut('「臺中」正確應該不會被切開', HMM=False)))
  12. 「/臺中/」/正確/應該/不會/被/切開

3. 關鍵詞提取

基於 TF-IDF 演算法的關鍵詞抽取

import jieba.analyse

  • jieba.analyse.extract_tags(sentence, topK=20, withWeight=False, allowPOS=())
    • sentence 為待提取的文字
    • topK 為返回幾個 TF/IDF 權重最大的關鍵詞,預設值為 20
    • withWeight 為是否一併返回關鍵詞權重值,預設值為 False
    • allowPOS 僅包括指定詞性的詞,預設值為空,即不篩選
  • jieba.analyse.TFIDF(idf_path=None) 新建 TFIDF 例項,idf_path 為 IDF 頻率檔案

程式碼示例 (關鍵詞提取)

  1. https://github.com/fxsjy/jieba/blob/master/test/extract_tags.py
  2. 關鍵詞提取所使用逆向檔案頻率(IDF)文字語料庫可以切換成自定義語料庫的路徑
  3. 用法: jieba.analyse.set_idf_path(file_name)# file_name為自定義語料庫的路徑
  4. 自定義語料庫示例:https://github.com/fxsjy/jieba/blob/master/extra_dict/idf.txt.big
  5. 用法示例:https://github.com/fxsjy/jieba/blob/master/test/extract_tags_idfpath.py
  6. 關鍵詞提取所使用停止詞(StopWords)文字語料庫可以切換成自定義語料庫的路徑
  7. 用法: jieba.analyse.set_stop_words(file_name)# file_name為自定義語料庫的路徑
  8. 自定義語料庫示例:https://github.com/fxsjy/jieba/blob/master/extra_dict/stop_words.txt
  9. 用法示例:https://github.com/fxsjy/jieba/blob/master/test/extract_tags_stop_words.py
  10. 關鍵詞一併返回關鍵詞權重值示例
  11. 用法示例:https://github.com/fxsjy/jieba/blob/master/test/extract_tags_with_weight.py

基於 TextRank 演算法的關鍵詞抽取

  • jieba.analyse.textrank(sentence, topK=20, withWeight=False, allowPOS=('ns', 'n', 'vn', 'v')) 直接使用,介面相同,注意預設過濾詞性。
  • jieba.analyse.TextRank() 新建自定義 TextRank 例項
    演算法論文: TextRank: Bringing Order into Texts

    基本思想:

    1. 待抽取關鍵詞的文字進行分詞
    2. 以固定視窗大小(預設為5,通過span屬性調整),詞之間的共現關係,構建圖
    3. 計算圖中節點的PageRank,注意是無向帶權圖

使用示例:

  1. #encoding=utf-8
  2. from __future__ import unicode_literals
  3. import sys
  4. sys.path.append("../")
  5. import jieba
  6. import jieba.posseg
  7. import jieba.analyse
  8. print('='*40)
  9. print('1. 分詞')
  10. print('-'*40)
  11. seg_list = jieba.cut("我來到北京清華大學", cut_all=True)
  12. print("Full Mode: "+"/ ".join(seg_list))# 全模式
  13. seg_list = jieba.cut("我來到北京清華大學", cut_all=False)
  14. print("Default Mode: "+"/ ".join(seg_list))# 預設模式
  15. seg_list = jieba.cut("他來到了網易杭研大廈")
  16. print(", ".join(seg_list))
  17. seg_list = jieba.cut_for_search("小明碩士畢業於中國科學院計算所,後在日本京都大學深造")# 搜尋引擎模式
  18. print(", ".join(seg_list))
  19. print('='*40)
  20. print('2. 新增自定義詞典/調整詞典')
  21. print('-'*40)
  22. print('/'.join(jieba.cut('如果放到post中將出錯。', HMM=False)))
  23. #如果/放到/post/中將/出錯/。
  24. print(jieba.suggest_freq(('中','將'),True))
  25. #494
  26. print('/'.join(jieba.cut('如果放到post中將出錯。', HMM=False)))
  27. #如果/放到/post/中/將/出錯/。
  28. print('/'.join(jieba.cut('「臺中」正確應該不會被切開', HMM=False)))
  29. #「/臺/中/」/正確/應該/不會/被/切開
  30. print(jieba.suggest_freq('臺中',True))
  31. #69
  32. print('/'.join(jieba.cut('「臺中」正確應該不會被切開', HMM=False)))
  33. #「/臺中/」/正確/應該/不會/被/切開
  34. print('='*40)
  35. print('3. 關鍵詞提取')
  36. print('-'*40)
  37. print(' TF-IDF')
  38. print('-'*40)
  39. s ="此外,公司擬對全資子公司吉林歐亞置業有限公司增資4.3億元,增資後,吉林歐亞置業註冊資本由7000萬元增加到5億元。吉林歐亞置業主要經營範圍為房地產開發及百貨零售等業務。目前在建吉林歐亞城市商業綜合體專案。2013年,實現營業收入0萬元,實現淨利潤-139.13萬元。"
  40. for x, w in jieba.analyse.extract_tags(s, withWeight=True):
  41. print('%s %s'%(x, w))
  42. print('-'*40)
  43. print(' TextRank')
  44. print('-'*40)
  45. for x, w in jieba.analyse.textrank(s, withWeight=True):
  46. print('%s %s'%(x, w))
  47. print('='*40)
  48. print('4. 詞性標註')
  49. print('-'*40)
  50. words = jieba.posseg.cut("我愛北京天安門")
  51. for word, flag in words:
  52. print('%s %s'%(word, flag))
  53. print('='*40)
  54. print('6. Tokenize: 返回詞語在原文的起止位置')
  55. print('-'*40)
  56. print(' 預設模式')
  57. print('-'*40)
  58. result = jieba.tokenize('永和服裝飾品有限公司')
  59. for tk in result:
  60. print("word %s\t\t start: %d \t\t end:%d"%(tk[0],tk[1],tk[2]))
  61. print('-'*40)
  62. print(' 搜尋模式')
  63. print('-'*40)
  64. result = jieba.tokenize('永和服裝飾品有限公司', mode='search')
  65. for tk in result:
  66. print("word %s\t\t start: %d \t\t end:%d"%(tk[0],tk[1],tk[2]))

輸出:

  1. Building prefix dict from the default dictionary ...
  2. ========================================
  3. 1.分詞
  4. ----------------------------------------
  5. Loading model from cache C:\Users\ADMINI~1\AppData\Local\Temp\jieba.cache
  6. FullMode:我/來到/北京/清華/清華大學/華大/大學
  7. Loading model cost 1.252 seconds.
  8. DefaultMode:我/來到/北京/清華大學
  9. Prefix dict has been built succesfully.
  10. 他,來到,了,網易,杭研,大廈
  11. 小明,碩士,畢業,於,中國,科學,學院,科學院,中國科學院,計算,計算所,,,後,在,日本,京都,大學,日本京都大學,深造
  12. ========================================
  13. 2.新增自定義詞典/調整詞典
  14. ----------------------------------------
  15. 如果/放到/post/中將/出錯/。
  16. 494
  17. 如果/放到/post/中/將/出錯/。
  18. 「/臺/中/」/正確/應該/不會/被/切開
  19. 69
  20. 「/臺中/」/正確/應該/不會/被/切開
  21. ========================================
  22. 3.關鍵詞提取
  23. ----------------------------------------
  24. TF-IDF
  25. ----------------------------------------
  26. 歐亞0.7300142700289363
  27. 吉林0.659038184373617
  28. 置業0.4887134522112766
  29. 萬元0.3392722481859574
  30. 增資0.33582401985234045
  31. 4.30.25435675538085106
  32. 70000.25435675538085106
  33. 20130.25435675538085106
  34. 139.130.25435675538085106
  35. 實現0.19900979900382978
  36. 綜合體0.19480309624702127
  37. 經營範圍0.19389757253595744
  38. 億元0.1914421623587234
  39. 在建0.17541884768425534
  40. 全資0.17180164988510638
  41. 註冊資本0.1712441526
  42. 百貨0.16734460041382979
  43. 零售0.1475057117057447
  44. 子公司