结巴中文分词原理分析4

栏目: 编程工具 · 发布时间: 5年前

内容简介:结巴分词基本用法1

作者: 白宁超,工学硕士,现工作于四川省计算机研究院,著有《自然语言处理理论与实战》一书, 点击阅读原文可直达原文链接, 作者公众号: 机器学习和自然语言处理( 公众号ID:datathinks)

结巴分词基本用法1

1

分词模式设置

安装结巴分词

  • 全自动安装:easy_install jieba 或者 pip install jieba / pip3 install jieba

  • 半自动安装:先下载 http://pypi.python.org/pypi/jieba/ ,解压后运行 python setup.py install

  • 手动安装:将 jieba 目录放置于当前目录或者 site-packages 目录

  • 通过 import jieba 来引用

本机是win10 64位,已经安装了pip工具,关于pip下载安装(here),然后win+R,输入pip install jieba,效果如下:

本机是win10 64位,已经安装了pip工具,关于pip下载安装(here),然后win+R,输入pip install jieba,效果如下:

结巴中文分词原理分析4

结巴几种模式下的分词操作:(以下默认已导入:import jieba)

(1)全模式分词:

>>> import jieba

>>> str= "我是白宁超来自博客园"

>>> seg_list=jieba.cut(str,cut_all=True)

>>> print( "Full Mode: " "/ " . join (seg_list))  # 全模式

Full Mode: 我/ 是/ 白/ 宁/ 超/ 来自/ 博客/ 博客园

结果分析:显然我的名字:白宁超,没有正确分词,这是因为全模式把句子中所有可以成词的词语都扫描出来, 速度非常快,但是不能解决歧义。

(2)精确模式分词

>>> seg_list=jieba.cut(str,cut_all=False)

>>> print( "Default Mode: " "/ " . join (seg_list))  # 精确模式

Default Mode: 我/ 是/ 白宁超/ 来自/ 博客园

>>> seg_list=jieba.cut(str)

>>> print( "Default Mode: " "/ " . join (seg_list))  # 默认模式

Default Mode: 我/ 是/ 白宁超/ 来自/ 博客园

结果分析:首先默认模式就是精确模式,即cut_all=False。这里很好的将“白宁超”划分为一个词。与全模式分词是有区别的。精确模式适合文本分析。

(3)默认精确模式分词

>>> seg_list = jieba.cut( "他来到了网易杭研大厦" )  # 默认是精确模式

>>> print( "【新词发现】\t" + ", " . join (seg_list))

【新词发现】  他, 来到, 了, 网易, 杭研, 大厦

结果分析: 此处杭研并没有在词典中,但是也被Viterbi算法识别出来了。实际上是基于汉字成词能力的 HMM 模型,使用了 Viterbi 算法可以发现新词。也可以在自定义字典去收集新词。

(4)搜索引擎模式分词

>>> seg_list = jieba.cut_for_search( "小明硕士毕业于中国科学院计算所,后在日本京都大学深造" )  # 搜索引擎模式

>>> print( "搜索引擎模式:\t" + ", " . join (seg_list))

搜索引擎模式:小明, 硕士, 毕业, 于, 中国, 科学, 学院, 科学院, 中国科学院, 计算, 计算所, ,, 后, 在, 日本, 京都, 大学, 日本京都大学, 深造

结果分析:在精确模式的基础上,对长词再次切分,提高召回率,适合用于搜索引擎分词。

(5)繁体分词

>>> str= '' '此開卷第一回也.作者自云:因曾歷過一番夢幻之后,故將真事隱去,

而借 "通靈" 之說,撰此《石頭記》一書也.故曰 "甄士隱" 云云.但書中所記

何事何人?自又云:“今風塵碌碌,一事無成,忽念及當日所有之女子,一

一細考較去,覺其行止見識,皆出于我之上.何我堂堂須眉,誠不若彼裙釵

哉?實愧則有余,悔又無益之大無可如何之日也! '' '

>>> str=jieba.cut(str)

>>> print( '/ ' . join (str))

