"结巴"中文分词

1. 结巴中文分词

    结巴分词是国内程序员用开发的一个中文分词模块, 源码已托管在github,https://github.com/fxsjy/jieba

2. 结巴分词算法:

    a. 基于Trie树结构实现高效的词图扫描,生成句子中汉字所有可能成词情况所构成的有向无环图(DAG)
    b. 采用了动态规划查找最大概率路径, 找出基于词频的最大切分组合

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

3. 结巴分词理解 (转载自:http://tieba.baidu.com/p/3145509319)

     第一条:基于Trie树结构实现高效的词图扫描,生成句子中汉字所有可能成词情况所构成的有向无环图(DAG)
     结巴分词自带了一个叫做dict.txt的词典, 里面有2万多条词, 包含了词条出现的次数(这个次数是于作者自己基于人民日报语料等资源训练得出来的)和词性. 这个第一条的trie树结构的词图扫描, 说的就是把这2万多条词语, 放到一个trie树中, 而trie树是有名的前缀树, 也就是说一个词语的前面几个字一样, 就表示他们具有相同的前缀, 就可以使用trie树来存储, 具有查找速度快的优势.
     聪明的人可能会想到把 dict.txt中所有的词汇全部删掉, 然后再试试结巴能不能分词, 结果会发现, 结巴依然能够分词, 不过分出来的词, 大部分的长度为2.这个就是第三条, 基于HMM来预测分词了.
     接着说DAG有向无环图, 就是后一句的 生成句子中汉字所有可能成词情况所构成的有向无环图, 这个是说的, 给定一个句子, 要你分词, 也就是给定一个 待分词的句子, 对这个句子进行生成有向无环图. 如果对有向无环图理解不了可以百度或者google搜索, 也可以看这篇 http://book.51cto.com/art/201106/269048.htm比较形象的用图来表示了一个待分词句子的切分情况.
     作者是怎么切分的呢?

     1. 根据dict.txt生成trie树

     2, 对待分词句子, 根据dict.txt生成的trie树, 生成DAG, 实际上通俗的说, 就是对待分词句子, 根据给定的词典进行查词典操作, 生成几种可能的句子切分. dag是啥玩意?记录了啥呢? 作者的源码中记录的是句子中某个词的开始位置, 从0到n-1(n为句子的长度), 每个开始位置作为字典的键, value是个list, 其中保存了可能的词语的结束位置(通过查字典得到词, 开始位置+词语的长度得到结束位置)
例如:{0:[1,2,3]} 这样一个简单的DAG, 就是表示0位置开始, 在1,2,3位置都是词, 就是说0~1, 0~2,0~3这三个起始位置之间的字符, 在dict.txt中是词语.

      第二条:采用了动态规划查找最大概率路径, 找出基于词频的最大切分组合
      作者的代码中讲字典在生成trie树的同时, 也把每个词的出现次数转换为了频率. 关于频率和概率, 这里在啰嗦几句: 按照定义, 频率其实也是一个0~1之间的小数, 是 事件出现的次数/实验中的总次数, 因此在试验次数足够大的情况下, 频率约等于概率, 或者说频率的极限就是概率. 不过通常人们混淆的是频率和次数, 经常把频率等同于事件出现的次数, 比如这里就是某个词语出现的次数, 所以, 频率在引起混淆的时候, 对中国人来说, 还是先理解为出现次数, 然后理解发现有问题, 就理解为出现次数/总数这个比率吧.
      动态规划中, 先查找待分词句子中已经切分好的词语, 对该词语查找该词语出现的频率(次数/总数), 如果没有该词(既然是基于词典查找, 应该是有的), 就把词典中出现频率最小的那个词语的频率作为该词的频率, 也就是说P(某词语)=FREQ.get('某词语',min_freq), 然后根据动态规划查找最大概率路径的方法, 对句子从右往左反向计算最大概率(一些教科书上可能是从左往右, 这里反向是因为汉语句子的重心经常落在后面, 就是落在右边, 因为通常情况下形容词太多, 后面的才是主干, 因此, 从右往左计算, 正确率要高于从左往右计算, 这个类似于逆向最大匹配), P(NodeN)=1.0, P(NodeN-1)=P(NodeN)*Max(P(倒数第一个词))...依次类推, 最后得到最大概率路径, 得到最大概率的切分组合.

       第三条, 对于未登录词,采用了基于汉字成词能力的HMM模型,使用了Viterbi算法
       未登录词, 作者说的是什么意思? 其实就是词典 dict.txt 中没有记录的词. 上面说了, 把dict.txt中的所有词语都删除了, 结巴分词一样可以分词, 就是说的这个.
        怎么做到的? 这个就基于作者采用的HMM模型了, 中文词会按照BEMS四个状态来标记, B是开始begin位置, E是end, 是结束位置, M是middle, 是中间位置, S是singgle, 单独成词的位置, 没有前, 也没有后. 也就是说, 他采用了状态为(B,E,M,S)这四种状态来标记中文词语, 比如北京可以标注为 BE, 即 北/B 京/E, 表示北是开始位置, 京是结束位置, 中华民族可以标注为BMME, 就是开始, 中间, 中间, 结束.
        要统计的主要有三个概率表:
       1). 位置转换概率,即B(开头),M(中间),E(结尾),S(独立成词)四种状态的转移概率; {'B': {'E': 0.8518218565181658, 'M': 0.14817814348183422}, 'E': {'B': 0.5544853051164425, 'S': 0.44551469488355755}, 'M': {'E': 0.7164487459986911, 'M': 0.2835512540013088}, 'S': {'B': 0.48617017333894563, 'S': 0.5138298266610544}}
           P(E|B) = 0.851, P(M|B) = 0.149,说明当我们处于一个词的开头时,下一个字是结尾的概率 要远高于下一个字是中间字的概率,符合我们的直觉,因为二个字的词比多个字的词更常见。

        2). 位置到单字的发射概率,比如P("和"|M)表示一个词的中间出现”和"这个字的概率

        3). 词语以某种状态开头的概率,其实只有两种,要么是B,要么是S。这个就是起始向量, 就是HMM系统的最初模型状态

       实际上, BEMS之间的转换有点类似于2元模型, 就是2个词之间的转移
       二元模型考虑一个单词后出现另外一个单词的概率,是N元模型中的一种。
       例如:一般来说,"中国"之后出现"北京"的概率大于"中国"之后出现"北海"的概率,也就是:中国北京 比 中国北海出现的概率大些, 更有可能是一个中文词语.
       不过, 作者这里应该不是用的2元分词模型的, 这里的BEMS只提供了单个汉字之间的转换, 发射概率, 并没有提供粒度更大的, 基于词语的发射和转移概率, 当然, 也有可能我理解的不够深入.
       给定一个 待分词的句子, 就是观察序列, 对HMM(BEMS)四种状态的模型来说, 就是为了找到一个最佳的BEMS序列, 这个就需要使用viterbi算法来得到这个最佳的隐藏状态序列, 具体的python版的viterbi算法请看维基百科:http://zh.wikipedia.org/wiki/%E7%BB%B4%E7%89%B9%E6%AF%94%E7%AE%97%E6%B3%95维特比算法
       通过作者之前训练得到的概率表和viterbi算法, 就可以得到一个概率最大的BEMS序列, 按照B打头, E结尾的方式, 对待分词的句子重新组合, 就得到了分词结果. 比如 对待分词的句子 '全世界都在学中国话' 得到一个BEMS序列 [S,B,E,S,S,S,B,E,S] 这个序列只是举例, 不一定正确, 通过把连续的BE凑合到一起得到一个词, 单独的S放单, 就得到一个分词结果了: 上面的BE位置和句子中单个汉字的位置一一对应, 得到全/S 世界/BE 都/S 在/S 学/S 中国/BE 话/S 从而将句子切分为词语.

