《自然语言处理》- Jieba分词器的使用

《自然语言处理》- Jieba分词器的使用

Scroll Down

1. jieba 中文分词处理

import jieba

text = "大部分情况下,词汇是我们对句子和文章理解的基础,因此需要一个工具去把完整的文本中分解成粒度更细的词。"

cut_result = jieba.cut(text, cut_all=True)  # 全模式
print(cut_result)
print("\n全模式 : " + "/ ".join(cut_result))

cut_result = jieba.cut(text, cut_all=False)  # 精确模式
print("\n精确模式 : " + "/ ".join(cut_result))

# 搜索引擎模式
seg_result = jieba.cut_for_search(text)
print("\n搜索引擎模式 : " + "/ ".join(seg_result))
<generator object Tokenizer.cut at 0x000001527DC81B48>

全模式 : 大部/ 大部分/ 部分/ 情况/ 下/ ,/ 词汇/ 是/ 我们/ 对/ 句子/ 和文/ 文章/ 理解/ 的/ 基础/ ,/ 因此/ 需要/ 一个/ 工具/ 去/ 把/ 完整/ 的/ 文本/ 中分/ 分解/ 分解成/ 粒度/ 更/ 细/ 的/ 词/ 。

精确模式 : 大部分/ 情况/ 下/ ,/ 词汇/ 是/ 我们/ 对/ 句子/ 和/ 文章/ 理解/ 的/ 基础/ ,/ 因此/ 需要/ 一个/ 工具/ 去/ 把/ 完整/ 的/ 文本/ 中/ 分解成/ 粒度/ 更细/ 的/ 词/ 。

搜索引擎模式 : 大部/ 部分/ 大部分/ 情况/ 下/ ,/ 词汇/ 是/ 我们/ 对/ 句子/ 和/ 文章/ 理解/ 的/ 基础/ ,/ 因此/ 需要/ 一个/ 工具/ 去/ 把/ 完整/ 的/ 文本/ 中/ 分解/ 分解成/ 粒度/ 更细/ 的/ 词/ 。
  • jieba.lcut 以及 jieba.lcut_for_search 直接返回 list
    1. 作用和 cut 与 cut_for_search 没有区别, 只是返回值不同
str = "大家好, 我很喜欢自然语言处理"
lcut_result = jieba.lcut(str, cut_all=True)  # 全模式
print(" 全模式 : ", lcut_result)

seg_lcut_result = jieba.lcut_for_search(str)
print(" 搜索模式 : ", seg_lcut_result)
 全模式 :  ['大家', '好', ',', ' ', '', '我', '很', '喜欢', '自然', '自然语言', '语言', '处理']
 搜索模式 :  ['大家', '好', ',', ' ', '我', '很', '喜欢', '自然', '语言', '自然语言', '处理']

1.2 用户自定义词典

  • 作用 : 很多时候我们需要针对自己的场景进行分词,会有一些领域内的专有词汇。
  • 操作:
    1. 可以用jieba.load_userdict(file_name)加载用户字典
    2. 少量的词汇可以自己用下面方法手动添加:
    3. 用 add_word(word, freq=None, tag=None) 和 del_word(word) 在程序中动态修改词典
    4. 用 suggest_freq(segment, tune=True) 可调节单个词语的词频,使其能(或不能)被分出来。
print("调节词频前 : ", '/ '.join(jieba.cut("如果放到旧字典中将出错", HMM=False)))

# 调节 '中', '将' 两个词的频率, 保证这两个词可以分出来
print(jieba.suggest_freq(segment=('中', '将'), tune=True))

print("调节词频后 : ", '/ '.join(jieba.cut("如果放到旧字典中将出错", HMM=False)))
调节词频前 :  如果/ 放到/ 旧/ 字典/ 中将/ 出错
494
调节词频后 :  如果/ 放到/ 旧/ 字典/ 中/ 将/ 出错

1.3 关键词提取

  • 基于 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.analyse as analyse

sentence = open('./data/NBA.txt', encoding='utf-8').read()  # 读取文本

extract_res = analyse.extract_tags(sentence, topK=20, withWeight=False, allowPOS=())  # 返回值为 List
print(" ".join(extract_res))
韦少 杜兰特 全明星 全明星赛 MVP 威少 正赛 科尔 投篮 勇士 球员 斯布鲁克 更衣柜 NBA 三连庄 张卫平 西部 指导 雷霆 明星队
  • 使用 TF-IDF 抽取西游记关键词
#  errors='ignore' 忽略读取错误的部分
words = open(u'./data/西游记.txt', errors='ignore').read()

