中文分词(Chinese Word Segmentation) 指的是将一个汉字序列切分成一个一个单独的词。分词就是将连续的字序列按照一定的规范重新组合成词序列的过程。我们知道,在英文的行文中,单词之间是以空格作为自然分界符的,而中文只是字、句和段能通过明显的分界符来简单划界,唯独词没有一个形式上的分界符,虽然英文也同样存在短语的划分问题,不过在词这一层上,中文比之英文要复杂得多、困难得多。
与英文为代表的拉丁语系语言相比,英文以空格作为天然的分隔符,而中文由于继承自古代汉语的传统,词语之间没有分隔。 古代汉语中除了连绵词和人名地名等,词通常就是单个汉字,所以当时没有分词书写的必要。而现代汉语中双字或多字词居多,一个字不再等同于一个词。
现代汉语的基本表达单元虽然为“词”,且以双字或者多字词居多,但由于人们认识水平的不同,对词和短语的边界很难去区分。 例如:“对随地吐痰者给予处罚”,“随地吐痰者”本身是一个词还是一个短语,不同的人会有不同的标准,同样的“海上”“酒厂”等等,即使是同一个人也可能做出不同判断,如果汉语真的要分词书写,必然会出现混乱,难度很大。
中文分词的方法其实不局限于中文应用,也被应用到英文处理,如手写识别,单词之间的空格就不很清楚,中文分词方法可以帮助判别英文单词的边界。
到底哪种分词算法的准确度更高,目前并无定论。对于任何一个成熟的分词系统来说,不可能单独依靠某一种算法来实现,都需要综合不同的算法。例如,海量科技的分词算法就采用“复方分词法”,所谓复方,就是像中西医结合般综合运用机械方法和知识方法。对于成熟的中文分词系统,需要多种算法综合处理问题
有了成熟的分词算法,是否就能容易的解决中文分词的问题呢?事实远非如此。中文是一种十分复杂的语言,让计算机理解中文语言更是困难。在中文分词过程中,有两大难题一直没有完全突破。
歧义是指同样的一句话,可能有两种或者更多的切分方法。主要的歧义有两种:交集型歧义和组合型歧义,例如:表面的,因为“表面”和“面的”都是词,那么这个短语就可以分成“表面 的”和“表 面的”。这种称为交集型歧义(交叉歧义)。像这种交集型歧义十分常见,前面举的“和服”的例子,其实就是因为交集型歧义引起的错误。“化妆和服装”可以分成“化妆 和 服装”或者“化妆 和服 装”。由于没有人的知识去理解,计算机很难知道到底哪个方案正确。
命名实体(人名、地名)、新词,专业术语称为未登录词。也就是那些在分词词典中没有收录,但又确实能称为词的那些词。最典型的是人名,人可以很容易理解。句子“王军虎去广州了”中,“王军虎”是个词,因为是一个人的名字,但要是让计算机去识别就困难了。如果把“王军虎”做为一个词收录到字典中去,全世界有那么多名字,而且每时每刻都有新增的人名,收录这些人名本身就是一项既不划算又巨大的工程。即使这项工作可以完成,还是会存在问题,例如:在句子“王军虎头虎脑的”中,“王军虎”还能不能算词?
除了人名以外,还有机构名、地名、产品名、商标名、简称、省略语等都是很难处理的问题,而且这些又正好是人们经常使用的词,因此对于搜索引擎来说,分词系统中的新词识别十分重要。新词识别准确率已经成为评价一个分词系统好坏的重要标志之一。
支持三种分词模式:
支持繁体分词
支持自定义词典
“结巴”中文分词算法
jieba.cut
方法接受三个输入参数: 需要分词的字符串;cut_all 参数用来控制是否采用全模式;HMM 参数用来控制是否使用 Hidden Markov Model (HMM)模型
! pip3 install jieba --user
Looking in indexes: https://mirrors.163.com/pypi/simple/ Collecting jieba Downloading https://mirrors.163.com/pypi/packages/c6/cb/18eeb235f833b726522d7ebed54f2278ce28ba9438e3135ab0278d9792a2/jieba-0.42.1.tar.gz (19.2 MB) |████████████████████████████████| 19.2 MB 5.5 MB/s eta 0:00:01 Building wheels for collected packages: jieba Building wheel for jieba (setup.py) ... done Created wheel for jieba: filename=jieba-0.42.1-py3-none-any.whl size=19314478 sha256=fc1caf3779617163018e2bada6fd3396db7d0ea2ece4189f4bd50e218fc3e871 Stored in directory: /home/fli/.cache/pip/wheels/56/4a/b1/390288a7f489bd85658e785332ec02a46a61da35d9d2197757 Successfully built jieba Installing collected packages: jieba Successfully installed jieba-0.42.1
import jieba
# 全模式
seg_list = jieba.cut("我来到北京清华大学", cut_all=True)
print("Full Mode: " + "/ ".join(seg_list))
Building prefix dict from the default dictionary ... Dumping model to file cache /tmp/jieba.cache Loading model cost 0.545 seconds. Prefix dict has been built successfully.
Full Mode: 我/ 来到/ 北京/ 清华/ 清华大学/ 华大/ 大学
# 精确模式
seg_list = jieba.cut("我来到北京清华大学", cut_all=False)
print("Default Mode: " + "/ ".join(seg_list))
Default Mode: 我/ 来到/ 北京/ 清华大学
# 搜索引擎模式
seg_list = jieba.cut_for_search("小明硕士毕业于中国科学院计算所,后在日本京都大学深造")
print(", ".join(seg_list))
小明, 硕士, 毕业, 于, 中国, 科学, 学院, 科学院, 中国科学院, 计算, 计算所, ,, 后, 在, 日本, 京都, 大学, 日本京都大学, 深造
test_sent = (
"李小福是创新办主任也是云计算方面的专家; 什么是八一双鹿\n"
"例如我输入一个带“韩玉赏鉴”的标题,在自定义词库中也增加了此词为N类\n"
"「台中」正確應該不會被切開。mac上可分出「石墨烯」;此時又可以分出來凱特琳了。"
)
# 未使用个人字典
words = jieba.cut(test_sent)
print('/'.join(words))
李小福/是/创新/办/主任/也/是/云/计算/方面/的/专家/;/ /什么/是/八/一双/鹿/ /例如/我/输入/一个/带/“/韩玉/赏鉴/”/的/标题/,/在/自定义词/库中/也/增加/了/此/词为/N/类/ /「/台/中/」/正確/應該/不會/被/切開/。/mac/上/可/分出/「/石墨/烯/」/;/此時/又/可以/分出/來凱/特琳/了/。
# 加载个人字典后的结果
jieba.load_userdict("data/userdict.txt")
words = jieba.cut(test_sent)
print('/'.join(words))
李小福/是/创新办/主任/也/是/云计算/方面/的/专家/;/ /什么/是/八一双鹿/ /例如/我/输入/一个/带/“/韩玉赏鉴/”/的/标题/,/在/自定义词/库中/也/增加/了/此/词为/N/类/ /「/台中/」/正確/應該/不會/被/切開/。/mac/上/可/分出/「/石墨/烯/」/;/此時/又/可以/分出/來/凱特琳/了/。
关键词提取说白了就是对文章进行总结,从一篇文章中抽取出比较重要的一些词汇,帮助阅读者高效率地了解文章的大意。尤其是对互联网环境下,每天大量的信息涌出,若不加以预处理,则会成为网页浏览者的负担。关键词提取技术可以非常简单,也可以非常复杂,但是其任务框架都一样,输入一个文章,输出几个关键词。 那么给定一篇文章,关键词是怎么抽取出来的呢?
当前关键词提取算法主要可以分成两个流派:
其思路是,先定义一个关键词指标,然后为文章中所有词汇计算关键词指标,把词汇按照指标从大到小排列,指标大的优先选为关键词。这种思路很简单,有点儿像班里选班长,老师说选学习成绩最好的同学当班长,那么选拔方法就是,先定义一个指标,比如考试总分,然后,给每个学生的语文、数学、物理成绩加总,排名,总分排第一的当班长(关键词)。当然,老师可以指定班里有任意多个班长,例如选K个班长,那么就是成绩排名前K个学生当班长。统计流派的关键在于,计算每个词汇的关键词指标,这个指标是根据词汇在文章中的表现统计并计算出来的,所以有Statistical其名。
在对关键词进行提取时,可以有多种指标,影响力最大的两个是:TF-IDF指标和 PageRank指标。TF-IDF基于词袋模型(Bag-of-Words),把文章表示成词汇的集合,由于集合中词汇元素之间的顺序位置与集合内容无关,所以TF-IDF指标不能有效反映文章内部的词汇组织结构。PageRank指标,基于网络模型(Graph Model),把文章表示成网络的结构,网络中的节点表示词汇,节点之间的边为词汇之间的位置邻接关系,网络结构比集合结构包含信息多,考虑了文章内词汇的顺序,所以PageRank指标一般比TF-IDF指标表现更好。
其思路是,将关键词提取任务,定义为一个对词汇进行二分类的任务。即给定一个词汇,要么是关键词,要么不是关键词,对其分类,是关键词为1,不是就是0。那么,关键词提取问题就变成了一个预测问题。预测问题,需要一个预测函数,这个函数就是规则,给定词汇,获得该词汇的特征,然后预测该词汇是否为关键词。
规则可以人工指定,也可以通过机器学习(Machine Learning)的方法获得。人工指定规则,一般比较难,费脑子,谁也不清楚究竟到底啥样儿的词是关键词。所以大家就想着让程序自己去获得规则,即通过机器学习。机器学习的方法相对省脑子,但是费体力,要手工标关键词,然后把标记过的样本放到模型里去把规则给学习出来。机器学习过程中,需要指定一些词汇特征,用于训练。这些特征,一般也不知道,所以也需要人工指定,比如,考虑词频、词汇包含的字数、词性、词汇的位置等等。现在深度学习成为关键词提取新的发展方向,但是深度学习的方法只能通过复杂网络的训练帮你抽象出词汇特征,但是还得依赖于人工标注,依然需要人去标记文章。
import jieba.analyse
sentence = (
"苍茫的天涯是我的爱,绵绵的青山脚下花正开,什么样的节奏是最呀最摇摆,\
什么样的歌声才是最开怀,弯弯的河水从天上来,流向那万紫千红一片海,\
哗啦啦的歌谣是我们的期待,一路边走边唱才是最自在,我们要唱就要唱得最痛快,\
你是我天边最美的云彩,让我用心把你留下来,悠悠的唱着最炫的民族风,\
让爱卷走所有的尘埃,你是我心中最美的云彩,怎么没就让你留下来,\
永远都唱着最炫的民族风,是整片天空最美的姿态,我听见你心中永远的天籁,\
登上天外云霄的舞台")
jieba.analyse.extract_tags(sentence, topK=15, withWeight=False, allowPOS=())
['最美', '云彩', '留下来', '什么样', '永远', '花正开', '爱卷', '悠悠的', '万紫千红', '民族', '整片', '天外', '心中', '开怀', '弯弯的']
其基本思想是将待抽取关键词的文本进行分词,以固定窗口大小(默认为5,通过span属性调整),词之间的共现关系,构建图 计算图中节点的PageRank,注意是无向带权图。
jieba.analyse.textrank(sentence, topK=15, withWeight=False,
allowPOS=('ns', 'n', 'vn', 'v'))
['留下来', '登上', '整片', '姿态', '歌声', '开怀', '歌谣', '期待', '天空', '舞台', '用心', '就让', '天籁', '河水', '摇摆']