贝叶斯定理
贝叶斯定理解决了现实生活里经常遇到的问题:已知某条件概率,如何得到两个事件交换后的概率,也就是在已知P(A|B)的情况下如何求得P(B|A)。这里先解释什么是条件概率:
表示事件B已经发生的前提下,事件A发生的概率,叫做事件B发生下事件A的条件概率。其基本求解公式为:
贝叶斯定理:
朴素贝叶斯的思想基础是这样的:对于给出的待分类项,求解在此项出现的条件下各个类别出现的概率,哪个最大,就认为此待分类项属于哪个类别。
贝叶斯方法的新实例分类目标是在给定描述实例的属性值{a1,a2…an}下,得到,vj为所有的类别。
使用贝叶斯公式重写为:
朴素贝叶斯分类器基于一个简单的假定:在给定目标值时属性值之间相互条件独立。
有
朴素贝叶斯分类器:
朴素贝叶斯分类器训练,即得到先验概率和后验概率:
代码:
def trainNB1(trainMatrix, trainCategory):
''' 训练naive bayes模型。
:param trainMatrix:
:param trainCategory:
:return:
'''
numTrainDocs = len(trainMatrix)
numWords = len(trainMatrix[0])
#p(1)的概率
pAbusive = sum(trainCategory)/float(numTrainDocs)
#计算p(w|ci),eg.:p(w0|c0).....p(wn|c0),p(w0|c1).....p(wn|c1)
# p0Num = zeros(numWords); p1Num = zeros(numWords)
# p0Denom = 0.0; p1Denom = 0.0
# 由于要计算所有概率p(wj|ci)的乘积,如果其中一项为0,则结果为0,这里做修正
# 将所有单词的出现次数初始化为1,分母初始化为2
p0Num = ones(numWords); p1Num = ones(numWords)
p0Denom = 2.0; p1Denom = 2.0
for i in range(numTrainDocs):
if trainCategory[i] == 1:
p1Num += trainMatrix[i]
p1Denom += sum(trainMatrix[i])
else:
p0Num += trainMatrix[i]
p0Denom += sum(trainMatrix[i])
p1Vec = p1Num/p1Denom
p0Vec = p0Num/p0Denom
# 由于概率都比较小,为了防止乘积下溢,改为log
p1Vec = log(p1Num / p1Denom)
p0Vec = log(p0Num / p0Denom)
# 返回概率:p(w|0),p(w|1),p(1)
return p0Vec,p1Vec,pAbusive
使用分类器进行预测:
对比上面最后的公式,由于为了防止下溢,去了对数值,所以改为求和。。
def classfyNB(vec2Classify, p0Vec, p1Vec, pAbusive):
p1 = sum(vec2Classify * p1Vec) + log(pAbusive)
p0 = sum(vec2Classify * p0Vec) + log(1-pAbusive)
if p1 > p0:
return 1
else:
return 0
参考:
http://www.cnblogs.com/rongyux/p/5602037.html
https://wizardforcel.gitbooks.io/dm-algo-top10/content/naive-bayes.html
完整代码见github:
https://github.com/zhanggw/algorithm/blob/master/machine-learning/bayes