使用朴素贝叶斯对电子邮件进行分类
- 收集数据:提供文本文件。
- 准备数据:将文本文件解析成词条向量。
- 分析数据:检查词条确保解析的正确性。
- 训练算法:使用我们之前建立的trainNB0()函数。
- 测试算法:使用
classifyNB
,并且构建一个新的测试函数来计算文档集的错误率。 - 使用算法:构建一个完整的程序对一组文档进行分类,将错分的文档输出到屏幕上。
一、准备数据:切分文本
如何从文本文档中构建自己的词列表?
对于一个文本字符串,可以使用正则表示式来切分句子,其中分隔符是除单词、数字外的任意字符串:
>>> import re
>>> regEx = re.compile('\\W*')
>>> listOfTokens = regEx.split(mySent)
>>> listOfTokens
['This', 'book', 'is', 'the', 'best', 'book', 'on', 'Python', 'or', 'M',
'L', '', 'I', 'have', 'ever', 'laid', 'eyes', 'upon', '']
现在得到了一系列词组成的词表,但是里面的空字符串需要去掉。可以计算每个字符串的长度,只返回长度大于0的字符串:
>>> [tok for tok in listOfTokens if len(tok) > 0]
最后,我们发现句子中的第一个单词是大写的。如果目的是句子查找,那么这个特点会很有用。
但这里的文本只看成词袋,所以我们希望所有词的形式都是统一的,不论它们出现在句子中间、结尾还是开头。
Python中有一些内嵌的方法,可以将字符串全部转换成小写 (.lower())
或者大写 (.upper())
,借助这些方法可以达到目的。于是,可以进行如下处理:
>>> [tok.lower() for tok in listOfTokens if len(tok) > 0]
['this', 'book', 'is', 'the', 'best', 'book', 'on', 'python', 'or', 'm',
'l', 'i', 'have', 'ever', 'laid', 'eyes', 'upon']
二、测试算法:使用朴素贝叶斯进行交叉验证
def textParse(bigString): # 将字符串转换为字符列表
# 使用\W 或者\W+ 都可以将字符数字串分割开,产生的空字符将会在后面的列表推导式中过滤掉
listOfTokens = re.split(r'\W+', bigString) # 将特殊符号作为切分标志进行字符串切分,即非字母、非数字
return [tok.lower() for tok in listOfTokens if len(tok) > 2] # 除了单个字母,例如大写的I,其它单词变成小写
def spamTest():
docList = []; classList = []; fullText = []