分类目录归档:中文分词

Python自然语言处理实践: 在NLTK中使用斯坦福中文分词器

Start your future on Coursera today.

斯坦福大学自然语言处理组是世界知名的NLP研究小组,他们提供了一系列开源的Java文本分析工具,包括分词器(Word Segmenter),词性标注工具(Part-Of-Speech Tagger),命名实体识别工具(Named Entity Recognizer),句法分析器(Parser)等,可喜的事,他们还为这些工具训练了相应的中文模型,支持中文文本处理。在使用NLTK的过程中,发现当前版本的NLTK已经提供了相应的斯坦福文本处理工具接口,包括词性标注,命名实体识别和句法分析器的接口,不过可惜的是,没有提供分词器的接口。在google无果和阅读了相应的代码后,我决定照猫画虎为NLTK写一个斯坦福中文分词器接口,这样可以方便的在Python中调用斯坦福文本处理工具。

首先需要做一些准备工作,第一步当然是安装NLTK,这个可以参考我们在gensim的相关文章中的介绍《如何计算两个文档的相似度》,不过这里建议check github上最新的NLTK源代码并用“python setup.py install”的方式安装这个版本:https://github.com/nltk/nltk。这个版本新增了对于斯坦福句法分析器的接口,一些老的版本并没有,这个之后我们也许还会用来介绍。而我们也是在这个版本中添加的斯坦福分词器接口,其他版本也许会存在一些小问题。其次是安装Java运行环境,以Ubuntu 12.04为例,安装Java运行环境仅需要两步:

sudo apt-get install default-jre
sudo apt-get install default-jdk

最后,当然是最重要的,你需要下载斯坦福分词器的相应文件,包括源代码,模型文件,词典文件等。注意斯坦福分词器并不仅仅支持中文分词,还支持阿拉伯语的分词,需要下载的zip打包文件是这个: Download Stanford Word Segmenter version 2014-08-27,下载后解压。

准备工作就绪后,我们首先考虑的是在nltk源代码里的什么地方来添加这个接口文件。在nltk源代码包下,斯坦福词性标注器和命名实体识别工具的接口文件是这个:nltk/tag/stanford.py ,而句法分析器的接口文件是这个:nltk/parse/stanford.py , 虽然在nltk/tokenize/目录下有一个stanford.py文件,但是仅仅提供了一个针对英文的tokenizer工具PTBTokenizer的接口,没有针对斯坦福分词器的接口,于是我决定在nltk/tokenize下添加一个stanford_segmenter.py文件,作为nltk斯坦福中文分词器的接口文件。NLTK中的这些接口利用了Linux 下的管道(PIPE)机制和subprocess模块,这里直接贴源代码了,感兴趣的同学可以自行阅读:
继续阅读

中文分词入门之字标注法全文文档

Start your future on Coursera today.

将“中文分词入门之字标注法”这个系列整理成了一个PDF文档放到微盘中了,感兴趣的同学可以下载:

微盘:中文分词入门之字标注法.pdf
百度网盘:中文分词入门之字标注法.pdf

如果愿意看网页,也可以从这个标签进入:字标注中文分词

另外在上一节关于CRF中文分词的介绍中,通过CRF++训练了一个CRF中文分词模型,实际训练的时间比较长,为了方便大家测试,也把这个CRF模型上传到微盘了,感兴趣的同学可以下载:crf_model

注:原创文章,转载请注明出处“我爱自然语言处理”:www.52nlp.cn

本文链接地址:http://www.52nlp.cn/中文分词入门之字标注法全文文档

中文分词入门之字标注法4

Start your future on Coursera today.

上一节主要介绍的是利用最大熵工具包来做字标注中文分词,这一节我们直奔主题,借用条件随机场工具“CRF++: Yet Another CRF toolkit”来完成字标注中文分词的全过程。

