今天学习NB(nave Bayes)算法.看看此算法是不是真NB。
朴素贝叶斯法基于两点:
- 朴素贝叶斯定理
- 特征条件独立假设(强假设,实际情况不是这样)
1.学习方法及分类方法
1.1 NB基本算法流程
已知输入:
含有
N
个样本的训练集,
输出:
x⃗
的类别
y
- 计算先验概率及条件概率
先验概率:每一维上的条件概率:P(Y=ck)=∑Ni=1I(y(i)=ck)N,k=1,2,...,K P(Xj=ajl|Y=ck)=∑Ni=1I(x(i)j=ajl,y(i)=ck)∑Ni=1I(yi=ck)需要计算总的概率参数个数为: K∗∑jSj- 对于待分类特征值
x⃗ =(x1,x2,...xn)T
,分别计算:
P(Y=ck)∏j=1nP(xj=ajl|Y=ck),k=1,2,...K - 求最大值下的类别
y=argmaxckP(Y=ck)∏j=1nP(xj=ajl|Y=ck) 1.2 贝叶斯平滑
以上条件概率和先验概率估计通过最大似然估计得出,其中会出现概率为0的情况,此时会影响到后验概率的计算结果。解决此问题的方法可采用贝叶斯估计。
条件概率的贝叶斯估计为:Pλ(Xj=ajl|Y=ck)=∑Ni=1I(x(i)j=ajl,y(i)=ck)+λ∑Ni=1I(yi=ck)+λSj其中, λ⩾0 ,当 λ=0 时,为最大似然估计,当 λ=1 时, 这时称为拉普拉斯平滑,显然此式子满足概率条件。
先验概率的拉普拉斯平滑公式为:
P(Y=ck)=∑Ni=1I(y(i)=ck)+λN+λK1.3 代码实验
《机器学习实战》中,文本分类,主要流程为:
- 根据大量样本文本,提取字符向量列表(类似于特征提取)
- 训练过程:(1)计算先验概率(2)计算字符特征向量列表中每个单词的条件概率,即出现频率
- 测试过程:将待测试文本转换为特征向量列表,然后计算后验概率。
from numpy import * def loadDataSet(): postingList=[['my', 'dog', 'has', 'flea', 'problems', 'help', 'please'], ['maybe', 'not', 'take', 'him', 'to', 'dog', 'park', 'stupid'], ['my', 'dalmation', 'is', 'so', 'cute', 'I', 'love', 'him'], ['stop', 'posting', 'stupid', 'worthless', 'garbage'], ['mr', 'licks', 'ate', 'my', 'steak', 'how', 'to', 'stop', 'him'], ['quit', 'buying', 'worthless', 'dog', 'food', 'stupid']] classVec = [0,1,0,1,0,1] #1 is abusive, 0 not return postingList,classVec #根据训练样本提取特征向量 def createVocabList(dataSet): vocabSet = set([]) #create empty set for document in dataSet: vocabSet = vocabSet | set(document) #union of the two sets return list(vocabSet) #将文本集转换为标准特征向量 def setOfWords2Vec(vocabList, inputSet): returnVec = [0]*len(vocabList) for word in inputSet: if word in vocabList: returnVec[vocabList.index(word)] = 1 else: print "the word: %s is not in my Vocabulary!" % word return returnVec #分类训练,计算先验概率和条件概率 def trainNB0(trainMatrix,trainCategory): numTrainDocs = len(trainMatrix) numWords = len(trainMatrix[0]) pAbusive = sum(trainCategory)/float(numTrainDocs) p0Num = ones(numWords); p1Num = ones(numWords) #change to ones() p0Denom = 2.0; p1Denom = 2.0 #change to 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]) p1Vect = log(p1Num/p1Denom) #change to log() p0Vect = log(p0Num/p0Denom) #change to log() return p0Vect,p1Vect,pAbusive #预测 def classifyNB(vec2Classify, p0Vec, p1Vec, pClass1): p1 = sum(vec2Classify * p1Vec) + log(pClass1) #element-wise mult p0 = sum(vec2Classify * p0Vec) + log(1.0 - pClass1) if p1 > p0: return 1 else: return 0
- 对于待分类特征值
x⃗ =(x1,x2,...xn)T
,分别计算: