jieba分词
上一篇jieba中文分词(一)分词与自定义字典已介绍了jieba中文分词安装,分词原理,分词方法,自定义字典,添加字典等多种常用分词方法。本篇将继续介绍jieba分词关键词提取、词性标注、及常见问题。
关键词提取
关键词提取,将文本中最能表达文本含义的词语抽取出来,有点类似于论文的关键词或者摘要。关键词抽取可以采取:
有监督学习:
文本作为输入,关键词作为标注,进行训练得到模型。此方法难点在于需要大量人工标注。
无监督学习:
先抽取出候选词,对每个候选词打分,取出前K个分值高的作为最后的关键词。jieba分词实现了基于TF-IDF和基于TextRank的关键词抽取算法。
基于 TF-IDF 算法的关键词抽取
基于TF-IDF的关键词抽取算法,目标是获取文本中词频高,也就是TF大的,且语料库其他文本中词频低的,也就是IDF大的。这样的词可以作为文本的标志,用来区分其他文本。
importjieba.analysejieba.analyse.extract_tags(sentence,topK=20,withWeight=False,allowPOS=())
sentence:为待提取的文本
topK:为返回几个 TF/IDF 权重最大的关键词,默认值为 20
withWeight:为是否一并返回关键词权重值,默认值为 False
allowPOS:仅包括指定词性的词,默认值为空,即不筛选
代码示例:
importjiebaimportjieba.analysetopK=5file_name='test.txt'"""test.txt西三旗硅谷先锋小区半地下室出租,便宜可合租硅谷工信处女干事每月经过下属科室都要亲口交代24口交换机等技术性器件的安装工作"""withopen(file_name,'rb')asf:content=f.read()tags=jieba.analyse.extract_tags(content,topK=topK)print(",".join(tags))print('*'*40)#关键词提取所使用逆向文件频率(IDF)文本语料库可以切换成自定义语料库的路径jieba.analyse.set_idf_path("../extra_dict/idf.txt.big");tags=jieba.analyse.extract_tags(content,topK=topK)print(",".join(tags))print('*'*40)#关键词提取所使用停止词文本语料库可以切换成自定义语料库的路径jieba.analyse.set_stop_words("../extra_dict/stop_words.txt")jieba.analyse.set_idf_path("../extra_dict/idf.txt.big");tags=jieba.analyse.extract_tags(content,topK=topK)print(",".join(tags))print('*'*40)#关键词一并返回关键词权重值示例withWeight=Truetags=jieba.analyse.extract_tags(content,topK=topK,withWeight=withWeight)fortagintags:print("tag:%s\t\tweight:%f"%(tag[0],tag[1]))
硅谷, 西三旗, 工信处, 女干事, 24
硅谷, 西三旗, 先锋, 小区, 合租
硅谷, 西三旗, 先锋, 小区, 合租
tag: 硅谷 weight: 1.039545
tag: 西三旗 weight: 0.519773
tag: 先锋 weight: 0.519773
tag: 小区 weight: 0.519773
tag: 合租 weight: 0.519773
基于 TextRank 算法的关键词抽取
jieba.analyse.textrank(sentence,topK=20,withWeight=False,allowPOS=('ns','n','vn','v'))
sentence:为待提取的文本
topK:为返回几个权重最大的关键词,默认值为 20
withWeight:为是否一并返回关键词权重值,默认值为 False
allowPOS:仅包括指定词性的词,默认过滤词性
算法论文:TextRank: Bringing Order into Texts[1]
一般步骤:
先将文本进行分词和词性标注,将特定词性的词(比如名词)作为节点添加到图中。
出现在一个窗口中的词语之间形成一条边,窗口大小可设置为2~10之间,默认为5,它表示一个窗口中有多少个词语。
对节点根据入度节点个数以及入度节点权重进行打分,入度节点越多,且入度节点权重大,则打分高。
然后根据打分进行降序排列,输出指定个数的关键词。
代码示例:
tags=jieba.analyse.textrank(content,topK=5,withWeight=True)fortagintags:print("tag:%s\t\tweight:%f"%(tag[0],tag[1]))
tag: 硅谷 weight: 1.000000
tag: 女干事 weight: 0.847395
tag: 技术性 weight: 0.800966
tag: 器件 weight: 0.794530
tag: 交换机 weight: 0.766318
词性标注
通过查询字典的方式获取识别词的词性,通过HMM隐马尔科夫模型来获取未登录词的词性,从而完成整个语句的词性标注。但可以看到查询字典的方式不能解决一词多词性的问题,也就是词性歧义问题。故精度上还是有所欠缺的。
标注句子分词后每个词的词性,词性标示兼容ICTCLAS 汉语词性标注集。
除了jieba默认分词模式,提供paddle模式下的词性标注功能。
代码示例:
importjiebaimportjieba.possegaspsegjieba.add_word('数据STUDIO')words=pseg.cut("我关注了微信公众号数据STUDIO")print('jieba默认模式')forword,flaginwords:print('%s%s'%(word,flag))print('+'*10)jieba.enable_paddle()#启动paddle模式。words=pseg.cut("我关注了微信公众号数据STUDIO",use_paddle=True)#paddle模式print('paddle模式')forword,flaginwords:print('%s%s'%(word,flag))print('+'*10)
jieba默认模式
我 r
关注 v
了 ul
微信 vn
公众 n
号 m
数据STUDIO x
Paddle enabled successfully......
paddle模式
我 r
关注 v
了 u
微信公众号数据STUDIO nz
默认模式词性和专名类别标签集合如下表。
(↔️滑动)
paddle模式词性和专名类别标签集合如下表,其中词性标签 24 个(小写字母),专名类别标签 4 个(大写字母)。
(↔️滑动)
并行分词
原理:将目标文本按行分隔后,把各行文本分配到多个 Python 进程并行分词,然后归并结果,从而获得分词速度的可观提升。
基于 python 自带的 multiprocessing 模块,目前暂不支持 Windows。
jieba.enable_parallel(4)
开启并行分词模式,参数为并行进程数
jieba.disable_parallel()
关闭并行分词模式
Tokenize:返回词语在原文的起止位置
注意,输入参数只接受 unicode
默认模式
importjiebaimportjieba.possegaspsegfromprettytableimportPrettyTablejieba.add_word('数据STUDIO')jieba.add_word('微信公众号')result=jieba.tokenize(u'我关注了微信公众号数据STUDIO')x=PrettyTable(["word","start","end"])x.align["word"]="l"#左对齐x.padding_width=2#列边和内容之间有两个空格(默认为一个空格)fortkinresult:x.add_row([tk[0],tk[1],tk[2]])print(x)
搜索模式
result=jieba.tokenize(u'我关注了微信公众号数据STUDIO',mode='search')x=PrettyTable(["word","start","end"])x.align["word"]="l"#左对齐x.padding_width=2#列边和内容之间有两个空格(默认为一个空格)fortkinresult:x.add_row([tk[0],tk[1],tk[2]])print(x)
延迟加载机制
jieba 采用延迟加载,import jieba
和jieba.Tokenizer()
不会立即触发词典的加载,一旦有必要才开始加载词典构建前缀字典。如果你想手工初始 jieba,也可以手动初始化。
importjiebajieba.initialize()#手动初始化(可选)
有了延迟加载机制后,你可以改变主词典的路径:
下载你所需要的词典,然后覆盖 jieba/dict.txt 即可;
或者用:
jieba.set_dictionary('data/dict.txt.big')
常见问题
“台中”总是被切成“台 中”?(以及类似情况)
P(台中) < P(台)×P(中),“台中”词频不够导致其成词概率较低
解决方法:强制调高词频
jieba.add_word('台中')
或者jieba.suggest_freq('台中', True)
“今天天气 不错”应该被切成“今天 天气 不错”?(以及类似情况)
解决方法:强制调低词频
jieba.suggest_freq(('今天', '天气'), True)
或者直接删除该词jieba.del_word('今天天气')
切出了词典中没有的词语,效果不理想?
解决方法:关闭新词发现
jieba.cut('丰田太省了', HMM=False)
jieba.cut('我们中出了一个叛徒', HMM=False)
更多问题[2]
参考资料
[1]
TextRank算法论文:http://web.eecs.umich.edu/~mihalcea/papers/mihalcea.emnlp04.pdf
[2]
更多问题:/fxsjy/jieba/issues?sort=updated&state=closed
-- 数据STUDIO --