1200字范文,内容丰富有趣,写作的好帮手!
1200字范文 > 使用朴素贝叶斯过滤垃圾邮件

使用朴素贝叶斯过滤垃圾邮件

时间:2019-03-29 16:20:22

相关推荐

使用朴素贝叶斯过滤垃圾邮件

1.解析并切分文本文件

2.随机构建训练测试集

3.使用贝叶斯分类算法分类

4.验证结果错误率

贝叶斯算法在另一篇文章中注释详细有述

另,该文参照《机器学习实战》,在代码中可能由于版本原因书中正则表达式切分词时有错误,目前未解决

文中有一部分为测试问题的输出函数

#!/usr/bin/env python# -*- coding: UTF-8 -*-'''=================================================@Project -> File :bayes -> bayesOfEmail@IDE :PyCharm@Author :zgq@Date :/1/10 20:14@Desc :=================================================='''import refrom numpy import *import random#2、创建一个包含在所有句子中的不重复出现的词列表def createVocabList(dataSet):vocabSet=set([]) #创建一个set变量,她可以去掉重复的词for document in dataSet:vocabSet=vocabSet | set(document) #将词条列表输给set构造函数,set就回返回一个不重复的listreturn list(vocabSet)#3、将输入的一句话转换为词向量(one hot类型)def setOfWords2Vec(vocabList,inputSet):returnVec=[0]*len(vocabList) #先将这个返回的词向量初始化一个长度为onehot的向量for word in inputSet:#对于传入这句话的每个单词来判断是否有 有放1没有放oif word in vocabList:returnVec[vocabList.index(word)]=1else:print("the word: %s is not in my Vocabulary!" % word)return returnVec#训练算法:从词向量计算概率def trainNB0(trainMatrix,trainCategory): #trainMatrix是一个矩阵是一个二维的,每一行是一个样本(由词向量组成的矩阵)#此处是上边要传递的不是原先的都是单词的矩阵,而是one hot类型的矩阵numTrainDocs=len(trainMatrix) #len(矩阵)返回行数numWords=len(trainMatrix[0]) #trainMatrix返回矩阵一行的长度,即每条样本的属性数(词数)pAbusive=sum(trainCategory)/float(numTrainDocs)#文档属于侮辱性类的概率,第一项为侮辱性类词向量次数、第二行为总样本数p0Num=ones(numWords) #做了一个全为0的向量(0,0,0,0),长度为样本数p1Num=ones(numWords)p0Denom=2.0 #p1Denom=2.0for i in range(numTrainDocs): #遍历文本矩阵每一行,即遍历每一条样本if trainCategory[i]==1:p1Num=p1Num+trainMatrix[i] #如果该行种类为1的话,将这行词向量盖上到这个(0,0,0,0,0,0,0) 上去#如果这句话是侮辱性的句子,将这句话的里边的所有词都放入P1num中,最后执行完毕后会是一个(3,1,0,11,15……),对应于我的词汇表中每个词出现的次数p1Denom=p1Denom+sum(trainMatrix[i]) #加和该句话的总词数else:p0Num=p0Num+trainMatrix[i]p0Denom=p0Denom+sum(trainMatrix[i])#在上面的过程中,步骤为对句子构成的词向量构成的矩阵,对每一句话,如果这句话是侮辱性类别的,在我们词表中记录她出现了,出现一次次数加一#最后得到的是 p1Num 所有的词在句子为侮辱性的情况下出现的次数。#而对于P1Denom,对与每句属于类被1的句子,都将这句话的词数加进去,最后得到了,这个总的 矩阵中,语料中,是侮辱性的词语总数#因为 p1Num为一个向量,记录了每个词在所有的侮辱性句子中出现的总次数,将其除以侮辱性句子总词数,获得在c概率下p(w|1)p1Vect=log(p1Num/p1Denom) #词向量除以浮点数,结果为我们的词汇表中每一个词在侮辱性句子下出现的概率p0Vect=log(p0Num/p0Denom)return p0Vect,p1Vect,pAbusive#利用词向量概率来构建贝叶斯分类函数def classifyNB(vec2Classify,p0Vec,p1Vec,pClass1):p1=sum(vec2Classify*p1Vec)+log(pClass1)p0=sum(vec2Classify*p0Vec)+log(1-pClass1)if p1>p0:return 1else:return 0#接受一个大字符串并将其解析为字符串列表def textParse(bigString):listOfTokens=re.split(r'\W*',bigString) #将字符串切分return [tok.lower() for tok in listOfTokens if len(tok)>2] #去掉长度小于2的字符串,且转化为小写#文件解析及完整的垃圾邮件测试函数def spamTest():docList=[]classList=[]fullText=[]for i in range(1,26):wordList=textParse(open('email/spam/%d.txt' % i).read()) #spam是正面的,ham是负面的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)#解析函数中输出什么?print("解析函数中输出的wordlist:")print(wordList)print("解析函数中输出的docList:")print(fullText)print("输出classlist")print(classList)print("测试一下open。read函数")test_open=open('email/spam/1.txt').read()print(test_open)print("测试parse函数")print(textParse(test_open))print("创建词汇表:")vocabList=createVocabList(docList)#创建不重复的词汇表用于构建one hot 向量print("随机选择10个作为测试集放到testSet中,并且将其从trainingSet中删除")#此处选择的只是它的标签(就是它是第几个)而没有选择了本身,最后的选择是一个index【1,5,18,26,3……】trainingSet=list(range(50)) #range()函数产生一个从0到50的列表 即trainingSet=[0,1,2,3……,49,50]testSet=[] #训练集为50里面不放回的随机选10个for i in range(10):randIndex=int(random.uniform(0,len(trainingSet))) #返回一个从0到len范围的随机数testSet.append(trainingSet[randIndex])del(trainingSet[randIndex]) #不放回的随机抽取,把当前这个序号抽出来之后,后面就不会抽到她了print("对于选为训练集的每一个文本,都将其转化为onehot类型的词向量,最后构成一个矩阵")trainMat=[]trainClasses=[]for docIndex in trainingSet:trainMat.append(setOfWords2Vec(vocabList,docList[docIndex])) #这边的doclist是将邮件刚解析为list后的东西,需要将其转换为此词向量trainClasses.append((classList[docIndex])) #将其对应的类别也安排上#使用朴素贝叶斯分类器进行分类,此处是求出了两个向量,一个是基于one hot词汇表上每个词对应是好词或者是坏此的概率,最后要用这个概率来求最后的总概率p0V,p1V,pSpam=trainNB0(array(trainMat),array(trainClasses))#开始使用训练集进行测试errorCount=0for docIndex in testSet:print("测试集",docIndex,":",docList[docIndex])wordVector=setOfWords2Vec(vocabList,docList[docIndex])print('the right sequence is: %d' %classList[docIndex],'and our predict sequence is: %d' % classifyNB(array(wordVector),p0V,p1V,pSpam))if classifyNB(array(wordVector),p0V,p1V,pSpam)!=classList[docIndex]:errorCount=errorCount+1print('the error rate is:',float(errorCount)/len(testSet))spamTest()

