Python

中文分词

2018-01-11  本文已影响177人  我为峰2014

【转】https://zhuanlan.zhihu.com/p/22047433?iam=6e4e2b01ef856ed9c067d5f1560f9d56&utm_source=qq&utm_medium=social

一个中文文本从形式上看是由汉字(包括标点符号等)组成的一个字符串。由字可组成词,由词可组成句子,进而由一些句子组成段、节、章、篇。可见,如果需要处理一篇中文语料,从中正确的识别出词是一件非常基础而重要的工作。

1、中文分词概述

显而易见,中文以字为基本书写单位,词语之间没有明显的区分标记。中文分词就是由机器在词与词之间加上标记进行区分。例如:

输入: 我是学生。

输出: 我/是/学生/。

1.1 中文分词的关键问题

中文分词的关键问题为:切分歧义消解和未登录词识别

1.2 歧义切分定义

歧义切分的表示可以由下示例:

输入待切分句子:提高人民生活水平

可以切分输出 :提高/人民/生活/水平

或者切分输出:提/高人/民生/活水/平

明显第二个输出为歧义切分

1.3未登录词定义

常见的未登录词有实体名词、专有名词与新词

实体名词包括有:

中国人名:李素丽 老张 李四 王二麻子

中国地名:定福庄 白沟 三义庙 韩村 河马甸

翻译人名:乔治•布什 叶利钦 包法利夫人 酒井法子

翻译地名:阿尔卑斯山 新奥尔良 约克郡

机构名 :方正公司 联想集团 国际卫生组织 外贸部

商标字号:非常可乐 乐凯 波导 杉杉 同仁堂

专业术语和新词语

专业术语:万维网 主机板 模态 逻辑 贝叶斯算法

缩略语 :三个代表 五讲四美 打假 扫黄打非 计生办

新词语 :卡拉OK 波波族 美刀 港刀

未登录词没有明确边界,缺少英语中的分隔符、大小写、词的形态、冠词等语法信息,识别比较困难。

因此通常每一类未登录词都要构造专门的识别算法。

2、分词主要技术方法

2.1 基于词典的分词

词典中一般存储着:词、词频、词性等信息,可以通过统计标注好的熟语料和常用词典得到。

基于词典分词方法首先需要对句子进行原子切分,即找出句子中可能蕴含组成的所有词,然后构成词图。还是之前例子,输入:

提高人民生活水平

输出所有包括的词:

提 —提高

高 —高人

人 —人民

民 —民生

生—生活

活—活水

水 —水平

则可以构成词图如下:

词图.jpg

上述工作主要重点是词典存储于并快速匹配,多采用双数组Tie树的方法生成词典树,用自动机匹配词串。

2.2词典分词的歧义消解问题

歧义消解可以转换为对于上述在词图上寻找统计意义上的最佳路径。常用一元、二元模型进行。

基于一元模型进行评价:

统计词表中每个词的词频,并将其转化为路径代价C=-log(f/N)切分路径的代价为路径上所有词的代价之和寻求代价最小的路径。上述例子就是根据词典中<提高><高人><人民><民生><生活><活水><水平><平>这几个词的词频f,认为词频越高的路径代价越小,找出最短的路径。

基于二元模型进行评价:

相对于一元模型,二元模型还需要一个词转移统计词典,例如记录了<提高>衔接<人民>的次数,词转移统计词典实质上是一个稀疏矩阵。基于二元模型进行评价需要在一元模型的基础上增加转移路径代价。词典中转移次数多的衔接认为该衔接转移路径代价小。计算方法可以用Viterbi算法。

2.3词典分词的未登陆词问题

简单来说,可以将未登陆词的识别转换成序列标注问题即打标签,然后用HMM或其它统计学习方法求解。例如中国人名识别可以表示为(姓+名)的形式,例如对于一个人名:金三胖 可以正确标注序列为:金/姓 三胖/名,则人名可以识别出来。具体可参见张华平相关论文《基于层叠隐马尔可夫模型的中文命名实体识别》、《基于角色标注的中国人名自动识别研究》、《基于角色标注的中文机构名识别》。

2.4基于字的分词

基于字的分词可以平衡的看待词表词和未登录词的识别问题。

汉语中词都是有字组成的,可以将分词视为字的序列标注问题。例如对于“占”这个字可以有以下词位标注:

基于字的分词实现很简单,例如对于句子

上海/计划/到/本/世纪/末/实现/人均/国内/生产/总值/五千美元/。

可以有如下词位序列标注:

上/B海/E计/B划/E到/S本/S世/B纪/E末/S实/B现/E人/B均/E国/B内/E生/B产/E总/B值/E五/B千/M美/M元/E。/S

根据标注BMES实现了分词。

转换成序列标注问题后常用算法有HMM (隐马模型)、MEMM(最大熵隐马模型)、CRF等。下面简单比较一下:

隐马模型一个最大的缺点就是由于其输出独立性假设,导致其不能考虑上下文的特征,限制了特征的选择。

最大熵隐马模型则解决了隐马的问题,可以任意选择特征,但由于其在每一节点都要进行归一化,所以只能找到局部的最优值,同时也带来了标记偏见的问题,即凡是训练语料中未出现的情况全都忽略掉。

条件随机场则很好的解决了这一问题,他并不在每一个节点进行归一化,而是所有特征进行全局归一化,因此可以求得全局的最优值。

2.5 主要分词技术评价

速度快,效率高,易修改,灵活性强。

主要依赖词典和规则库,对于歧义词和未登录词的识别能力较低。

对于歧义词和未登录词的识别能力较好。

