干货:一个案例看懂“结巴”分词(Jieba),入行NLP必备

如需转载请联系华章科技

可以采用如下方式进行安装:

pipinstalljieba

Jieba分词结合了基于规则和基于统计这两类方法。

首先基于前缀词典进行词图扫描,前缀词典是指词典中的词按照前缀包含的顺序排列,例如词典中出现了“上”,之后以“上”开头的词都会出现在这一部分,例如“上海”,进而会出现“上海市”,从而形成一种层级包含结构。

如果将词看作节点,词和词之间的分词符看作边,那么一种分词方案则对应着从第一个字到最后一个字的一条分词路径。

因此,基于前缀词典可以快速构建包含全部可能分词结果的有向无环图,这个图中包含多条分词路径,有向是指全部的路径都始于第一个字、止于最后一个字,无环是指节点之间不构成闭环。

01Jieba的三种分词模式

Jieba提供了三种分词模式:

精确模式:试图将句子最精确地切开,适合文本分析。

全模式:把句子中所有可以成词的词语都扫描出来,速度非常快,但是不能解决歧义。

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

下面是使用这三种模式的对比。

importjiebasent='中文分词是文本处理不可或缺的一步!'seg_list=(sent,cut_all=True)print('全模式:','/'.join(seg_list))seg_list=(sent,cut_all=False)print('精确模式:','/'.join(seg_list))seg_list=(sent)print('默认精确模式:','/'.join(seg_list))seg_list=_for_search(sent)print('搜索引擎模式','/'.join(seg_list))

运行结果如下:

全模式:

中文/分词/是/文本/文本处理/本处/处理/不可/不可或缺/或缺/的/一步//

精确模式:

中文/分词/是/文本处理/不可或缺/的/一步/!

默认精确模式:

中文/分词/是/文本处理/不可或缺/的/一步/!

搜索引擎模式:

中文/分词/是/文本/本处/处理/文本处理/不可/或缺/不可或缺/的/一步/!

可以看到,全模式和搜索引擎模式下,Jieba将会把分词的所有可能都打印出来。一般直接使用精确模式即可,但是在某些模糊匹配场景下,使用全模式或搜索引擎模式更适合。

接下来将结合具体案例,讲解Jieba分词的具体用法。

02实战之高频词提取

高频词一般是指文档中出现频率较高且非无用的词语,其一定程度上代表了文档的焦点所在。针对单篇文档,可以作为一种关键词来看。对于如新闻这样的多篇文档,可以将其作为热词,发现舆论焦点。

高频词提取其实就是自然语言处理中的TF(TermFrequency)策略。其主要有以下干扰项:

标点符号:一般标点符号无任何价值,需要去除。

停用词:诸如“的”“是”“了”等常用词无任何意义,也需要剔除。

下面采用Jieba分词,针对搜狗实验室的新闻数据,进行高频词的提取。

数据见:

该数据本质上是一个分类语料,这里我们只挑选其中一个类别,统计该类的高频词。

首先,进行数据的读取:

defget_content(path):withopen(path,'r',encoding='gbk',errors='ignore')asf:content=''forlinf:l=()content+=lreturncontent

该函数用于加载指定路径下的数据。

定义高频词统计的函数,其输入是一个词的数组:

defget_TF(words,topK=10):tf_dic={}forwinwords:tf_dic[w]=tf_(w,0)+1returnsorted(tf_(),key=lambdax:x[1],reverse=True)[:topK]

最后,主函数如下,这里仅列举了求出高频词的前10个:

defmain():importglobimportrandomimportjiebafiles=('./data/news/C000013/*.txt')corpus=[get_content(x)forxinfiles]sample_inx=(0,len(corpus))split_words=list((corpus[sample_inx]))print('样本之一:'+corpus[sample_inx])print('样本分词效果:'+'/'.join(split_words))print('样本的topK(10)词:'+str(get_TF(split_words)))

运行主函数,结果如下:

样本之一:

中国卫生部官员24日说,截至2005年底,中国各地报告的尘肺病病人累计已超过60万例,职业病整体防治形势严峻。卫生部副部长陈啸宏在当日举行的“国家职业卫生示范企业授牌暨企业职业卫生交流大会”上说,中国各类急性职业中毒事故每年发生200多起,上千人中毒,直接经济损失达上百亿元。职业病病人总量大、发病率较高、经济损失大、影响恶劣。卫生部24日公布,2005年卫生部共收到全国30个省、自治区、直辖市(不包括西藏、港、澳、台)各类职业病报告12212例,其中尘肺病病例报告9173例,占75.11%。陈啸宏说,矽肺和煤工尘肺是中国最主要的尘肺病,且尘肺病发病工龄在缩短。去年报告的尘肺病病人中最短接尘时间不足三个月,平均发病年龄40.9岁,最小发病年龄20岁。陈啸宏表示,政府部门执法不严、监督不力,企业生产水平不高、技术设备落后等是职业卫生问题严重的原因。“但更重要的原因是有些企业法制观念淡薄,社会责任严重缺位,缺乏维护职工健康的强烈的意识,职工的合法权益不能得到有效的保障。”他说。为提高企业对职业卫生工作的重视,卫生部、国家安全生产监督管理总局和中华全国总工会24日在京评选出56家国家级职业卫生工作示范企业,希望这些企业为社会推广职业病防治经验,促使其他企业作好职业卫生工作,保护劳动者健康。

