机器学习_算法_朴素贝叶斯
2013-08-23 21:52
411 查看
参考:
http://blog.csdn.net/marvin521/article/details/9262445
/article/9009331.html
naive bayes 还是很简单的,网上的很多细节都没有说清楚,我直接看了原版的《Machine learning in action》
把细节都扒了出来,流程是这样的
1.根据所有邮件构建一个特征向量,向量的维度就是邮件所有单词的最小集合,[0,0,0,0,0]
2.训练Naive Bayes classfier,生成特征向量对垃圾/非垃圾邮件判断的权重,纬度和特征向量一致[1,2.1,4,2,5]/[1,-1,0.2,4,5]
(我一开始以为NB不需要训练,直接计算的,所以很多位置弄错了)
3.开始测试,将测试的邮件转为特征向量,这里有两点,一定要注意,网上都没有提到,我看代码才搞清楚,不知到为什么一直没人提到过
a) 转换时,如果特征向量里没有这个纬度的话,就不考虑,比如我输入的是"我是谁呢",特征向量里没有“呢”这个纬度,不考虑,生成(0,1,0,1,1)
b)转换时,如果一个纬度出现两次,只用考虑一次比如“我是谁谁”,还是生成(0,1,0,1,1)
4.将生成的向量与垃圾/非垃圾权重向量乘积(相当于屏蔽某些特征)再求和
5.比较大小,判断类型
Bayes公式在这里的应用
Bayes就是通过先验概率求后验概率
P(A|B) = P(B|A) * P(A) / P(B)
符号说明:
R:邮件中垃圾邮件的概率
r:邮件中正常邮件的概率
Xi:出现纬度i的概率
则判断是否是垃圾邮件可以通过:
P(R|X1,X2,X3.....Xn) <> P(r|X1,X2,X3.....Xn) 大小关系确定测试邮件的归属
由bayes公式
=> P(X1,X2,...Xn|R) * P(R) / P(X1,X2,...Xn) <> P( P(X1,X2,...Xn|r) * P(r) / P(X1,X2,...Xn)
因为是邮件中的文本,可以简单认为是文本间是相互独立的,所以
=>P(X1|R) *P(X2|R)...P(Xn|R) * P(R) <> P(X1|r)*P(X2|R),...*P(Xn|r) * P(r)
测试邮件中并不能包含所有的特征文本,可能P(Xn|R) = 0,造成两边无法比较的情况 0 <> 0
可以取对数来化解,Ln(X)的单调性和 X是一致的
=>Ln(P(X1|R) *P(X2|R)...P(Xn|R) * P(R) ) <> Ln(P(X1|r)*P(X2|R),...*P(Xn|r) * P(r))
=>P(X1|R) + P(X2|R) +....+ P(Xn|R) + P(R) <> P(X1|r) + P(X2|r)....+P(Xn|r) * P(r)
我也在这里实现一下
http://blog.csdn.net/marvin521/article/details/9262445
/article/9009331.html
naive bayes 还是很简单的,网上的很多细节都没有说清楚,我直接看了原版的《Machine learning in action》
把细节都扒了出来,流程是这样的
1.根据所有邮件构建一个特征向量,向量的维度就是邮件所有单词的最小集合,[0,0,0,0,0]
2.训练Naive Bayes classfier,生成特征向量对垃圾/非垃圾邮件判断的权重,纬度和特征向量一致[1,2.1,4,2,5]/[1,-1,0.2,4,5]
(我一开始以为NB不需要训练,直接计算的,所以很多位置弄错了)
3.开始测试,将测试的邮件转为特征向量,这里有两点,一定要注意,网上都没有提到,我看代码才搞清楚,不知到为什么一直没人提到过
a) 转换时,如果特征向量里没有这个纬度的话,就不考虑,比如我输入的是"我是谁呢",特征向量里没有“呢”这个纬度,不考虑,生成(0,1,0,1,1)
b)转换时,如果一个纬度出现两次,只用考虑一次比如“我是谁谁”,还是生成(0,1,0,1,1)
4.将生成的向量与垃圾/非垃圾权重向量乘积(相当于屏蔽某些特征)再求和
5.比较大小,判断类型
Bayes公式在这里的应用
Bayes就是通过先验概率求后验概率
P(A|B) = P(B|A) * P(A) / P(B)
符号说明:
R:邮件中垃圾邮件的概率
r:邮件中正常邮件的概率
Xi:出现纬度i的概率
则判断是否是垃圾邮件可以通过:
P(R|X1,X2,X3.....Xn) <> P(r|X1,X2,X3.....Xn) 大小关系确定测试邮件的归属
由bayes公式
=> P(X1,X2,...Xn|R) * P(R) / P(X1,X2,...Xn) <> P( P(X1,X2,...Xn|r) * P(r) / P(X1,X2,...Xn)
因为是邮件中的文本,可以简单认为是文本间是相互独立的,所以
=>P(X1|R) *P(X2|R)...P(Xn|R) * P(R) <> P(X1|r)*P(X2|R),...*P(Xn|r) * P(r)
测试邮件中并不能包含所有的特征文本,可能P(Xn|R) = 0,造成两边无法比较的情况 0 <> 0
可以取对数来化解,Ln(X)的单调性和 X是一致的
=>Ln(P(X1|R) *P(X2|R)...P(Xn|R) * P(R) ) <> Ln(P(X1|r)*P(X2|R),...*P(Xn|r) * P(r))
=>P(X1|R) + P(X2|R) +....+ P(Xn|R) + P(R) <> P(X1|r) + P(X2|r)....+P(Xn|r) * P(r)
我也在这里实现一下
#-*- coding:utf-8 -*- ''' Created on Aug 24, 2013 @author: blacklaw ''' from numpy import * 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] def docs2set(data): retSet = set() for li in data: retSet = retSet | set(li) return retSet def list2vect(li, wordsSet): retVect = zeros(len(wordsSet)) for word in li: if word in wordsSet: retVect[list(wordsSet).index(word)] = 1 else: print "%s not in wordsSet" % word return retVect def trainNB(martix, wordsSet, category): ''' pRvect = zeros(len(wordsSet)) prvect = zeros(len(wordsSet)) ''' # use ones not zeros: caution, log(0) will be error pRvect = ones(len(wordsSet)) prvect = ones(len(wordsSet)) RSum = rSum = 0 for i,vect in enumerate(martix): if category[i] == 1: # 1 means Rubbish pRvect += vect RSum += sum(vect) else: prvect += vect rSum += sum(vect) return log(pRvect/RSum), log(prvect/rSum) def testNB(pRvect, prvect, testDoc, wordsSet, category): testVect = list2vect(testDoc, wordsSet) R = float(sum(category)) / len(category) r = 1 - R ''' Caution: we have trained NB pR/rvect use log() so there use "+ R" "sum", not * R ''' pFromR = R + sum(pRvect * testVect) pFromr = r + sum(prvect * testVect) print pFromR, pFromr return pFromR > pFromr if __name__ == "__main__": wordsSet = docs2set(postingList) martix = [] for posting in postingList: martix.append(list2vect(posting, wordsSet)) pRvect, prvect = trainNB(martix, wordsSet, classVec) print testNB(pRvect, prvect, ['love', 'my', 'dalmation'], wordsSet, classVec) print testNB(pRvect, prvect, ['stupid', 'garbage'], wordsSet, classVec)
结果: -8.3333169375 -6.2615727688 False -3.30943641665 -5.8561076607 True
相关文章推荐
- 【学习笔记】斯坦福大学公开课(机器学习) 之生成学习算法:朴素贝叶斯
- 机器学习入门算法及其java实现-朴素贝叶斯
- 机器学习经典算法3-朴素贝叶斯
- 机器学习(四):分类算法之朴素贝叶斯
- 文本分类算法--朴素贝叶斯
- 机器学习四 -- 基于概率论的分类方法:朴素贝叶斯
- 朴素贝叶斯算法
- 朴素贝叶斯算法文本分类原理
- 机器学习_阅读笔记_朴素贝叶斯
- 机器学习之朴素贝叶斯
- 机器学习学习笔记之三:朴素贝叶斯
- 清华大学计算机科学与技术系朱军教授:机器学习里的贝叶斯基本理论、模型和算法
- 机器学习理论与实战(三)朴素贝叶斯
- 机器学习实战--朴素贝叶斯
- 机器学习(6)-贝叶斯算法
- 机器学习 Python实现 贝叶斯算法
- 挖掘算法(1)朴素贝叶斯算法
- 机器学习实战python版 朴素贝叶斯示例 垃圾邮件分类 从个人广告中获取趋于趋向
- 【机器学习-斯坦福】学习笔记6 - 朴素贝叶斯
- 斯坦福机器学习之朴素贝叶斯