使用朴素贝叶斯过滤垃圾邮件

使用朴素贝叶斯解决一些现实生活中的问题时,需要先从文本内容得到字符串列表,然后生成词向量。下面这个例子中,将了解朴素贝叶斯的一个著名的应用:电子邮件垃圾过滤。

(1)收集数据:提供文本文件
(2)准备数据:将文本文件解析成词条向量
(3)分析数据:检查词条确保解析的正确性
(4)训练算法:使用我们之前建立的trainNB()函数
(5)测试数据:使用classifyNB(),并且构建一个新的测试函数来计算文档集的错误率。
(6)使用算法:构建一个完整的程序对一组文档进行分类,将错误的文档输出到屏幕上。

一、准备数据:切分文本
如何从文本文档中构建自己的词列表?
1、对于一个文本字符串,可以使用python的string.split()方法将其划分。


>>> 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', 'upon.']

结果: 标点符号也被当成了词的一部分。

2、可以使用正则表达式来切分句子,其中分隔符是除单词、数字外的任意字符串。


>>> 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', '']

现在得到了一系列词组成的词表,但是里面的空字符串需要去掉。

3、可以计算每个字符串的长度,只返回长度大于0的字符串。

>>> [tok 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']

4、这里的文本看成词袋时,希望所有的词的形式是统一的,不论它们出现在句子中间、结尾还是开头。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):
    import re
    listOfTokens=re.split(r'\W*', bigString)
    return [tok.lower() for tok in listOfTokens if len(tok) >2]


# 导入spam与ham下的文本文件,并将它们解析为词列表。
def spamTest():
    docList=[]
    classList=[]
    fullText=[]
    for i in range(1, 26):
        wordList=textParse(open('/Users/lb1/Desktop/小学伴-机器学习/机器学习实战源代码/machinelearninginaction/Ch04/email/spam/%d.txt' % i).read())
        docList.append(wordList)
        fullText.extend(wordList)
        classList.append(1)
        wordList=textParse(open('/Users/lb1/Desktop/小学伴-机器学习/机器学习实战源代码/machinelearninginaction/Ch04/email/ham/%d.txt' % i).read())
        docList.append(wordList) #数据集
        fullText.extend(wordList)
        classList.append(1)
    vocabList=createVocabList(docList) #得到词列表

    trainingSet=range(50)
    testSet=[]
    for i in range(10):
        randIndex=int(random.uniform(0, len(trainingSet))) #方法将随机生成下一个实数,它在 [x, y) 范围内。
        testSet.append(trainingSet[randIndex])
        del(trainingSet[randIndex])

    trainMat=[]
    trainClasses=[]
    for docIndex in trainingSet:
        trainMat.append(setOfWords2Vec(vocabList, docList[docIndex]))
        trainClasses.qppend(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)

你可能感兴趣的:(监督学习)