上节课,我们学习了自然语言处理课程(一):自然语言处理在网文改编市场的应用,了解了相关的基础理论。接下来,我们将要了解一些具体的、可操作的技术方法。
作为小说爱好者的你,是否有设想过通过一些计算机工具对小说做一些有趣的事情呢?阅读本文,你可以了解到如何运用现在最流行、最容易运用的jieba分词包,统计一个段落的词频,然后来通过词频推断小说的关键情节、核心人物。
作为文本分析和情感分析最基础的工作就是对文本进行分词,后期的文本挖掘、情感分析、规律探寻等工作很大程度上取决于分词的精确度。在当代的中文自然语言分析领域,Jieba分词包因为它的简易性和高效性被广大工作者广泛的运用。
值得一提的是,小编在网上做了调查,想对Jieba分词包的作者SunJunyi做一个简单的介绍,但无奈信息太少,也源于他本人很低调,没有过多的信息,有兴趣的朋友可以在链接https://github.com/fxsjy?tab=repositories通过邮件联系到他本人(小编没有尝试过)。
本篇文章会在Jieba分词包的运用原理以及实际运用进行介绍,并会分享我们在文本分析用到的实例。
原理介绍
在介绍Jieba分词原理之前,我们先用最直接的思维角度来设想如果我们自己进行分词,我们会如何去分词。
举个简单的例子,我们有一句话是“我现在去公司开会“,人类最直观的想法就是从左向右扫描此句,然后分词成“我/现在/去/公司/开会”。但作为计算机机器,当人工智能还停留在我们的幻想时,我们能做的、可能就是给计算机一本词典,让它根据词典来分词。这样的方法可以应用于大部分句子,但当遇到一词多义、或者有双重理解词语组合的情况时,分析就变得不那么容易了。
例如‘松江大学城书店‘,正确的分词方法应该是’松江/大学城/书店‘,但由于词典里或许没有大学城这个词语的缘故,计算机会把词分成’松江/大学/城/书店’,这样的分词就是错误的。Jieba分词包针对这一类的问题,运用有效的统计模型与中文语言的特性相结合,将分词的效果提升了很多档次。
Jieba分词包的高效首先离不开对语料库的精心选择。在作者SunJunyi通过大量的训练之后,在名为dict.txt的文件里录入了两万多条词作为参考,进行最基本的布局。但是大家可以设想,假设我们是什么都不知道、只能通过查找这个字典来进行词语归类的机器人,我们每一次分句都要基本上阅读上万条词语 ,我们的眼睛和大脑都会受不了。虽然计算机比人的效率高了数个数量级,但每一次进行如此大量的查找也会非常的耗时。
Jieba分词包在这里运用到了数据结构里的trie(前缀树或字典树)对词语进行高效的分类,便于查找。
如上图所示,这就是最简单的trie的原理在分词上的运用:我们有Johnny、Joe、Jane和Jack四个名字,假设我们要让计算机查找名字Jack是否存在,普通的方法来说,计算机可能会扫描所有的字符串,非常耗时低效,但trie的从上至下搜索、每一次只判定一个字母、如果某个特定的节点(node)的下一个节点(child node)不再符合搜索要求,那么搜索就会停止,这样效率就会大大的提高。
此外,trie也结合了计算机领域另一个知识,名为有向无环图(DAG),trie与有向无环图的结合很高效的解决了第一段所提到的双重理解词语组合的问题。举个例子:
通过设定,计算机自动识别出了两种分词方法,分别为’有/意见/分歧/’ 和 ‘有意/见/分歧’,这就是trie和DAG的最基本应用。
那么如何从这两个切分组合中筛选出一个更优的呢?这里就要用到一点点统计学的知识,既然一个句子有多个分词方式,那么我们就应该选择使得这个句子出现概率最大的切分组合。学过概率论与数理统计的同学可以很容易得把这个思想同极大似然估计(Maximum Likelihood Estimation)联系起来。
在制定了切分方案的评价准则后, jieba分词包运用了动态规划来找出词频最大切分组合。动态规划涉及到很多内容,我们就不做详细的介绍,但它在这里起到的效果很通俗易懂。举个例子:假设一个句子K,它可以被计算机随机分为a,b,c三种分词形式,那么计算机就通过大量的运算,在标准正确的情况下取概率最大的一种分词形式。在这里,动态规划法对分词分好之后每个词语出现的频率进行了统计(频率=次数/总数),得到最大的概率切分组合从而完成分词。
可能还有的同学会问,那么如果有没有录入字典的词该怎么办呢?这里Jieba分词包用到了HMM模型和经典的维特比(Viterbi)算法,将未登录的词语分为开始、中间、结束和单独成词四种分类来自动分词。总的来说,Jieba分词包在拥有HMM模型和维特比算法以后,即使词典一个词都没有也能够进行大致的分词,只是准确率会有所降低。
实际运用
Jieba 分词细分为了三种,分为精确模式、全模式和搜索引擎模式(在实际运用会进行介绍),每一个模式都有着自己的特定用法,但大体差别不大,这里我们用Python为大家进行演示。
其中word1为全模式,word2为精确模式,word3为搜索引擎模式,在这个例子里面,全模式和搜索引擎模式是差不多的,都将所有的词组展示了出来,但顺序有所不同,精确模式只输出了句子分词最大可能性的一组。
这里需要注意的一点:所有的word1,word2,word3并不是一个字符串,而是一个迭代器(iterator),要通过print(‘ ‘.join(word1))的方式正常输出中文字符,否则直接print只会出现对象的地址。如果嫌这个很麻烦,也可以直接使用lcut()或lcut_for_search()直接将分词放进一个list,直接运用。
此外,我们还可以用load_userdict(file_name)添加自己想添加的字典,让判断变得更加的准确,示例如下:
当我们只用jieba的默认字典时,牛肉和饼干被默认为两个词语。然后我们在与程序文件相同目录的地方创建一个文本文档,将’牛肉饼干’输入进去,作为一个词组,得到的分词就不一样了。当然,我们也可以直接添加“牛肉饼干”这个词。
除此之外,Jieba分词包还支持一些其他的功能,我们在这里就不一一的介绍了,详情可以参考jieba在github上面README.txt的详细介绍。
实例分享
在进行了较为枯燥的介绍后,终于来到了好玩又令人激动地实例分享,我们这次对红楼梦的几个段落进行文本统计,所需要的工具包为jieba。
首先我们要做的是导出txt文件里红楼梦的文本,分割为短句,并对每个短句进行一定的处理,保证文本的整洁和规律。具体步骤为:
1. 依换行符,句号,逗号等分隔符将全文分为短句。
2. 删除每个短句前后的空格。
3. 剔除没有任何文字和数字的短句。
然后我们就可以进行分词了,这里的后半部分小编将字典进行了排序,不是本文的重点,重点是要知道怎么利用jieba进行分词。这里小编把每一个短句切分为词语,并把这个结果写入一个字典里。如果字典已经有这个词了,那么这个词对应的频数+1,如果没有,那么就添加这一个词,频数设置为1。
最后就是将结果持久化存储到本地了,这里就不做详细的介绍了,有兴趣的可以下去了解。
- 发表于: 2018-05-22
- 原文链接:https://kuaibao.qq.com/s/20180522G1FL4E00?refer=cp_1026
- 腾讯「云+社区」是腾讯内容开放平台帐号(企鹅号)传播渠道之一,根据《腾讯内容开放平台服务协议》转载发布内容。