朴素贝叶斯法
朴素贝叶斯法是基于贝叶斯定理与特征条件独立假设的分类方法。对于给定的训练数据集,首先基于特征条件独立假设学习输入/输出的联合概率分布;然后基于此模型,对给定的输入x,利用贝叶斯定理求出后验概率最大的输出y。
换句话说,在已知条件概率和先验概率的情况下(即,在事件Bi发生条件下发生事件A的概率,和发生事件Bi的概率),求后验概率(即,在事件A发生条件下事件Bi发生的概率)。
先验概率:根据以往经验和分析得到的概率。
后验概率:基于新的信息,修正原来的先验概率后所获得更接近实际情况的概率估计。后验概率是条件概率,但并不是所有的条件概率都是后验概率。
条件概率:在发生A的条件下B发生的概率。
定理:
贝叶斯定理:
其中P=(Y=ck)是先验概率,根据数据集可以求得;P(Y=ck|X=x)是后验概率,也是条件概率,在已知输入的情况下求输出Y=ck的概率;P(X=x|Y=ck)是条件概率,即在Y=ck发生情况下,X=x的概率。
由于上式,分母项都相同,所以求分子项最大即可。
其中,X是特征向量,其有多个维度,即 X={x1,x2,x3...,xn}。假设各个特征取值是相互独立的,可得下式:
算法:
朴素贝叶斯算法
注意:
1.如果在计算条件概率时,一个概率值为0,那么最后的乘积也是0。这会影响后验概率的计算结果,使分类产生偏差。为了降低这种影响,可以采用贝叶斯估计。
具体的公式改动如下,
其思想就是,给每种情况初始值加1,使其概率不为0。
2.另外遇到一个问题就是下溢出,这是由于太多很小的数相乘造成的。
这种解决方法是对乘机取自然对数。在代数中,ln(a*b*c)=ln(a)+ln(b)+ln(c)。
所以,
附python源码
#coding: utf-8 or # -*- coding: utf-8 -*- # author=altman import numpy as np import copy as cp #获得特征向量可能值 def createWordList(data): wordSet = set([]) for document in data: wordSet = wordSet | set(document) return list(wordSet) #将多维数据转化为一维向量,方便计算 def word2Vec(wordList,inputWord): returnVec = [0]*len(wordList) for word in inputWord: if word in wordList: returnVec[wordList.index(word)] = 1 return returnVec #训练函数,根据给定数据和标签,计算概率 def train(trainMatrix,trainLabels): numTrainDocs = len(trainMatrix) numWords = len(trainMatrix[0]) pAbusive = (sum(trainLabels)+1.0)/(float(numTrainDocs)+2.0*1.0) p0Num = np.ones(numWords) p1Num = np.ones(numWords) p0Denom = 3.0 + len(trainLabels)-sum(trainLabels) p1Denom = 3.0 + sum(trainLabels) for i in range(numTrainDocs): if trainLabels[i] == 1: p1Num += trainMatrix[i] else: p0Num += trainMatrix[i] p0Vect = np.log(p0Num/p0Denom) p1Vect = np.log(p1Num/p1Denom) return p0Vect,p1Vect,pAbusive #分类函数 def classify(vec2Clssify,p0Vect,p1Vect,pClass1): p1 = sum(vec2Clssify*p1Vect) + np.log(pClass1) p0 = sum(vec2Clssify*p0Vect) + np.log(1-pClass1) if p1>p0: return 1 else: return 0 def main(): data = [[1,'s'],[1,'m'],[1,'m'],[1,'s'],[1,'s'],[2,'s'],[2,'m'],[2,'m'],[2,'l'],[2,'l'],[3,'l'],[3,'m'],[3,'m'],[3,'l'],[3,'l']] labels = [0,0,1,1,0,0,0,1,1,1,1,1,1,1,0] wordList = createWordList(data) dataMatrix = [] for item in data: dataMatrix.append(word2Vec(wordList,item)) p0,p1,pAB = train(dataMatrix,labels) goal = [3,'l'] wordVec = np.array(word2Vec(wordList,goal)) print(classify(wordVec,p0,p1,pAB)) if __name__ == '__main__': main()