有了前一节朴素贝叶斯分类文本的基础,这一节将进行两个实例应用:过滤垃圾邮件和从个人广告中获取区域倾向。
实例一:过滤垃圾邮件
由于邮件信息以文本的形式存放,我们首先要做的就是从切分文本,使用正则表达式将其拆分成词组,然后除去其中的空字符,并且将句首字母都转换为小写,完成准备数据的工作,就可以进行分类了。
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源。