当前位置:文档之家› 机器学习实验之朴素贝叶斯(垃圾邮件判断)

机器学习实验之朴素贝叶斯(垃圾邮件判断)

机器学习实训实验报告(四)专业班级学号姓名实验项目名称:利用朴素贝叶斯过滤垃圾邮件实验内容:1、了解概率分类器的意义,理解条件概率的计算方法2、了解朴素贝叶斯的理论知识,了解基于以上理论知识构建分类器的方法3、根据朴素贝叶斯的一般步骤进行过滤垃圾邮件的任务实验过程:算法分析:简介:朴素贝叶斯算法的分类模型是基于Bayes定理的,下面就简单介绍一下Bayes定理.设X为一个类别未知的数据样本,H为某个假设,C表示类别集合,若数据样本X属于一个特定的类别c,那么分类问题就是决定P(H/X),即在获得数据样本X时,H假设成立的概率.由于P(H),P(X), P(X/H)的概率值可以从(供学习使用的)数据集合中得到,Bayes 定理描述了如何根据P(H), P(X),P(X/H)计算获得的P(H/X),有关的具体公式定义描述如下算法过程:我们假设训练集为m个样本n个维度,如下:(x(1)1,x(1)2,...x(1)n,y1),(x(2)1,x(2 )2,...x(2)n,y2),...(x(m)1,x(m)2,...x( m)n,ym)(x1(1),x2(1),...xn(1),y1),( x1(2),x2(2),...xn(2),y2),...(x1(m),x 2(m),...xn(m),ym)共有K个特征输出类别,分别为C1,C2,...,CKC1,C2,...,CK,每个特征输出类别的样本个数为m1,m2,...,mKm1,m2,...,mK,在第k 个类别中,如果是离散特征,则特征XjXj各个类别取值为mjlmjl。

其中l取值为源程序代码:from numpy import *import redef 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']]classV ec = [0,1,0,1,0,1] #类别:1代表侮辱性文字,0代表正常return postingList,classVec#函数说明:将切分的词条整理成不重复的词条列表def createV ocabList(dataSet):vocabSet = set([]) ##创建一个空的不重复列表for document in dataSet:vocabSet = vocabSet | set(document) #取并集return list(vocabSet)#函数说明:根据vocabList,将inputSet向量化,每个元素为1或0 def setOfWords2Vec(vocabList, inputSet):returnVec = [0]*len(vocabList) #创建一个其中所含元素都为0的向量for word in inputSet: #遍历每个词条if word in vocabList: #如果词条存在于词汇表中,则置1returnVec[vocabList.index(word)] = 1else: print ("the word: %s is not in my Vocabulary!" % word)return returnVec#函数说明:朴素贝叶斯分类器训练函数def trainNB0(trainMatrix,trainCategory):numTrainDocs = len(trainMatrix) #计算训练的文档数目numWords = len(trainMatrix[0]) #计算每篇文档的词条数1,2,...Sj1,2,...Sj,SjSj为特征j不同的取值数。

输出为实例X(test)X(test)的分类。

算法流程如下:1) 如果没有Y的先验概率,则计算Y的K个先验概率:P(Y=Ck)=(mk+λ)/(m+Kλ)P(Y=C k)=(mk+λ)/(m+Kλ),否则P(Y=Ck)P(Y=Ck)为输入的先验概率。

2) 分别计算第k个类别的第j维特征的第l个个取值条件概率:P(Xj=xjl|Y=Ck)P(Xj=xjl|Y=Ck)a)如果是离散值:P(Xj=xjl|Y=Ck)=mkjl+λmk+SjλP( Xj=xjl|Y=Ck)=mkjl+λmk+Sjλλλ可以取值为1,或者其他大于0的数字。

