3. 分词
3.1. 概述
分词是自然语言处理(NLP)中的基础环节,它的准确性对词性标注、句法分析、词向量生成以及后续的文本分析有着重要影响。英文文本中的单词通常由空格隔开,只有少数短语如“how many”或“New York”需要特殊处理,因此分词不是问题。而中文文本缺少自然的分隔符,需要通过专门的工具进行切分。因此,在处理中文文本时,分词是必不可少的第一步。
3.2. 中文分词的挑战
中文分词与英文不同,缺少天然的单词边界,而且中文的词汇组合极其多样,容易产生歧义。因此,中文分词一直是NLP领域的重要难题,主要面临的挑战包括分词标准、切分歧义以及未登录词的识别。
3.2.1 分词标准
例如,在处理人名时,有些算法认为姓和名应该分开,而另一些则认为不应该。此外,像“花草”这样的词,有些人认为是一个整体,而另一些人则倾向于拆分成“花/草”。这就需要制定一致的分词标准,使得在不同场景下,分词结果具有更好的适应性。
3.2.2 切分歧义
不同的分词方式可能带来不同的理解,主要分为以下几类:
-
组合型歧义:分词的粒度不同会带来不同的切分结果。比如“中华人民共和国”,粗粒度的结果是“中华人民共和国”,细粒度则是“中华/人民/共和国”。在情感分析或文本分类等场景中,粗粒度分词效果更好,而在搜索引擎中,为了更全面地检索信息,细粒度分词更合适。此外,某些词串如“他/将/来/网商银行”中的“将来”,既可以是一个词,也可以是单独的词,这种情况也被称为“固有型歧义”。
-
交集型歧义:同一个词串,由于不同的前后组合方式,可能会有多种分词结果。比如“商务处女干事”,可以分为“商务处/女干事”或“商务/处女/干事”。这种歧义无法仅通过单个词解决,需要结合整个句子的语义上下文,因此也被称为“偶发型歧义”。
-
真歧义:即使是人类分词也会产生歧义的情况。例如“下雨天留客天天留人不留”,既可以理解为“下雨天/留客天/天留/人不留”,也可以理解为“下雨天/留客天/天留人不/留”。这种情况需要通过更广泛的语境来确定分词方式。
根据统计,每100个汉字中大约会出现1.2次切分歧义,其中交集型歧义和组合型歧义的比例约为12:1,而真歧义的出现频率较低。
3.2.3 未登录词
未登录词(又称新词)是指那些词典中未收录的新词,主要包括:
- 新兴词汇:如网络流行语“超女”、“给力”等。
- 专有名词:如人名、地名、机构名称等,例如“南苏丹”、“特朗普”、“花呗”等。
- 专业术语:如特定领域的词汇“苏丹红”、“禽流感”等。
- 其他专有名词:如新发布的电影名、产品名、书籍名等。
未登录词的出现会显著影响分词的准确度,其识别难度也很大。原因在于新词的出现速度通常比词典更新快,无法单纯依赖词典来解决。此外,未登录词的长度不固定,且与上下文的结合会产生歧义。例如,“e租宝”这样的词汇包含英文字母,这也增加了识别的难度。此时,可以借助基于统计的分词算法,如HMM(隐马尔科夫模型)结合Viterbi算法,来处理这些复杂的情况。
3.3. 中文分词的方法
目前的分词方法主要分为两大类:基于词典的规则匹配和基于统计的机器学习方法。
3.3.1 基于词典的分词方法
这种方法通过将文本与词典进行匹配,如果在词典中找到对应的词条,则将其作为分词结果。根据不同的匹配策略,常见方法包括正向最大匹配法、逆向最大匹配法、双向匹配法和全切分路径选择等。
- 正向最大匹配法:从左到右扫描文本,优先匹配最长的词。例:“商务处女干事”会被切分为“商务处/女干事”。
- 逆向最大匹配法:从右到左扫描文本,同样优先匹配最长的词。例:“他从东经过我家”会被切分为“他/从/东/经过/我家”。
- 双向匹配法:同时进行正向和逆向匹配,并选择词数较少的结果。但这并不总是能得到最佳结果。
- 全切分路径选择:将所有可能的切分结果列出,从中选择最优路径。选择方法包括n最短路径法和n元语法模型。
3.3.2 基于统计的分词方法
基于统计的分词方法将分词问题看作序列标注任务,通过机器学习或深度学习模型对句子中的每个字进行位置标注(B-词首,E-词尾,M-词中,S-单字词)。例如,“网商银行是蚂蚁金服微贷事业部的最重要产品”可以被标注为“BMMESBMMEBMMMESBMEBE”。
常见的基于统计的分词方法包括:
- HMM(隐马尔科夫模型):利用观测序列和隐藏序列的概率关系,对文本进行序列标注,并通过Viterbi算法找到最可能的标注序列。
- CRF(条件随机场):通过条件概率来建模输入与输出序列之间的关系,适合复杂特征的分词任务。
- 深度学习:将句子作为输入,分词结果作为输出,通过神经网络进行训练,得到对新句子的预测能力。
3.4. 分词的质量与性能
中文分词在自然语言处理中的作用至关重要,衡量分词工具的性能主要看两方面:分词的准确度和速度。分词的准确度会影响后续的词性标注、句法分析等环节,而分词速度则决定了应用的响应效率。
不同分词工具在这两方面表现不一。如果对分词精度有很高要求,可以开发特定领域的分词工具,如专门面向金融领域的分词工具。对于更广泛的应用场景,jieba分词作为一款开源工具,兼具不错的速度和精度,适合通用场景。
中文分词是中文自然语言处理中的一个重要环节,为后面的词向量编码,词性标注,句法分析以及文本分析打下了坚实的基础。同时,由于中文缺少空格等分隔符,并且汉字间的组合特别多,很容易产生歧义,这些都加大了中文分词的难度。基于词典的字符串匹配算法和基于统计的分词算法,二者各有优缺点,我们可以考虑结合使用。随着深度学习的兴起,我们可以考虑利用深度学习来进行序列标注和中文分词。
4. Jieba分词
4.1. 概述
上一篇文章探讨了自然语言处理中的中文分词难题,并介绍了基于字符串匹配和统计的方法。为了应对这些挑战,jieba分词作为一个广受欢迎的开源工具,以其出色的分词精度和速度成为许多用户的首选。本文将深入讲解jieba分词的使用方法与原理,以便更好地理解其实现机制以及如何应对分词难点。
4.1.1 特点
jieba库支持四种分词模式,其中最常用的为前三种:
- 精确模式:将文本精确地切分为单词,重建时能精确地还原原始文本。没有多余的词。
- 全模式:将一段文本中的所有可能词语全都列出,这样能获得不同的分词组合,但会有重复,无法完整还原文本。
- 搜索引擎模式:基于精确模式,再对长词进行进一步切分,适合搜索引擎中建立索引,以提高检索效果。
- Paddle模式:基于PaddlePaddle深度学习框架,通过双向GRU模型进行序列标注,实现分词和词性标注。使用时需要安装
paddlepaddle-tiny
。
4.1.2 安装说明
jieba对Python 2/3均兼容,安装方式有以下几种:
- 自动安装:
pip install jieba
或pip3 install jieba
- 半自动安装:下载 jieba 后,解压并运行
python setup.py install
- 手动安装:将jieba目录放入当前目录或
site-packages
目录。
如需使用Paddle模式,还需安装paddlepaddle-tiny
:pip install paddlepaddle-tiny==1.6.1
。
4.1.3 算法
jieba分词基于以下原理进行分词:
- 词图扫描:利用前缀词典构建句子中所有可能词语的有向无环图(DAG)。
- 动态规划:通过动态规划算法,找到基于词频的最大概率路径,得到最佳切分方案。
- 未登录词处理:对于词典中未包含的词语,采用HMM模型,通过Viterbi算法进行处理。
4.2. jieba分词的使用方法
jieba分词是一个开源项目,地址为:fxsjy/jieba。它在速度和精度上都有很好的表现,以下是它的主要功能和使用方法。
4.2.1 分词
jieba.cut
方法接受四个参数:
- 待分词的文本
cut_all
:控制是否采用全模式HMM
:控制是否使用HMM模型use_paddle
:控制是否启用Paddle模式
jieba.cut_for_search
则更适用于搜索引擎构建索引,分词粒度较细。两者返回的都是一个可迭代的生成器对象,可以用for
循环遍历,也可以使用jieba.lcut
来直接返回列表。
使用示例:
import jieba
seg_list = jieba.cut("我来到北京清华大学", cut_all=True)
print("全模式: " + "/ ".join(seg_list))
seg_list = jieba.cut("我来到北京清华大学", cut_all=False)
print("精确模式: " + "/ ".join(seg_list))
seg_list = jieba.cut("他来到了网易杭研大厦")
print(", ".join(seg_list))
seg_list = jieba.cut_for_search("小明硕士毕业于中国科学院计算所,后在日本京都大学深造")
print(", ".join(seg_list))
输出结果:
- 全模式:我/ 来到/ 北京/ 清华/ 清华大学/ 华大/ 大学
- 精确模式:我/ 来到/ 北京/ 清华大学
- 新词识别:他, 来到, 了, 网易, 杭研, 大厦(“杭研”未在词典中,但通过HMM被识别)
- 搜索引擎模式:小明, 硕士, 毕业, 于, 中国, 科学, 学院, 计算所, 日本, 京都, 大学
4.2.2 自定义词典
可以使用jieba.load_userdict
方法加载自定义词典,从而添加未在jieba词库中的词汇。自定义词典的格式为每行一个词,包含词语、词频和词性,词频和词性可以省略。加载自定义词典后,可以显著提高分词的准确性。
jieba.load_userdict("user_dict.txt")
在加载自定义词典前后的分词对比:
- 原结果:李小福 / 是 / 创新 / 办 / 主任 / 也 / 是 / 云 / 计算 / 方面 / 的 / 专家 /
- 加载自定义词典后:李小福 / 是 / 创新办 / 主任 / 也 / 是 / 云计算 / 方面 / 的 / 专家 /
4.2.3 调整词典
可以通过add_word()
和del_word()
动态调整词典中的词汇。此外,suggest_freq()
可以调整某个词语的词频,从而影响其在分词时的结果。
jieba.add_word("台中")
print('/'.join(jieba.cut('「台中」正确应该不会被切开')))
输出为:“台中”不会再被错误地拆分。
4.2.4 关键词提取
jieba支持基于TF-IDF和TextRank两种关键词提取方法,能够从文本中提取最能表达内容的关键词。
- TF-IDF 适用于获取文本中频率较高但在其他文本中较少出现的词。
- TextRank 根据词语间的共现关系构建图结构,基于节点的相互重要性进行评分。
示例:
from jieba import analyse
text = "线程是程序执行时的最小单位,它是进程的一个执行流..."
tfidf = analyse.extract_tags(text)
textrank = analyse.textrank(text)
print("TF-IDF:", tfidf)
print("TextRank:", textrank)
4.2.5 词性标注
jieba.posseg
模块支持对分词后的词进行词性标注,可以兼容ICTCLAS词性标注集。
import jieba.posseg as pseg
words = pseg.cut("我爱北京天安门")
for word, flag in words:
print('%s %s' % (word, flag))
4.2.6 并行分词
jieba支持多进程分词,通过enable_parallel()
启用,可以显著提升分词速度,特别是在处理大规模文本时。
jieba.enable_parallel(4)
4.3. jieba分词源码结构
jieba分词库主要包含以下模块:
- 基本API封装:如
cut
、add_word
等方法。 - 基于字符串匹配的分词:通过内置的词典进行词语匹配。
- 统计分词:使用HMM模型处理新词。
- 关键词提取:实现了TF-IDF和TextRank两种方法。
- 词性标注:基于HMM模型进行词性标注。
4.4. jieba分词原理解析
jieba分词结合了字符串匹配和统计方法,具体步骤如下:
- 初始化:加载词典,生成词语和词频映射关系。
- 切分短语:使用正则表达式将文本切分为短语段落。
- 构建DAG:通过前缀词典生成所有可能的词语组合,构成有向无环图。
- 动态规划求解:从后向前计算每个节点的最大路径概率,并记下最大概率时的路径。
- 生成分词结果:根据路径切分短语,对于词典中没有的词,使用HMM模型进行识别。
jieba分词是一款强大的中文分词工具,通过结合字符串匹配和HMM模型,它既能快速处理常见词汇,又能识别新词,保持较高的分词精度。阅读jieba的源码不仅能加深对分词原理的理解,还能学习到HMM模型在实际应用中的运用,对于中文处理和机器学习研究者都是宝贵的参考。