jieba中文处理
1. 中文分词
jieba是一个在中文自然语言处理中用的最多的工具包之一,它以分词起家,目前已经能够实现包括分词、词性标注以及命名实体识别等多种功能。既然Jieba是以分词起家,我们自然要首先学习Jieba的中文分词功能。Jieba提供了三种分词模式:
- 精确模式 在该模式下,Jieba会将句子进行最精确的切分
- 全模式 把句子中所有可以成词的词语都扫描出来,优点在于该模式非常快,缺点也很明显,就是不能有效解决歧义的问题
- 搜索引擎模式 在精确模式的基础上,对长词进行再次切分,该模式适合用于搜索引擎构建索引的分词
在jieba分词中,最常用的分词函数有两个,分别是cut
和cut_for_search
,分别对应于“精确模式/全模式”和“搜索引擎模式”。
当然,两者的输入参数也不一样,cut函数的输入主要有三个,分别是:
- 需要分词的字符串
-
cut_all
用来控制是否采用全模式 -
HMM
参数用来控制是否使用HMM模型
cut_for_search
函数主要有两个参数:
- 需要分词的字符串
-
HMM
参数用来控制是否使用HMM模型
# coding:utf-8
import jieba
sent = "抑郁症已成为全球头号致残元凶,女性患病几率远高于男性。三个年龄群体的人最容易患上抑郁症,包括年轻人,孕妇及产后妇女,老年人。由抑郁症引发的冷漠情绪、动力不足等精神状态,会导致人无法适应日常生活。关注心理健康,别让抑郁打倒你!"
# 精确模式
seg_list = jieba.cut(sent)
print("精确模式:", '/ '.join(seg_list))
print('-'*100)
# 全模式
seg_list = jieba.cut(sent, cut_all=True)
print("全模式:", '/ '.join(seg_list))
print('-'*100)
# 搜索引擎模式
seg_list = jieba.cut_for_search(sent)
print("搜索引擎模式:", '/ '.join(seg_list))
Building prefix dict from the default dictionary ...
Loading model from cache /var/folders/4z/5wdk0_qx6pv3zbbsdj0s4ys40000gn/T/jieba.cache
Loading model cost 1.022 seconds.
Prefix dict has been built succesfully.
精确模式: 抑郁症/ 已/ 成为/ 全球/ 头号/ 致残/ 元凶/ ,/ 女性/ 患病/ 几率/ 远高于/ 男性/ 。/ 三个/ 年龄/ 群体/ 的/ 人/ 最/ 容易/ 患上/ 抑郁症/ ,/ 包括/ 年轻人/ ,/ 孕妇/ 及/ 产后/ 妇女/ ,/ 老年人/ 。/ 由/ 抑郁症/ 引发/ 的/ 冷漠/ 情绪/ 、/ 动力/ 不足/ 等/ 精神状态/ ,/ 会/ 导致/ 人/ 无法/ 适应/ 日常生活/ 。/ 关注/ 心理健康/ ,/ 别/ 让/ 抑郁/ 打倒/ 你/ !
----------------------------------------------------------------------------------------------------
全模式: 抑郁/ 抑郁症/ 已成/ 成为/ 全球/ 头号/ 致残/ 元凶/ / / 女性/ 患病/ 几率/ 远高于/ 高于/ 男性/ / / 三个/ 年龄/ 群体/ 的/ 人/ 最/ 容易/ 患上/ 抑郁/ 抑郁症/ / / 包括/ 年轻/ 年轻人/ / / 孕妇/ 及/ 产后/ 妇女/ / / 老年/ 老年人/ / / 由/ 抑郁/ 抑郁症/ 引发/ 的/ 冷漠/ 情绪/ / / 动力/ 不足/ 等/ 精神/ 精神状态/ 状态/ / / 会/ 导致/ 人/ 无法/ 适应/ 日常/ 日常生活/ 常生/ 生活/ / / 关注/ 注心/ 心理/ 心理健康/ 健康/ / / 别/ 让/ 抑郁/ 打倒/ 你/ /
----------------------------------------------------------------------------------------------------
搜索引擎模式: 抑郁/ 抑郁症/ 已/ 成为/ 全球/ 头号/ 致残/ 元凶/ ,/ 女性/ 患病/ 几率/ 高于/ 远高于/ 男性/ 。/ 三个/ 年龄/ 群体/ 的/ 人/ 最/ 容易/ 患上/ 抑郁/ 抑郁症/ ,/ 包括/ 年轻/ 年轻人/ ,/ 孕妇/ 及/ 产后/ 妇女/ ,/ 老年/ 老年人/ 。/ 由/ 抑郁/ 抑郁症/ 引发/ 的/ 冷漠/ 情绪/ 、/ 动力/ 不足/ 等/ 精神/ 状态/ 精神状态/ ,/ 会/ 导致/ 人/ 无法/ 适应/ 日常/ 常生/ 生活/ 日常生活/ 。/ 关注/ 心理/ 健康/ 心理健康/ ,/ 别/ 让/ 抑郁/ 打倒/ 你/ !
需要注意的是,cut
和cut_for_search
返回的都是generator,如果想直接返回列表,需要使用lcut
和lcut_for_search
如果在一些特定场景中,需要使用一些特殊词汇进行分词,就需要加载自定义的分词词典:
jieba.load_userdict(filename)
其中,用户字典的格式为:
朝三暮四 3 i
朝秦暮楚 1
汤姆
公主坟
每一行表示一个单词,每行最多由三部分组成
词语 词频(可省略) 词性(可省略)
如果只是少量词汇,可以使用
add_word(word, freq=None, tag=None)
需要注意的是,如果没有给出词频和词性信息,在后续的处理中可能会造成一定的影响。
2. 关键词提取
jieba提供了两种关键词提取算法,分别是TF-IDF以及TextRank
2.1 基于TF-IDF算法的关键词提取
关于TF-IDF的原理,可以参考吴军老师的《数学之美》,里面给出了很详细的说明。本文只介绍利用TF-IDF算法提取关键词。
from jieba import analyse
analyse.extract_tags(sentence, topK = 20, withWeight = False, allowPOS=())
其中:
- sentence 表示待提取的文本
- topK 表示返回的TF-IDF最大的前n个词语的数量
- withWeight 表示是否返回权重值,默认为False
- allowPOS 仅包括特定词性的单词,默认值为空,即不筛选
from jieba import analyse
with open('./西游记.txt') as f:
lines = f.read()
words = analyse.extract_tags(lines, allowPOS=('n'))
print(' '.join(words))
行者 八戒 师父 菩萨 妖精 长老 呆子 悟空 徒弟 国王 小妖 妖怪 铁棒 不题 师徒 老者 妖魔 兄弟 妖王 意思
2.2 基于TextRank算法的关键词提取
TextRank的用法与extract_tags的函数定义完全一致
from jieba import analyse
with open('./西游记.txt') as f:
lines = f.read()
words = analyse.textrank(lines, allowPOS=('n'))
print(' '.join(words))
行者 师父 八戒 菩萨 妖精 国王 长老 意思 悟空 形容 呆子 徒弟 小妖 铁棒 问道 兄弟 公主 弟子 道士 贫僧
3. 词性标注
词性标注主要是在分词的基础上,对词的词性进行判别,在jieba中可以使用如下方式进行:
from jieba import posseg as psg
words = psg.cut(sent)
for word, tag in words:
print(f"{word} {tag}")
抑郁症 i
已 d
成为 v
全球 n
头号 n
致残 v
元凶 n
, x
女性 n
患病 n
几率 n
远高于 nr
男性 n
。 x
三个 m
年龄 n
群体 n
的 uj
人 n
最 d
容易 a
患上 n
抑郁症 i
, x
包括 v
年轻人 n
, x
孕妇 n
及 c
产后 n
妇女 n
, x
老年人 n
。 x
由 p
抑郁症 i
引发 v
的 uj
冷漠 n
情绪 n
、 x
动力 n
不足 a
等 u
精神状态 n
, x
会 v
导致 v
人 n
无法 n
适应 v
日常生活 i
。 x
关注 v
心理健康 n
, x
别 d
让 v
抑郁 a
打倒 v
你 r
! x
其他
并行分词
在jieba中采用将目标文档按行分割,对每一行采用一个Python进程进行分词处理,然后将结果归并到一起(有点类似于MapReduce)。据说目前尚不支持Windows,仅支持Linux和MacOS。
启动并行分词使用如下命令:
jieba.enable_parallel(n)
- n 表示并行的进程数量。
关闭并行分词使用如下命令:
jieba.disable_parallel()
%%time
jieba.enable_parallel(6)
with open('./西游记.txt') as f:
content = f.read()
words = ' '.join(jieba.cut(content))
CPU times: user 274 ms, sys: 88.6 ms, total: 363 ms
Wall time: 1.66 s
%%time
jieba.disable_parallel()
with open('./西游记.txt') as f:
content = f.read()
words = ' '.join(jieba.cut(content))
CPU times: user 5.91 s, sys: 73.8 ms, total: 5.98 s
Wall time: 6.02 s
返回词语在原文的起止位置
使用tokenize函数后,会获得一个词语信息的元组,元组中的第一个元素是分词得到的结果,第二个元素是词的起始位置,第三个元素是词的终止位置。
result = jieba.tokenize(sent)
for tk in result:
print(f"word {tk[0]}\t\t start: {tk[1]} \t\t end:{tk[2]}")
word 抑郁症 start: 0 end:3
word 已 start: 3 end:4
word 成为 start: 4 end:6
word 全球 start: 6 end:8
word 头号 start: 8 end:10
word 致残 start: 10 end:12
word 元凶 start: 12 end:14
word , start: 14 end:15
word 女性 start: 15 end:17
word 患病 start: 17 end:19
word 几率 start: 19 end:21
word 远高于 start: 21 end:24
word 男性 start: 24 end:26
word 。 start: 26 end:27
word 三个 start: 27 end:29
word 年龄 start: 29 end:31
word 群体 start: 31 end:33
word 的 start: 33 end:34
word 人 start: 34 end:35
word 最 start: 35 end:36
word 容易 start: 36 end:38
word 患上 start: 38 end:40
word 抑郁症 start: 40 end:43
word , start: 43 end:44
word 包括 start: 44 end:46
word 年轻人 start: 46 end:49
word , start: 49 end:50
word 孕妇 start: 50 end:52
word 及 start: 52 end:53
word 产后 start: 53 end:55
word 妇女 start: 55 end:57
word , start: 57 end:58
word 老年人 start: 58 end:61
word 。 start: 61 end:62
word 由 start: 62 end:63
word 抑郁症 start: 63 end:66
word 引发 start: 66 end:68
word 的 start: 68 end:69
word 冷漠 start: 69 end:71
word 情绪 start: 71 end:73
word 、 start: 73 end:74
word 动力 start: 74 end:76
word 不足 start: 76 end:78
word 等 start: 78 end:79
word 精神状态 start: 79 end:83
word , start: 83 end:84
word 会 start: 84 end:85
word 导致 start: 85 end:87
word 人 start: 87 end:88
word 无法 start: 88 end:90
word 适应 start: 90 end:92
word 日常生活 start: 92 end:96
word 。 start: 96 end:97
word 关注 start: 97 end:99
word 心理健康 start: 99 end:103
word , start: 103 end:104
word 别 start: 104 end:105
word 让 start: 105 end:106
word 抑郁 start: 106 end:108
word 打倒 start: 108 end:110
word 你 start: 110 end:111
word ! start: 111 end:112
其他分词器
除了本文介绍的jieba分词工具包以外,还有很多好用的中文分词工具,比如
- NLPIR,又名ICTCLAS(据说是要收费的,但是我看文档,并没有提到收费)