样本分词效果:

中国卫生部/官员/24/日/说/,/截至/2005/年底/,/中国/各地/报告/的/尘肺病/病人/累计/已/超过/60/万例/,/职业病/整体/防治/形势严峻/。/卫生部/副/部长/陈啸宏/在/当日/举行/的/“/国家/职业/卫生/示范/企业/授牌/暨/企业/职业/卫生/交流/大会/”/上/说/,/中国/各类/急性/职业/中毒/事故/每年/发生/200/多起/,/上千人/中毒/,/直接/经济损失/达上/百亿元/。/职业病/病人/总量/大/、/发病率/较/高/、/经济损失/大/、/影响/恶劣/。/卫生部/24/日/公布/,/2005/年/卫生部/共/收到/全国/30/个省/、/自治区/、/直辖市/(/不/包括/西藏/、/港/、/澳/、/台/)/各类/职业病/报告/12212/例/,/其中/尘肺病/病例/报告/9173/例/,/占/75/./11/%/。/陈啸宏/说/,/矽肺/和/煤工/尘肺/是/中国/最/主要/的/尘肺病/,/且/尘肺病/发病/工龄/在/缩短/。/去年/报告/的/尘肺病/病人/中/最/短/接尘/时间/不足/三个/月/,/平均/发病/年龄/40/./9/岁/,/最小/发病/年龄/20/岁/。/陈啸宏/表示/,/政府部门/执法不严/、/监督/不力/,/企业/生产/水平/不高/、/技术设备/落后/等/是/职业/卫生/问题/严重/的/原因/。/“/但/更/重要/的/原因/是/有些/企业/法制观念/淡薄/,/社会/责任/严重/缺位/,/缺乏/维护/职工/健康/的/强烈/的/意识/,/职工/的/合法权益/不能/得到/有效/的/保障/。/”/他/说/。/为/提高/企业/对/职业/卫生/工作/的/重视/,/卫生部/、/国家/安全/生产/监督管理/总局/和/中华全国总工会/24/日/在/京/评选/出/56/家/国家级/职业/卫生/工作/示范/企业/,/希望/这些/企业/为/社会/推广/职业病/防治/经验/,/促使/其他/企业/作好/职业/卫生/工作/,/保护/劳动者/健康/。

样本的topK(10)词:

[(',',22),('、',11),('的',11),('。',10),('企业',8),('职业',7),('卫生',6),('尘肺病',5),('说',4),('报告',4)]

通过上面的结果,我们可以发现,诸如“的”“,”“。”“说”等词占据着很高的位置,而这类词对把控文章焦点并无太大意义。我们需要的是类似“尘肺病”这种能够简要概括重点的词汇。常用的办法,是自定义一个停用词典,当遇到这些词时,过滤掉即可。

因此,我们可以自定义词典,然后按照如下方式来进行优化。

首先,整理常用的停用词(包括标点符号),按照每行一个写入到一个文件中(data目录下的stop_)。然后定义如下函数,用于过滤停用词:

defstop_words(path):withopen(path)asf:return[()forlinf]

接下来修改main函数中第11行分词的部分,改为:

split_words=[(corpus[sample_inx])ifxnotinstop_words('./data/stop_')]

高频词前10位结果如下:

样本的topK(10)词:

[('企业',8),('职业',7),('卫生',6),('尘肺病',5),('卫生部',4),('报告',4),('职业病',4),('中国',3),('陈啸宏',3),('工作',3)]

对比之前的结果,会发现效果要想有所提升,必须去除了无用标点符号以及“的”等干扰词。注意,本节实战中所用的停用词典为笔者整理的通用词典,一般实践过程中,需要根据自己的任务,定期更新维护。

上面演示了通过Jieba按照常规切词来提取高频词汇的过程。事实上,常用的中文分词器在分词效果上差距并不是特别大,但是在特定场景下常常表现的并不是那么尽如人意。

通常这种情况下,我们需要定制自己的领域词典,用以提升分词的效果。Jieba分词就提供了这样的功能,用户可以加载自定义词典:

_userdict('./data/user_')

Jieba要求的用户词典格式一般如下:

朝三暮四3i大数据5汤姆nz公主坟

每一行为三个部分:词语、词频(可省略)、词性(可省略),用空格隔开,顺序不可颠倒。该词典文件需为utf8编码。

在提取高频词时,通过更合理的自定义词典加载,能够获得更佳的效果。当然这里仅仅演示了一篇文档的高频词计算,多篇文档的高频词提取也可按照该思路进行整体统计计算。

本文摘编自《Python自然语言处理实战:核心技术与算法》,经出版方授权发布。

延伸阅读《Python自然语言处理实战》

推荐语:阿里巴巴、前明略数据和七牛云的高级专家和科学家撰写,零基础掌握NLP的核心技术、方法论和经典算法。

版权声明:本站所有作品(图文、音视频)均由用户自行上传分享,仅供网友学习交流,不声明或保证其内容的正确性,如发现本站有涉嫌抄袭侵权/违法违规的内容。请举报,一经查实,本站将立刻删除。

相关推荐