中文分词

作者: 我为峰2014 | 来源:发表于2018-01-11 16:15 被阅读177次

【转】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 抢占

  • 词中M 独占鳌头

  • 单字词S 已占全国

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

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

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

上/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. 搜索引擎模式,在精确模式的基础上,对长词再次切分,提高召回率,适合用于搜索引擎分词。

算法:

  • 基于前缀词典实现高效的词图扫描,生成句子中汉字所有可能成词情况所构成的有向无环图 (DAG)

  • 采用了动态规划查找最大概率路径, 找出基于词频的最大切分组合

  • 对于未登录词,采用了基于汉字成词能力的 HMM 模型,使用了 Viterbi 算法

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

主要方法:

  • jieba.cut 方法接受三个输入参数: 需要分词的字符串;cut_all 参数用来控制是否采用全模式;HMM 参数用来控制是否使用 HMM 模型

  • jieba.cut_for_search 方法接受两个参数:需要分词的字符串;是否使用 HMM 模型。该方法适合用于搜索引擎构建倒排索引的分词,粒度比较细

  • 待分词的字符串可以是 unicode 或 UTF-8 字符串、GBK 字符串。注意:不建议直接输入 GBK 字符串,可能无法预料地错误解码成 UTF-8

  • jieba.cut 以及 jieba.cut_for_search 返回的结构都是一个可迭代的 generator,可以使用 for 循环来获得分词后得到的每一个词语(unicode),或者用

  • jieba.lcut 以及 jieba.lcut_for_search 直接返回 list

  • jieba.Tokenizer(dictionary=DEFAULT_DICT) 新建自定义分词器,可用于同时使用不同词典。jieba.dt 为默认分词器,所有全局分词相关函数都是该分词器的映射。例如:

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自己的词典不够,你还可以自己添加)。

  • 开发者可以指定自己自定义的词典,以便包含 jieba 词库里没有的词。虽然 jieba 有新词识别能力,但是自行添加新词可以保证更高的正确率

  • 用法: jieba.load_userdict(file_name) # file_name 为文件类对象或自定义词典的路径

  • 词典格式和 dict.txt 一样,一个词占一行;每一行分三部分:词语、词频(可省略)、词性(可省略),用空格隔开,顺序不可颠倒。file_name 若为路径或二进制方式打开的文件,则文件必须为 UTF-8 编码。

  • 词频省略时使用自动计算的能保证分出该词的词频。

调整词典

  • 使用 add_word(word, freq=None, tag=None) 和 del_word(word) 可在程序中动态修改词典。

  • 使用 suggest_freq(segment, tune=True) 可调节单个词语的词频,使其能(或不能)被分出来。

  • 注意:自动计算的词频在使用 HMM 新词发现功能时可能无效。

关键词提取

  • 基于 TF-IDF 算法的关键词抽取。

  • 基于 TextRank 算法的关键词抽取。

词性标注

  • jieba.posseg.POSTokenizer(tokenizer=None) 新建自定义分词器,tokenizer 参数可指定内部使用的 jieba.Tokenizer 分词器。jieba.posseg.dt 为默认词性标注分词器。

  • 标注句子分词后每个词的词性,采用和 ictclas 兼容的标记法。

并行分词

  • 原理:将目标文本按行分隔后,把各行文本分配到多个 Python 进程并行分词,然后归并结果,从而获得分词速度的可观提升

  • 基于 python 自带的 multiprocessing 模块,目前暂不支持 Windows。

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

相关文章

  • “结巴”中文分词:做最好的 Python中文分词组件

    “结巴”中文分词:做最好的 Python中文分词组件 1 jieba中文分词简介: 中文分词是中文NLP的第一步,...

  • 第3章 中文分词技术

    本章要点: 中文分词的概念与分类 常用分词的技术介绍 开源中文分词工具-Jieba简介 实战分词之高频词提取 中文...

  • 配置Hanlp自然语言处理进阶

    中文分词 中文分词中有众多分词工具,如结巴、hanlp、盘古分词器、庖丁解牛分词等;其中庖丁解牛分词仅仅支持jav...

  • 分词系统评测

    1.11款开放中文分词引擎大比拼 2.常用的开源中文分词工具 3.11大Java开源中文分词器的使用方法和分词效果...

  • python笔记 | 舆情分析如何做?

    中文分词原理及分词工具介绍 中文分词(Chinese Word Segmentation) 指的是将一个汉字序列切...

  • 中文分词工具及中文语料资源

    关键词: 中文分词;分词;自然语言处理;中文语料 最近要做中文自然语言处理相关任务,牵涉到使用中文分词工具和相关算...

  • 结巴中文分词的用法

    jieba “结巴”中文分词:做最好的 Python 中文分词组件"Jieba" (Chinese for "to...

  • python 结巴分词

    jieba “结巴”中文分词:做最好的 Python 中文分词组件“Jieba” (Chinese for “to...

  • 基于Trie 树实现简单的中文分词

    中文分词简介 中文分词是中文自然语言处理的基础,中文分词的正确率如何直接影响后续的词性标注(也有些词性标注算法不需...

  • Python中文分词及词频统计

    中文分词 中文分词(Chinese Word Segmentation),将中文语句切割成单独的词组。英文使用空格...

网友评论

本文标题:中文分词

本文链接:https://www.haomeiwen.com/subject/wactoxtx.html