(1)模型体积大占内存。例如一个可供生产环境用的CRF模型至少使用前中后3个字符的组合做特征模板,在一两百兆的语料上训练,模型体积至少上百兆。

(2)速度慢。相较于基于词语的BiGram分词器,一个拖速度的地方是特征函数的查询次数多、速度慢,另一个弱点则是概率图的节点更多(4倍文本长度个节点,4是BMES标签的个数)。

(3)不易修改。有时候用户对分词结果不满意,却无法方便地修正它。包括CRF在内的其他模型都需要重新训练,或者修改代码。而基于词语的NGram词典和词频词典可以轻松修改。


在自然语言处理过程中,为了能更好地处理句子,往往需要把句子拆开分成一个一个的词语,这样能更好的分析句子的特性,这个过程叫做——分词.

Github上已经有造好的轮子了,用别人的吧,而且,假如自己造的轮子在短时间内也没有别人的好用,废话少说,我们看看jieba中文分词。

结巴分词支持三种分词模式:

  1. 精确模式,试图将句子最精确地切开,适合文本分析;

  2. 全模式,把句子中所有的可以成词的词语都扫描出来, 速度非常快,但是不能解决歧义;

  3. 搜索引擎模式,在精确模式的基础上,对长词再次切分,提高召回率,适合用于搜索引擎分词。

算法:

(这应该是分词的原理,以后挑个好日子,坐下来,好好地去梳理下)

主要方法:

import jieba
​
seg_list = jieba.cut("我来到北京清华大学",cut_all=True)
print("Full Mode: " + "/ ".join(seg_list))  # 全模式
​
seg_list = jieba.cut("我来到北京清华大学",cut_all=False)
print("Default Mode: " + "/ ".join(seg_list))  # 精确模式
​
seg_list = jieba.cut("他来到了网易杭研大厦") #默认是精确模式
print(", ".join(seg_list))
​
seg_list = jieba.cut_for_search("小明硕士毕业于中国科学院计算所,后在日本京都大学深造") #搜索引擎模式
print(", ".join(seg_list))
输出:
Building prefix dict from the default dictionary ...
Dumping model to file cache C:\Users\lenovo\AppData\Local\Temp\jieba.cache
Loading model cost 5.787 seconds.
Prefix dict has been built succesfully.
Full Mode: 我/ 来到/ 北京/ 清华/ 清华大学/ 华大/ 大学
Default Mode: 我/ 来到/ 北京/ 清华大学
他, 来到, 了, 网易, 杭研, 大厦
小明, 硕士, 毕业, 于, 中国, 科学, 学院, 科学院, 中国科学院, 计算, 计算所, ,, 后, 在, 日本, 京都, 大学, 日本京都大学, 深造

添加自定义词典(如果觉得jieba自己的词典不够,你还可以自己添加)。

调整词典

关键词提取

词性标注

并行分词

Tokenize

当然,你要是还想更加深入的了解,推荐《NLP汉语自然语言处理》

书籍简介

这本书是一本研究汉语自然语言处理方面的基础性,综合性书籍,涉及NLP的语言理论,算法和工程的方方面面,内容复杂。

本书包括NLP的语言理论部分,算法部分,案例部分,涉及汉语的发展历史,传统的句法理论,认知语言理论。需要指出的是系统的介绍认知语言学和算法设计相结合的中文NLP书籍,并从认识语言学的视角重新认识和分析了NLP的句法和语义相结合的数据结构。

分词

中文NLP比外文要难,难再第一步就是要将文本进行切词。我们知道中文常用字也就3500左右,但是单字往往意义不多,对理解句子的意思帮助不大。而且中文词之间没有空格等标识符,这增加了NLP的难度。

NLP第一步,就是从分词开始,目前市面上有ICTCLASS,jieba,HanNLP等,了解其分词算法原理,对更好的学习编程,使用编程语言处理文本数据有好处。

既然,我们掌握了基本的分词技术,那就来制作一个词云吧

用到的工具

  1. 原始数据:txt格式,可以用爬虫爬点网页数据做原始数据。为简单就先用txt练手好了。

  2. 提取关键词:jieba分词、停用词表

  3. 在线词云生成工具:TAGUL

简单分析一下

生成词云最关键的问题是中文分词,统计分析各个词的权重(权重较高的字体显示较大)。这些问题jieba分词已经帮我们解决了。我们只需要

import jieba.analyse

使用

jieba.analyse.extract_tags(sentence, topK=20, withWeight=False, allowPOS=())

方法即可,当然只是提取关键词还是不够的,因为有些没有意义的常用词诸如“我的”、“或者”、“一个”等词,会出现在结果里面,还需要一个“停用词表”来帮我们过滤结果。

我们的目标是提取关键词,并得到“关键词+制表符+权重”的文本,这里关键词和权重用制表符隔开是为了在用在线工具的时候,能顺利导入权重的值,决定词的大小(size)。

步骤:

  1. 安装jieba pip install jieba

  2. 准备好txt文件和停用词表(网上可以下载到,txt格式即可)

  3. 编写代码

代码

import jieba.analyse
​
path = '你的txt文件路径'
file_in = open(path, 'r',encoding='utf-8',errors='ignore')
content = file_in.read()
​
try:
 jieba.analyse.set_stop_words('你的停用词表路径')
 tags = jieba.analyse.extract_tags(content, topK=100, withWeight=True)
 for v, n in tags:
 #权重是小数,为了凑整,乘了一万
 print( v + '\t' + str(int(n * 10000)))
​
finally:
 file_in.close()

打开TAGUL,开始制作词云,把结果贴进import words里

TAGUL的教程https://www.zhihu.com/question/35976761/answer/67023767?from=profile_answer_card

上一篇 下一篇

猜你喜欢

热点阅读