关于条件随机场(CRF)的背景知识,推荐参考阅读一些经典的文献:《条件随机场文献阅读指南》,另外再额外推荐一个tutorial:《Classical Probabilistic Models and Conditional Random Fields》, 这份关于CRF的文档分别从概率模型(NB,HMM,ME, CRF)之间的关系以及概率图模型背景来介绍条件随机场,比较清晰:

While a Hidden Markov Model is a sequential extension to the Nave Bayes Model, Conditional Random Fields can be understood as a sequential extension to the Maximum Entropy Model.

如果这些还不够过瘾,推荐课程图谱上收录的Coursera创始人之一Daphne Koller的“概率图模型公开课”,相信拿下这门课之后,对于上述概率模型,会有一种“一览众山小”的感觉。
继续阅读

中文分词入门之字标注法3

Start your future on Coursera today.

最近要整理一下课程图谱里的中文课程,需要处理中文,首当其冲的便是中文分词的问题。目前有一些开源的或者商用的中文分词器可供选择,但是出于探索或者好奇心的目的,想亲手打造一套实用的中文分词器,满足实际的需求。这些年无论是学习的时候还是工作的时候,林林总总的接触了很多实用的中文分词器,甚至在这里也写过一些Toy级别的中文分词相关文章,但是没有亲手打造过自己的分词器,甚为遗憾。目前自己处于能自由安排工作的阶段,所以第一步就是想从中文信息处理的桥头堡“中文分词”入手,打造一个实用的中文分词器,当然,首先面向的对象是课程图谱所在的教育领域。

大概4年前,这里写了两篇关于字标注中文分词的文章:中文分词入门之字标注法,文中用2-tag(B,I)进行说明并套用开源的HMM词性标注工具Citar(A simple Trigram HMM part-of-speech tagger)做了演示,虽然分词效果不太理想,但是能抛砖引玉,也算是有点用处。这次捡起中文分词,首先想到的依然是字标注分词方法,在回顾了一遍黄昌宁老师和赵海博士在07年第3期《中文信息学报》上发表的《中文分词十年回顾》后,决定这次从4-tag入手,并且探索一下最大熵模型和条件随机场(CRF)在中文分词字标注方法上的威力。这方面的文献大家可参考张开旭博士维护的“中文分词文献列表”。这里主要基于已有文献的思路和现成的开源工具做一些验证,包括张乐博士的最大熵模型工具包(Maximum Entropy Modeling Toolkit for Python and C++)和条件随机场的经典工具包CRF++(CRF++: Yet Another CRF toolkit)。

这个系列也将补充两篇文章,一篇简单介绍背景知识并介绍如何利用现成的最大熵模型工具包来做中文分词,另外一篇介绍如何用CRF++做字标注分词,同时基于CRF++的python接口提供一份简单的 CRF Python 分词代码,仅供大家参考。至于最大熵和CRF++的背景知识,这里不会过多涉及,推荐大家跟踪一下课程图谱上相关的机器学习公开课

这次使用的中文分词资源依然是SIGHAN提供的backoff 2005语料,目前封闭测试最好的结果是4-tag+CFR标注分词,在北大语料库上可以在准确率,召回率以及F值上达到92%以上的效果,在微软语料库上可以到达96%以上的效果。不清楚这份中文分词资源的同学可参考很早之前写的这篇文章:中文分词入门之资源。以下我们将转入这篇文章的主题,基于最大熵模型的字标注中文分词。
继续阅读

Darts: Double-ARray Trie System 翻译文档

Start your future on Coursera today.

Darts: Double-ARray Trie System

开篇

Darts 是用于构建双数组 Double-Array [Aoe 1989] 的简单的 C++ Template Library . 双数组 (Double-Array) 是用于实现 Trie 的一种数据结构, 比其它的类 Trie 实现方式(Hash-Tree, Digital Trie, Patricia Tree, Suffix Array) 速度更快。 原始的 Double-Array 使能够支持动态添加删除 key, 但是 Darts 只支持把排好序的词典文件转换为静态的 Double-Array.

