第 4 章 分词与词性标注

只有让机器理解我们的文字,才能利用机器进行文本数据分析,而这样的过程也是自然语言处理中的重要一环。自然语言处理过程一般包括分词、词性标注、命名实体识别、句法分析等,其中分词是自然语言处理的基础,是文本数据结构化处理的关键步骤,搜索引擎、机器翻译、自动摘要生成等技术都涉及到分词技术,合理的分词结果对于后续的文本数据分析效果至关重要,所以说分词是文本数据分析过程中不容忽视的重要环节。词性标注是给句子中每个词一个词性类别的任务,同样属于自然语言处理中的基本操作,是信息检索等领域不可或缺的步骤。鉴于中英文分词原理的差异,本章将分别进行说明,并结合实例向读者介绍多种分词、词性标注工具的使用方法,并对比不同工具的效果。

本章具体内容安排如下:4.1 节围绕中文相关处理展开,包括 jieba 、Yaha 、Genius、finalseg、scseg、pynlpir 等工具包的分词及词性标注功能的实现,4.2 节则主要介绍英文文本处理工具包 NLTK。

4.1 中文分词与词性标注

从形式上看,每一段中文文本都可以被认为是由汉字与标点符号组成的一个字符串。由字可组成词,由词可组成词组,由词组可组成句子,进而由一些句子组成段、节、章、篇。在我们的日常生活中,一个中文文本或是几个汉字的组合能够具有被赋予多种含义,作为人类,我们通常可以很容易地根据语境或是场景来对不同文本的语义进行理解,并从中分离出具有实际意义的词语,例如我们能够一眼看出“小明吃了水果然后去超市”这段话中并不含有“果然”一词的语义,但对于计算机来说,能做到这一点则需要更多复杂的工作。在接下来的内容中,我们将向大家介绍几类 Python 中常用的中文分词与词性标注工具,这些工具结合词库与算法在很大程度上解决了计算机的中文分词问题,掌握它们的使用方法,能给我们的文本数据分析带来极大的便利。

4.1.1 jieba

4.1.1.1 了解 jieba

(1)分词及词性标注原理

对于给定的待分词文本,jieba 主要分词处理思路如下:

(1.1)加载模块自带 dict.txt 词典, 从自带的词典中构建待分词的语句的有向无环图(DAG);

(1.2)对于词典中未收录的词,使用 HMM 模型的 Viterbi 算法尝试分词处理;

(1.3)已收录词和未收录词全部分词完毕后,根据有向无环图的最大概率路径使用 Python 的 yield 语法生成一个词语生成器, 逐词语返回。

词性标注的基本原理可以概括为:对于需要标注的词,如果词典中包括该词,就从词典中读取该词的词性;如果词典中没有该词,则用 Viterbi 算法来进行词性估计。

(2)特点

(2.1)支持多种分词模式

jieba 支持以下三种分词模式:精确模式,对语句进行最精确地切分,只用于文本数据分析;全模式,把句子中所有的可以成词的词语都扫描出来, 该模式速度非常快,但是不能解决歧义;搜索引擎模式,在精确模式的基础上,对长词再次切分,提高召回率,适合用于搜索引擎分词。

(2.2)支持繁体分词

(2.3)支持自定义词典

(2.4)待分词的字符串可以是 unicode 或 UTF-8 编码

4.1.1.2 jieba 中文分词函数

安装了 jieba 后,直接导入 jieba 模块,即可调用该模块下的函数,主要用于分词的函数及调用方式见下表:

@todo 补充函数说明表 4.1.1.2

(1)jieba.cut

jieba.cut 是 jieba 模块下进行中文语句分词的主要函数,调用方式为:jieba.cut(sentence, cut_all=False, HMM=True)

参数说明:

sentence:需要分词处理的字符串

cut_all:分词模式,True 代表全模式,False 代表精确模式,默认缺失值为 False

HMM:是否使用 HMM 模型,默认缺失值为True

jieba.cut 返回的结果是一个可迭代的 generator,可以使用 for 循环来获得分词后得到的每一个词语,也可以用 list() 函数进行转化

例 1 利用 jieba.cut 对语句“我爱文本数据分析”进行分词处理


In [1]:import jieba
       seg_list = jieba.cut("我爱文本数据分析")  # 默认是精确模式
       seg_list
Out[1]:<generator object cut at 0x7f30d0270140>
In [2]:for i in jieba.cut("我爱文本数据分析"):
           print i
       我
       爱
       文本
       数据分析
In [3]:for i in jieba.cut("我爱文本数据分析",cut_all=True): # 全模式
           print i
       我
       爱
       文本
       本数
       数据
       数据分析
       分析           
