背景:广告商往往想知道关于一个人的一些特定人口统计信息,以便能更好地定向推销广告。
我们将分别从美国的两个城市中选取一些人,通过分析这些人发布的信息,来比较这两个城市的人们在广告用词上是否不同。如果结论确实不同,那么他们各自常用的词是那些,从人们的用词当中,我们能否对不同城市的人所关心的内容有所了解。
1、收集数据:导入RSS源
使用python下载文本,在http://code.google.com/p/feedparser/下浏览相关文档,安装feedparse,首先解压下载的包,并将当前目录切换到解压文件所在的文件夹,然后在python提示符下输入:
# python setup.py install
创建一个bayes.py文件,添加以下代码:
#创建一个包含在所有文档中出现的不重复词的列表 def createVocabList(dataSet): vocabSet=set([]) #创建一个空集 for document in dataSet: vocabSet=vocabSet|set(document) #创建两个集合的并集 return list(vocabSet) def setOfWords2VecMN(vocabList,inputSet): returnVec=[0]*len(vocabList) #创建一个其中所含元素都为0的向量 for word in inputSet: if word in vocabList: returnVec[vocabList.index(word)]+=1 return returnVec #朴素贝叶斯分类器训练函数 def trainNBO(trainMatrix,trainCategory): numTrainDocs=len(trainMatrix) numWords=len(trainMatrix[0]) pAbusive=sum(trainCategory)/float(numTrainDocs) p0Num=ones(numWords);p1Num=ones(numWords) #计算p(w0|1)p(w1|1),避免其中一个概率值为0,最后的乘积为0 p0Demo=2.0;p1Demo=2.0 #初始化概率 for i in range(numTrainDocs): if trainCategory[i]==1: p1Num+=trainMatrix[i] p1Demo+=sum(trainMatrix[i]) else: p0Num+=trainMatrix[i] p0Demo+=sum(trainMatrix[i]) #p1Vect=p1Num/p1Demo #p0Vect=p0Num/p0Demo p1Vect=log(p1Num/p1Demo) #计算p(w0|1)p(w1|1)时,大部分因子都非常小,程序会下溢出或得不到正确答案(相乘许多很小数,最后四舍五入会得到0) p0Vect=log(p0Num/p0Demo) return p0Vect,p1Vect,pAbusive #朴素贝叶斯分类函数 def classifyNB(vec2Classify,p0Vec,p1Vec,pClass1): p1=sum(vec2Classify*p1Vec)+log(pClass1) p0=sum(vec2Classify*p0Vec)+log(1.0-pClass1) if p1>p0: return 1 else: return 0 #文件解析及测试函数 def textParse(bigString): import re listOfTokens=re.split(r‘\W*‘,bigString) return [tok.lower() for tok in listOfTokens if len(tok)>2]
添加以下代码:
#RSS源分类器及高频词去除函数 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) for pairW in top30Words: if pairW[0] in vocabList:vocabList.remove(pairW[0]) trainingSet=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=trainNBO(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
函数localWords()使用了两个RSS源作为参数,RSS源要在函数外导入,这样做的原因是RSS源会随时间而改变,重新加载RSS源就会得到新的数据.
>>> reload(bayes) <module ‘bayes‘ from ‘bayes.pyc‘> >>> import feedparser >>> ny=feedparser.parse(‘http://newyork.craigslist.org/stp/index.rss‘) >>> sy=feedparser.parse(‘http://sfbay.craigslist.org/stp/index.rss‘) >>> vocabList,pSF,pNY=bayes.localWords(ny,sf) the error rate is: 0.2 >>> vocabList,pSF,pNY=bayes.localWords(ny,sf) the error rate is: 0.3 >>> vocabList,pSF,pNY=bayes.localWords(ny,sf) the error rate is: 0.55
为了得到错误率的精确估计,应该多次进行上述实验,然后取平均值
2、分析数据:显示地域相关的用词
可以先对向量pSF与pNY进行排序,然后按照顺序打印出来,将下面的代码添加到文件中:
#最具表征性的词汇显示函数 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**" 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**" for item in sortedNY: print item[0]
函数getTopWords()使用两个RSS源作为输入,然后训练并测试朴素贝叶斯分类器,返回使用的概率值。然后创建两个列表用于元组的存储,与之前返回排名最高的X个单词不同,这里可以返回大于某个阈值的所有词,这些元组会按照它们的条件概率进行排序。
保存bayes.py文件,在python提示符下输入:
时间: 2024-10-11 04:12:58