Darts 既可以像 Hash 一样作为简单的词典使用,也能非常高效的执行分词词典中必须的 Common Prefix Search 操作。

自2003年7月起, 两个开源的日语分词系统 MeCabChaSen 都使用了 Darts .

继续阅读

日文分词器 Mecab 文档

Start your future on Coursera today.

一、日文分词器 MeCab 简介

mecab (http://mecab.sourceforge.net/) 是奈良先端科学技術大学院的工藤拓开发的日文分词系统, 该作者写过多个 machine learning 方面的软件包, 最有名的就是 CRF++, 目前该作者在 google@Japan 工作。

mecab 是基于CRF 的一个日文分词系统,代码使用 c++ 实现, 基本上内嵌了 CRF++ 的代码, 同时提供了多种脚本语言调用的接口(python, perl, ruby 等).整个系统的架构采用通用泛化的设计, 用户可以通过配置文件定制CRF训练中需要使用的特征模板。 甚至, 如果你有中文的分词语料作为训练语料,可以在该架构下按照其配置文件的规范定制一个中文的分词系统。

日文NLP 界有几个有名的开源分词系统, Juman, Chasen, Mecab.   Juman 和 Chasen 都是比较老的系统了, Mecab 系统比较新, 在很多方面都优于 Juman 和 Chasen, mecab 目前开发也比较活跃。 Mecab 虽然使用 CRF 实现, 但是解析效率上确相当高效, 据作者的介绍, Mecab 比基于 HMM 的 Chasen 的解析速度要快。 笔者在一台 Linux 机器上粗略测试过其速度,将近达到 2MB/s, 完全达到了工程应用的需求, 该系统目前在日文 NLP 界被广泛使用。

中文和日文的有着类似的分词需求,因此mecab 对于中文处理来说有着很好的借鉴价值, 由于mecab 的内部模块化得很清晰,如果能读懂其文档的话,是比较容易能看懂整套代码的。 可惜目前中文的资料很少, 而其自带的文档又都是日文的, 所以了解它的中国人不多。

笔者把 mecab 自带的文档从日文翻译成中文, 希望mecab对于中文分词有兴趣的读者能有借鉴价值。日语水平很烂, 大家凑合着看吧。 对于自由的文档翻译,有一句话: Document is like sex. If it's good, it's very very good. If it's bad, it's better than nothing.

二、关于 MeCab (和布蕪)

Mecab 是京都大学情报学研究科-日本电信电话股份有限公司通信科学基础研究所通过 Unit Project 的合作研究共同开发的词法分析引擎。其设计的基本方针是不依赖于具体的语言,词典,语料库, 采用 Conditional Random Fields (CRF) 模型进行参数估计, 性能优于使用隐马模型的 ChaSen 。同时, 平均解析速度高于 ChaSenJumanKAKASI 这些日文词法分析器. 顺便说一下, Mecab (和布蕪, めかぶ), 是作者最喜欢的食物.

目录

继续阅读

Itenyh版-用HMM做中文分词五:一个混合的分词器

Start your future on Coursera today.

        在上一节中,我们看到了HMM分词器的优势在于它的灵活性,能够联系上文情况作出是否分词的判断,但是过于灵活又会出现一些低级的分词错误。一种扬长避短的想法是使用词典限定HMM的分词。具体的做法是,用基于词典的分词方法分出N种结果,然后用HMM挑出最有可能的分词结果。

       介绍一下分词使用的词典,在《中文分词入门之资源》有提到:

        Mandarin.dic                             分词词典,约40000条词汇

        对于一段文本,找出所有可能的切分结果叫做全切分,全切分可以保证切分结果集对正确切分结果100%的召回率,换句话说全切分中一定包含正确结果(在不包含未登录词的前提之下)。长度为n的句子,最大全切分数量可以达到2`(n-1)个,因此全切分计算量会随着句子长度增加急剧上升。举例,句子“研究生命起源”的全切分如下:

研/究/生/命

研/究/生命

研究/生/命

研究/生命

研究生/命

共有5个切分方案,其中倒数第二个是正确切分。下面讲一下我对句子进行全切分用的具体算法。

        如上图,考虑构建一颗多叉树,其中每一条从root到叶子节点的路径均为一种分词结果,所有root到叶子节点的路径就是全切分的结果。树的建立方法是使用的递归:

        对句子进行正向词典匹配,结果为:

        研            对剩余句子:究生命    进行词典匹配

        研究        对剩余句子:生命        进行词典匹配

        研究生    对剩余句子:命            进行词典匹配

        全切分结果准备就绪,下面的问题是如何从备选分词中选出最佳分词结果,因为备选结果只有有限的数量,因此可以使用枚举算法求最佳解:

                                                          ArgmaxC,O  P(C|O)

解法在第2集中已经提到,等价于求:

ArgmaxC,O  P(O|C)P(C)

       为了避免计算溢出(小数位数太多计算机无法表示),我们改为求:

                                                          ArgminC,O  -lnP(O|C) – lnP(C)

        对于句子“研究生命”,分词结果如下:

        研/究/生/命:44.24491284128293

        研/究/生命:37.12604972173189

        研究/生/命:33.59480382540995

        研究/生命:26.49050292705271

        研究生/命:32.15705471620734

        其中“研究/生命”拥有最低值,被选为最优解。再举一些有意思的分词结果:

        研究生/研究/生活

        结合/成/分子

        他/说/的/确实/在/理

        可以看出这种混合分词器能够灵活的掌握字符间的分和,消除一些歧义分词。

        下面是我对几种分词方法的实验结果,同时使用了ICTCLAS2011作为一个权威的分词效果比对,其中ICTCLAS2011使用的是它自带的词典,其他分词方法使用的词典是Mandarin.dic

                                      每秒分词     P         R            F

普通最大词匹配          5482401      0.76   0.85      0.80

扩展的最大匹配          1118591      0.79   0.75      0.77

普通的Markov           1590173      0.76   0.72      0.74

混合的Markov           46818        0.73   0.84      0.78

ICTCLAS2011           942973       0.92   0.92     0.92

          可以看出ICTCLAS果然是名不虚传,相对于混合的Markov,ICTCLAS使用的是层叠式的HMM模型,可以很好的识别出未登录词;其次ICTCLAS使用了基于N-最短路径的切分,对计算效率也有很大的提高。

          PS:因为之前没有想过要分享分词的程序,所以写得比较混乱,最近也很忙,我会尽快整理发上来的。

 

 

Itenyh版-用HMM做中文分词四:A Pure-HMM 分词器

Start your future on Coursera today.

先介绍一下使用的资源,分词使用的语料来自于SIGHAN Bakeoff 2005的 icwb2-data.rar,《中文分词入门之资源》里有很详细的介绍:

/icwb2-data.rar/training/msr_training.utf8  用以训练HMM,其中包含已分词汇约2000000个

/icwb2-data.rar/testing/pku_test.utf8           测试集

/icwb2-data.rar/scripts/score                           一个perl脚本,测试分词效果

         我们使用经典的字符标注模型,首先需要确定标注集,在前面的介绍中,我们使用的是{B,E}的二元集合,研究表明基于四类标签的字符标注模型明显优于两类标签,原因是两类标签过于简单而损失了部分信息。四类标签的集合是 {B,E,M,S},其含义如下:

B:一个词的开始

E:一个词的结束

M:一个词的中间

S:单字成词

举例:你S现B在E应B该E去S幼B儿M园E了S

用四类标签为msr_training.utf8做好标记后,就可以开始用统计的方法构建一个HMM。我们打算构建一个2-gram(bigram)语言模型,也即一个1阶HMM,每个字符的标签分类只受前一个字符分类的影响。现在,我们需要求得HMM的状态转移矩阵 A 以及混合矩阵 B。其中:

                                     Aij = P(Cj|Ci)  =  P(Ci,Cj) / P(Ci) = Count(Ci,Cj) / Count(Ci)

                                     Bij = P(Oj|Ci)  =  P(Oj,Ci) / P(Ci) = Count(Oj,Ci) / Count(Ci)

公式中C = {B,E,M,S},O = {字符集合},Count代表频率。在计算Bij时,由于数据的稀疏性,很多字符未出现在训练集中,这导致概率为0的结果出现在B中,为了修补这个问题,我们采用加1的数据平滑技术,即:

                                     Bij = P(Oj|Ci)  =  (Count(Oj,Ci) + 1)/ Count(Ci)

         这并不是一种最好的处理技术,因为这有可能低估或高估真实概率,更加科学的方法是使用复杂一点的Good—Turing技术,这项技术的的原始版本是图灵当年和他的助手Good在破解德国密码机时发明的。求得的矩阵A如下:

        B       M                    E              S

B  0.0 | 0.19922840916814916 | 0.8007715908318509 | 0.0

M  0.0 | 0.47583202978061256 | 0.5241679702193874 | 0.0

E  0.6309567616935934 | 0.0 | 0.0 | 0.36904323830640656

S  0.6343402140354506 | 0.0 | 0.0 | 0.36565844303914763

矩阵中出现的概率为0的元素表明B-B, B-S, M-B, M-S, E-M, E-E, S-M, S-E这8种组合是不可能出现的。这是合乎逻辑的。求得的矩阵B,部分如下:

   o1               o2            o3                o4

B 7.8127868094E-7 1.460991186336E-4 0.007293548529516 6.047041844505E-4……

M ……

E …….

S ……

我们设定初始向量Pi = {0.5, 0.0, 0.0, 0.5}(M和E不可能出现在句子的首位)。至此,HMM模型构建完毕。其实用统计方法构建HMM并不复杂,麻烦的是写程序,特别是需要将分类标签和字符集合进行编码,这是个极其繁琐的过程。

我用的JAVA写程序,因此使用的Jahmm这个开源项目来进行相关的计算,对于一个HMM模型,现在我们可以写入一个观察序列,用Viterbi算法获得一个隐藏序列(分词结果)。具体做法是(举例为虚构):

1 . 对测试集按标点符号,空格,换行符拆分为一条一条的只包含字符的单句:

……

中共中央总书记

国家主席

……

2. 将句子转化为对应的编码,也即观察序列:

……

101 121 101 47 1010 32 1992

332 3241 893 2111

……

3. 输入观察序列,使用Viterbi算法输出隐藏序列(0:B,1:M,2:E,3:S)

……

0112333

0202

……

4. 输出最终分词结果:

……

中共中央/总/书/记

国家/主席

……

现在我们在对测试集pku_test.utf8分词,并用perl脚本进行评测,结果如下=== SUMMARY:
=== TOTAL INSERTIONS:    5627
=== TOTAL DELETIONS:    10639
=== TOTAL SUBSTITUTIONS:    18194
=== TOTAL NCHANGE:    34460
=== TOTAL TRUE WORD COUNT:    104372
=== TOTAL TEST WORD COUNT:    99360:

=== TOTAL TRUE WORDS RECALL:  0.724   正确切分出的词的数目/应切分出的词的总数

=== TOTAL TEST WORDS PRECISION: 0.760  正确切分出的词的数目/切分出的词的总数

=== F MEASURE:      0.742   F1 = 2 * Precision*Recall / (Precision + Recall)

=== OOV Recall Rate:    0.250      未登录词召回率

精度为:76%,召回为:72.4%。一个不太让人满意的结果,我们来看看他都干了些什么:

                                                        改判/被/告人/死/刑立/即/执行

这是一个较典型的例子,可见分词结果中出现了“告人”,“刑立”等字典中不存在的词,这些是由于HMM分词的“自由度”太大造成的,当然这种较大的“自由度”也有好处,比如:

                                                        检察院/鲍绍坤/检察/长

         看!HMM成功的识别出一个人名,这是基于词典的分词方法做不到的。实际上,在ICTCLAS系统中(2004)就是用的HMM来识别人名。下一节将会介绍一个基于词典的混合HMM分词器。

Itenyh版-用HMM做中文分词三:前向算法和Viterbi算法的开销

Start your future on Coursera today.

上文中始终未提到前向算法与Viterbi算法,主要是因为想特意强调一下数学解不等同于算法解。算法解考虑进了计算的性能问题,算法是为计算机设计的。

首先看一下“评估”问题中的时间开销。回顾一下公式:

P(O) = sigmaO P(O|C)P(C)= sigmaO P(C1)P(O1|C1)P(C2|C1)P(O2|C2)…P(Ci|Ci-1)P(Oi|Ci)

如果我们使用枚举的方法来求解,那么对于C来说,设有N种状态,序列长度为T,那么所有可能的隐藏序列组合为N`T(N的T次方)个,对于每一个序列需要的乘法次数为2T次,而加法需要T次,那么总共需要的计算次数为2T*N`T的级数(精确的,需要(2T-1)N`T次乘法,N`T-1词加法)。例如N=5,T=100,那么需要约2*100*5`100约10`72次计算,显然我们需要一个更好的算法。

         考虑上图这个简单的例子,图中描述了两个隐藏序列:abb,cbb。为了求得P(O),使用枚举算法有:

Pia * P(O1|a)*Pab*P(O2|b)*Pbb*P(O3|b) + Pic * P(O1|c)*Pcb*P(O2|b)*Pbb*P(O3|b)

Pi代表初始概率,使用前向算法有:

(Pia* P(O1|a) *Pab + Pic * P(O1|c)*Pcb) *P(O2|b)*Pbb* P(O3|b)

其中前向算法中的第一个大括号中的式子为局部概率a2(b),可以清楚的看到枚举算法用了10次乘法和1次加法,而前向算法把乘法次数减少到了7次,原因就是前向算法使用了大家熟知的“乘法分配律”提取了公因式。看起来好像提升不多,不过当计算量大的话这种提升就很可观了。事实上,前向算法将计算次数减低到了N`2*T的级数,那么对于N=5,T=100只需要约3000次计算即可。

         现在使用上面的例子考虑一下Viterbi算法,使用枚举算法我们需要计算:

Pia * P(O1|a)*Pab*P(O2|b)*Pbb*P(O3|b) 和 Pic * P(O1|c)*Pcb*P(O2|b)*Pbb* P(O3|b)

并比较求得其中较大的一个,而使用Viterbi算法,我们首先比较:

Pia *P(O1|a)*Pab 与 Pic * P(O1|c)*Pcb 的大小,选出较大的一个再乘以 Pbb* P(O3|b)

10次乘法一次比较,减少到5词乘法一次比较。

         总结一下,前向算法和Viterbi算法分别从两种角度向我们展现了降低计算复杂度的方法,一种是提取公因式减少计算次数,例如计算(1+2+3)* 5 和 1*5+2*5+3*5,从数学角度来看只是表达的不同,但对于计算者(无论是人还是计算机)来说,少的计算次数意味着更小的计算时间开销;另一种是,去掉不必要的计算,要找到最大的隐藏序列,如果在子序列上都不能取得最大还有必要去计算全序列吗?

Itenyh版-用HMM做中文分词二:模型准备

Start your future on Coursera today.

本质上看,分词可以看做一个为文本中每个字符分类的过程,例如我们现在定义两个类别:E代表词尾词,B代表非词尾词,于是分词“你/现在/应该/去/幼儿园/了”可以表达为:你E现B在E应B该E去E幼B儿B园E了B,分类完成后只需要对结果进行“解读”就可以得到分词结果了。

那么如何找到这个分类序列EBEBEEBBEB呢?我们可以求得所有可能出现的分类序列的出现概率然后选择其中概率最大的一个,用数学表达为:

                                                 argmax C  P(C1,C2,C3….Ci) (1)

其中C代表一个分类标识,这里,C 属于 {E,B} 进一步的:

P(C1,C2,C3….Ci) = P(C1)P(C2,C3…..Ci|C1)=P(C1)P(C2|C1)P(C3…..Ci|C1,C2)=

P(C1)P(C2|C1)P(C3|C2,C1)P(C4|C3,C2,C1)…P(Ci|Ci-1….C1)

这里,我们假设第i个分类标记只依赖于第i-1个标记,那么我们可以得到分类标记的马尔科夫链了:

                                 P(C1,C2,C3….Ci) =P(C1)P(C2|C1)P(C3|C2)…P(Ci|Ci-1)

我们称P(Cj|Ci)为i到j的状态转移概率,可以通过在大量预料中使用统计的方法求得。如果我们用(1)这个模型为上例找到了EBEBEEBBEB这个序列,看似好像是一个好的解决方案,不难想到的问题是,对于任何一个10个字符组成的文本,我们都会得到这个相同的序列,也即相同的分词结果,这太可怕了!问题在于我们只考虑了分类标记而没有考虑被分词的对象,也即每一个具体的字符,我们称这些字符为观察值,用O表示,现在把它们考虑进来,我们要找的是:

                                argmax C  P(C1,C2,C3….Ci | O1, O2, O3……Oi) = P(C|O)(1)

         给定了O的情况下,最有可能出现的C的序列,也是HMM的“解码问题”,根据贝叶斯公式有:

                                               P(C|O) = P(O|C)P(C) / P(O)

        由于P(O)对于每一种序列来说都是一样的,因此可以去掉,因此,(1)等价于 :

                                                  argmax C P(O|C)P(C) (2)

P(C)的求法上面已经讲过了,对于P(O|C),HMM有两个假设:(a)已知类地序列,观察值在统计上是独立的; (b)某类的概率密度函数不依赖其他类。也就是说依赖性仅仅存在于产生类的序列,而在类内,观察值服从类自己的规则。因此对于:

                              P(O|C) = P(O1, O2, O3……Oi | C1,C2,C3….Ci )

根据假设a,观察序列具有统计意义上的独立性,因此:

                   P(O1, O2, O3……Oi | C1,C2,C3….Ci )=P(O1|C) * P(O2|C)……P(Oi|C)

根据假设b,对于Oi的分类Ci与Cj没有依赖关系,所以有:

                      P(O1|C) * P(O2|C)……P(Oi|C) = P(O1|C1) * P(O2|C2)……P(Oi|Ci)

同样的P(Oi|Ci) 可以通过在大量预料中使用统计的方法求得。至此我们在一个马尔科夫链上加入了观察值数据,构造了一个HMM,这个模型已经可以具备一定的分词能力啦!

尽管没有用到,顺便回顾一下HMM要解决的第一个问题“评估”,也即求一个给定观察序列的概率,即:P(O),用全概率公式展开有:P(O) = sigmaO P(O|C)P(C)(sigmaO代表对O的集合求和),同样需要计算P(O|C),因此计算上和“解码”有相似之处。

PS : 关于模型(1),在论文HMM Tutorial中写的是:

图中O是观察值,q是代表分类序列,λ指HMM模型,可见作者用的是qO的联合概率,而(1)中用的是O作为条件的条件概率。这个模型和模型(2)是相等的,因此所求的的序列也和模型(1)相等。个人认为,从理解来看,既然给定了O,是不是把O作为条件概率更合适呢?