jieba分詞學習筆記(二)

2021-09-19 15:54:15 字數 4387 閱讀 5507

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即可...