朴素贝叶斯最著名的一个应用:电子邮件垃圾过滤。
准备数据:切分文本
采用正则表达式和split()函数进行,和Java语言的字符串分割基本类似,略去不讲
1 def textParse(bigString): #input is big string, #output is word list 2 import re 3 listOfTokens = re.split(r'W*', bigString) 4 return [tok.lower() for tok in listOfTokens if len(tok) > 2] 5 6 def spamTest(): 7 docList=[]; classList = []; fullText =[] 8 for i in range(1,26): #1,2,3.。。25 9 wordList = textParse(open('email/spam/%d.txt' % i).read()) 10 docList.append(wordList) 11 fullText.extend(wordList) 12 classList.append(1) 13 wordList = textParse(open('email/ham/%d.txt' % i).read()) 14 docList.append(wordList) 15 fullText.extend(wordList) 16 classList.append(0) 17 vocabList = createVocabList(docList)#create vocabulary 18 trainingSet = range(50); testSet=[] #create test set 19 for i in range(10): 20 randIndex = int(random.uniform(0,len(trainingSet))) 21 testSet.append(trainingSet[randIndex]) 22 del(trainingSet[randIndex]) 23 trainMat=[]; trainClasses = [] 24 for docIndex in trainingSet:#train the classifier (get probs) trainNB0 25 trainMat.append(bagOfWords2VecMN(vocabList, docList[docIndex])) 26 trainClasses.append(classList[docIndex]) 27 p0V,p1V,pSpam = trainNB0(array(trainMat),array(trainClasses)) 28 errorCount = 0 29 for docIndex in testSet: #classify the remaining items 30 wordVector = bagOfWords2VecMN(vocabList, docList[docIndex]) 31 if classifyNB(array(wordVector),p0V,p1V,pSpam) != classList[docIndex]: 32 errorCount += 1 33 print "classification error",docList[docIndex] 34 print 'the error rate is: ',float(errorCount)/len(testSet) 35 #return vocabList,fullText
第一个函数传入一个字符串,将其转化成字符串列表,并且去掉少于两个字符的字符串,并将所有字符串转换为小写
第二个函数对贝叶斯垃圾邮件分类器进行自动化处理。导入文件夹spam和ham下的文版文件,并将其解析为词列表。接下来构建一个测试集和一个训练集,两个集合中的邮件都是随机选出的。总数有50封电子邮件,其中10封电子邮件被随机选择为测试集。分类器所需要的概率计算只利用训练集中的文档来完成。trainingSet是一个整数列表,值从0到49。接下来,随机选择其中10个文件,选出的数字所对应的文档被添加到测试集,同时也将其从训练集中剔除。这种随机选择数据的一部分作为训练集,而剩余部分作为测试集的过程叫做留存交叉验证。