jieba分詞有多種模式可供選擇。可選的模式包括:
同時也提供了hmm模型的開關。
其中全切分模式就是輸出乙個字串的所有分詞,
精確模式是對句子的乙個概率最佳分詞,
而搜尋引擎模式提供了精確模式的再分詞,將長詞再次拆分為短詞。
效果大抵如下:
# encoding=utf-8
import jieba
seg_list = jieba.cut("我來到北京清華大學", cut_all=true)
print("full mode: " + "/ ".join(seg_list)) # 全模式
seg_list = jieba.cut("我來到北京清華大學", cut_all=false)
print("default mode: " + "/ ".join(seg_list)) # 精確模式
seg_list = jieba.cut("他來到了網易杭研大廈") # 預設是精確模式
print(", ".join(seg_list))
seg_list = jieba.cut_for_search("小明碩士畢業於中國科學院計算所,後在日本京都大學深造") # 搜尋引擎模式
print(", ".join(seg_list))
的結果為
【全模式】: 我/ 來到/ 北京/ 清華/ 清華大學/ 華大/ 大學
【精確模式】: 我/ 來到/ 北京/ 清華大學
【新詞識別】:他, 來到, 了, 網易, 杭研, 大廈 (此處,「杭研」並沒有在詞典中,但是也被viterbi演算法識別出來了)
【搜尋引擎模式】: 小明, 碩士, 畢業, 於, 中國, 科學, 學院, 科學院, 中國科學院, 計算, 計算所, 後, 在, 日本, 京都, 大學, 日本京都大學, 深造
其中,新詞識別即用hmm模型的viterbi演算法進行識別新詞的結果。
值得詳細研究的模式是精確模式,以及其用於識別新詞的hmm模型和viterbi演算法。
在載入詞典之後,jieba分詞要進行分詞操作,在**中就是核心函式jieba.cut()
,**如下:
def cut(self, sentence, cut_all=false, hmm=true):
'''the main function that segments an entire sentence that contains
chinese characters into seperated words.
parameter:
- sentence: the str(unicode) to be segmented.
- cut_all: model type. true for full pattern, false for accurate pattern.
- hmm: whether to use the hidden markov model.
'''sentence = strdecode(sentence)
if cut_all:
re_han = re_han_cut_all
re_skip = re_skip_cut_all
else:
re_han = re_han_default
re_skip = re_skip_default
if cut_all:
cut_block = self.__cut_all
elif hmm:
cut_block = self.__cut_dag
else:
cut_block = self.__cut_dag_no_hmm
blocks = re_han.split(sentence)
for blk in blocks:
if not blk:
continue
if re_han.match(blk):
for word in cut_block(blk):
yield word
else:
tmp = re_skip.split(blk)
for x in tmp:
if re_skip.match(x):
yield x
elif not cut_all:
for xx in x:
yield xx
else:
yield x
其中,
docstr中給出了預設的模式,精確分詞 + hmm模型開啟。
第12-23行進行了變數配置。
第24行做的事情是對句子進行中文的切分,把句子切分成一些只包含能處理的字元的塊(block),丟棄掉特殊字元,因為一些詞典中不包含的字元可能對分詞產生影響。
24行中re_han預設值為re_han_default,是乙個正規表示式,定義如下:
# \u4e00-\u9fd5a-za-z0-9+#&\._ : all non-space characters. will be handled with re_han
re_han_default = re.compile("([\u4e00-\u9fd5a-za-z0-9+#&\._]+)", re.u)
可以看到諸如空格、製表符、換行符之類的特殊字元在這個正規表示式被過濾掉。
25-40行使用yield實現了返回結果是乙個迭代器,即文件中所說:
jieba.cut 以及 jieba.cut_for_search 返回的結構都是乙個可迭代的 generator,可以使用 for 迴圈來獲得分詞後得到的每乙個詞語(unicode)其中,31-40行,如果遇到block是非常規字元,就正則驗證一下直接輸出這個塊作為這個塊的分詞結果。如標點符號等等,在分詞結果中都是單獨乙個詞的形式出現的,就是這十行**進行的。
關鍵在28-30行,如果是可分詞的block,那麼就呼叫函式cut_block
,預設是cut_block = self.__cut_dag
,進行分詞
__cut_dag
的作用是按照dag,即有向無環圖進行切分單詞。其**如下:
def __cut_dag(self, sentence):
dag = self.get_dag(sentence)
route = {}
self.calc(sentence, dag, route)
x = 0
buf = ''
n = len(sentence)
while x < n:
y = route[x][1] + 1
l_word = sentence[x:y]
if y - x == 1:
buf += l_word
else:
if buf:
if len(buf) == 1:
yield buf
buf = ''
else:
if not self.freq.get(buf):
recognized = finalseg.cut(buf)
for t in recognized:
yield t
else:
for elem in buf:
yield elem
buf = ''
yield l_word
x = y
if buf:
if len(buf) == 1:
yield buf
elif not self.freq.get(buf):
recognized = finalseg.cut(buf)
for t in recognized:
yield t
else:
for elem in buf:
yield elem
對於乙個sentence,首先 獲取到其有向無環圖dag,然後利用dp對該有向無環圖進行最大概率路徑的計算。
計算出最大概率路徑後迭代,如果是登入詞,則輸出,如果是單字,將其中連在一起的單字找出來,這些可能是未登入詞,使用hmm模型進行分詞,分詞結束之後輸出。
至此,分詞結束。
其中,值得跟進研究的是第2行獲取dag
,第4行計算最大概率路徑
和第20和34行的使用hmm模型進行未登入詞的分詞
,在後面的文章中會進行解讀。
dag = self.get_dag(sentence)
...self.calc(sentence, dag, route)
...recognized = finalseg.cut(buf)
中文分詞jieba學習筆記
四 詞性標註 五 並行分詞 六 返回詞語在原文的起止位置 注意 hmm模型 隱馬爾可夫模型 可以識別新詞 jieba.load userdict filename filename為自定義詞典的路徑 在使用的時候,詞典的格式和jieba分詞器本身的分詞器中的詞典格式必須保持一致,乙個詞佔一行,每一行...
jieba分詞學習總結
1 jieba.cut 引數1 需要分詞的字串 引數2 是否採用全模式,預設是精確模式 seg list jieba.cut 這是乙個測試 cut all false 可以用 join seg list 2 新增自定義詞典 jieba.load userdict filename filename為...
jieba 利用jieba分詞
目錄 三種分詞模式 新增自定義詞典進行分詞 jieba提供了三種分詞模式,分別是全模式,精確模式和搜尋引擎模式。全模式下會將所有可能的詞語都進行分詞,精確模式下會盡可能的將句子精確切開,搜尋引擎模式實在精確模式的基礎上,對長詞再進行劃分,提高分詞的召回率。使用cut和cut for search即可...