时间: 2024-08-31 18:48:39

"结巴"中文分词的相关文章

[python] 使用Jieba工具中文分词及文本聚类概念

        前面讲述了很多关于Python爬取本体Ontology.消息盒InfoBox.虎扑图片等例子,同时讲述了VSM向量空间模型的应用.但是由于InfoBox没有前后文和语义概念,所以效果不是很好,这篇文章主要是爬取百度5A景区摘要信息,再利用Jieba分词工具进行中文分词,最后提出文本聚类算法的一些概念知识.         相关文章:         [Python爬虫] Selenium获取百度百科旅游景点的InfoBox消息盒         [python爬虫] Seleni

11款开放中文分词引擎大比拼

来自: http://blog.csdn.net/matthewei6/article/details/50610882 在逐渐步入DT(Data Technology)时代的今天,自然语义分析技术越发不可或缺.对于我们每天打交道的中文来说,并没有类似英文空格的边界标志.而理解句子所包含的词语,则是理解汉语语句的第一步.汉语自动分词的任务,通俗地说,就是要由机器在文本中的词与词之间自动加上空格. 一提到自动分词,通常会遇到两种比较典型的质疑.一种质疑是来自外行人的:这件事看上去平凡之极,好像一点

一文详解如何用 python 做中文分词

打算绘制中文词云图?那你得先学会如何做中文文本分词.跟着我们的教程,一步步用 Python 来动手实践吧.   需求 在此前发布的文章<从零开始教你用 Python 做词云>一文中,我们介绍了英文文本的词云制作方法.大家玩儿得可还高兴? 文中提过,选择英文文本作为示例,是因为处理起来最简单.但是很快就有读者尝试用中文文本做词云了.按照前文的方法,你成功了吗? 估计是不成功的.因为这里面缺了一个重要的步骤. 观察你的英文文本.你会发现英文单词之间采用空格作为强制分隔符. 例如: Yes Mini

