使用朴素贝叶斯分类器从个人广告获取区域倾向
使用不同城市的广告训练一个分类器,目的就是使用该分类器进行分类,通过观察单词的条件概率值,来发现特定城市的相关内容。
1.收集数据
接下来需要使用python下载文件,Universal Feed Parser是python中最常用的RSS库。在python提示符下敲入>>>pip install feedparser即可导入该库。feedparser是一个Python的Feed解析库,可以处理RSS ,CDF,Atom 。使用它我们可从任何 RSS 或 Atom 订阅源得到标题、链接和文章的条目了。RSS(Really Simple Syndication,简易信息聚合)是一种描述和同步网站内容的格式你可以认为是一种定制个性化推送信息的服务。它能够解决你漫无目的的浏览网页的问题。它不会过时,信息越是过剩,它的意义也越加彰显。网络中充斥着大量的信息垃圾,每天摄入了太多自己根本不关心的信息。让自己关注的信息主动来找自己,且这些信息都是用户自己所需要的,这就是RSS的意义。feedparser 最为核心的函数自然是 parse() 解析 URL 地址的函数。我们知道,每个RSS和Atom订阅源都包含一个标题(d.feed.title)和一组文章条目(d.entries)通常每个文章条目都有一段摘要(d.entries[i].summary),或者是包含了条目中实际文本的描述性标签(d.entries[i].description)d.entries属性,该属性为列表,表示一组文章条目。
具体数据的提取参照下列源码:
def calcMostFreq(vocabList,fullText):
import operator
freqDict = {}
for token in vocabList:
freqDict[token] = fullText.count(token)
#根据单词出现的次数降序排列
sortedFreq = sorted(freqDict.iteritems(),key=operator.itemgetter(1),reverse=True)
return sortedFreq[:30]
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)
#数据集中去除前30个出现频率较高的单词
for pairW in top30Words:
if pairW[0] in vocabList:
vocabList.remove(pairW[0])
trainingSet = list(i for i in range(2*minLen))
testSet = []
#随机20个数据用于测试
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,pSam = trainNB0(array(trainMat),array(trainClasses))
errorCount = 0
for docIndex in testSet:
wordVector = bagOfWords2VecMN(vocabList,docList[docIndex])
if classifyNB(array(wordVector),p0V,p1V,pSam) != classList[docIndex]:
errorCount += 1
print('the error rate is :',float(errorCount)/len(testSet))
return vocabList,p0V,p1V
feed1和feed0在此处代表两个不同地区的RSS源,调用该函数时,需要制定feedparser对象。如np = feedparser.parse('http://....rss')。calcMostFreq()用于返回前30个频率最高的单词。feed1['entries'][i]['summary']得到的是第i组entries文章条目中的summary属性值。同理也是随机获取20个样本添加到测试集中,前面介绍的比较详细,不再赘述。
2.分析数据:显示地域相关用词
设置了阈值,只有概率大于阈值的值才会被添加到对应的列表中,并且被展示。代码较简单,不多解释。
#最具表特征性的词汇显示函数
def getTopWords(nf,sf):
import operator
vocabList,p0V,p1V = localWords(nf,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")
#输出item元组的单词项
for item in sortedSF:
print(item[0])
sortedNY = sorted(topNY,key=lambda pair:pair[1],reserve=True)
print("NY**NY**NY**NY**NY")
for item in sortedNY:
print(item[0])