- 签证留学 |
- 笔译 |
- 口译
- 求职 |
- 日/韩语 |
- 德语
我们将使用上述公式,对每个类计算该值,然后比较这两个概率值的大小。如何计算呢?首先可以通过类别i(侮辱性留言或非侮辱性留言)中文档数除以总的文档数来计算概率p(ci)。接下来计算p(w|ci),这里就要用到朴素贝叶斯假设。如果将w展开为一个个独立特征,那么就可以将上述概率写作p(w0,w1,w2,wN|ci)。这里假设所有词都互相独立,该假设也称作条件独立性假设,它意味着可以使用p(w0|ci)p(w1lci)p(w2lci)...p(wN|ci)来计算上述概率,这就极大地简化了计算的过程。
该函数的伪代码如下:
计算每个类别中的文档数目
对每篇训练文档:
对每个类别:
如果词条出现文档中→增加该词条的计数值
增加所有词条的计数值
对每个类别:
对每个词条:
将该词条的数目除以总词条数目得到条件概率
返回每个类别的条件概率
我们利用下面的代码来实现上述伪码。打开文本编辑器,将这些代码添加到bayes.py文件中。该函数使用了NumPy的一些函数,故应确保将from numpy import*语句添加到bayes.py文件的最前面。
程序清单1-2朴素贝叶斯分类器训练函数
代码函数中的输入参数为文档矩阵trainMatrix,以及由每篇文档类别标签所构成的向量trainCategory。首先,计算文档属于侮辱性文档(class=1)的概率,即p(1)。因为这是一个二类分类问题,所以可以通过1-P(1)得到P(0)。对于多于两类的分类问题,则需要对代码稍加修改。
计算p(wilc1)和p(wi|c0),需要初始化程序中的分子变量和分母变量①。由于w中元素如此众多,因此可以使用NumPy数组快速计算这些值。上述程序中的分母变量是一个元素个数等于词汇表大小的NumPy数组。在for循环中,要遍历训练集trainMatrix中的所有文档。一旦某个词语(侮辱性或正常词语)在某一文档中出现,则该词对应的个数(p1Num或者pONum)就加1,而且在所有的文档中,该文档的总词数也相应加1②。对于两个类别都要进行同样的计算处理。
最后,对每个元素除以该类别中的总词数③。利用NymPy可以很好实现,用一个数组除以浮点数即可,若使用常规的Python列表则难以完成这种任务,读者可以自己尝试一下。最后,函数会返回两个向量和一个概率。
接下来试验一下。将程序清单1-2中的代码添加到bayes.py文件中,在Python提示符下输入:
>>> from numpy import*
>>> reload(bayes)
>>> listOPosts, listClasses = bayes.loadDataSet ()
该语句从预先加载值中调入数据。
>>>myvocabList = bayes.createVocabList(listOPosts)
至此我们构建了一个包含所有词的列表myVocabList。
>>> trainMat=[ ]
>>> for postinDoc in listOPosts:
>>>trainMat.append (bayes.setOfWords2Vec (myVocabList, postinDoc))
该for循环使用词向量来填充trainMat列表。下面给出属于侮辱性文档的概率以及两个类别的概率向量。
>>> p0V,p1V,pAb=bayes.trainNB0 (trainMat,listClasses)
接下来看这些变量的内部值:
>>> pAb
0.5
这就是任意文档属于侮辱性文档的概率。
首先,我们发现文档属于侮辱类的概率pAb为0.5,该值是正确的。接下来,看一看在给定文档类别条件下词汇表中单词的出现概率,看看是否正确。词汇表中的第一个词是cute,其在类别0中出现1次,而在类别1中从未出现。对应的条件概率分别为0.04166667与0.0。该计算是正确的。我们找找所有概率中的最大值,该值出现在P(1)数组第21个下标位置,大小为0.15789474。在myVocabList的第26个下标位置上可以查到该单词是stupid。这意味着stupid是最能表征类别1(侮辱性文档类)的单词。
使用该函数进行分类之前,还需解决函数中的一些缺陷。