运行结果

解析函数中输出的wordlist:[]解析函数中输出的docList:[]输出classlist[1, 0, 1, 0, 1, 0, 1, 0, 1, 0, 1, 0, 1, 0, 1, 0, 1, 0, 1, 0, 1, 0, 1, 0, 1, 0, 1, 0, 1, 0, 1, 0, 1, 0, 1, 0, 1, 0, 1, 0, 1, 0, 1, 0, 1, 0, 1, 0, 1, 0]测试一下open。read函数--- Codeine 15mg -- 30 for $203.70 -- VISA Only!!! ---- Codeine (Methylmorphine) is a narcotic (opioid) pain reliever-- We have 15mg & 30mg pills -- 30/15mg for $203.70 - 60/15mg for $385.80 - 90/15mg for $562.50 -- VISA Only!!! ---测试parse函数[]创建词汇表:随机选择10个作为测试集放到testSet中,并且将其从trainingSet中删除对于选为训练集的每一个文本,都将其转化为onehot类型的词向量,最后构成一个矩阵测试集 28 : []the right sequence is: 1 and our predict sequence is: 1测试集 16 : []the right sequence is: 1 and our predict sequence is: 1测试集 25 : []the right sequence is: 0 and our predict sequence is: 1测试集 11 : []the right sequence is: 0 and our predict sequence is: 1测试集 7 : []the right sequence is: 0 and our predict sequence is: 1测试集 9 : []the right sequence is: 0 and our predict sequence is: 1测试集 2 : []the right sequence is: 1 and our predict sequence is: 1测试集 3 : []the right sequence is: 0 and our predict sequence is: 1测试集 47 : []the right sequence is: 0 and our predict sequence is: 1测试集 0 : []the right sequence is: 1 and our predict sequence is: 1the error rate is: 0.6

定位到正则表达式切分文本出现错误,但是暂时不知道如何解决

本内容不代表本网观点和政治立场,如有侵犯你的权益请联系我们处理。
网友评论
网友评论仅供其表达个人看法,并不表明网站立场。