此開卷/ 第一回/ 也/ ./ 作者/ 自云/ :/ 因曾/ 歷過/ 一番/ 夢/ 幻之后/ ,/ 故將/ 真事/ 隱去/ ,/

/ 而/ 借/  "/ 通靈/ " / 之/ 說/ ,/ 撰此/ 《/ 石頭記/ 》/ 一書/ 也/ ./ 故/ 曰/  "/ 甄士/ 隱/ " / 云云/ ./ 但書中/ 所記/

/ 何事何/ 人/ ?/ 自又云/ :/ “/ 今風/ 塵碌碌/ ,/ 一事/ 無成/ ,/ 忽念及/ 當日/ 所/ 有/ 之/ 女子/ ,/ 一/

/ 一細/ 考較/ 去/ ,/ 覺其/ 行止/ 見識/ ,/ 皆/ 出于/ 我/ 之/ 上/ ./ 何/ 我堂/ 堂須/ 眉/ ,/ 誠不若/ 彼/ 裙釵/

/ 哉/ ?/ 實愧則/ 有/ 余/ ,/ 悔/ 又/ 無益/ 之/ 大/ 無/ 可/ 如何/ 之/ 日/ 也/ !

>>>

(6) jieba.lcut 全模式、精准模式、搜索引擎模式

>>> seg_list=jieba.lcut(str,cut_all=True,HMM=True)<br>>>> type(seg_list)<br>< class   'list' ><br>>>> seg_list<br>[ '我' '是' '白' '宁' '超' '来自' '博客' '博客园' ]<br>>>> print( "Full Mode: "   "/ " . join (seg_list))  # 全模式隐马<br>Full Mode: 我/ 是/ 白/ 宁/ 超/ 来自/ 博客/ 博客园<br>>>> type( "/ " . join (seg_list))<br>< class   'str' >

结果分析:显然调用jieba.lcut返回list类型,"/ ".join(seg_list)是将list转化为string类型。

(7)自定义分词器

#encoding=utf-8

from __future__ import print_function, unicode_literals

import sys

sys.path.append( "../" )

import jieba

jieba.load_userdict( "userdict.txt" )

import jieba.posseg  as pseg

jieba.add_word( '凱特琳' )

jieba.del_word( '自定义词' )

test_sent = (

"李小福和李铁军是创新办主任也是云计算方面的专家; 什么是八一双鹿\n"

"例如我输入一个带“韩玉赏鉴”的标题,在自定义词库中也增加了此词为N类\n"

"「台中」正確應該不會被切開。mac上可分出「石墨烯」;此時又可以分出來凱特琳了。"

)

words = jieba.cut(test_sent)

print( '/' . join (words))

print( "=" *40)

result = pseg.cut(test_sent)

for in result:

   print(w.word,  "/" , w.flag,  ", " , end= ' ' )

print( "\n" "=" *40)

terms = jieba.cut( 'easy_install is great' )

print( '/' . join (terms))

terms = jieba.cut( 'python 的正则表达式是好用的' )

print( '/' . join (terms))

print( "=" *40)

# test frequency tune

testlist = [

( '今天天气不错' , ( '今天' '天气' )),

( '如果放到post中将出错。' , ( '中' '将' )),

( '我们中出了一个叛徒' , ( '中' '出' )),

]