b)如果是稀疏二项离散值:P(Xj=xjl|Y=Ck)=P(j|Y=Ck)xjl+(1−P(j|Y=Ck)(1−xjl)P(Xj=xjl|Y=Ck) =P(j|Y=Ck)xjl+(1−P(j|Y=Ck)(1−xjl)此时ll只有两种取值。

c)如果是连续值不需要计算各个l的取值概率,直接求正态分布的参数:P(Xj=xj|Y=Ck)=12πσ2k−−−−√exp(−(xj−μk)22σ2k)P(Xj=xj|Y=C k)=12πσk2exp(−(xj−μk)22σk2)需要求出μk和σ2kμk和σk2。

μkμk为在样本类别CkCk中,所有XjXj的平均值。

σ2kσk2为在样本类别CkCk中,所有XjXj的方差。

pAbusive = sum(trainCategory)/float(numTrainDocs) #文档属于侮辱类的概率p0Num = zeros(numWords); p1Num = zeros(numWords)#词条出现数初始化为1p0Denom = 0.0; p1Denom = 0.0 #分母初始化为0for i in range(numTrainDocs):if trainCategory[i] == 1:#统计属于侮辱类的总词数,出现一次,次数+1p1Num += trainMatrix[i]p1Denom += sum(trainMatrix[i])else:#统计属于非侮辱类的总词数,出现一次,次数+1p0Num += trainMatrix[i]p0Denom += sum(trainMatrix[i])#对应个数除以总数,此处可以用log()防止下溢出p1Vect = p1Num/p1Denomp0Vect = p0Num/p0Denomreturn p0Vect,p1Vect,pAbusive#返回属于侮辱类的条件概率数组,属于非侮辱类的条件概率数组,文档属于侮辱类的概率#函数说明:朴素贝叶斯分类器分类函数def classifyNB(vec2Classify, p0Vec, p1Vec, pClass1):#对应元素相乘,且所有词的对应值相加,并将此值加入到对数概率中p1 = sum(vec2Classify * p1Vec) + log(pClass1)p0 = sum(vec2Classify * p0Vec) + log(1.0 - pClass1)if p1 > p0:return 1else:return 0#函数说明:便利函数,封装操作def testingNB():listOPosts,listClasses = loadDataSet() #加载数据myV ocabList = createV ocabList(listOPosts) #整理词条trainMat=[]#遍历listOPosts,向trainMat插入向量化后的listOPostsfor postinDoc in listOPosts:trainMat.append(setOfWords2Vec(myVocabList, postinDoc))p0V,p1V,pAb = trainNB0(array(trainMat),array(listClasses))#记:侮辱类的条件概率数组,非侮辱类的条件概率数组,文档是侮辱类的概率testEntry = ['love', 'my', 'dalmation']#根据myV ocabList,向量化testEntrythisDoc = array(setOfWords2Vec(myVocabList, testEntry))#输出分类print (testEntry,'classified as: ',classifyNB(thisDoc,p0V,p1V,pAb))#根据myV ocabList,向量化testEntrytestEntry = ['stupid', 'garbage']thisDoc = array(setOfWords2Vec(myVocabList, testEntry))print (testEntry,'classified as: ',classifyNB(thisDoc,p0V,p1V,pAb))#函数说明:朴素贝叶斯词袋模型3)对于实例X(test)X(test),分别计算:P(Y=Ck)∏j=1nP(Xj=x(test)j|Y=C k)P(Y=Ck)∏j=1nP(Xj=xj(test)|Y=Ck)4)确定实例X(test)X(test)的分类CresultCresultCresult=argmaxCkP(Y=Ck)∏j=1nP(Xj=X( test)j|Y=Ck)调试过程中的关键问题及修改:1、错误:正则分割函数pile():结果为全部是空格和逗号解决方法:改为pile('[ ,.]+')意思是按空格和.分割2、报错:UnicodeDecodeError: 'gbk' codec can't decode byte 0xae in position 199: illegal multibyte sequence原因:是打印的某种编码类型的字符串到终端,所以由于编码不匹配,导致出现此问题。

相关主题