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

jieba分词

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

关键词提取

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

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

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

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

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

import jieba.analyse
jieba.analyse.extract_tags(sentence, 
              topK=20, 
              withWeight=False, 
              allowPOS=())

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

代码示例:

import jieba
import jieba.analyse

topK = 5
file_name = 'test.txt'
"""
test.txt
西三旗硅谷先锋小区半地下室出租,便宜可合租硅谷
工信处女干事每月经过下属科室都要亲口交代24口交换机等技术性器件的安装工作
"""
with open(file_name, 'rb') as f:
    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 = True
tags = jieba.analyse.extract_tags(content, topK=topK, withWeight=withWeight)
for tag in tags:
    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 算法的关键词抽取
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) 
for tag in tags:
    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模式下的词性标注功能。

代码示例:
import jieba
import jieba.posseg as pseg
jieba.add_word('数据STUDIO')

words = pseg.cut("我关注了微信公众号数据STUDIO") 
print('jieba默认模式')
for word, flag in words:
    print('%s %s' % (word, flag))
print('+'*10)
jieba.enable_paddle() #启动paddle模式。
words = pseg.cut("我关注了微信公众号数据STUDIO",use_paddle=True) #paddle模式
print('paddle模式')
for word, flag in words:
    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

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

标签含义标签含义标签含义标签含义
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

默认模式
import jieba
import jieba.posseg as pseg
from prettytable import PrettyTable  
jieba.add_word('数据STUDIO')
jieba.add_word('微信公众号')
result = jieba.tokenize(u'我关注了微信公众号数据STUDIO')

x = PrettyTable(["word", "start", "end"])  
x.align["word"] = "l"# 左对齐
x.padding_width = 2 # 列边和内容之间有两个空格(默认为一个空格)
for tk in result:
    x.add_row([tk[0], tk[1], tk[2]])
print(x)

wordstartend
01
关注13
34
微信公众号49
数据STUDIO917

搜索模式
result = jieba.tokenize(u'我关注了微信公众号数据STUDIO', mode='search')
x = PrettyTable(["word", "start", "end"])  
x.align["word"] = "l"# 左对齐
x.padding_width = 2 # 列边和内容之间有两个空格(默认为一个空格)
for tk in result:
    x.add_row([tk[0], tk[1], tk[2]])
print(x)

wordstartend
01
关注13
34
公众68
微信公众号49
数据911
数据STUDIO917

延迟加载机制

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

import jieba
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.umich.edu/~mihalcea/papers/mihalcea.emnlp04.pdf

[2]

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

-- 数据STUDIO -- 

  • 3
    点赞
  • 25
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
中文分词词性标注关键词提取是NLP中常用的三个功能,可以通过开源NLP工具包如jieba、THULAC和NLTK等来实现,下面是具体步骤: 1.中文分词:将一段文本切分成一个个单独的词语。jieba是目前比较流行的Python中文分词工具包,使用方法非常简单。首先安装jieba,然后在代码中导入jieba模块,在文本输入时调用jieba模块分词函数即可完成中文分词操作。 例如,下面展示了在Python中使用jieba对一段中文文本进行分词的示例代码: ``` import jieba text = '我喜欢看电影' seg_list = jieba.cut(text, cut_all=False) # cut_all=False表示精确模式 print("分词结果:", "/".join(seg_list)) ``` 输出结果为:“分词结果:我/喜欢/看/电影” 2.词性标注:给分词的每个词语附加上其词性的标记,例如“名词”、“动词”、“形容词”等。THULAC是一个高效准确的中文词法分析工具,支持中文分词词性标注等操作,可以自动识别出中文文本中的人名、地名、各类数字、日期等,并正确定位他们在句子中的位置。使用方法与jieba相似,通过安装THULAC库,并调用相关函数即可完成中文分词词性标注。 例如,下面展示了在Python中使用THULAC对一段中文文本进行分词和词性标注的示例代码: ``` import thulac thu1 = thulac.thulac() #默认模式 text = '我喜欢看电影' seg_list = thu1.cut(text, text=True) #进行分词和词性标注 print("分词和词性标注结果:", seg_list) ``` 输出结果为:”分词和词性标注结果:[['我', 'r'], ['喜欢', 'v'], ['看', 'v'], ['电影', 'n']]“ 3.关键词提取:从一段文本中提取出最具代表性的关键词,常用于文本摘要、文本分类、信息检索等应用场景中。NLTK是Python较为常用的自然语言处理工具包之一,其提供了多种文本预处理功能,其中包括关键词提取功能。只需要按照以下步骤,即可使用NLTK实现关键词提取: - 安装NLTK:在Python命令行或终端中输入命令“pip install nltk”即可完成安装。 - 导入相关模块:使用以下代码导入nltk和nltk.corpus模块,以及相关的停用词库。 ```python import nltk from nltk.corpus import stopwords from nltk.tokenize import word_tokenize ``` - 加载和处理文本:首先需要载入一段文本,并进行分词处理和词性标注。为了减少干扰项,还需要进行一些过滤操作,例如过滤停用词、标点符号等。这里以一个简单的示例为例: ```python text = '我喜欢看电影,特别喜欢科幻电影。' stop_words = set(stopwords.words('chinese')) # 载入中文停用词库 word_tokens = word_tokenize(text) # 将句子进行分词处理 filtered_sentence = [w for w in word_tokens if not w in stop_words] # 过滤停用词 ``` - 提取关键词:使用NLTK提供的Collocations和FreqDist函数,实现对文本关键词提取。其中Collocations可以检查文本中的共现频率最高的词对或短语,而FreqDist可以对文本中出现的词语进行频率统计,找出出现频率最高的单词和短语。 ```python bigram_measures = nltk.collocations.BigramAssocMeasures() finder = nltk.collocations.BigramCollocationFinder.from_words(filtered_sentence) keywords = finder.nbest(bigram_measures.raw_freq, 3) # 提取出现频率前三的词语 ``` 输出结果为:[(‘喜欢’, ‘科幻’), (‘科幻’, ‘电影’), (‘看’, ‘电影’)] 综上所述,中文分词词性标注关键词提取是常见的NLP功能,在Python中可以通过开源工具库来实现,具体实现流程见上述示例代码。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值