In [4]:list(jieba.cut("我爱文本数据分析"))
Out[4]:[u'\u6211', u'\u7231', u'\u6587\u672c', u'\u6570\u636e\u5206\u6790'] # 列表元素为中文词汇对应的 Unicode 编码

可以看到,jieba.cut 直接返回的是 generator,为了查看分词结果,使用 for 循环语句打印得到的每一个词语,如果直接对 generator 列表处理,返回的列表元素为分词结果对应的 Unicode 编码。

(2)jieba.cut_for_search

jieba.cut_for_search 是适用于搜索引擎构建倒排索引(Inverted index)的分词函数,调用方式为:jieba.cut_for_search(sentence, HMM=True)

参数说明:

sentence:需要分词处理的字符串

HMM:是否使用 HMM 模型,默认缺失值为True

和 ieba.cut 一样,jieba.cut_for_search 返回的结果也是一个可迭代的 generator。

例 2 利用 jieba.cut_for_search 对语句“我爱文本数据分析”进行分词处理


In [5]:seg_list = jieba.cut_for_search("我爱文本数据分析")
       seg_list
Out[5]:<generator object cut_for_search at 0x7f30d02703c0>
In [6]:for i in jieba.cut_for_search("我爱文本数据分析"):
           print i
       我
       爱
       文本
       数据
       分析
       数据分析

与 jieba.cut 函数的分词结果进行对比,可以发现多出了“数据”和“分析”两个分词结果。

(3)jieba.lcut

jieba.cut 返回的结果是 generator,jieba.lcut 可以直接返回列表结果,直接使用 jieba.lcut 进行分词可以省去对 jieba.cut 分词结果的列表化处理。

例 3 利用 jieba.lcut 对语句“我爱文本数据分析”进行分词处理


In [7]:jieba.lcut("我爱文本数据分析")
Out[7]:[u'\u6211', u'\u7231', u'\u6587\u672c', u'\u6570\u636e\u5206\u6790']
In [8]:print "/".join(jieba.lcut("我爱文本数据分析"))
       我/爱/文本/数据分析

(4)jieba.lcut_for_search

jieba.lcut_for_search 函数的作用与 jieba.lcut 相似:jieba.cut_for_search 返回的结果是 generator,jieba.lcut_for_search 可以直接返回列表结果,直接使用 jieba.lcut_for_search 进行分词可以省去对 jieba.cut_for_search 分词结果的列表化处理。

例 4 利用 jieba.lcut_for_search 对语句“我爱文本数据分析”进行分词处理


In [9]:jieba.lcut_for_search("我爱文本数据分析")
Out[9]:[u'\u6211',
        u'\u7231',
        u'\u6587\u672c',
        u'\u6570\u636e',
        u'\u5206\u6790',
        u'\u6570\u636e\u5206\u6790']
In [10]:print "/".join(jieba.lcut_for_search("我爱文本数据分析"))
        我/爱/文本/数据/分析/数据分析

(5)jieba.tokenize

jieba.tokenize 函数可以对指定语句进行切分并以元组的形式返回词语在原文的起止位置:(词语,开始位置,结束位置),返回结果是 generator,调用方式为:jieba.tokenize(sentence, mode=u'default', HMM=True)

参数说明:

sentence:需要分词处理的字符串,必须是 Unicode 形式,在字符串引号前加一个 u 即可

mode:取值为"default" 或者 "search", "search" 表示精细切分

HMM:是否使用 HMM 模型,默认缺失值为True

例 5 利用 jieba.tokenize 对语句“我爱文本数据分析”进行分词处理


In [11]:jieba.tokenize(u"我爱文本数据分析")
Out[11]:<generator object tokenize at 0x7f30d01f85a0>
In [12]:for i in jieba.tokenize(u"我爱文本数据分析"):
            print i
        (u'\u6211', 0, 1)
        (u'\u7231', 1, 2)
        (u'\u6587\u672c', 2, 4)
        (u'\u6570\u636e\u5206\u6790', 4, 8)

从输出结果可以看到,每一个分词结果都保存在一个元组中,元组中另外两个元素分别为该词汇在语句中的起始位置。

(6)jieba.load_userdict

jieba 分词的一个特点就是支持自定义词典,jieba.load_userdict 函数即可实现这一功能。虽然 jieba 有新词识别能力,但是使用者通过自定义的词典,可以包含 jieba 自带词库里没有的词汇,从而保证更高的正确率。调用方式为:jieba.load_userdict(file)

参数说明:

file:词典文件对象或自定义词典的路径,文件必须为 UTF-8 编码

注意:自定义词典格式需要和 jieba 自带词库 dict.txt 一样,每一行从左至右分别为词语、词频、词性三部分,各部分之间用空格分开,其中词性部分可以省略,词频越大成词的概率越大。

