jieba分词怎么操作_jieba分词学习笔记(二)

分词模式

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.cut()

在载入词典之后,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,进行分词

jieba.__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)

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值