分享

Jieba中文分词 (二) ——词性标注与关键词提取

 三浦春花 2021-12-21

jieba分词

上一篇jieba中文分词(一)分词与自定义字典已介绍了jieba中文分词安装,分词原理,分词方法,自定义字典,添加字典等多种常用分词方法。本篇将继续介绍jieba分词关键词提取、词性标注、及常见问题。

关键词提取

关键词提取,将文本中最能表达文本含义的词语抽取出来,有点类似于论文的关键词或者摘要。关键词抽取可以采取:

  • 有监督学习:
    文本作为输入,关键词作为标注,进行训练得到模型。此方法难点在于需要大量人工标注。

  • 无监督学习:
    先抽取出候选词,对每个候选词打分,取出前K个分值高的作为最后的关键词。jieba分词实现了基于TF-IDF和基于TextRank的关键词抽取算法。

基于 TF-IDF 算法的关键词抽取

基于TF-IDF的关键词抽取算法,目标是获取文本中词频高,也就是TF大的,且语料库其他文本中词频低的,也就是IDF大的。这样的词可以作为文本的标志,用来区分其他文本。

  1. import jieba.analyse
  2. jieba.analyse.extract_tags(sentence, 
  3.               topK=20
  4.               withWeight=False, 
  5.               allowPOS=())

sentence: 为待提取的文本
topK: 为返回几个 TF/IDF 权重最大的关键词,默认值为 20
withWeight: 为是否一并返回关键词权重值,默认值为 False
allowPOS: 仅包括指定词性的词,默认值为空,即不筛选