(7)jieba.add_word

jieba.add_word 函数用于给词典中增加新的词汇,调用方式为:jieba.add_word(word, freq=None, tag=None)

参数说明:

word:需要增加到词典的词汇

freq:词频,可省略

tag:词性,可省略

例 6


In [13]:print "/".join(jieba.cut("江州市长江大桥参加了长江大桥的通车仪式"))
        江州/市/长江大桥/参加/了/长江大桥/的/通车/仪式
In [14]:jieba.add_word("江大桥",freq =50000)
In [15]:print "/".join(jieba.cut("江州市长江大桥参加了长江大桥的通车仪式"))
        江州/市长/江大桥/参加/了/长江大桥/的/通车/仪式

(8)jieba.del_word

jieba.del_word 函数用于删除词典中的词汇,调用方式为:jieba.del_word(word)

(9)jieba.suggest_freq

jieba.suggest_freq 函数用于调节词语的词频,用于将一个词汇中的字符分开或者合并以增加该切分出该词汇的可能性。调用方式为:suggest_freq(segment, tune=True)

参数说明:

segment:某一词汇预期被切分的形式

tune:取值为 True 时,调整词频

注意: HMM 新词发现功能可能会影响到 suggest_freq 函数的结果,如果调用该函数后分词结果没有改变,调用分词函数时可以设置 HMM=False。

例 7


In [16]:print "/".join(jieba.cut("结巴分词是很好的中文分词工具"))
        结巴/分词/是/很/好/的/中文/分词/工具
In [17]:jieba.suggest_freq(("结巴分词"), True)
Out[17]:1
In [18]:print "/".join(jieba.cut("结巴分词是很好的中文分词工具"))
        结巴分词/是/很/好/的/中文/分词/工具

例 8


In [16]:print "/".join(jieba.cut("在不断的练习中将有所进步"))
        在/不断/的/练习/中将/有所/进步
In [17]:jieba.suggest_freq(("中","将"), True)
Out[17]:494
In [18]:print "/".join(jieba.cut("在不断的练习中将有所进步"))
        在/不断/的/练习/中/将/有所/进步

4.1.1.3 jieba 中文词性标注

posseg 包是 jieba 中实现词性标注功能的包,具体词性类别见下表:

@todo 补充词性对照表

posseg 包中定义了以下词性标注函数:

(1) cut

cut 函数可以同时实现分词和词性标注,以 pair(u'词', u'词性') 的形式返回标注结果,即将分词结果和对应的词性保存为一个 pair 对象,调用方式为:posseg.cut(sentence, HMM=True)

参数说明:

sentence:需要词性标注的文本

HMM:是否使用 HMM 发现新词,默认缺失值为 True

例 9


In [19]:import jieba
       from jieba import posseg
       pos = list(jieba.posseg.cut("我爱文本数据分析"))
       pos
Out[19]:[pair(u'\u6211', u'r'),
        pair(u'\u7231', u'v'),
        pair(u'\u6587\u672c', u'n'),
        pair(u'\u6570\u636e\u5206\u6790', u'l')]
In [20]: for i in pos:
             print i
         我/r
         爱/v
         文本/n
         数据分析/l

(2) lcut

lcut 函数与 cut 函数的作用一样,但是可以直接返回结果列表,调用方式为:posseg.lcut(sentence, HMM=True)

例 10


In [21]:jieba.posseg.lcut("我爱文本数据分析")
Out[21]:[pair(u'\u6211', u'r'),
         pair(u'\u7231', u'v'),
         pair(u'\u6587\u672c', u'n'),
         pair(u'\u6570\u636e\u5206\u6790', u'l')]
In [22]:for a,b in jieba.posseg.lcut("我爱文本数据分析"):
            if b=="n":
                print a
        文本

4.1.1.4 jieba 中文分词与词性标注案例

案例一

