本文主要描述了朴素贝叶斯分类方法,包括模型导出和学习描述。实例部分总结了《machine learning in action》一书中展示的一个该方法用于句子感情色彩分类的程序。
- 方法概述
- 学习(参数估计)
- 实现:朴素贝叶斯下的文本分类
模型概述
朴素贝叶斯方法,是指
-
朴素:特征条件独立
-
贝叶斯:基于贝叶斯定理
根据贝叶斯定理,对一个分类问题,给定样本特征x,样本属于类别y的概率是
p(y|x)=p(x|y)p(y)p(x)。。。。。。(1)
在这里,x是一个特征向量,将设x维度为M。因为朴素的假设,即特征条件独立,根据全概率公式展开,公式(1)可以表达为
p(y=ck|x)=∏Mi=1p(xi|y=ck)p(y=ck)∑kp(y=ck)∏Mi=1P(xi|y=ck)。。。。(2)
这里,只要分别估计出,特征
xi
在每一类的条件概率就可以了。类别y的先验概率可以通过训练集算出,同样通过训练集上的统计,可以得出对应每一类上的,条件独立的特征对应的条件概率向量。
如何统计,就是下一部分——学习——所关心的内容。
学习(参数估计)
下面介绍如何从数据中,学习得到朴素贝叶斯分类模型。概述分类方法,并提出一个值得注意的问题。
学习
训练集TrainingSet=
{(x1,y1),(x2,y2),...,(xN,yN)}
包含N条训练数据,其中
xi=(x(1)i,x(2)i,...,x(M)i)T
是M维向量,
yi∈{c1,c2,...cK}
属于K类中的一类。
-
学习 1.首先,我们来计算公式(2)中的
p(y=ck)
p(y=ck)=∑Ni=1I(yi=ck)N。。。。(3)
其中
I(x)
为指示函数,若括号内成立,则计1,否则为0。
-
学习 2.接下来计算分子中的条件概率,设
M
维特征的第
j
维有
L
个取值,则某维特征的某个取值
ajl
,在给定某分类
ck
下的条件概率为:
p(xj=ajl|y=ck)=∑Ni=1I(xji=ajl,yi=ck)∑Ni=1I(yi=ck)。。。(4)
经过上述步骤,我们就得到了模型的基本概率,也就完成了学习的任务。
分类
通过学到的概率,给定未分类新实例
X
,就可以通过上述概率进行计算,得到该实例属于各类的后验概率
p(y=ck|X)
,因为对所有的类来说,公式(2)中分母的值都相同,所以只计算分子部分即可,具体步骤如下:
-
分类 1.计算该实例属于
y=ck
类的概率
p(y=ck|X)=p(y=ck)∏j=1np(X(j)=x(j)|y=ck)。。。(5)
分类 2.确定该实例所属的分类
y
y=argmaxckp(y=ck|X)。。。。(6)
于是我们得到了新实例的分类结果
拉普拉斯平滑
到这里好像方法已经介绍完了,实则有一个小问题需要注意,在公式(3)(4)中,如果从样本中算出的概率值为0该怎么办呢?
下面介绍一种简单方法,给学习步骤中的两个概率计算公式,分子和分母都分别加上一个常数,就可以避免这个问题。更新过后的公式如下:
-
p(y=ck)=∑Ni=1I(yi=ck)+λN+Kλ。。。。(7)
K
是类的个数
p(xj=ajl|y=ck)=∑Ni=1I(xji=ajl,yi=ck)+λ∑Ni=1I(yi=ck)+Ljλ。。。(8)
Lj
是第
j
维特征的最大取值
可以证明,改进以后的(7)(8)仍然是概率。平滑因子
λ=0
即为(3)(4)实现的最大似然估计,这时会出现在本节开始时提到的0概率问题;而
λ=1
则避免了0概率问题,这种方法被称为拉普拉斯平滑。
实现:朴素贝叶斯下的文本分类
根据上面的算法流程,在这里实现一个句子极性划分的例子。所谓句子极性是指,句子所表达的情感色彩,例如积极/消极,这里(书里)使用的是侮辱性/非侮辱性。其实是什么类别不重要,只要给定有标签的训练数据,就可以得到分类模型。
下面简述实现思想和流程,给出代码。
算法思想和流程
给定的训练集是标定了
侮辱性/非侮辱性 的句子(因为是英语句子,所以基本视分词为已经解决的问题,如果是汉语,则要先进行分词),我们认为特征就是句子中的单个词语。单个词语有极性表征,整个句子所包含的单词的极性表征就是句子的极性。
由以上的基础,应用朴素贝叶斯分类,就变成了这样的问题
-
初始化步,构建可以表征句子的特征向量(词汇表)。并根据这个特征向量,把训练集表征出来。从训练集中分离部分数据作为测试集。
-
学习步,计算
类的先验概率和
特征向量对应每一类的条件概率向量
-
分类步, 计算测试集中待分类句子在每一类的分类后验概率,取最大值作为其分类,并与给定标签比较,得到误分类率。
代码
初始化:
<code class="language-python hljs has-numbering" style="display: block; padding: 0px; color: inherit; box-sizing: border-box; font-family: 'Source Code Pro', monospace;font-size:undefined; white-space: pre; border-radius: 0px; word-wrap: normal; background: transparent;"><span class="hljs-function" style="box-sizing: border-box;"><span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box;">def</span> <span class="hljs-title" style="box-sizing: border-box;">loadDataSet</span><span class="hljs-params" style="color: rgb(102, 0, 102); box-sizing: border-box;">()</span>:</span><span class="hljs-comment" style="color: rgb(136, 0, 0); box-sizing: border-box;">#数据格式</span>
postingList=[[<span class="hljs-string" style="color: rgb(0, 136, 0); box-sizing: border-box;">'my'</span>, <span class="hljs-string" style="color: rgb(0, 136, 0); box-sizing: border-box;">'dog'</span>, <span class="hljs-string" style="color: rgb(0, 136, 0); box-sizing: border-box;">'has'</span>, <span class="hljs-string" style="color: rgb(0, 136, 0); box-sizing: border-box;">'flea'</span>, <span class="hljs-string" style="color: rgb(0, 136, 0); box-sizing: border-box;">'problems'</span>, <span class="hljs-string" style="color: rgb(0, 136, 0); box-sizing: border-box;">'help'</span>, <span class="hljs-string" style="color: rgb(0, 136, 0); box-sizing: border-box;">'please'</span>],
[<span class="hljs-string" style="color: rgb(0, 136, 0); box-sizing: border-box;">'maybe'</span>, <span class="hljs-string" style="color: rgb(0, 136, 0); box-sizing: border-box;">'not'</span>, <span class="hljs-string" style="color: rgb(0, 136, 0); box-sizing: border-box;">'take'</span>, <span class="hljs-string" style="color: rgb(0, 136, 0); box-sizing: border-box;">'him'</span>, <span class="hljs-string" style="color: rgb(0, 136, 0); box-sizing: border-box;">'to'</span>, <span class="hljs-string" style="color: rgb(0, 136, 0); box-sizing: border-box;">'dog'</span>, <span class="hljs-string" style="color: rgb(0, 136, 0); box-sizing: border-box;">'park'</span>, <span class="hljs-string" style="color: rgb(0, 136, 0); box-sizing: border-box;">'stupid'</span>],
[<span class="hljs-string" style="color: rgb(0, 136, 0); box-sizing: border-box;">'my'</span>, <span class="hljs-string" style="color: rgb(0, 136, 0); box-sizing: border-box;">'dalmation'</span>, <span class="hljs-string" style="color: rgb(0, 136, 0); box-sizing: border-box;">'is'</span>, <span class="hljs-string" style="color: rgb(0, 136, 0); box-sizing: border-box;">'so'</span>, <span class="hljs-string" style="color: rgb(0, 136, 0); box-sizing: border-box;">'cute'</span>, <span class="hljs-string" style="color: rgb(0, 136, 0); box-sizing: border-box;">'I'</span>, <span class="hljs-string" style="color: rgb(0, 136, 0); box-sizing: border-box;">'love'</span>, <span class="hljs-string" style="color: rgb(0, 136, 0); box-sizing: border-box;">'him'</span>],
[<span class="hljs-string" style="color: rgb(0, 136, 0); box-sizing: border-box;">'stop'</span>, <span class="hljs-string" style="color: rgb(0, 136, 0); box-sizing: border-box;">'posting'</span>, <span class="hljs-string" style="color: rgb(0, 136, 0); box-sizing: border-box;">'stupid'</span>, <span class="hljs-string" style="color: rgb(0, 136, 0); box-sizing: border-box;">'worthless'</span>, <span class="hljs-string" style="color: rgb(0, 136, 0); box-sizing: border-box;">'garbage'</span>],
[<span class="hljs-string" style="color: rgb(0, 136, 0); box-sizing: border-box;">'mr'</span>, <span class="hljs-string" style="color: rgb(0, 136, 0); box-sizing: border-box;">'licks'</span>, <span class="hljs-string" style="color: rgb(0, 136, 0); box-sizing: border-box;">'ate'</span>, <span class="hljs-string" style="color: rgb(0, 136, 0); box-sizing: border-box;">'my'</span>, <span class="hljs-string" style="color: rgb(0, 136, 0); box-sizing: border-box;">'steak'</span>, <span class="hljs-string" style="color: rgb(0, 136, 0); box-sizing: border-box;">'how'</span>, <span class="hljs-string" style="color: rgb(0, 136, 0); box-sizing: border-box;">'to'</span>, <span class="hljs-string" style="color: rgb(0, 136, 0); box-sizing: border-box;">'stop'</span>, <span class="hljs-string" style="color: rgb(0, 136, 0); box-sizing: border-box;">'him'</span>],
[<span class="hljs-string" style="color: rgb(0, 136, 0); box-sizing: border-box;">'quit'</span>, <span class="hljs-string" style="color: rgb(0, 136, 0); box-sizing: border-box;">'buying'</span>, <span class="hljs-string" style="color: rgb(0, 136, 0); box-sizing: border-box;">'worthless'</span>, <span class="hljs-string" style="color: rgb(0, 136, 0); box-sizing: border-box;">'dog'</span>, <span class="hljs-string" style="color: rgb(0, 136, 0); box-sizing: border-box;">'food'</span>, <span class="hljs-string" style="color: rgb(0, 136, 0); box-sizing: border-box;">'stupid'</span>]]
classVec = [<span class="hljs-number" style="color: rgb(0, 102, 102); box-sizing: border-box;">0</span>,<span class="hljs-number" style="color: rgb(0, 102, 102); box-sizing: border-box;">1</span>,<span class="hljs-number" style="color: rgb(0, 102, 102); box-sizing: border-box;">0</span>,<span class="hljs-number" style="color: rgb(0, 102, 102); box-sizing: border-box;">1</span>,<span class="hljs-number" style="color: rgb(0, 102, 102); box-sizing: border-box;">0</span>,<span class="hljs-number" style="color: rgb(0, 102, 102); box-sizing: border-box;">1</span>]<span class="hljs-comment" style="color: rgb(136, 0, 0); box-sizing: border-box;">#1 侮辱性文字 , 0 代表正常言论</span>
<span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box;">return</span> postingList,classVec
<span class="hljs-function" style="box-sizing: border-box;"><span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box;">def</span> <span class="hljs-title" style="box-sizing: border-box;">createVocabList</span><span class="hljs-params" style="color: rgb(102, 0, 102); box-sizing: border-box;">(dataSet)</span>:</span><span class="hljs-comment" style="color: rgb(136, 0, 0); box-sizing: border-box;">#创建词汇表</span>
vocabSet = set([])
<span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box;">for</span> document <span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box;">in</span> dataSet:
vocabSet = vocabSet | set(document) <span class="hljs-comment" style="color: rgb(136, 0, 0); box-sizing: border-box;">#创建并集</span>
<span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box;">return</span> list(vocabSet)
<span class="hljs-function" style="box-sizing: border-box;"><span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box;">def</span> <span class="hljs-title" style="box-sizing: border-box;">bagOfWord2VecMN</span><span class="hljs-params" style="color: rgb(102, 0, 102); box-sizing: border-box;">(vocabList,inputSet)</span>:</span><span class="hljs-comment" style="color: rgb(136, 0, 0); box-sizing: border-box;">#根据词汇表,讲句子转化为向量</span>
returnVec = [<span class="hljs-number" style="color: rgb(0, 102, 102); box-sizing: border-box;">0</span>]*len(vocabList)
<span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box;">for</span> word <span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box;">in</span> inputSet:
<span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box;">if</span> word <span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box;">in</span> vocabList:
returnVec[vocabList.index(word)] += <span class="hljs-number" style="color: rgb(0, 102, 102); box-sizing: border-box;">1</span>
<span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box;">return</span> returnVec</code><ul class="pre-numbering" style="box-sizing: border-box; position: absolute; width: 50px; top: 0px; left: 0px; margin: 0px; padding: 6px 0px 40px; border-right-width: 1px; border-right-style: solid; border-right-color: rgb(221, 221, 221); list-style: none; text-align: right; background-color: rgb(238, 238, 238);"><li style="box-sizing: border-box; padding: 0px 5px;">1</li><li style="box-sizing: border-box; padding: 0px 5px;">2</li><li style="box-sizing: border-box; padding: 0px 5px;">3</li><li style="box-sizing: border-box; padding: 0px 5px;">4</li><li style="box-sizing: border-box; padding: 0px 5px;">5</li><li style="box-sizing: border-box; padding: 0px 5px;">6</li><li style="box-sizing: border-box; padding: 0px 5px;">7</li><li style="box-sizing: border-box; padding: 0px 5px;">8</li><li style="box-sizing: border-box; padding: 0px 5px;">9</li><li style="box-sizing: border-box; padding: 0px 5px;">10</li><li style="box-sizing: border-box; padding: 0px 5px;">11</li><li style="box-sizing: border-box; padding: 0px 5px;">12</li><li style="box-sizing: border-box; padding: 0px 5px;">13</li><li style="box-sizing: border-box; padding: 0px 5px;">14</li><li style="box-sizing: border-box; padding: 0px 5px;">15</li><li style="box-sizing: border-box; padding: 0px 5px;">16</li><li style="box-sizing: border-box; padding: 0px 5px;">17</li><li style="box-sizing: border-box; padding: 0px 5px;">18</li><li style="box-sizing: border-box; padding: 0px 5px;">19</li><li style="box-sizing: border-box; padding: 0px 5px;">20</li><li style="box-sizing: border-box; padding: 0px 5px;">21</li><li style="box-sizing: border-box; padding: 0px 5px;">22</li></ul>
训练:
<code class="language-python hljs has-numbering" style="display: block; padding: 0px; color: inherit; box-sizing: border-box; font-family: 'Source Code Pro', monospace;font-size:undefined; white-space: pre; border-radius: 0px; word-wrap: normal; background: transparent;"><span class="hljs-function" style="box-sizing: border-box;"><span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box;">def</span> <span class="hljs-title" style="box-sizing: border-box;">trainNB0</span><span class="hljs-params" style="color: rgb(102, 0, 102); box-sizing: border-box;">(trainMatrix,trainCategory)</span>:</span>
numTrainDocs = len(trainMatrix)
numWords = len(trainMatrix[<span class="hljs-number" style="color: rgb(0, 102, 102); box-sizing: border-box;">0</span>])
pAbusive = sum(trainCategory)/float(numTrainDocs)
p0Num = ones(numWords);p1Num = ones(numWords)<span class="hljs-comment" style="color: rgb(136, 0, 0); box-sizing: border-box;">#计算频数初始化为1</span>
p0Denom = <span class="hljs-number" style="color: rgb(0, 102, 102); box-sizing: border-box;">2.0</span>;p1Denom = <span class="hljs-number" style="color: rgb(0, 102, 102); box-sizing: border-box;">2.0</span> <span class="hljs-comment" style="color: rgb(136, 0, 0); box-sizing: border-box;">#即拉普拉斯平滑</span>
<span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box;">for</span> i <span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box;">in</span> range(numTrainDocs):
<span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box;">if</span> trainCategory[i]==<span class="hljs-number" style="color: rgb(0, 102, 102); box-sizing: border-box;">1</span>:
p1Num += trainMatrix[i]
p1Denom += sum(trainMatrix[i])
<span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box;">else</span>:
p0Num += trainMatrix[i]
p0Denom += sum(trainMatrix[i])
p1Vect = log(p1Num/p1Denom)<span class="hljs-comment" style="color: rgb(136, 0, 0); box-sizing: border-box;">#注意</span>
p0Vect = log(p0Num/p0Denom)<span class="hljs-comment" style="color: rgb(136, 0, 0); box-sizing: border-box;">#注意</span>
<span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box;">return</span> p0Vect,p1Vect,pAbusive<span class="hljs-comment" style="color: rgb(136, 0, 0); box-sizing: border-box;">#返回各类对应特征的条件概率向量</span>
<span class="hljs-comment" style="color: rgb(136, 0, 0); box-sizing: border-box;">#和各类的先验概率</span></code><ul class="pre-numbering" style="box-sizing: border-box; position: absolute; width: 50px; top: 0px; left: 0px; margin: 0px; padding: 6px 0px 40px; border-right-width: 1px; border-right-style: solid; border-right-color: rgb(221, 221, 221); list-style: none; text-align: right; background-color: rgb(238, 238, 238);"><li style="box-sizing: border-box; padding: 0px 5px;">1</li><li style="box-sizing: border-box; padding: 0px 5px;">2</li><li style="box-sizing: border-box; padding: 0px 5px;">3</li><li style="box-sizing: border-box; padding: 0px 5px;">4</li><li style="box-sizing: border-box; padding: 0px 5px;">5</li><li style="box-sizing: border-box; padding: 0px 5px;">6</li><li style="box-sizing: border-box; padding: 0px 5px;">7</li><li style="box-sizing: border-box; padding: 0px 5px;">8</li><li style="box-sizing: border-box; padding: 0px 5px;">9</li><li style="box-sizing: border-box; padding: 0px 5px;">10</li><li style="box-sizing: border-box; padding: 0px 5px;">11</li><li style="box-sizing: border-box; padding: 0px 5px;">12</li><li style="box-sizing: border-box; padding: 0px 5px;">13</li><li style="box-sizing: border-box; padding: 0px 5px;">14</li><li style="box-sizing: border-box; padding: 0px 5px;">15</li><li style="box-sizing: border-box; padding: 0px 5px;">16</li><li style="box-sizing: border-box; padding: 0px 5px;">17</li></ul>
分类:
<code class="language-python hljs has-numbering" style="display: block; padding: 0px; color: inherit; box-sizing: border-box; font-family: 'Source Code Pro', monospace;font-size:undefined; white-space: pre; border-radius: 0px; word-wrap: normal; background: transparent;"><span class="hljs-function" style="box-sizing: border-box;"><span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box;">def</span> <span class="hljs-title" style="box-sizing: border-box;">classifyNB</span><span class="hljs-params" style="color: rgb(102, 0, 102); box-sizing: border-box;">(vec2Classify,p0Vec,p1Vec,pClass1)</span>:</span>
p1 = sum(vec2Classify * p1Vec) + log(pClass1)<span class="hljs-comment" style="color: rgb(136, 0, 0); box-sizing: border-box;">#注意</span>
p0 = sum(vec2Classify * p0Vec) + log(<span class="hljs-number" style="color: rgb(0, 102, 102); box-sizing: border-box;">1</span>-pClass1)<span class="hljs-comment" style="color: rgb(136, 0, 0); box-sizing: border-box;">#注意</span>
<span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box;">if</span> p1 > p0:
<span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box;">return</span> <span class="hljs-number" style="color: rgb(0, 102, 102); box-sizing: border-box;">1</span>
<span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box;">else</span>:
<span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box;">return</span> <span class="hljs-number" style="color: rgb(0, 102, 102); box-sizing: border-box;">0</span>
<span class="hljs-function" style="box-sizing: border-box;"><span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box;">def</span> <span class="hljs-title" style="box-sizing: border-box;">testingNB</span><span class="hljs-params" style="color: rgb(102, 0, 102); box-sizing: border-box;">()</span>:</span><span class="hljs-comment" style="color: rgb(136, 0, 0); box-sizing: border-box;">#流程展示</span>
listOPosts,listClasses = loadDataSet()<span class="hljs-comment" style="color: rgb(136, 0, 0); box-sizing: border-box;">#加载数据</span>
myVocabList = createVocabList(listOPosts)<span class="hljs-comment" style="color: rgb(136, 0, 0); box-sizing: border-box;">#建立词汇表</span>
trainMat = []
<span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box;">for</span> postinDoc <span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box;">in</span> listOPosts:
trainMat.append(setOfWords2Vec(myVocabList,postinDoc))
p0V,p1V,pAb = trainNB0(trainMat,listClasses)<span class="hljs-comment" style="color: rgb(136, 0, 0); box-sizing: border-box;">#训练</span>
<span class="hljs-comment" style="color: rgb(136, 0, 0); box-sizing: border-box;">#测试</span>
testEntry = [<span class="hljs-string" style="color: rgb(0, 136, 0); box-sizing: border-box;">'love'</span>,<span class="hljs-string" style="color: rgb(0, 136, 0); box-sizing: border-box;">'my'</span>,<span class="hljs-string" style="color: rgb(0, 136, 0); box-sizing: border-box;">'dalmation'</span>]
thisDoc = setOfWords2Vec(myVocabList,testEntry)
<span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box;">print</span> testEntry,<span class="hljs-string" style="color: rgb(0, 136, 0); box-sizing: border-box;">'classified as: '</span>,classifyNB(thisDoc,p0V,p1V,pAb)</code><ul class="pre-numbering" style="box-sizing: border-box; position: absolute; width: 50px; top: 0px; left: 0px; margin: 0px; padding: 6px 0px 40px; border-right-width: 1px; border-right-style: solid; border-right-color: rgb(221, 221, 221); list-style: none; text-align: right; background-color: rgb(238, 238, 238);"><li style="box-sizing: border-box; padding: 0px 5px;">1</li><li style="box-sizing: border-box; padding: 0px 5px;">2</li><li style="box-sizing: border-box; padding: 0px 5px;">3</li><li style="box-sizing: border-box; padding: 0px 5px;">4</li><li style="box-sizing: border-box; padding: 0px 5px;">5</li><li style="box-sizing: border-box; padding: 0px 5px;">6</li><li style="box-sizing: border-box; padding: 0px 5px;">7</li><li style="box-sizing: border-box; padding: 0px 5px;">8</li><li style="box-sizing: border-box; padding: 0px 5px;">9</li><li style="box-sizing: border-box; padding: 0px 5px;">10</li><li style="box-sizing: border-box; padding: 0px 5px;">11</li><li style="box-sizing: border-box; padding: 0px 5px;">12</li><li style="box-sizing: border-box; padding: 0px 5px;">13</li><li style="box-sizing: border-box; padding: 0px 5px;">14</li><li style="box-sizing: border-box; padding: 0px 5px;">15</li><li style="box-sizing: border-box; padding: 0px 5px;">16</li><li style="box-sizing: border-box; padding: 0px 5px;">17</li><li style="box-sizing: border-box; padding: 0px 5px;">18</li><li style="box-sizing: border-box; padding: 0px 5px;">19</li></ul>
注意:上述代码中标有注意的地方,是公式中概率连乘变成了对数概率相加。此举可以在数学上证明不会影响分类结果,且在实际计算中,避免了因概率因子远小于1而连乘造成的下溢出。