代码示例:

  1. import jieba
  2. import jieba.analyse
  3. topK = 5
  4. file_name = 'test.txt'
  5. '''
  6. test.txt
  7. 西三旗硅谷先锋小区半地下室出租,便宜可合租硅谷
  8. 工信处女干事每月经过下属科室都要亲口交代24口交换机等技术性器件的安装工作
  9. '''
  10. with open(file_name, 'rb') as f:
  11.     content = f.read()
  12. tags = jieba.analyse.extract_tags(content, topK=topK)
  13. print(', '.join(tags))
  14. print('*'*40)
  15. # 关键词提取所使用逆向文件频率(IDF)文本语料库可以切换成自定义语料库的路径
  16. jieba.analyse.set_idf_path('../extra_dict/idf.txt.big');
  17. tags = jieba.analyse.extract_tags(content, topK=topK)
  18. print(', '.join(tags))
  19. print('*'*40)
  20. # 关键词提取所使用停止词文本语料库可以切换成自定义语料库的路径
  21. jieba.analyse.set_stop_words('../extra_dict/stop_words.txt')
  22. jieba.analyse.set_idf_path('../extra_dict/idf.txt.big');
  23. tags = jieba.analyse.extract_tags(content, topK=topK)
  24. print(', '.join(tags))
  25. print('*'*40)
  26. # 关键词一并返回关键词权重值示例
  27. withWeight = True
  28. tags = jieba.analyse.extract_tags(content, topK=topK, withWeight=withWeight)
  29. for tag in tags:
  30.     print('tag: %s\t\t weight: %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 算法的关键词抽取

  1. jieba.analyse.textrank(sentence, 
  2.         topK=20
  3.         withWeight=False, 
  4.         allowPOS=('ns''n''vn''v')) 

sentence: 为待提取的文本
topK: 为返回几个权重最大的关键词,默认值为 20
withWeight: 为是否一并返回关键词权重值,默认值为 False
allowPOS: 仅包括指定词性的词,默认过滤词性

算法论文:TextRank: Bringing Order into Texts[1]

一般步骤:

  • 先将文本进行分词和词性标注,将特定词性的词(比如名词)作为节点添加到图中。

  • 出现在一个窗口中的词语之间形成一条边,窗口大小可设置为2~10之间,默认为5,它表示一个窗口中有多少个词语。

  • 对节点根据入度节点个数以及入度节点权重进行打分,入度节点越多,且入度节点权重大,则打分高。

  • 然后根据打分进行降序排列,输出指定个数的关键词。

代码示例:

  1. tags = jieba.analyse.textrank(content, 
  2.              topK=5
  3.              withWeight=True) 
  4. for tag in tags:
  5.     print('tag: %s\t\t weight: %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模式下的词性标注功能。

代码示例:

  1. import jieba
  2. import jieba.posseg as pseg
  3. jieba.add_word('数据STUDIO')
  4. words = pseg.cut('我关注了微信公众号数据STUDIO'
  5. print('jieba默认模式')
  6. for word, flag in words:
  7.     print('%s %s' % (word, flag))
  8. print(' '*10)
  9. jieba.enable_paddle() #启动paddle模式。
  10. words = pseg.cut('我关注了微信公众号数据STUDIO',use_paddle=True) #paddle模式
  11. print('paddle模式')
  12. for word, flag in words:
  13.     print('%s %s' % (word, flag))
  14. print(' '*10)

jieba默认模式
我 r
关注 v
了 ul
微信 vn
公众 n
号 m
数据STUDIO x

Paddle enabled successfully......
paddle模式
我 r
关注 v
了 u
微信公众号数据STUDIO nz

默认模式词性和专名类别标签集合如下表。
(↔️滑动)

标签含义标签含义标签含义标签含义
n名词f方位词al形容词性惯用语m数词
nr人名v动词b区别词mq数量词
nr1汉语姓氏vd副动词bl区别词性惯用语q量词
nr2汉语名字vn名动词z状态词qv动量词
nrj日语人名vshi动词“是”r代词qt时量词
nrf音译人名vyou动词“有”rr人称代词d副词
ns地名vf趋向动词rz指示代词p介词
nsf音译地名vx形式动词rzt时间指示代词pba介词“把”
nt机构团体名vi不及物动词(内动词)rzs处所指示代词pbei介词“被”
nz其它专名vl动词性惯用语rzv谓词性指示代词c连词
nl名词性惯用语vg动词性语素ry疑问代词cc并列连词
ng名词性语素a形容词ryt时间疑问代词cc并列连词
t时间词ad副形词rys处所疑问代词

tg时间词性语素an名形词ryv谓词性疑问代词

s处所词ag形容词性语素rg代词性语素

paddle模式词性和专名类别标签集合如下表,其中词性标签 24 个(小写字母),专名类别标签 4 个(大写字母)。
(↔️滑动)

标签含义标签含义标签含义标签含义
n普通名词f方位名词s处所名词t时间
nr人名ns地名nt机构名nw作品名
nz其他专名v普通动词vd动副词vn名动词
a形容词ad副形词an名形词d副词
m数量词q量词r代词p介词
c连词u助词xc其他虚词w标点符号
PER人名LOC地名ORG机构名TIME时间

并行分词

原理:将目标文本按行分隔后,把各行文本分配到多个 Python 进程并行分词,然后归并结果,从而获得分词速度的可观提升。

基于 python 自带的 multiprocessing 模块,目前暂不支持 Windows。

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

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

Tokenize:返回词语在原文的起止位置

注意,输入参数只接受 unicode

默认模式

  1. import jieba
  2. import jieba.posseg as pseg
  3. from prettytable import PrettyTable  
  4. jieba.add_word('数据STUDIO')
  5. jieba.add_word('微信公众号')
  6. result = jieba.tokenize(u'我关注了微信公众号数据STUDIO')
  7. x = PrettyTable(['word''start''end'])  
  8. x.align['word'] = 'l'# 左对齐
  9. x.padding_width = 2 # 列边和内容之间有两个空格(默认为一个空格)
  10. for tk in result:
  11.     x.add_row([tk[0], tk[1], tk[2]])
  12. print(x)
wordstartend
01
关注13
34
微信公众号49
数据STUDIO917

搜索模式

  1. result = jieba.tokenize(u'我关注了微信公众号数据STUDIO', mode='search')
  2. x = PrettyTable(['word''start''end'])  
  3. x.align['word'] = 'l'# 左对齐
  4. x.padding_width = 2 # 列边和内容之间有两个空格(默认为一个空格)
  5. for tk in result:
  6.     x.add_row([tk[0], tk[1], tk[2]])
  7. print(x)
wordstartend
01
关注13
34
公众68
微信公众号49
数据911
数据STUDIO917

延迟加载机制

jieba 采用延迟加载,import jiebajieba.Tokenizer() 不会立即触发词典的加载,一旦有必要才开始加载词典构建前缀字典。如果你想手工初始 jieba,也可以手动初始化。

  1. import jieba
  2. jieba.initialize()  # 手动初始化(可选)

有了延迟加载机制后,你可以改变主词典的路径:

  • 下载你所需要的词典,然后覆盖 jieba/dict.txt 即可;

  • 或者用:

jieba.set_dictionary('data/dict.txt.big')

常见问题

  1. “台中”总是被切成“台 中”?(以及类似情况)

P(台中) < P(台)×P(中),“台中”词频不够导致其成词概率较低

解决方法:强制调高词频

jieba.add_word('台中') 或者 jieba.suggest_freq('台中', True)

  1. “今天天气 不错”应该被切成“今天 天气 不错”?(以及类似情况)

解决方法:强制调低词频

jieba.suggest_freq(('今天', '天气'), True)

或者直接删除该词 jieba.del_word('今天天气')

  1. 切出了词典中没有的词语,效果不理想?

解决方法:关闭新词发现

jieba.cut('丰田太省了', HMM=False)jieba.cut('我们中出了一个叛徒', HMM=False)

更多问题[2]

参考资料

[1]

TextRank算法论文: http://web.eecs./~mihalcea/papers/mihalcea.emnlp04.pdf

[2]

更多问题: https://github.com/fxsjy/jieba/issues?sort=updated&state=closed

-- 数据STUDIO -- 

    本站是提供个人知识管理的网络存储空间,所有内容均由用户发布,不代表本站观点。请注意甄别内容中的联系方式、诱导购买等信息,谨防诈骗。如发现有害或侵权内容,请点击一键举报。
    转藏 分享 献花(0

    0条评论

    发表

    请遵守用户 评论公约

    类似文章 更多