当前位置:   article > 正文

【Python机器学习】朴素贝叶斯——使用朴素贝叶斯过滤垃圾邮件

【Python机器学习】朴素贝叶斯——使用朴素贝叶斯过滤垃圾邮件

使用朴素贝叶斯解决一些现实生活中的问题时,需要先从文本内容中得到字符串列表,然后生成词向量。

使用朴素贝叶斯对电子邮件进行分类的过程:

1、收集数据:提供文本文件

2、准备数据:将文本文件解析成词条向量

3、分析数据:检查词条确保解析的正确性

4、训练算法

5、测试算法:构建一个新的测试函数来计算文档集的错误率

6、使用算法:构建一个完整的程序对一组文档进行分类,输出错分的文档。

准备数据:切分文本

对于一个文本字符串,可以使用Python的string.split()方法将其切分。但是这种方法下,标点符号也会被当成词的一部分。可以使用正则表达式来切分句子,其中分隔符是除单词、数字外的任意字符串。比如:

  1. import re
  2. mySent='This book is the best book on Python on M.L. I have ever laid eyes upon.'
  3. regEx=re.compile('\\W')
  4. listOfTokens=regEx.split(mySent)
  5. print(listOfTokens)

现在得到了一系列词组成的词表,但是里面的空字符串需要去掉。可以计算每个字符串的长度,只返回长度大于0的字符串,并且,句子的第一个单词是大写的,如果目的是句子查找,那么这个特点会很有用,但是这里的文本只看出词袋,所以我们希望所有词的形式都是统一的:

print([tok.lower() for tok in listOfTokens if len(tok)>0])

现在拿一封完整的电子邮件观察实际处理结果:

需要注意的是,由于‘URL:answer.py?hl=en&answer=174623’的一部分,因而会出现en和py这样的单词,当对URL进行切分时,会得到很多词。我们是想去掉这些单词,因此在实现时会过滤掉长度小于3的字符串。在实际的解析程序中,要用更高级的过滤器来对诸如HTML和URL的对象进行处理。

测试算法:使用朴素贝叶斯进行交叉验证

下面将文本解析器集成到一个完整分类器中:

  1. def textParse(bigString):
  2. import re
  3. listOfTokens=re.split(r'\W',bigString)
  4. #小写、切分、长度大于等于3
  5. return [tok.lower() for tok in listOfTokens if len(tok)>2]
  6. def spamTest():
  7. docList=[]
  8. classList=[]
  9. fullText=[]
  10. for i in range(1,126):
  11. #打开文件
  12. wordList=textParse(open('email/spam/%d.txt' % i).read())
  13. #文档列表添加文本
  14. docList.append(wordList)
  15. #全文本列表增加文档列表
  16. fullText.extend(wordList)
  17. #列表增加1
  18. classList.append(1)
  19. wordList=textParse(open('email/ham/%d.txt' % i).read())
  20. docList.append(wordList)
  21. fullText.extend(wordList)
  22. classList.append(0)
  23. vocabList=createVocabList(docList)
  24. trainingSet=range(50)
  25. testSet=[]
  26. for i in range(10):
  27. #随机构建训练集
  28. #random.uniform:范围内随机生成实数
  29. randIndex=int(random.uniform(0,len(trainingSet)))
  30. #测试集中增加,并在训练集中删除
  31. testSet.append(trainingSet[randIndex])
  32. del(trainingSet[randIndex])
  33. trainMat=[]
  34. trainClasses=[]
  35. for docIndex in trainingSet:
  36. trainMat.append(setOfWords2Vec(vocabList,docList[docIndex]))
  37. trainClasses.append(classList[docIndex])
  38. p0V,p1V,pSpam=trainNBO(array(trainMat),array(trainClasses))
  39. errorCount=0
  40. for docIndex in testSet:
  41. wordVector=setOfWords2Vec(vocabList,docList[docIndex])
  42. #对测试集分类
  43. if classifyNB(array(wordVector),p0V,p1V,pSpam) != classList[docIndex]:
  44. errorCount=errorCount+1
  45. print('错误率:',float(errorCount)/len(testSet))

第一个函数textParse()接受一个大字符串并将其解析为字符串列表。该函数去掉少于两个字符的字符串,并将所有字符串转为小写。

第二个函数spamTest()对贝叶斯垃圾邮件分类器进行自动化处理。导入文件夹spam与ham文件夹下的文本文件,并将它们解析成词列表。之后构建一个测试集与训练集,两个集合中的邮件都是随机选出的。50封电子邮件中,随机选择10封为测试集。分类器所需要的概率计算只利用训练集中的文档来完成。Python变量trainingSet是一个整数列表,其中的值从0到49。测试集外的剩余部分作为测试集的过程称为留存交叉验证。假定现在只完成了一次迭代,那么为了更精确地估计分类器的错误率,就应该进行多次迭代后求出平均错误率。

接下来的for循环遍历训练集的所有文档,对每封邮件基于词汇表并构建词向量。这些词用于计算分类所需的概率。然后遍历测试集,对其中每封邮件进行分类。如果邮件分类错误,则错误数加一,最后给出总的错误百分比。

运行结果:

函数spamTest()会输出在10封随机选择的邮件上的分类错误率。

声明:本文内容由网友自发贡献,不代表【wpsshop博客】立场,版权归原作者所有,本站不承担相应法律责任。如您发现有侵权的内容,请联系我们。转载请注明出处:https://www.wpsshop.cn/w/一键难忘520/article/detail/924525?site
推荐阅读
相关标签
  

闽ICP备14008679号