背景:广告商往往想知道关于一个人的一些特定人口统计信息,以便能更好地定向推销广告。

我们将分别从美国的两个城市中选取一些人,通过分析这些人发布的信息,来比较这两个城市的人们在广告用词上是否不同。如果结论确实不同,那么他们各自常用的词是那些,从人们的用词当中,我们能否对不同城市的人所关心的内容有所了解。

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] #返回出现次数最高的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']) #每次访问一条RSS源
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提示符下输入:

>>> reload(bayes)
<module 'bayes' from 'bayes.pyc'>
>>> bayes.getTopWords(ny,sf)
the error rate is: 0.55
SF**SF**SF**SF**SF**SF**SF**SF**SF**SF**SF**SF**SF**SF**
how
last
man
...
veteran
still
ends
late
off
own
know
NY**NY**NY**NY**NY**NY**NY**NY**NY**NY**NY**NY**NY**NY**
someone
meet
...
apparel
recalled
starting
strings

当注释掉用于移除高频词的三行代码,然后比较注释前后的分类性能,去掉这几行代码之后,错误率为54%,,而保留这些代码得到的错误率为70%。这里观察到,这些留言中出现次数最多的前30个词涵盖了所有用词的30%,vocabList的大小约为3000个词,也就是说,词汇表中的一小部分单词却占据了所有文本用词的一大部分。产生这种现象的原因是因为语言中大部分都是冗余和结构辅助性内容。另一个常用的方法是不仅移除高频词,同时从某个预定高频词中移除结构上的辅助词,该词表称为停用词表。

最后输出的单词,可以看出程序输出了大量的停用词,可以移除固定的停用词看看结果如何,这样做的花,分类错误率也会降低。

【Machine Learning in Action --4】朴素贝叶斯从个人广告中获取区域倾向的更多相关文章

  1. Machine Learning in Action(3) 朴素贝叶斯算法

    贝叶斯决策一直很有争议,今年是贝叶斯250周年,历经沉浮,今天它的应用又开始逐渐活跃,有兴趣的可以看看斯坦福Brad Efron大师对其的反思,两篇文章:“Bayes'Theorem in the 2 ...

  2. 《Machine Learning in Action》—— 白话贝叶斯,“恰瓜群众”应该恰好瓜还是恰坏瓜

    <Machine Learning in Action>-- 白话贝叶斯,"恰瓜群众"应该恰好瓜还是恰坏瓜 概率论,可以说是在机器学习当中扮演了一个非常重要的角色了.T ...

  3. machine learning for hacker记录(3) 贝叶斯分类器

    本章主要介绍了分类算法里面的一种最基本的分类器:朴素贝叶斯算法(NB),算法性能正如英文缩写的一样,很NB,尤其在垃圾邮件检测领域,关于贝叶斯的网上资料也很多,这里推荐那篇刘未鹏写的http://mi ...

  4. 机器学习实战 [Machine learning in action]

    内容简介 机器学习是人工智能研究领域中一个极其重要的研究方向,在现今的大数据时代背景下,捕获数据并从中萃取有价值的信息或模式,成为各行业求生存.谋发展的决定性手段,这使得这一过去为分析师和数学家所专属 ...

  5. 【机器学习实战】第4章 朴素贝叶斯(Naive Bayes)

    第4章 基于概率论的分类方法:朴素贝叶斯 朴素贝叶斯 概述 贝叶斯分类是一类分类算法的总称,这类算法均以贝叶斯定理为基础,故统称为贝叶斯分类.本章首先介绍贝叶斯分类算法的基础——贝叶斯定理.最后,我们 ...

  6. 《Machine Learning in Action》—— 浅谈线性回归的那些事

    <Machine Learning in Action>-- 浅谈线性回归的那些事 手撕机器学习算法系列文章已经肝了不少,自我感觉质量都挺不错的.目前已经更新了支持向量机SVM.决策树.K ...

  7. 《Machine Learning in Action》—— Taoye给你讲讲Logistic回归是咋回事

    在手撕机器学习系列文章的上一篇,我们详细讲解了线性回归的问题,并且最后通过梯度下降算法拟合了一条直线,从而使得这条直线尽可能的切合数据样本集,已到达模型损失值最小的目的. 在本篇文章中,我们主要是手撕 ...

  8. 一步步教你轻松学朴素贝叶斯模型算法Sklearn深度篇3

    一步步教你轻松学朴素贝叶斯深度篇3(白宁超   2018年9月4日14:18:14) 导读:朴素贝叶斯模型是机器学习常用的模型算法之一,其在文本分类方面简单易行,且取得不错的分类效果.所以很受欢迎,对 ...

  9. 【机器学习实战笔记(3-2)】朴素贝叶斯法及应用的python实现

    文章目录 1.朴素贝叶斯法的Python实现 1.1 准备数据:从文本中构建词向量 1.2 训练算法:从词向量计算概率 1.3 测试算法:根据现实情况修改分类器 1.4 准备数据:文档词袋模型 2.示 ...

随机推荐

  1. RSA算法记录----摘抄

    RSA算法原理(一)   "公钥加密算法". 因为它是计算机通信安全的基石,保证了加密数据不会被破解.你可以想象一下,信用卡交易被破解的后果. 进入正题之前,我先简单介绍一下,什么 ...

  2. 开发中常用的 $.extend 总结

    工作中常见$.extend( ),所以就查了一些它的用法. 一.Jquery的扩展方法原型是: extend(dest, src1, src2, src3...) 它的含义是将src1,src2,sr ...

  3. document对象相关的几个常用的方法

    方法  描述 var newP=createElement("p"); 创建了一个p标签,p也可替换为div,span等 var oldTxt=createTextNode(&qu ...

  4. 圆形图片CustomShapeImageView

    第三方控件 [GitHub的源码下载] (https://github.com/MostafaGazar/CustomShapeImageView) 1:依赖包 dependencies { ... ...

  5. Eclipse Bug: Unhandled event loop exception No more handles

    我的解决方法如下: I had the same problem, turned out that TeamViewer was causing this. In your TeamViewer go ...

  6. Android实现动画循环的方式

    每次想到循环播放.重复执行时,脑海中总是冒出在while(true)的实现方式. Thread thread = new Thread(new Runnable(){ public void run( ...

  7. power oj 2480 放积木[二进制状压DP]

    题目链接[https://www.oj.swust.edu.cn/problem/show/2480] 题意:中文题目. 题解:二进制状态转移+坏点判断. #include<cstdio> ...

  8. linux下安装nginx+php

    参考:http://blog.csdn.net/ihelloworld/article/details/7029796 http://blog.chinaunix.net/uid-21374062-i ...

  9. jqGrid使用整理

    jqGrid使用整理 jqGrid是一款处理表格展现的jQuery插件,支持分页.滚动加载.搜索.锁定.拖动等一系列对表格的常规操作.以下是最近项目中实践jqGrid的整理 1.引入到项目中来 jqG ...

  10. java 方法学习

    手写随机代码 public class suiji{private static final int N = 200;private static final int LEFT = 40;privat ...