安居多伦多
  • 多市生活
    • 多市生活
    • 加国税务
    • 旅游度假
    • 生活安全
    • 行车安全
    • 窍门集锦
  • 多市书苑
    • 热门
    • 小说
    • 教育
  • 家居信息
    • 家居信息
    • 房屋保养
    • 房屋贷款
    • 房屋租赁
    • 房屋建筑
    • 房前屋后
    • 家居风水
  • 健康保健
    • 健康保健
    • 饮食起居
    • 食品安全
    • 健身锻炼
  • 书苑账户
    • 书苑登入
    • 书苑注册
    • 忘记书苑密码
    • 书苑账户信息
    • 关于我们
    • 联系我们
    • 隐私政策
多伦多书苑
在线书籍:随时阅读,随身听书。
所有书籍 | 人文 | 人物 | 人生 | 健康 | 儿童 | 医学 | 历史 | 历史 | 古典 | 哲学宗教 | 商业 | 外国 | 寓言 | 小说 | 教育 | 风水 | 管理 | 语言 |
为使本公益资源网站能继续提供免费阅读,请勿屏蔽广告。谢谢!报告弹出广告被滥用。
  1. 安居多伦多
  2. 网上书苑
  3. IT
  4. AI
  5. 机器学习实战

机器学习实战

2022-03-09 0人点赞 0条评论
点赞
x
语速1.0: 2.0
进度0:

上一页   |   返回目录   |   下一页

4.6 示例:使用朴素贝叶斯过滤垃圾邮件

在前面那个简单的例子中,我们引入了字符串列表。使用朴素贝叶斯解决一些现实生活中的问题时,需要先从文本内容得到字符串列表,然后生成词向量。下面这个例子中,我们将了解朴素贝叶斯的一个最著名的应用:电子邮件垃圾过滤。首先看一下如何使用通用框架来解决该问题。

示例:使用朴素贝叶斯对电子邮件进行分类

1. 收集数据:提供文本文件。

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

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

4. 训练算法:使用我们之前建立的trainNB0()函数。

5. 测试算法:使用classifyNB(),并且构建一个新的测试函数来计算文档集的错误率。

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

下面首先给出将文本解析为词条的代码。然后将该代码和前面的分类代码集成为一个函数,该函数在测试分类器的同时会给出错误率。

4.6.1 准备数据:切分文本

前一节介绍了如何创建词向量,并基于这些词向量进行朴素贝叶斯分类的过程。前一节中的词向量是预先给定的,下面介绍如何从文本文档中构建自己的词列表。

对于一个文本字符串,可以使用Python的string.split()方法将其切分。下面看看实际的运行效果。在Python提示符下输入:

>>> mySent='This book is the best book on Python or M.L. I have ever laid eyes upon.'
>>> mySent.split()
['This', 'book', 'is', 'the', 'best', 'book', 'on', 'Python', 'or', 'M.L.','I', 'have', 'ever', 'laid', 'eyes', 'upo

可以看到,切分的结果不错,但是标点符号也被当成了词的一部分。可以使用正则表示式来切分句子,其中分隔符是除单词、数字外的任意字符串。

>>> 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

现在得到了一系列词组成的词表,但是里面的空字符串需要去掉。可以计算每个字符串的长度,只返回长度大于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', 'l

现在来看数据集中一封完整的电子邮件的实际处理结果。该数据集放在email文件夹中,该文件夹又包含两个子文件夹,分别是spam与ham。

>>> emailText = open('email/ham/6.txt').read()
>>> listOfTokens=regEx.split(emailText)

文件夹ham下的6.txt文件非常长,这是某公司告知我他们不再进行某些支持的一封邮件。需要注意的是,由于是URL:answer.py?hl=en&answer=174623的一部分,因而会出现en和py这样的单词。当对URL进行切分时,会得到很多的词。我们是想去掉这些单词,因此在实现时会过滤掉长度小于3的字符串。本例使用一个通用的文本解析规则来实现这一点。在实际的解析程序中,要用更高级的过滤器来对诸如HTML和URI的对象进行处理。目前,一个URI最终会解析成词汇表中的单词,比如www.whitehouse.gov会被解析为三个单词。文本解析可能是一个相当复杂的过程。接下来将构建一个极其简单的函数,你可以根据情况自行修改。

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

下面将文本解析器集成到一个完整分类器中。打开文本编辑器,将下面程序清单中的代码添加到bayes.py文件中。

程序清单4-5 文件解析及完整的垃圾邮件测试函数

def textParse(bigString):
import re
listOfTokens = re.split(r'\W*', bigString)
return [tok.lower() for tok in listOfTokens if len(tok) > 2]
def spamTest():
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 = 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 'the error rate is: ',float(errorCount)/len(testSet)

第一个函数textParse()接受一个大字符串并将其解析为字符串列表。该函数去掉少于两个字符的字符串,并将所有字符串转换为小写。你可以在函数中添加更多的解析操作,但是目前的实现对于我们的应用足够了。

第二个函数spamTest()对贝叶斯垃圾邮件分类器进行自动化处理。导入文件夹spam与ham下的文本文件,并将它们解析为词列表❶。接下来构建一个测试集与一个训练集,两个集合中的邮件都是随机选出的。本例中共有50封电子邮件,并不是很多,其中的10封电子邮件被随机选择为测试集。分类器所需要的概率计算只利用训练集中的文档来完成。Python变量trainingSet是一个整数列表,其中的值从0到49。

接下来,随机选择其中10个文件❷。选择出的数字所对应的文档被添加到测试集,同时也将其从训练集中剔除。这种随机选择数据的一部分作为训练集,而剩余部分作为测试集的过程称为留存交叉验证(hold-out cross validation)。假定现在只完成了一次迭代,那么为了更精确地估计分类器的错误率,就应该进行多次迭代后求出平均错误率。

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

下面对上述过程进行尝试。输入程序清单4-5的代码之后,在Python提示符下输入:

>>> bayes.spamTest()
the error rate is: 0.0
>>> bayes.spamTest()
classification error ['home', 'based', 'business', 'opportunity', 'knocking', 'your', 'door', 'don',
the error rate is: 0.1

函数spamTest()会输出在10封随机选择的电子邮件上的分类错误率。既然这些电子邮件是随机选择的,所以每次的输出结果可能有些差别。如果发现错误的话,函数会输出错分文档的词表,这样就可以了解到底是哪篇文档发生了错误。如果想要更好地估计错误率,那么就应该将上述过程重复多次,比如说10次,然后求平均值。我这么做了一下,获得的平均错误率为6%。

这里一直出现的错误是将垃圾邮件误判为正常邮件。相比之下,将垃圾邮件误判为正常邮件要比将正常邮件归到垃圾邮件好。为避免错误,有多种方式可以用来修正分类器,这些将在第7章中进行讨论。

目前我们已经使用朴素贝叶斯来对文档进行分类,接下来将介绍它的另一个应用。下一个例子还会给出如何解释朴素贝叶斯分类器训练所得到的知识。

上一页   |   返回目录   |   下一页

类似书籍

Python机器学习手册:从数据预处理到深度学习
Python机器学习手册:从数据预处理到深度学习
Python机器学习实践指南
Python机器学习实践指南
Python机器学习——预测分析核心算法
Python机器学习——预测分析核心算法
Author:

标签: 暂无
最后更新:2022-03-09
< 上一篇

本书评论

取消回复

©2021 安居多伦多 - 版权所有

本站由 好事来 Hostlike.com 提供技术支持。