for sent, seg  in testlist:

   print( '/' . join (jieba.cut(sent, HMM=False)))

   word =  '' . join (seg)

   print( '%s Before: %s, After: %s' % (word, jieba.get_FREQ(word), jieba.suggest_freq(seg, True)))

   print( '/' . join (jieba.cut(sent, HMM=False)))

   print( "-" *40

结果分析:

首先对一段话分词处理:

test_sent = (

"李小福和李铁军是创新办主任也是云计算方面的专家; 什么是八一双鹿\n"

"例如我输入一个带“韩玉赏鉴”的标题,在自定义词库中也增加了此词为N类\n"

"「台中」正確應該不會被切開。mac上可分出「石墨烯」;此時又可以分出來凱特琳了。"

)

words = jieba.cut(test_sent)

print( '/' . join (words))

李小福/和/李铁/军是/创新办/主任/也/是/云计算/方面/的/专家/;/ /什么/是/八一双鹿/

/例如/我/输入/一个/带/“/韩玉赏鉴/”/的/标题/,/在/自定义词/库中/也/增加/了/此/词为/N/类/

/「/台中/」/正確/應該/不會/被/切開/。/mac/上/可/分出/「/石墨/烯/」/;/此時/又/可以/分出/來/凱特琳/了/

此处“李小福“和“李铁军”都是人名,结果却分词“李小福”和“李铁”,而“军是”当做一个词处理,显然不对。我们可以将“李铁军”当着一个词加入自定义文本中:

import sys

sys.path.append( "../" )

import jieba

jieba.load_userdict( "userdict.txt" )

jieba.add_word( '李铁军' )

test_sent = (

"李小福和李铁军是创新办主任也是云计算方面的专家; 什么是八一双鹿\n"

"例如我输入一个带“韩玉赏鉴”的标题,在自定义词库中也增加了此词为N类\n"

"「台中」正確應該不會被切開。mac上可分出「石墨烯」;此時又可以分出來凱特琳了。"

)

words = jieba.cut(test_sent)

print( '/' . join (words))

李小福/和/李铁军/是/创新办/主任/也/是/云计算/方面/的/专家/;/ /什么/是/八一双鹿/

/例如/我/输入/一个/带/“/韩玉赏鉴/”/的/标题/,/在/自定义词/库中/也/增加/了/此/词为/N/类/

/「/台中/」/正確/應該/不會/被/切開/。/mac/上/可/分出/「/石墨/烯/」/;/此時/又/可以/分出/來/凱特琳/了/。

结果显然经过自定义分词有所好转。而石墨/烯分词错误。

李小福/和/李铁军/是/创新办/主任/也/是/云计算/方面/的/专家/;/ /什么/是/八一双鹿/

/例如/我/输入/一个/带/“/韩玉赏鉴/”/的/标题/,/在/自定义词/库中/也/增加/了/此/词为/N/类/

/「/台中/」/正確/應該/不會/被/切開/。/mac/上/可/分出/「/石墨烯/」/;/此時/又/可以/分出/來/凱特琳/了/。

(8) 词性标注

print( "=" *40)

result = pseg.cut(test_sent)

for in result:

   print(w.word,  "/" , w.flag,  ", " , end= ' ' )

print( "\n" "=" *40)

terms = jieba.cut( 'easy_install is great' )

print( '/' . join (terms))

terms = jieba.cut( 'python 的正则表达式是好用的' )

print( '/' . join (terms))

print( "=" *40)  

# 结果

========================================

李小福 / nr ,  和 / c ,  李铁军 / x ,  是 / v ,  创新办 / i ,  主任 / b ,  也 / d ,  是 / v ,  云计算 / x ,  方面 / n ,  的 / uj ,  专家 / n ,  ; / x ,    / x ,  什么 / r ,  是 / v ,  八一双鹿 / nz , 

/ x ,  例如 / v ,  我 / r ,  输入 / v ,  一个 / m ,  带 / v ,  “ / x ,  韩玉赏鉴 / nz ,  ” / x ,  的 / uj ,  标题 / n ,  , / x ,  在 / p ,  自定义词 / n ,  库中 / nrt ,  也 / d ,  增加 / v ,  了 / ul ,  此 / r ,  词 / n ,  为 / p ,  N / eng ,  类 / q , 

/ x ,  「 / x ,  台中 / s ,  」 / x ,  正確 / ad ,  應該 / v ,  不 / d ,  會 / v ,  被 / p ,  切開 / ad ,  。/ x ,  mac / eng ,  上 / f ,  可 / v ,  分出 / v ,  「 / x ,  石墨烯 / x ,  」 / x ,  ;/ x ,  此時 / c ,  又 / d ,  可以 / c ,  分出 / v ,  來 / zg ,  凱特琳 / x ,  了 / ul ,  。/ x ,

========================================

easy_install/ /is/ /great

python/ /的/正则表达式/是/好用/的

========================================

结果分析:李小福 / nr ,   李铁军 / x 都是名字,属于名词,而李铁军 / x显然词性不对,这是由于刚刚jieba.add_word('李铁军')时候,没有进行词性参数输入,我们看看jieba.add_word('李铁军')源码:

def add_word(self, word, freq=None, tag=None)
jieba.add_word('李铁军',tag='nr')修改后结果

运行结果:

========================================

李小福 / nr ,  和 / c ,  李铁军 / nr ,  是 / v ,  创新办 / i ,  主任 / b ,  也 / d ,  是 / v ,  云计算 / x ,  方面 / n ,  的 / uj ,  专家 / n ,  ; / x ,    / x ,  什么 / r ,  是 / v ,  八一双鹿 / nz , 

/ x ,  例如 / v ,  我 / r ,  输入 / v ,  一个 / m ,  带 / v ,  “ / x ,  韩玉赏鉴 / nz ,  ” / x ,  的 / uj ,  标题 / n ,  , / x ,  在 / p ,  自定义词 / n ,  库中 / nrt ,  也 / d ,  增加 / v ,  了 / ul ,  此 / r ,  词 / n ,  为 / p ,  N / eng ,  类 / q , 

/ x ,  「 / x ,  台中 / s ,  」 / x ,  正確 / ad ,  應該 / v ,  不 / d ,  會 / v ,  被 / p ,  切開 / ad ,  。/ x ,  mac / eng ,  上 / f ,  可 / v ,  分出 / v ,  「 / x ,  石墨烯 / x ,  」 / x ,  ;/ x ,  此時 / c ,  又 / d ,  可以 / c ,  分出 / v ,  來 / zg ,  凱特琳 / x ,  了 / ul ,  。/ x ,

========================================

(9)  自定义调整词典

# test frequency tune

testlist = [

( '今天天气不错' , ( '今天' '天气' )),

( '如果放到post中将出错。' , ( '中' '将' )),

( '我们中出了一个叛徒' , ( '一' '个' )),

]

for sent, seg  in testlist:

   print( '/' . join (jieba.cut(sent, HMM=False)))

   word =  '' . join (seg)

   print( '%s Before: %s, After: %s' % (word, jieba.get_FREQ(word), jieba.suggest_freq(seg, True)))

   print( '/' . join (jieba.cut(sent, HMM=False)))

   print( "-" *40)

结果:

========================================

今天天气/不错

今天天气 Before: 3, After: 0

今天天气/不错

----------------------------------------

如果/放到/post/中将/出错/。

中将 Before: 763, After: 494

如果/放到/post/中/将/出错/。

----------------------------------------

我们/中/出/了/一个/叛徒

一个 Before: 142747, After: 454

我们/中/出/了/一/个/叛徒

----------------------------------------

结果分析:列表中的每一条数据如('今天天气不错', ('今天', '天气')),其中('今天', '天气')调整分词颗粒精度的。如第三句正常分词:我们/中/出/了/一个/叛徒。我们假设某些情况下一和个分别分词,可以做如上处理。

  • 使用 add_word(word, freq=None, tag=None) 和 del_word(word) 可在程序中动态修改词典。

  • 使用   suggest_freq(segment, tune=True)  可调节单个词语的词频,使其能(或不能)被分出来。

注意:自动计算的词频在使用 HMM 新词发现功能时可能无效。

(10)  自定义调节词典解决歧义分词问题

>>> import jieba

>>> print( '/' . join (jieba.cut( '如果放到post中将出错。' , HMM=False)))

Building prefix dict  from the  default dictionary ...

Loading model  from cache C:\Users\cuitbnc\AppData\Local\Temp\jieba.cache

Loading model cost 1.069 seconds.

Prefix dict has been built succesfully.

如果/放到/post/中将/出错/。

>>> jieba.suggest_freq(( '中' '将' ), True)

494

>>> print( '/' . join (jieba.cut( '如果放到post中将出错。' , HMM=False)))

如果/放到/post/中/将/出错/。

>>> print( '/' . join (jieba.cut( '「台中」正确应该不会被切开' , HMM=False)))

「/台/中/」/正确/应该/不会/被/切开

>>> jieba.suggest_freq( '台中' , True)

69

>>> print( '/' . join (jieba.cut( '「台中」正确应该不会被切开' , HMM=False)))

「/台中/」/正确/应该/不会/被/切开

>>

总结:jieba.cut 方法接受三个输入参数: 需要分词的字符串;cut_all 参数用来控制是否采用全模式;HMM 参数用来控制是否使用 HMM 模型。jieba.cut 以及 jieba.cut_for_search 返回的结构都是一个可迭代的 generator,可以使用 for 循环来获得分词后得到的每一个词语(unicode)。

2

词性标注

jieba.posseg.POSTokenizer(tokenizer=None) 新建自定义分词器,tokenizer 参数可指定内部使用的jieba.Tokenizer 分词器。jieba.posseg.dt 为默认词性标注分词器。 标注句子分词后每个词的词性,采用和 ictclas 兼容的标记法。

用法示例

>>> import jieba.posseg  as pseg

>>> words = pseg.cut( "我爱北京天安门" )

>>>  for word, flag  in words:

...    print( '%s %s' % (word, flag))

...

我 r

爱 v

北京 ns

天安门 ns

3

并行分词

原理和用法

原理:将目标文本按行分隔后,把各行文本分配到多个 Python 进程并行分词,然后归并结果,从而获得分词速度的可观提升。 基于 python 自带的 multiprocessing 模块, 目前暂不支持 Windows。

用法:

jieba.enable_parallel(4) # 开启并行分词模式,参数为并行进程数

jieba.disable_parallel() # 关闭并行分词模式

例子:https://github.com/fxsjy/jieba/blob/master/test/parallel/test_file.py

import time

import sys

sys.path.append( "../" )

import jieba

jieba.initialize()

url = sys.argv[1]

content = open(url, "rb" ).read()

t1 = time.time()

words =  "/ " . join (jieba.cut(content))

t2 = time.time()

tm_cost = t2-t1

log_f = open( "1.log" , "wb" )

log_f.write(words.encode( 'utf-8' ))

log_f.close()

print( 'cost ' + str(tm_cost))

print( 'speed %s bytes/second' % (len(content)/tm_cost))

实验结果:在 4 核 3.4GHz Linux 机器上,对金庸全集进行精确分词,获得了 1MB/s 的速度,是单进程版的 3.3 倍。

注意:并行分词仅支持默认分词器 jieba.dt 和 jieba.posseg.dt。

4

参考文献

  1. 中文分词之HMM模型详解

  2. HMM相关文章

  3. 结巴分词GitHub源码

作者: 白宁超,工学硕士,现工作于四川省计算机研究院,研究方向是自然语言处理和机器学习。曾参与国家自然基金项目和四川省科技支撑计划等多个省级项目。著有《自然语言处理理论与实战》一书。

作者博客官网:

https://bainingchao.github.io/

作者公众号,欢迎关注:

结巴中文分词原理分析4

机器学习和自然语言处理

公众号ID:datathinks


以上所述就是小编给大家介绍的《结巴中文分词原理分析4》,希望对大家有所帮助,如果大家有任何疑问请给我留言,小编会及时回复大家的。在此也非常感谢大家对 码农网 的支持!

查看所有标签

猜你喜欢:

本站部分资源来源于网络,本站转载出于传递更多信息之目的,版权归原作者或者来源机构所有,如转载稿涉及版权问题,请联系我们

The Definitive Guide to MongoDB

The Definitive Guide to MongoDB

Peter Membrey、Wouter Thielen / Apress / 2010-08-26 / USD 44.99

MongoDB, a cross-platform NoSQL database, is the fastest-growing new database in the world. MongoDB provides a rich document orientated structure with dynamic queries that you’ll recognize from RDMBS ......一起来看看 《The Definitive Guide to MongoDB》 这本书的介绍吧!

图片转BASE64编码
图片转BASE64编码

在线图片转Base64编码工具

随机密码生成器
随机密码生成器

多种字符组合密码

HSV CMYK 转换工具
HSV CMYK 转换工具

HSV CMYK互换工具