《机器学习实战》学习笔记六:朴素贝叶斯的应用

有了前一节朴素贝叶斯分类文本的基础,这一节将进行两个实例应用:过滤垃圾邮件和从个人广告中获取区域倾向。

实例一:过滤垃圾邮件

由于邮件信息以文本的形式存放,我们首先要做的就是从切分文本,使用正则表达式将其拆分成词组,然后除去其中的空字符,并且将句首字母都转换为小写,完成准备数据的工作,就可以进行分类了。

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('F:\sourcecode\Ch04\email\spam\%d.txt' %i,encoding='gbk', errors='ignore').read())
        docList.append(wordList)
        fullText.extend(wordList)
        classList.append(1)
        wordList = textParse(open('F:\sourcecode\Ch04\email\ham\%d.txt' %i,encoding='gbk', errors='ignore').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("the error ratr is : ",float(errorCount/len(testSet)))

第二个函数中,导入了两个文件夹中的文本,并且将其解析为词列表,然后构建了一个训练集并且从其中随机选择十个文件作为测试集,有了训练集和测试集就可以构建分类器了,然后进行分类并且计算错误率。

实例二:从个人广告中获取区域倾向

之前的例子都是使用给定的数据来进行分类,而在这例子中,将使用网上的资源,这里用到一个技术叫RSS,查了一下百度,RSS(Really Simple Syndication,简易信息聚合),是一种描述和同步网站内容的格式,是目前使用最广泛的XML应用,RSS使网站之间信息共享,用户通过RSS源也能获取需要的数据,如电子书等。提供RSS服务的站点就叫做RSS源。
点这里查看一些常用的RSS源
在python中使用RSS需要用到RSS库,需要安装一个名叫feedparser的包,教程如下
点这里查看feedparser安装教程
有了以上准备,就可以进行编码了

def localWords(feed1,feed0):
    import feedparser
    docList=[]; classList = []; fullText =[]
    minLen = min(len(feed1['entries']),len(feed0['entries']))
    for i in range(minLen):
        wordList = textParse(feed1['entries'][i]['summary'])
        docList.append(wordList)
        fullText.extend(wordList)
        classList.append(1)
        wordList = textParse(feed0['entries'][i]['summary'])
        docList.append(wordList)
        fullText.extend(wordList)
        classList.append(0)
    vocabList = createVocabList(docList)#创建词汇表
    top30Words = calcMostFreq(vocabList,fullText)   #前三十个单词
    for pairW in top30Words:
        if pairW[0] in vocabList: vocabList.remove(pairW[0])#除去高频单词
    trainingSet = list(range(2*minLen)); testSet=[]           #创建测试集
    for i in range(20):
        randIndex = int(random.uniform(0,len(trainingSet)))
        testSet.append(trainingSet[randIndex])
        del(trainingSet[randIndex])
    trainMat=[]; trainClasses = []
    for docIndex in trainingSet:#训练分类器
        trainMat.append(bagOfWords2VecMN(vocabList, docList[docIndex]))
        trainClasses.append(classList[docIndex])
    p0V,p1V,pSpam = trainNB0(array(trainMat),array(trainClasses))
    errorCount = 0
    for docIndex in testSet:        #进行分类
        wordVector = bagOfWords2VecMN(vocabList, docList[docIndex])
        if classifyNB(array(wordVector),p0V,p1V,pSpam) != classList[docIndex]:
            errorCount += 1
    print ('the error rate is: ',float(errorCount)/len(testSet))
    return vocabList,p0V,p1V

ny = feedparser.parse('http://newyork.craigslist.org/stp/index.rss')
sf = feedparser.parse('http://sfbay.craigslist.org/stp/index.rss')

第一个函数中calcMostFreq()中,遍历了单词表中的词,并统计出现的次数,然后按次数降序对词典排序,返回次数最高的30个单词。
第二个函数中使用了两个RSS源做参数。RSS源要从函数外导入,调用calcMostFreq()来获取出现频率最高的30个词,并将其移除,剩下的代码就和spamTest()差不多了。

显示地域相关的用词:
def getTopWords(ny,sf):
    import operator
    vocabList,p0V,p1V=localWords(ny,sf)
    topNY=[]; topSF=[]
    for i in range(len(p0V)):
        if p0V[i] > -6.0 : topSF.append((vocabList[i],p0V[i]))
        if p1V[i] > -6.0 : topNY.append((vocabList[i],p1V[i]))
    sortedSF = sorted(topSF, key=lambda pair: pair[1], reverse=True)
    print ("SF**SF**SF**SF**SF**SF**SF**SF**SF**SF**SF**SF**SF**SF**SF**SF**")
    for item in sortedSF:
        print (item[0])
    sortedNY = sorted(topNY, key=lambda pair: pair[1], reverse=True)
    print ("NY**NY**NY**NY**NY**NY**NY**NY**NY**NY**NY**NY**NY**NY**NY**NY**")
    for item in sortedNY:
        print (item[0])

getTopWords(ny,sf)

这个函数使用两个RSS源作为输入,然后训练并测试朴素贝叶斯分类器,返回使用的概率值。然后创建两个列表用于元祖的存储,这个可以返回大于某个阈值的所有词,并按照概率进行排序。
由于墙的存在,获取不到国外网站的信息,并没有的到相应的输出结果,等时间充足,我在学一下如何处理中文的RSS源。

源码及测试集下载

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值