从数据堂(http://more.datatang.com/)网站下载新浪社会新闻 2013 年 4 月- 7 月数据 new.txt(数据网址:http://more.datatang.com/data/44293),其中包括新浪社会新闻的标题、url、发布时间,共2万条数据。

@todo插入数据文件截图 4.1.1.4

将数据上传到 Jupyter Notebook 文件列表,新建一个 Python notebook,用于运行相关命令并保存分析结果。首先读取文本数据:


In [1]:with open ("new.txt") as f:
           read=f.readlines()
       read[0:3]
Out[1]:['http://news.sina.com.cn/c/2013-07-12/134927651359.shtml|\xe7\xbd\……\xa4\xba|(07\xe6\x9c\x8812\xe6\x97\xa5 13:49)\n',
 'http://news.sina.com.cn/c/2013-07-12/134227651346.shtml|\xe6\xb9\……\xb0\x91|(07\xe6\x9c\x8812\xe6\x97\xa5 13:42)\n',
 'http://news.sina.com.cn/c/2013-07-12/131527651106.shtml|\xe8\xb4\……\xbc\xa4|(07\xe6\x9c\x8812\xe6\x97\xa5 13:15)\n']

从返回的结果 Out[1] 可以看出,每一条新闻数据都以一个字符串的形式保存,字符串中包括新闻网址、标题、发布时间三个元素,并以“|”隔开。下面利用 split 函数去除字符串中的“|”,同时将字符串中不同成分分离开来,并提取标题文本存放在列表 title 中:


In [2]:title=[]
       for i in read:
           title.append(i.split("|")[1].decode("utf-8")) # 去除“|”后标题索引位置为[1],并利用 decode 函数进行解码处理
In [3]:title[0:3]
Out[3]:[u'\u7f51\u6c11\……\u516c\u793a',
        u'\u6e56\u5357\……\u79fb\u6c11',
        u'\u8d35\u5dde\……\u6b7b3\u4f24']
In [4]:for i in title[0:3]:
           print i
       网民质疑广东江门核燃料项目:4月动工7月公示
       湖南家谱解密:六成人口是江西移民
       贵州六盘水吊车侧翻致23

直接对新闻标题进行分词处理,并将分词后结果保存在列表 new_seg 中:


In [3]:import jieba
       new_seg=[]
       for i in title:
           seg=jieba.lcut(i)
           new_seg.append(seg)

查看部分分词结果:


In [4]:for i in new_seg[0:5]:
           print "/" .join(i)
           网民/质疑/广东/江门/核燃料/项目/:/4/月/动工/7/月/公示
           湖南/家谱/解密/:/六成/人口/是/江西/移民
           贵州/六盘水/吊车/侧翻/致/2/死/3/伤
           北京公交/9/月/将/推/可/定制/商务/班车/ /保证/一人/一座
           美国/总统/奥巴马/会见/汪洋/和/杨洁篪

进一步采用搜索引擎模式对标题进行分词,将分词结果保存在列表 new_seg_for_search 中:


In [5]:new_seg_for_search=[]
       for i in title:
           seg=jieba.lcut_for_search(i)
           new_seg_for_search.append(seg)

查看部分分词结果:


In [6]:for i in new_seg_for_search[0:5]:
           print "/" .join(i)
           网民/质疑/广东/江门/燃料/核燃料/项目/:/4/月/动工/7/月/公示
           湖南/家谱/解密/:/六成/人口/是/江西/移民
           贵州/六盘/六盘水/吊车/侧翻/致/2/死/3/伤
           北京/公交/北京公交/9/月/将/推/可/定制/商务/班车/ /保证/一人/一座
           美国/总统/奥巴/巴马/奥巴马/会见/汪洋/和/杨洁篪

对分词结果进行词性标注,标注的结果保存在列表 new_posseg 中:


In [7]:from jieba import posseg
       new_posseg=[]
       for i in title:
           seg=jieba.posseg.lcut(i)
           new_posseg.append(seg)

直接筛选所有出现的形容词,保存到列表 mew_adj 中:


In [8]:mew_adj=[]
       for i in title:
           for a,b in jieba.posseg.lcut(i):
               if b=="a":
               mew_adj.append(a)

统计各个形容词出现的次数,查看出现次数最多的前五个词:


In [9]:from collections import Counter
       c=Counter(mew_adj)
       for i in c.most_common(5):
           print "word:",i[0],"count:",i[1]
       word: 大 count: 196
       word: 新 count: 163
       word: 最高 count: 143
       word: 严重 count: 129
       word: 高 count: 110

案例二

随着网络信息以及仓储物流等行业的迅速发展,网购已经成为现代人的重要购物方式,伴随而来的是网民在各种网络平台上所发表的购物观点、意见等评论文本数据的激增,这些评论文本包含了消费群体对所购买的商品或者服务的情感态度等信息,反映了用户通过互联网对产品各方面发表的看法,对电子商务平台销售者以及个体消费者都有重要的分析价值。通过评论分析,商家能够了解消费者对产品的看法,发现与竞争对手的差异,为产品改进、价格优化提供有价值信息;另外与商家的促销信息相比,在线评论具有独立性、非商业性,因此深得用户信赖,通过查看商品评价,消费者可以迅速了解到其他顾客对商品的评价、锁定关注属性的相关评价,支持消费决策,有效提高决策效率。鉴于网络评论文本数据分析的重要价值,本书多个分析实例都是围绕电子商务平台评论文本展开的,具体的评论文本抓取过程在案例中未做说明。

抓取亚马逊中国站上热门商品 “kindle” 电子书阅读器下 “kindle”、“kindle paperwhite”、“kindle voyage” 三个子类产品的商品评论语料作为分析实例,抓取的期间为 2014 年 10 月 3 日至 2015 年 8 月 24 日,共抓取评论文本 5632 条,保存为 CSV 格式文件 kindle_corpus.csv,并上传到 Jupyter Notebook 文件列表,新建一个 Python notebook,读取文本数据,并将数据保存到列表 corpus 中:


In [1]:import csv
       import jieba
In [2]:corpus=[]
       with open("kindle_corpus.csv") as f:
           reader=csv.reader(f)
           for i in reader:
               corpus.append(i)

查看 corpus 内元素形式:


In [3]:corpus[0:3]
Out[3]:[['', 'project_id', 'source_id', 'item_id', 'content', 'meta', 'pubdate'],
        ['0',
         '1',
         '1',
         'RIO4UTN75BRKS',
         '\xe5\x90\x8c\xe6\……\x9f\xef\xbc\x9f',
         '{"rating": "3"}',
         '2015-07-11'],
         ['1',
          '1',
          '1',
          'R4B71L8JMVEZ3',
          '\xe5\x88\x9a\xe5\……\x86\xe3\x80\x82',
          '{"rating": "5"}',
          '2015-07-08']]

可以看到 corpus 第一个列表元素即为 CSV 文件的第一行,即抓取的字段,包括:空格、project_id、source_id、'item_id'、content、meta、pubdate,分别代表序号(从 0 开始)、商品所属大类 id、商品所属子类 id(共三个子产品,取值为1、3、4,分别对应“kindle paperwhite”、“kindle voyage”和“kindle”)、商品 id、商品评论文本、商品评分(5分、4分、3分、2分、1分)和评论日期。将商品所属子类 id 为 3 的商品评论文本保存到列表 review 中:


In [4]:review=[]
       with open("kindle_corpus.csv") as f:
           reader=csv.reader(f)
           reader.next() # 跳过第一行字段内容
           for i in reader:
               if i[2]=="3":
                   review.append(i[4])
In [5]:len(review) # 查看评论数
Out[5]:1682
In [6]:for i in review[101:104]:
           print i + "\n"
       电子书阅读器着实不错啊,很顺手。就是套餐里面的电子书购书券不知道为什么迟迟不到账?!!

       1.价格太贵太离谱 2.软件缺乏人性化 3.翻页键不灵敏,基本上就是个摆设,毫无用处 4.每天阅读半小时也就2周的待机时间而已,待机数周纯粹骗人 建议入手499或者899

       不知道是不是我自己对这个小物寄予太大期望了,拿到手之后就用了。手感很棒,背面的logo太丑了。不伤眼,但是一翻页就闪屏,刷新闪屏,各种闪屏,体验不好,略失望

添加评论中频繁出现的新词到 jieba 自带词典:


In [7]:for i in ['学生党', '纸质书', '电源键','电子屏','阴阳屏','墨水屏','电纸书','电子墨水']:
           jieba.add_word(i,freq =50000)
In [8]:print "/".join(jieba.cut("学生党买电纸书遇到阴阳屏"))
       学生党/买/电纸书/遇到/阴阳屏

jieba 中并未直接提供停用词处理函数,需要使用者自行定义停用词词典对分词结果进行过滤操作。

加载停用词典:


In [9]:with open("stopwords.txt") as f: # 打开停用词典
           read=f.read().decode('utf-8') # 以 utf-8 编码格式解码字符串
           stop_words = read.splitlines() # 返回结果 read 为一个包含换行符的字符串,利用 splitlines 方法去掉输出结果里的换行符,或者用 split("\n")
In [10]:stop_words
Out[10]:[u',',
         u'?',
         u'\u3001',
         u'\u3002',
         ……]

分词并过滤停用词:


In [11]:review_segs=[] # 创建空列表 review_segs 用于存放所有评论的分词结果
        for i in review:
            review_seg=[] # 创建空列表 review_seg 用于存放每条评论的分词结果
            segs = jieba.cut(i)  
            for seg in segs:  
                if seg not in stop_words: 
                    review_seg.append(seg) # 对于每条评论分词后的词汇,如果不在停用词表中就添加到该条评论的分词列表中,也就是说,如果是停用词就过滤掉
            review_segs.append(review_seg) # 将每条评论的分词结果添加到列表 review_segs 中

随机选取评论文本,查看分词结果:


In [12]:print "/".join( review_segs[850])
        屏幕/不错/阴阳屏/限量版/好像/选/配套/保护套/颜色

直接对分词结果进行词性标注,同时过滤掉停用词,将词性标注结果保存在列表 review_pos 中:


In [13]:from jieba import posseg
        review_pos=[]
        for i in review:
            for a,b in posseg.lcut(i):
                if a not in stop_words: 
                    review_pos.append((a,b))

查看部分词性标注结果:


In [14]:for i in review_pos[0:5]:
            print i[0],i[1]
        pw eng
        对比 v
        来说 u
        优势 n
        亮度 n

分别将标注结果中的名词和形容词保存到列表 review_n 和 review_a,进行统计汇总后,查看出现次数较多的词汇:


In [15]:review_n=[]
        review_a=[]
        for i in review_pos:
            if i[1]=="n":
                review_n.append(i[0])
            elif i[1]=="a":
                review_a.append(i[0])
In [16]:from collections import Counter
        c1=Counter(review_n)
        for i in c1.most_common(5):
            print i[0],i[1]
        屏幕 531
        感觉 484
        电子书 362
        问题 333333

出现次数最多的名词是“屏幕”,可以推测“屏幕”在所有评论中被谈及的次数最多,是所有买家最关注的产品属性,“电子书”等也是大家关注的焦点。


In [17]:c2=Counter(review_a)
        for i in c2.most_common(5):
            print i[0],i[1]
        好 669
        不错 396
        方便 225
        明显 151
        舒服 139

从出现次数较多的形容词可以在一定程度上初步了解买家对产品的评价,如“方便”、“舒服”等。

4.1.2 Yaha 中文分词

4.1.2.1 了解 Yaha 中文分词

(1)分词原理

Yaha (“哑哈”)中文分词的词典是直接从 jieba 项目拷贝直接过来的,其算法的核心与我们之前讲到的 jieba 分词类似,同样基于对句子的最大概率路径的计算。与 jieba 不同的是, Yaha 分词在分词算法过程中去掉了很消耗内存的 Trie 树结构以及被项目研究者认为表现较差的 HMM 模型,利用“最大熵”算法实现大段文字的新词发现能力,同时使用者可以对分词的各个阶段进行定义。Yaha 分词的具体分词流程如下:

a.根据自定义的正则表达式规则切分目标语句,提取切分得到的独立词汇(如数字、英文单词等),这些词汇将被固定,不在之后的环节中被切分;

b.对目标语句进行预扫描,在词典中加入一些可能形成的新词,并确定其概率值;

c.结合内置词典与相关匹配模式创建有向无环图,对图中的词汇顶点赋予对应的概率值;

d.根据最优化算法(动态规划或Dijdstra算法)实现最大概率路径计算,二次处理其中不能成词的单字,或是输出多条分词路径,结合用户兴趣获得所需的分词结果。

(2)特点

(2.1)支持多种分词模式

和 jieba 分词一样支持以下三种分词模式:精确模式,对语句进行最精确地切分,只用于文本数据分析;全模式,把句子中所有的可以成词的词语都扫描出来, 该模式速度非常快,但是不能解决歧义;搜索引擎模式,在精确模式的基础上,对长词再次切分,提高召回率,适合用于搜索引擎分词。此外还支持备选路径,可生成最好的多条切词路径,在此基础上根据其它信息可得到更精确的分词模式。

(2.2)分词规则的调控插件

用户可通过添加插件的方式调整分词过程中的正则表达式与匹配模式,默认的 Yaha 分词插件有正则表达式插件、人名前缀插件以及地名后缀插件,同时用户也可以通过定制插件的方式在分词的分宜阶段加入个人的定制。

(2.3)新词学习功能

Yaha 分词自带的新词学习功能可以根据输入的大段文字学习自动,通过词语组成的规律得到文本当中的专业名词、名字、地点名词等等词语,可用于创建自定义词典,或在SNS等场合进行数据挖掘的工作。

(2.4)获取大段文本的关键字和摘要

Yaha 中的有关函数能够基于词汇在文本段落中的权重提取关键词,并根据关键词的分布情况对断句进行打分,由截取的断句拼接为文本的摘要。

(2.5)词语纠错功能

Yaha 库中的新功能,可以用于在搜索里对用户的错误输入进行纠正。

4.1.2.2 Yaha 中文分词方法

在调用 Yaha 分词函数之前,要先安装 Yaha 模块,在 notebook 代码单元格输入“!pip install yaha”,运行后在单元格下方可以看到如所示的安装进度提示:


Collecting yaha
  Downloading yaha-0.02.tar.gz (1.1MB)
    ……
Successfully built yaha
Installing collected packages: yaha
Successfully installed yaha-0.2

在 Yaha 模块中, Cuttor 类下定义了多个分词相关的方法,在调用类中的函数前需要将类“实例”化,即创建一个对象,类中的方法均可以作用于该对象。过程类似导入模块的操作,实例化类后即可调用类中的方法。

(1)cut

cut 方法是精确模式分词函数,返回一个 generator ,调用方式为:实例.cut(sentence)

例 1


In [1]:import yaha
       cuttor=yaha.Cuttor() # 实例化 Cuttor 类
       cuttor.cut("我爱文本数据分析") # 调用 cut 进行分词
Out[1]:<generator object cut at 0x7f51ac4de9b0>
In [2]:print "/".join(cuttor.cut("我爱文本数据分析"))
       我/爱/文本/数据分析

(2)cut_all

cut_all 方法是全模式分词函数,返回一个 generator ,调用方式为:实例.cut_all(sentence)

例 2


In [3]:print "/".join(cuttor.cut_all("我爱文本数据分析"))
       我/爱/文本/数据分析/数据/分析

(3)tokenize

与 jieba 分词一样,Yaha 中 tokenize 方法在分词的同时返回词汇起始位置,调用方式为:实例.tokenize( unicode_sentence, search=False)

例 3


 In [4]:for i in cuttor.tokenize(u"我爱文本数据分析"):
            print "word:"+i[0]+" "+"srart:"+str(i[1])+" "+"end:"+str(i[2])
        word:我 srart:0 end:1
        word:爱 srart:1 end:2
        word:文本 srart:2 end:4
        word:数据分析 srart:4 end:8

除 Cuttor 之外, Yaha 模块中还定义了 RegexCutting、SuffixCutting、SurnameCutting 等类,感兴趣的读者可以进一步了解。

4.1.3 Genius

4.1.3.1 了解 Genius 中文分词

Genius 是一个开源的 Python 中文分词组件,基于 wapiti 采用 CRF(Conditional Random Field) 条件随机场算法实现分词功能,其支持用户自定义合并词典,采用 trie 树进行合并词典查找,并且支持词性标注功能。

4.1.3.2 Genius 中文分词函数

在调用 Genius 分词函数之前,要先安装 Genius 模块,在 notebook 代码单元格输入“!pip install Genius”,运行后在单元格下方可以看到如所示的安装进度提示:


Collecting genius
  Downloading genius-3.1.6.tar.gz (18.7MB)
……
Successfully built genius libwapiti
Installing collected packages: nose, libwapiti, genius
Successfully installed genius-3.1.6 libwapiti-0.2.1 nose-1.3.7

(1)seg_text

seg_text 是 genius 模块中定义的分词函数,调用方式为:genius.seg_text(text,use_break,use_combine,use_tagging,use_parse_pinyin)

参数说明:

text: 需要分词的语句,必填参数且必须是 unicode

use_break: 代表对分词结构进行打断处理,默认值True

use_combine: 代表是否使用字典进行词合并,默认值False

use_tagging: 代表是否进行词性标注,默认值False

use_parse_pinyin: 代表是否对拼音进行分词处理,默认值False

例 1


In [1]:import genius
       seg_list = genius.seg_text(u"我爱文本数据分析",use_tagging=True)
       for i in seg_list:
           print i.text, i.tagging
       我 r
       爱 v
       文本 n
       数据分析 v

输出结果的第二列即为相应词汇的词性。

(2)seg_keywords

seg_keywords 是 genius 模块中保留歧义的适用于搜索引擎的分词函数,调用方式为:genius.seg_keywords(text, use_break,use_tagging,use_parse_pinyin)

参数说明:

text: 需要分词的语句,必填参数且必须是 unicode

use_break: 代表对分词结构进行打断处理,默认值True

use_tagging: 代表是否进行词性标注,默认值False

use_parse_pinyin: 代表是否对拼音进行分词处理,默认值False

例2


In [2]:seg_list = genius.seg_keywords(u"我爱文本数据分析")
       print('/'.join([word.text for word in seg_list]))
       我/爱/文/文本/本/数据/分析

4.1.4 finalseg

finalseg 是基于 HMM 模型的中文分词模块,采用的算法是 Viterbi,有新词识别功能,并可以选择性打开该功能。在线分词效果展示地址:https://finalseg.appspot.com/。执行语句 “!easy_install finalseg” 即可完成 finalseg 安装, cut 函数为 finalseg 中的分词函数,调用方式为:finalseg.cut(sentence, find_new_word=False)

参数说明:

sentence:待分词语句

find_new_word:是否开启新词识别功能,缺失值默认为 False


In [2]:import finalseg
In [3]:print "/".join(finalseg.cut("我爱文本数据分析"))
       我/爱/文本/数据/分析

4.1.5 scseg

scseg 中文分词,是基于 mmseg 的简单分词模块,支持汉字数字和拼音分词,使用者可以自定义词典。执行语句 “!pip install scseg” 即可完成 scseg 安装。该模块主要包括以下两个分词函数:

(1)seg_text

seg_text 为 scseg 模块的分词函数,调用方式为:scseg.seg_text(text, ext_dict_words=set([]), use_combine=True)

参数说明:

text:需要分词的语句

ext_dict_words:用户自定义的扩展字典

use_combine:是否需要合并处理,默认缺失值为 True

例 1


In[1]:import scseg
      seg_list = scseg.seg_text(u'我爱文本数据分析,wenben shuju')
      print '/'.join(seg_list)
      我爱/文本/数据/分析/wenben/shuju

(2)seg_keywords

seg_keywords 为 scseg 模块中保留歧义的适用于搜索引擎的分词函数,可以枚举出所有可能的切分方式,调用方式为:scseg.seg_keywords(text)

例 2


In [2]:seg_list = scseg.seg_keywords(u'我爱文本数据分析,wenben shuju')
       print '/'.join(seg_list)
       我爱/分析/爱文/shuju/文本/数据/wenben

4.1.6 pynlpir

pynlpir 中文分词是利用 NLPIR 进行中文分词的 Python 包,支持新词发现与自适应分词功能,从较长的文本内容中,基于信息交叉熵自动发现新特征语言,并自适应测试语料的语言概率分布模型,实现自适应分词。

其中 segment 是利用 NLPIR 进行中文分词的函数,分词结果以列表形式返回,若只设置分词参数则列表元素为分词后词汇的字符串,如:[“我”,“是”,……];若分词的同时进行词性标注,则列表元素为有分词后词汇字符串和相应的词性构成的元组,如:[(“我”,“pronoun”),(“是”,“verb”),……]。调用方式为:pynlpir.segment(s, pos_tagging=True, pos_names=u'parent', pos_english=True)

参数说明:

s: 需要分词的中文语句,必须为 Unicode 或者 UTF-8 编码的字符串

pos_tagging: 是否使用词性标注,默认缺失值为 True

pos_names: 返回何种类型的词性标注,即词性划分的层次,只有当参数 “pos_tagging” 取值为 “True” 时才需要进行设置. 有以下可选值,取值为字符串类型:
(1)data:返回 NLPIR 原始的词性编号
(2)parent:默认缺失值,表示使用常用词性表示方式,如将“国家科学基金会”这类词归为“noun”
(3)child:表示使用专用的、准确的词性表示方式,如将“国家科学基金会”这类词归为“transcribed toponym”
(4)all:表示综合使用多种表示方式分层标注词性,如将“国家科学基金会”这类词归为“noun:toponym:transcribed toponym”

pos_english: 使用英文还是中文显示词性标注结果,默认取值为“True”,即英文表示,也仅在参数 “pos_tagging” 取值为 “True” 时才需要进行设置.

4.1.7 SnowNLP

SnowNLP 是基于 Python 的中文文本处理库,自带已经训练好的字典,支持中文分词、词性标注、情感分析等文本数据分析功能。执行语句 “!pip install snownlp” 即可完成安装,该库定义的 SnowNLP 类包含了分词、词性标注、情感分析等方法,分词方法 words 的调用方式为:


from snownlp import SnowNLP 
实例 = SnowNLP(text) # 实例化,text 为需要分词处理的字符串
实例.words # 调用分词方法,得到分词结果列表

4.1.8 smallseg

smallseg 是一个开源的、基于 DFA 的轻量级中文分词模块,使用 RMM 字符串分割算法。其特点在于:可自定义词典,分词后可以返回登录词列表和未登录词列表,并且有一定的新词识别能力。smallseg 模块的安装也十分简单,将下载包中 smallseg.py 拷贝到 Python 安装目录的 Lib 文件夹中即可完成安装。

smallseg 模块中常用的分词方法是类 SEG 下定义的 cut 方法,该方法可以实现中文语句的切分,返回 识别出的登录词列表和未登录词列表,实例化类 SEG 后,通过“实例.cut(sentence)”即可实现对该分词方法的调用。

4.1.9 snailseg

snailseg 是一个基于 Python 的简单的中文分词库,通过统计单字在词语中出现的概率大小进行分词,选择最大可能的分词方案。snailseg 模块的安装也十分简单,将 snailseg 目录放置于当前目录或者 site-packages 目录即可完成安装。模块中的 cut 函数可以实现中文语句的切分,调用方式为:snailseg.cut(sentence)。

results matching ""

    No results matching ""