extract_word = analyse.extract_tags(words, topK=10, withWeight=True, allowPOS=())
extract_word
[('行者', 0.149712969050074),
 ('八戒', 0.0684507752483343),
 ('师父', 0.06131446245667119),
 ('三藏', 0.05297033399354041),
 ('唐僧', 0.034778995818127),
 ('大圣', 0.0324254151715385),
 ('沙僧', 0.03158386691903323),
 ('妖精', 0.02770001861295469),
 ('菩萨', 0.02576378770669382),
 ('和尚', 0.024268051645726228)]






[('行者', 0.149712969050074),
 ('八戒', 0.0684507752483343),
 ('师父', 0.06131446245667119),
 ('三藏', 0.05297033399354041),
 ('唐僧', 0.034778995818127),
 ('大圣', 0.0324254151715385),
 ('沙僧', 0.03158386691903323),
 ('妖精', 0.02770001861295469),
 ('菩萨', 0.02576378770669382),
 ('和尚', 0.024268051645726228)]

1.4 关于TF-IDF 算法的关键词抽取补充

  • TF-IDF 算法介绍 :

    1. TF : 一个单词在句子中出现的频率, 计算方法 : 某个单词在文章中出现的次数 / 文章的总单词数
    2. IDF : 逆文档频率, log(语料库的文档数/包含该词的文档数 + 1)
    3. TF-IDF = 词频(TF) * 逆文档频率(IDF)
  • 关键词提取所使用逆向文件频率(IDF)文本语料库可以切换成自定义语料库的路径

  • 用法: jieba.analyse.set_idf_path(file_name) # file_name为自定义语料库的路径

    1. 自定义语料库示例见 这里
    2. 用法示例见 这里
  • 关键词提取所使用停止词(Stop Words)文本语料库可以切换成自定义语料库的路径

    1. 用法: jieba.analyse.set_stop_words(file_name) # file_name为自定义语料库的路径
    2. 自定义语料库示例见 这里
    3. 用法示例见 这里
  • 关键词一并返回关键词权重值示例

  • 用法示例见 这里

1.5 基于 TextRank 算法的关键词抽取

  • jieba.analyse.textrank(sentence, topK=20, withWeight=False, allowPOS=('ns', 'n', 'vn', 'v')) 直接使用,接口相同,注意默认过滤词性。
  • jieba.analyse.TextRank() 新建自定义 TextRank 实例
  • 算法论文: TextRank: Bringing Order into Texts
  • 基本思想:
    1. 将待抽取关键词的文本进行分词
    2. 以固定窗口大小(默认为5,通过span属性调整),词之间的共现关系,构建图
    3. 计算图中节点的PageRank,注意是无向带权图
import jieba.analyse as analyse

lines = open('./data/NBA.txt', encoding='utf-8').read()

# 使用TextRank算法对关键词抽取
# allowPOS 仅包括指定词性的词,默认值为空,即不筛选
word_tr = analyse.textrank(sentence=lines, topK=10, withWeight=False, allowPOS=('ns', 'n', 'vn', 'v'))
print(' '.join(word_tr))

res = analyse.textrank(sentence=lines, topK=10, withWeight=False, allowPOS=('ns', 'n'))
print(' '.join(res))
全明星赛 勇士 正赛 指导 对方 投篮 球员 没有 出现 时间
勇士 正赛 全明星赛 指导 投篮 玩命 时间 对方 现场 结果
words_my = open('./data/西游记.txt', errors='ignore').read()

print(analyse.textrank(words_my, topK=10, withWeight=False, allowPOS=('ns', 'n', 'vn', 'v')))
print(analyse.textrank(words_my, topK=10, withWeight=True, allowPOS=('ns', 'n')))
['行者', '师父', '八戒', '三藏', '大圣', '不知', '菩萨', '妖精', '只见', '长老']
['行者', '师父', '八戒', '三藏', '大圣', '菩萨', '妖精', '国王', '长老', '徒弟']
['行者', '师父', '八戒', '三藏', '大圣', '不知', '菩萨', '妖精', '只见', '长老']
[('行者', 1.0), ('师父', 0.4068394703674021), ('八戒', 0.3983011869139073), ('三藏', 0.3907378862237123), ('大圣', 0.24021798730344252), ('菩萨', 0.20177693035598557), ('妖精', 0.18936895377629598), ('国王', 0.15925294307325125), ('长老', 0.15196050918328696), ('徒弟', 0.10709412067136634)]

