Python3:《机器学习实战》之朴素贝叶斯(3)过滤垃圾邮件
前言:
使用朴素贝叶斯解决一些现实生活的问题时,需要先从文本内容得到字符串列表,然后生成词向量。下面这个例子中,我们将了解朴素贝叶斯的一个最著名的应用:电子邮件垃圾过滤。
示例:使用朴素贝叶斯对电子邮件进行分类
- 收集数据:提供文本文件。
- 准备数据:将文本文件解析成词条向量。
- 分析数据:检查词条确保解析的正确性。
- 训练算法:使用我们之前建立的trainNB0()函数。
- 测试算法:使用calssifyNB(),并且构建一个新的测试函数来计算文档集的错误率。
- 使用算法:构建一个完整的程序对一组文档进行分类,将错分的文档输出。
准备数据:切分文本
先前的次向量都是我们预先给定的,这次将介绍如何从文本文档中构建自己的词列表。对于一个文本字符串,可以使用Python的string.split()方法将其切分。
string.split()的使用详解,请打开传送门:http://blog.csdn.net/u011475210/article/details/77925994
代码实现:
def textParse(bigString):
"""
Function: 切分文本
Args: bigString:输入字符串
Returns: [*]:切分后的字符串列表
"""
import re
listOfTokens = re.split(r'\W*', bigString)
return [tok.lower() for tok in listOfTokens if len(tok) > 2]
Python中有一些内嵌的方法,可以将字符串全部转换成小写(.lower())或者大写(.upper()),借助这些方法可以达到目的。程序的最后一行就是用的这种方法。同时,如果某些文件包含一些URL(http://docs.google.com/support/bin/answer.py?hl=en&answer=66343),例如ham下的6.txt,那么切分文本时就会出现很多单词,如py、hl,很显然这些都是没用的,所以我们在程序最后一行只输出长度大于2的词条,好机智哦!
测试算法:使用朴素贝叶斯进行交叉验证
下面我们将文本解析器集成到一个完整的分类器中。
代码实现:
def spamTest():
"""
Function: 贝叶斯垃圾邮件分类器
Args: 无
Returns: float(errorCount)/len(testSet):错误率
vocabList:词汇表
fullText:文档中全部单词
"""
docList = []; classList = []; fullText = []
for i in range(1, 26):
wordList = textParse(open('email/spam/%d.txt' % i).read())
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)
vocabList = createVocabList(docList)
trainingSet = list(range(50)); testSet = []
for i in range(10):
randIndex = int(random.uniform(0, len(trainingSet)))
testSet.append(trainingSet[randIndex])
del(trainingSet[randIndex])
trainMat = []; trainClasses = []
for docIndex in trainingSet:
trainMat.append(setOfWords2Vec(vocabList, docList[docIndex]))
trainClasses.append(classList[docIndex])
p0V, p1V, pSpam = trainNB0(array(trainMat), array(trainClasses))
errorCount = 0
for docIndex in testSet:
wordVector = setOfWords2Vec(vocabList, docList[docIndex])
if classifyNB(array(wordVector), p0V, p1V, pSpam) != classList[docIndex]:
errorCount += 1
print("classification error",docList[docIndex])
print('the erroe rate is: ', float(errorCount)/len(testSet))
- 1
- 2
- 3
- 4
- 5
- 6
- 7
- 8
- 9
- 10
- 11
- 12
- 13
- 14
- 15
- 16
- 17
- 18
- 19
- 20
- 21
- 22
- 23
- 24
- 25
- 26
- 27
- 28
- 29
- 30
- 31
- 32
- 33
- 34
- 35
- 36
- 37
- 38
- 39
- 40
- 41
- 42
- 43
- 44
- 45
- 46
- 47
- 48
- 49
- 50
- 51
- 52
- 53
- 54
- 55
- 56
- 57
- 58
- 59
- 60
- 61
- 62
- 63
- 64
- 65
- 66
- 67
- 68
- 69
输出结果:
>>> bayes.spamTest()
the erroe rate is: 0.0
>>> bayes.spamTest()
the erroe rate is: 0.0
>>> bayes.spamTest()
classification error ['home', 'based', 'business', 'opportunity', 'knocking', 'your', 'door', 'don抰', 'rude', 'and', 'let', 'this', 'chance', 'you', 'can', 'earn', 'great', 'income', 'and', 'find', 'your', 'financial', 'life', 'transformed', 'learn', 'more', 'here', 'your', 'success', 'work', 'from', 'home', 'finder', 'experts']
classification error ['scifinance', 'now', 'automatically', 'generates', 'gpu', 'enabled', 'pricing', 'risk', 'model', 'source', 'code', 'that', 'runs', '300x', 'faster', 'than', 'serial', 'code', 'using', 'new', 'nvidia', 'fermi', 'class', 'tesla', 'series', 'gpu', 'scifinance', 'derivatives', 'pricing', 'and', 'risk', 'model', 'development', 'tool', 'that', 'automatically', 'generates', 'and', 'gpu', 'enabled', 'source', 'code', 'from', 'concise', 'high', 'level', 'model', 'specifications', 'parallel', 'computing', 'cuda', 'programming', 'expertise', 'required', 'scifinance', 'automatic', 'gpu', 'enabled', 'monte', 'carlo', 'pricing', 'model', 'source', 'code', 'generation', 'capabilities', 'have', 'been', 'significantly', 'extended', 'the', 'latest', 'release', 'this', 'includes']
the erroe rate is: 0.2
函数spamTest()会输出在10封随机选择的电子邮件上的分类错误率。因为是随机的,所以每次输出结果可能有些差别。所以如果想要更好的估计错误率,就需要多次重复求平均值。
报错信息汇总
运行报错:
>>> reload(bayes)
<module 'bayes' from 'E:\\机器学习实战\\mycode\\Ch04\\bayes.py'>
>>> bayes.spamTest()
Traceback (most recent call last):
File "<stdin>", line 1, in <module>
File "E:\机器学习实战\mycode\Ch04\bayes.py", line 221, in spamTest
wordList = textParse(open('email/ham/%d.txt' % i).read())
UnicodeDecodeError: 'gbk' codec can't decode byte 0xae in position 199: illegal multibyte sequence
一看就是编码问题,所以在程序中加入了打印信息,想看看是哪个文档读取出了问题,最后发现数据集ham下第23个文本中有不能识别的字符(®),修改之后程序运转正常。如果从我的github上下载的数据集,那就大可放心,不会出现这种问题的。
报错文档:
SciFinance now automatically generates GPU-enabled pricing & risk model source code that runs up to 50-300x faster than serial code using a new NVIDIA Fermi-class Tesla 20-Series GPU.
SciFinance® is a derivatives pricing and risk model development tool that automatically generates C/C++ and GPU-enabled source code from concise, high-level model specifications. No parallel computing or CUDA programming expertise is required.
SciFinance's automatic, GPU-enabled Monte Carlo pricing model source code generation capabilities have been significantly extended in the latest release. This includes:
运行报错:
>>> reload(bayes)
<module 'bayes' from 'E:\\机器学习实战\\mycode\\Ch04\\bayes.py'>
>>> bayes.spamTest()
Traceback (most recent call last):
File "<stdin>", line 1, in <module>
File "E:\机器学习实战\mycode\Ch04\bayes.py", line 239, in spamTest
del(trainingSet[randIndex])
TypeError: 'range' object doesn't support item deletion
range()函数报错,这里主要涉及到python版本问题,详情请打开传送门:http://blog.csdn.net/u011475210/article/details/77925697
系列教程持续发布中,欢迎订阅、关注、收藏、评论、点赞哦~~( ̄▽ ̄~)~
完的汪(∪。∪)。。。zzz