Chapter 4 - naïve Bayes
- 利用p(x|c)求p(c|x):
p(c|x)=p(x|c)p(c)p(x)
- 原理
对N维特征向量w(w1,w2,…,wN)的数据集有k个类别,c1 c2 c3 …ck,现在想知道一个实例(x,y)的分类
对(x,y)求分别属于k个类别的概率
p(ci|w)=p(w|ci)p(ci)p(w)
取最大的概率作为类别(其中在对不同类别计算的时候,分母p(w)对每个类别一样,因此可以抵消)
对分子,第二项很简单,第一项的话w的各个维度条件独立,所以
p(w|ci)=p(w(1)|ci)∗p(w(2)|ci)∗...∗p(w(N)|ci)=∏j=1Np(w(j)|ci)
(更多详细理论)
- 训练流程
# 我们的目的是通过上面等式中右边部分来计算左边部分,又分母抵消不用计算,所以我们需要计算的是上述的分子
def trainNB0(trainMatrix,trainCategory):
numTrainDocs = len(trainMatrix)
numWords = len(trainMatrix[0])
pAbusive = sum(trainCategory)/float(numTrainDocs)
p0Num = zeros(numWords); p1Num = zeros(numWords)
p0Denom = 0.0; p1Denom = 0.0
for i in range(numTrainDocs):
if trainCategory[i] == 1:
p1Num += trainMatrix[i]
p1Denom += sum(trainMatrix[i]) #注意为什么加的是特征的个数sum(),而不是实例的个数1
else:
p0Num += trainMatrix[i]
p0Denom += sum(trainMatrix[i])
# 向量除以一个数,向量里的每一维都除以这个数
p1Vect = p1Num/p1Denom # p1Vect = log(p1Num/p1Denom)
p0Vect = p0Num/p0Denom # p0Vect = log(p0Num/p0Denom)
return p0Vect,p1Vect,pAbusive
##### 多个小数相乘可能下溢,利用ln(a*b) = ln(a)+ln(b).将乘法改为加法,即改为注释
def classifyNB(vec2Classify, p0Vec, p1Vec, pClass1):
p1 = sum(vec2Classify * p1Vec) + log(pClass1)
p0 = sum(vec2Classify * p0Vec) + log(1.0 - pClass1)
if p1 > p0:
return 1
else:
return 0