现在的位置: 首页 > 综合 > 正文

《Natural Language Processing with Python》6.2节的一些错误

2013年07月07日 ⁄ 综合 ⁄ 共 2699字 ⁄ 字号 评论关闭

最近一直在阅读《Natural Language Processing with Python》,在阅读该书的6.2节的Sentence Segmentation时,发现错误比较多。现在记录下来,也许可以帮到其他人,也许以后可以整理一下给该书作者发个邮件。

在说明问题之前,在这里先列出我的软件版本:

Python2.5

Nltk2.0b2

本节内容简介

Sentence Segmentation(我不知道如何翻译,下文中称作“句子划分”)把一段文字分成一组句子,由于句子的结尾一般有比较特殊的标点,所以句子划分可以被看做一个针对标点符号的分类问题,即当我们遇到一个标点符号时,判断它是不是一个句子的结束。

本节中对于句子划分任务用的方法是:利用监督学习之朴素Bayes方法,和一般监督学习算法一样,其基本步骤为:

1,数据预处理:把数据整理成一种合适的格式,这样就便于下一步的特征提取。

 

2,特征提取:提取一些比较有分辨能力的特征。

 

3,准备训练数据和测试数据

 

4,训练:利用朴素贝叶斯算法训练。

 

5,测试:测试训练出来的分类器效果如何。

 

那么如何用该分类器来对一段文字进行句子划分呢?本节用的方法就是检查每个标点,判断它是不是句子的边界,如果是就把文字从该标点出分开。

 

错误之处及改正方法

下面我将指出该节代码中的错误之处,并给出相应的解决方法。

问题1:特征提取函数可能产生越界。

特征提取函数中的代码:

'next-word-capitalized': tokens[i+1][0].isupper()

有可能越界,即如果i是这tokens序列的最后一个字符的索引值,那么上面的代码就会越界。而且这种情况会经常发生,因为段文字的最后一个字符通常是“.?!”(对英文而言)中的一个,所以一定会执行改行代码。

解决办法:因为一般在句尾遇到“.?!”标点之一时,标志的一句话的结束,那我们就捕获该异常并把“next-word-capitalized”的值设置为True

问题2及解决方法:一个小的打印错误,书中忘了把对要分类的数据进行特征提取。

segment_sentence”函数中第4行的“classifier.classify(words, i) == True”应该改为“classifier.classify(punct_features(words, i))

问题3segment_sentence函数才执行完后,我如何才能获得句子划分的结果?由于保存划分结果的sents变量是一个局部变量,在执行完后,我们在函数外边是得不到结果的,而且其内部也没有打印该结果。

解决办法:在函数结尾加上一句“return sents”,让其把划分结果返回。

问题4:当我调用classifier.show_most_informative_features()”时,提示如下错误:

“File "E:/编程工具/py2.5/lib/site-packages/nltk/classify/naivebayes.py", line 144, in show_most_informative_features“

“TypeError: 'bool' object is unsubscriptable”

我针对该错误,找到文件“naivebayes.py”,其144行语句是:

 print ('%24s = %-14r %6s : %-6s = %s : 1.0' %

                   (fname, fval, l1[:6], l0[:6], ratio))

解决办法:由于,我们的分类任务的类别只有两个,即True和False,在代码中即用l1和l0来表示,由于在144行对其执行了下标操作,从而导致了前面的错误。我猜想nltk作者可能假设所有类别都是字符串,他们为了在输出的时候保持格式较短,才在这里做了下标操作。所以,我的解决办法是在对l1和l0进行下标操作之前把其转化为字符串,即把上面的代码改为:

 print ('%24s = %-14r %6s : %-6s = %s : 1.0' %

                   (fname, fval, str(l1)[:6], str(l0)[:6], ratio))

至此,我解决了我遇到的问题,我才可以放心的进行下面章节的学习。

抱歉!评论已关闭.