为什么说黑框眼镜naive事件 bayesian分类法是黑框眼镜naive事件的

朴素贝叶斯算法(Naive Bayesian)
时间: 17:09:43
&&&& 阅读:115
&&&& 评论:
&&&& 收藏:0
标签:&&&&&&&&&&&&&&&&&&&&&&&&&&&1、介绍
朴素贝叶斯方法,朴素指特征条件独立,贝叶斯指贝叶斯定理。算法可用来做分类,既可以是判别模型,也可以是生成模型。训练的时候,学习输入输出的联合概率分布,分类的时候,利用贝叶斯定理计算后验概率最大的输出。一句话总结:根据先验概率和条件概率分布,得到联合概率分布。如下所示:
2、模型讲解
条件概率分布的参数数量是指数级的,也就是X和Y的组合很多,造成维数灾难,导致实际无法运算。此处,朴素贝叶斯法对它做了条件独立性的假设:
也就是各个维度的特征在类确定的情况下都是独立分布的。这一假设简化了计算,也牺牲了一定的分类准确率。基于此假设,以及贝叶斯定理,后验概率为:
分母其实是P(X=x),等同于枚举ck求联合分布的和:∑P(X=x,Y=ck),此联合分布按公式:
拆开,等于上式分母。将独立性假设代入上式,得到:
朴素贝叶斯分类器可以表示为:
也就是给定参数,找一个概率最大的ck出来。注意到上式分母其实就是P(X=x),x给定了就固定了,跟ck一点关系都没有,所以分母可以去掉,得到:
后验概率最大化等价于期望风险最小化。如下解释
选择0-1损失函数,如下:
f(X)就是分类器的决策函数,损失函数的参数其实是一个联合分布。此时期望风险函数为:
上面说过,这是一个联合分布P(X,Y),是一个and(连乘)的形式,由此取条件期望为风险函数:
所谓条件期望,就是指X=x时,Y的期望。上式其实可以这么推回去:Ex∑[L()]P(ck|X)=∑P(X)∑[L()]P(X,ck)/P(X)=∑[L()]P(X,ck)=E[L()],格式比较乱,但愿意思到了。为了最小化上式,只需对每个X=x执行最小化,那么加起来肯定是极小化的,由此有:
3、参数估计
极大似然估计:
前面说过,朴素贝叶斯法要学习的东西就是P(Y=ck)和P(X=x|Y=ck),这两个概率的估计用极大似然估计法(简单讲,就是用样本猜测模型参数,或者说使得似然函数最大的参数)进行:
也就是用样本中ck的出现次数除以样本容量:
分子是样本中变量组合的出现次数,分母是上面说过的样本中ck的出现次数。
贝叶斯估计:
最大似然估计有个隐患,假设训练数据中没有出现某种参数和类别的组合怎么办?此时估计的概率值为0,但是这不代表真实数据中就没有这样的组合。解决办法是采用贝叶斯估计,以下显示的是先验概率的贝叶斯估计和条件概率的贝叶斯估计:
分子和分母分别比最大似然估计多了一点东西,其意义是在随机变量每个取值的频数上加一个常量,当此常量取0时,就是最大似然估计,当此常量取1时,称为拉普拉斯平滑,常用来解决零概率的问题。
4、算法流程
总结如下算法流程:
关于贝叶斯,还有很多知识,比如贝叶斯决策论、贝叶斯判定准则等等。请自行百度扩充。
朴素的贝叶斯分类器优点:在接受大量数据训练和查询时的高速度(尤其当训练量递增时更是如此);其对分类器的学习情况有着比较简单的解释,我们可以简单的通过查询学习时计算的一些概率值来了解其分类原理。朴素的贝叶斯分类缺点是它无法处理特征符合所产生的变化(即前面提到过的实际上难以满足的相互独立)。
简单放一点代码:
Created on Oct 19, 2010
@author: Peter
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]
#<span style="color: # 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])
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:
def bagOfWords2VecMN(vocabList, inputSet):
returnVec = [0]*len(vocabList)
for word in inputSet:
if word in vocabList:
returnVec[vocabList.index(word)] += 1
return returnVec
def testingNB():
listOPosts,listClasses = loadDataSet()
myVocabList = createVocabList(listOPosts)
trainMat=[]
for postinDoc in listOPosts:
trainMat.append(setOfWords2Vec(myVocabList, postinDoc))
p0V,p1V,pAb = trainNB0(array(trainMat),array(listClasses))
testEntry = [‘love‘, ‘my‘, ‘dalmation‘]
thisDoc = array(setOfWords2Vec(myVocabList, testEntry))
print testEntry,‘classified as: ‘,classifyNB(thisDoc,p0V,p1V,pAb)
testEntry = [‘stupid‘, ‘garbage‘]
thisDoc = array(setOfWords2Vec(myVocabList, testEntry))
print testEntry,‘classified as: ‘,classifyNB(thisDoc,p0V,p1V,pAb)
def textParse(bigString):
#input is big string, #output is word list
listOfTokens = re.split(r‘\W*‘, bigString)
return [tok.lower() for tok in listOfTokens if len(tok) & 2]
def spamTest():
docList=[]; classList = []; fullText =[]
for i in range(1,26):
wordList = textParse(open(‘email/spam/%d.txt‘ % i).read())
docList.append(wordList)
fullText.extend(wordList)
classList.append(1)
wordList = textParse(open(‘email/ham/%d.txt‘ % i).read())
docList.append(wordList)
fullText.extend(wordList)
classList.append(0)
vocabList = createVocabList(docList)#create vocabulary
trainingSet = range(50); testSet=[]
#create test set
for i in range(10):
randIndex = int(random.uniform(0,len(trainingSet)))
testSet.append(trainingSet[randIndex])
del(trainingSet[randIndex])
trainMat=[]; trainClasses = []
for docIndex in trainingSet:#train the classifier (get probs) trainNB0
trainMat.append(bagOfWords2VecMN(vocabList, docList[docIndex]))
trainClasses.append(classList[docIndex])
p0V,p1V,pSpam = trainNB0(array(trainMat),array(trainClasses))
errorCount = 0
for docIndex in testSet:
#classify the remaining items
wordVector = bagOfWords2VecMN(vocabList, docList[docIndex])
if classifyNB(array(wordVector),p0V,p1V,pSpam) != classList[docIndex]:
errorCount += 1
print "classification error",docList[docIndex]
print ‘the error rate is: ‘,float(errorCount)/len(testSet)
#return vocabList,fullText
def calcMostFreq(vocabList,fullText):
import operator
freqDict = {}
for token in vocabList:
freqDict[token]=fullText.count(token)
sortedFreq = sorted(freqDict.iteritems(), key=operator.itemgetter(1), reverse=True)
return sortedFreq[:30]
def localWords(feed1,feed0):
import feedparser
docList=[]; classList = []; fullText =[]
minLen = min(len(feed1[‘entries‘]),len(feed0[‘entries‘]))
for i in range(minLen):
wordList = textParse(feed1[‘entries‘][i][‘summary‘])
docList.append(wordList)
fullText.extend(wordList)
classList.append(1) #NY is class 1
wordList = textParse(feed0[‘entries‘][i][‘summary‘])
docList.append(wordList)
fullText.extend(wordList)
classList.append(0)
vocabList = createVocabList(docList)#create vocabulary
top30Words = calcMostFreq(vocabList,fullText)
#remove top 30 words
for pairW in top30Words:
if pairW[0] in vocabList: vocabList.remove(pairW[0])
trainingSet = range(2*minLen); testSet=[]
#create test set
for i in range(20):
randIndex = int(random.uniform(0,len(trainingSet)))
testSet.append(trainingSet[randIndex])
del(trainingSet[randIndex])
trainMat=[]; trainClasses = []
for docIndex in trainingSet:#train the classifier (get probs) trainNB0
trainMat.append(bagOfWords2VecMN(vocabList, docList[docIndex]))
trainClasses.append(classList[docIndex])
p0V,p1V,pSpam = trainNB0(array(trainMat),array(trainClasses))
errorCount = 0
for docIndex in testSet:
#classify the remaining items
wordVector = bagOfWords2VecMN(vocabList, docList[docIndex])
if classifyNB(array(wordVector),p0V,p1V,pSpam) != classList[docIndex]:
errorCount += 1
print ‘the error rate is: ‘,float(errorCount)/len(testSet)
return vocabList,p0V,p1V
def getTopWords(ny,sf):
import operator
vocabList,p0V,p1V=localWords(ny,sf)
topNY=[]; topSF=[]
for i in range(len(p0V)):
if p0V[i] & -6.0 : topSF.append((vocabList[i],p0V[i]))
if p1V[i] & -6.0 : topNY.append((vocabList[i],p1V[i]))
sortedSF = sorted(topSF, key=lambda pair: pair[1], reverse=True)
print "SF**SF**SF**SF**SF**SF**SF**SF**SF**SF**SF**SF**SF**SF**SF**SF**"
for item in sortedSF:
print item[0]
sortedNY = sorted(topNY, key=lambda pair: pair[1], reverse=True)
print "NY**NY**NY**NY**NY**NY**NY**NY**NY**NY**NY**NY**NY**NY**NY**NY**"
for item in sortedNY:
print item[0]
相关博客:
&标签:&&&&&&&&&&&&&&&&&&&&&&&&&&&原文:/taojake-ML/p/6114113.html
教程昨日排行
&&国之画&&&& &&&&&&
&& &&&&&&&&&&&&&&
鲁ICP备号-4
打开技术之扣,分享程序人生!温馨提示!由于新浪微博认证机制调整,您的新浪微博帐号绑定已过期,请重新绑定!&&|&&
LOFTER精选
网易考拉推荐
用微信&&“扫一扫”
将文章分享到朋友圈。
用易信&&“扫一扫”
将文章分享到朋友圈。
&其中P(AB)为A,B两个事件的联合概率。对上式利用乘法公式可以变形为:这样就得到了贝叶斯公式。贝叶斯文本分类就是基于这个公式,利用先验概率来得到文本的分类。&
&为第i个文本类别出现的概率,
&为文本类别为Ci时出现特征向量(w1,w2…wn)的概率,P(w1,w2…wn)为特征向量出现的概率。一般的会假设特征——词,在文本中出现的概率是独立的,也就是说词和词之间是不相关的(虽然这个不一定成立,但是为了简化计算往往又不得不这么做),那么这时候的联合概率就可以表示为乘积的形式,如下:&
对于特定的训练集合来说,上式中P(w1)P(w2)…P(wn)是一个固定的常数,那么在进行分类计算的时候可以省略掉这个分母的计算,如是得到:&
这样,只需要计算给定文本和各个类别之间的条件概率值,取最大的那个概率值所在的类别代表文本的类别就行了。
在贝叶斯分类器训练的时候,依照前面的公式可以知道,需要训练的参数有:
1.P(Ci) : 各个类别在所有的文档中出现的概率,这个只需要统计各个文本类别的数量,然后除以所有文档数就是需要的参数了。&
2.P(w|C): 各个词在各个类别中出现的概率,在类别C中出现了w的文档数除以C类文档总数&
在参数训练中,选定的特征——词,是事先从信息增益算法挑选出来的。
选取搜狗实验室的分类语料:商务类新闻和娱乐类新闻各100篇作为分类样本,测试集中商务类新闻文章19926篇,娱乐类新闻文章11987篇。其中商务类标记为正样本,娱乐类标记为负样本。
&&&&&&&& &&&&&&&& 分类结果:
Positive recall :94.817346%
Positive precision :95.778910%
Accuarcy : 94.044275%
&&&&&&&&&&&&&&&& 这样的结果对于其他分类起来将都已经是非常好的结果了。
5模型的优缺点
贝叶斯分类模型很大的一个优点就是训练过程非常简单,甚至是可以做到增量式训练,特征是对海量的训练集表现非常高效。
另外一个优点就是,模型的可读性也是比较强的,对于分类得到的结果可以进行解释。
最大的缺点,也就是一开始的假设,在现实世界中,特征属性之间往往是不独立的,所以在相关性很强的特征里使用此模型得到的分类结果会比较差。
&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&
阅读(1663)|
用微信&&“扫一扫”
将文章分享到朋友圈。
用易信&&“扫一扫”
将文章分享到朋友圈。
历史上的今天
loftPermalink:'',
id:'fks_',
blogTitle:'文本分类——Naive Bayes',
blogAbstract:'文本分类——Naive Bayes
{elseif x.moveFrom=='iphone'}
{elseif x.moveFrom=='android'}
{elseif x.moveFrom=='mobile'}
${a.selfIntro|escape}{if great260}${suplement}{/if}
{list a as x}
推荐过这篇日志的人:
{list a as x}
{if !!b&&b.length>0}
他们还推荐了:
{list b as y}
转载记录:
{list d as x}
{list a as x}
{list a as x}
{list a as x}
{list a as x}
{if x_index>4}{break}{/if}
${fn2(x.publishTime,'yyyy-MM-dd HH:mm:ss')}
{list a as x}
{if !!(blogDetail.preBlogPermalink)}
{if !!(blogDetail.nextBlogPermalink)}
{list a as x}
{if defined('newslist')&&newslist.length>0}
{list newslist as x}
{if x_index>7}{break}{/if}
{list a as x}
{var first_option =}
{list x.voteDetailList as voteToOption}
{if voteToOption==1}
{if first_option==false},{/if}&&“${b[voteToOption_index]}”&&
{if (x.role!="-1") },“我是${c[x.role]}”&&{/if}
&&&&&&&&${fn1(x.voteTime)}
{if x.userName==''}{/if}
网易公司版权所有&&
{list x.l as y}
{if defined('wl')}
{list wl as x}{/list}

我要回帖

更多关于 naive bayesian model 的文章

 

随机推荐