1.6 词性标注

  • jieba.posseg.POSTokenizer(tokenizer=None)
    1. 新建自定义分词器,tokenizer 参数可指定内部使用的 jieba.Tokenizer 分词器。jieba.posseg.dt 为默认词性标注分词器。
    2. 标注句子分词后每个词的词性,采用和 ictclas 兼容的标记法。
    3. 具体的词性对照表参见 : 汉语词性标注集
  • 常见词性介绍
    1. a: 形容词 j: 简称
    2. b: 区别词 k: 后接成分
    3. c: 连词 m: 数词
    4. d: 副词 n: 普通名词
    5. e: 叹词 nh: 人名
    6. g: 语素字 ni: 机构名
    7. h: 前接成分 nl: 处所名词
    8. i: 习用语 ns: 地名
    9. nt: 时间词 nz: 其他专名
    10. o: 拟声词 p: 介词
    11. q: 量词 r: 代词
    12. u: 助词 v: 动词
    13. wp: 标点符号 ws: 字符串
    14. x: 非语素字
import jieba.posseg as posseg

cut_result = posseg.cut('我很喜欢自然语言处理')  # 返回类型为 : generator

for word, flag in cut_result:
    print(" %s , %s" % (word, flag))
Building prefix dict from the default dictionary ...
Loading model from cache C:\Users\WANGTI~1\AppData\Local\Temp\jieba.cache
Loading model cost 0.628 seconds.
Prefix dict has been built successfully.


 我 , r
 很 , d
 喜欢 , v
 自然语言 , l
 处理 , v

1.7 并行分词

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

  • 用法:

    1. jieba.enable_parallel(4) # 开启并行分词模式,参数为并行进程数
    2. jieba.disable_parallel() # 关闭并行分词模式
  • 注意: 并行分词仅支持默认分词器 jieba.dt 和 jieba.posseg.dt。

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

  • 注意,输入参数只接受 unicode
  • 使用是 需要在字符串前加 u => u'我爱自然语言处理'
  • 返回值是迭代器类型, 遍历每个 item得到一个数组, item[0] : 单词, item[1] : 开始位置, item[2] : 结束位置
print("默认模式的 tokenize")

result_genera = jieba.tokenize(u'自然语言处理在很多领域都有应用') # 返回值类型的是一个迭代器(generator)
for tk in result_genera:
    print("%s\t\t start: %d \t\t end: %d" % (tk[0], tk[1], tk[2]))

print("=" * 40)

result_genera_search = jieba.tokenize(u'自然语言处理在很多领域都有应用', mode='search') # 返回值类型的是一个迭代器(generator)
for tk in result_genera_search:
    print("%s\t\t start: %d \t\t end: %d" % (tk[0], tk[1], tk[2]))
默认模式的 tokenize
自然语言		 start: 0 		 end: 4
处理		 start: 4 		 end: 6
在		 start: 6 		 end: 7
很多		 start: 7 		 end: 9
领域		 start: 9 		 end: 11
都		 start: 11 		 end: 12
有		 start: 12 		 end: 13
应用		 start: 13 		 end: 15
========================================
自然		 start: 0 		 end: 2
语言		 start: 2 		 end: 4
自然语言		 start: 0 		 end: 4
处理		 start: 4 		 end: 6
在		 start: 6 		 end: 7
很多		 start: 7 		 end: 9
领域		 start: 9 		 end: 11
都		 start: 11 		 end: 12
有		 start: 12 		 end: 13
应用		 start: 13 		 end: 15

1.9 命令行分词

  • 使用示例:python -m jieba news.txt > cut_result.txt

  • 命令行选项(翻译):

    1. 使用: python -m jieba [options] filename
  • 结巴命令行界面。

  1. 固定参数:
  • filename 输入文件
  1. 可选参数:
    -h, --help 显示此帮助信息并退出
    -d [DELIM], --delimiter [DELIM]
    使用 DELIM 分隔词语,而不是用默认的' / '。
    若不指定 DELIM,则使用一个空格分隔。
    -p [DELIM], --pos [DELIM]
    启用词性标注;如果指定 DELIM,词语和词性之间
    用它分隔,否则用 _ 分隔
    -D DICT, --dict DICT 使用 DICT 代替默认词典
    -u USER_DICT, --user-dict USER_DICT
    使用 USER_DICT 作为附加词典,与默认词典或自定义词典配合使用
    -a, --cut-all 全模式分词(不支持词性标注)
    -n, --no-hmm 不使用隐含马尔可夫模型
    -q, --quiet 不输出载入信息到 STDERR
    -V, --version 显示版本信息并退出
  • 如果没有指定文件名,则使用标准输入。