jieba.NET中文分词及jieba.NET与Lucene.Net的集成

jieba中文分词的.NET版本:jieba.NET jieba使用起来非常简单,同时分词的结果也令人印象深刻,有兴趣的可以到它的在线演示站点体验下(注意第三行文字). .NET平台上常见的分词组件是盘古分词,但是已经好久没有更新了.最明显的是内置词典,jieba的词典有50万个词条,而盘古的词典是17万,这样会造成明显不同的分词效果.另外,对于未登录词,jieba"采用了基于汉字成词能力的HMM模型,使用了Viterbi算法",效果看起来也不错. 基于以上两点,加上对于中文分词的兴趣

数学之美 系列二 -- 谈谈中文分词

谈谈中文分词----- 统计语言模型在中文处理中的一个应用 上回我们谈到利用统计语言模型进行语言处理,由于模型是建立在词的基础上的,对于中日韩等语言,首先需要进行分词.例如把句子 "中国航天官员应邀到美国与太空总署官员开会." 分成一串词:中国 / 航天 / 官员 / 应邀 / 到 / 美国 / 与 / 太空 / 总署 / 官员 / 开会. 最容易想到的,也是最简单的分词办法就是查字典.这种方法最早是由北京航天航空大学的梁南元教授提出的. 用 "查字典" 法,其实就

ASP.NET编写简单的中文分词程序

asp.net|程序|中文 几个月之前,在网上找到了一个中文词库素材(几百K),当时便想写一个分词程序了.我对汉语分词没有什么研究,也就凭自己臆想而写.若有相关方面专家,还请多给意见. 一.词库 词库大概有5万多词语(google能搜到,类似的词库都能用),我摘要如下: 地区    82重要    81新华社    80技术    80会议    80自己    79干部    78职工    78群众    77没有    77今天    76同志    76部门    75加强    75组

什么是中文分词

中文 什么是中文分词? 众所周知,英文是以词为单位的,词和词之间是靠空格隔开,而中文是以字为单位,句子中所有的字连起来才能描述一个意思.例如,英文句子I am a student,用中文则为:"我是一个学生".计算机可以很简单通过空格知道student是一个单词,但是不能很容易明白"学"."生"两个字合起来才表示一个词.把中文的汉字序列切分成有意义的词,就是中文分词,有些人也称为切词.我是一个学生,分词的结果是:我是 一个 学生. 目前主流的中文

用PHP简易实现中文分词

中文 hehe, 用PHP去做中文分词并不是一个太明智的举动, :p 下面是我根据网上找的一个字典档, 简易实现的一个分词程序. (注: 字典档是gdbm格式, key是词 value是词频, 约4万个常用词) 完整的程序演示及下载请参见: http://root.twomice.net/my_php4/dict/chinese_segment.php <?php//中文分词系统简易实现办法//切句单位:凡是ascii值<128的字符//常见双字节符号:<>,..?"&q

你不知道的秘籍 百度的中文分词三点原理

百度中文分词算法:指搜索引擎为了更好的辨别用户的需求,并且为了快速提供给用户需求性信息而使用的算法. 搜索引擎要在单位时间内处理千万亿级的页面数据量,因此搜索引擎拥有一个中文词库.比如百度现在大约有9万个中文词,那么搜索引擎就可以对千亿级的页面进行分析,按照中文词库进行了分类. 百度分词基本有三种分法 1.基于理解:傻瓜式匹配,小于等于3个中文字符百度是不进行切词的,比如搜索"大学堂". 2.基于统计:百度把一个词标红的原因:标红的词一般是一个关键词,你搜索"学"字