Machine Learning in Action(3) 朴素贝叶斯算法
贝叶斯决策一直很有争议,今年是贝叶斯250周年,历经沉浮,今天它的应用又开始逐渐活跃,有兴趣的可以看看斯坦福Brad Efron大师对其的反思,两篇文章:“Bayes'Theorem in the 21st Century”和“A250-YEAR ARGUMENT:BELIEF, BEHAVIOR, AND THE BOOTSTRAP”。俺就不参合这事了,下面来看看朴素贝叶斯分类器。
有时我们想知道给定一个样本时,它属于每个类别的概率是多少,即P(Ci|X),Ci表示类别,X表示测试样本,有了概率后我们可以选择最大的概率的类别。要求这个概率要用经典贝叶斯公式,如(公式一)所示:
(公式一)
(公式一)中的右边每项一般都是可以计算出的,例如(图一)中两个桶中分别装了黑色(Black)和灰色(Grey)的球。
(图一)
假设Bucket A和BucketB是类别,C1和C2,当给定一个球时,我们想判断它最可能从哪个桶里出来的,换句话说是什么类别?这就可以根据(公式一)来算,(公式一)的右边部分的每项都可以计算出来,比如P(gray|bucketA)=2/4,P(gray|bucketB)=1/3,更严格的计算方法是:
P(gray|bucketB) = P(gray andbucketB)/P(bucketB),
而P(gray and bucketB) = 1/7,P(bucketB)= 3/7
那么P(gray|bucketB)=P(gray and bucketB)/ P(bucketB)=(1/7)/(3/7)=1/3
这就是朴素贝叶斯的原理,根据后验概率来判断,选择P(Ci|X)最大的作为X的类别Ci,另外朴素贝叶斯只所以被称为朴素的原因是,它假设了特征之间都是独立的,如(图二)所示:
(图二)
尽管这个假设很不严密,但是在实际应用中它仍然很有效果,比如文本分类,下面就来看下文本分类实战,判断聊天信息是否是辱骂(abusive)信息(也就是类别为两类,是否辱骂信息),在此之前,先强调下,朴素贝叶斯的特征向量可以是多维的,上面的公式是一维的,二维的如(公式二)所示,都是相同的计算方法:
(公式二)
对文本分类,首先的任务就是把文本转成数字向量,也就是提取特征。特征可以说某个关键字在文章中出现的次数(bag of words),比如垃圾邮件中经常出现“公司”,“酬宾”等字样,特征多样,可以根据所需自己建立特征。本例子中采用标记字(token)的方法,标记字可以是任何字符的组合,比如URL,单词,IP地址等,当然判断是否是辱骂信息大多数都是类似于单词的形式。下面来根据代码说下:
首先我们获取一些训练集:
from numpy import * def loadDataSet():
postingList=[['my', 'dog', 'has', 'flea', 'problems', 'help', 'please'],
['maybe', 'not', 'take', 'him', 'to', 'dog', 'park', 'stupid'],
['my', 'dalmation', 'is', 'so', 'cute', 'I', 'love', 'him'],
['stop', 'posting', 'stupid', 'worthless', 'garbage'],
['mr', 'licks', 'ate', 'my', 'steak', 'how', 'to', 'stop', 'him'],
['quit', 'buying', 'worthless', 'dog', 'food', 'stupid']]
classVec = [0,1,0,1,0,1] #1 is abusive, 0 not
return postingList,classVec
训练集是从聊天室里摘取的6句话,每句话都有一个标签0或者1,表示是否是辱骂信息(abusive or not abusive)。当然可以把每个消息看成是一个文档,只不过文档单词比这个多,但是一样的道理。接下来处理训练集,看看训练集有多少个不同的(唯一的)单词组成。代码如下:
def createVocabList(dataSet):
vocabSet = set([]) #create empty set
for document in dataSet:
vocabSet = vocabSet | set(document) #union of the two sets
return list(vocabSet)
该函数返回一个由唯一单词组成的词汇表。接下来就是特征处理的关键步骤,同样先贴代码:
def setOfWords2Vec(vocabList, inputSet):
returnVec = [0]*len(vocabList)
for word in inputSet:
if word in vocabList:
returnVec[vocabList.index(word)] = 1
else: print "the word: %s is not in my Vocabulary!" % word
return returnVec
这个函数功能:输入词汇表和消息,通过逐个索引词汇表,然后看消息中的是否有对应的字在词汇表中,如果有就标记1,没有就标记0,这样就把每条消息都转成了和词汇表一样长度的有0和1组成的特征向量,如(图三)所示:
(图三)
有了特征向量,我们就可以训练朴素贝叶斯分类器了,其实就是计算(公式三)右边部分的三个概率,(公式三)如下:
(公式三)
其中w是特征向量。
代码如下:
def trainNB0(trainMatrix,trainCategory):
numTrainDocs = len(trainMatrix)
numWords = len(trainMatrix[0])
pAbusive = sum(trainCategory)/float(numTrainDocs)
p0Num = ones(numWords); p1Num = ones(numWords) #change to ones()
p0Denom = 2.0; p1Denom = 2.0 #change to 2.0
for i in range(numTrainDocs):
if trainCategory[i] == 1:
p1Num += trainMatrix[i]
p1Denom += sum(trainMatrix[i])
else:
p0Num += trainMatrix[i]
p0Denom += sum(trainMatrix[i])
p1Vect = log(p1Num/p1Denom) #change to log()
p0Vect = log(p0Num/p0Denom) #change to log()
return p0Vect,p1Vect,pAbusive
上面的代码中输入的是特征向量组成的矩阵,和一个由标签组成的向量,其中pAbusive是类别概率P(ci),因为只有两类,计算一类后,另外一类可以直接用1-p得出。接下来初始化计算p(wi|c1)和p(wi|c0)的分子和分母,这里惟一让人好奇的就是为什么分母p0Denom和p1Denom都初始化为2?这是因为在实际应用中,我们计算出了(公式三)右半部分的概率后,也就是p(wi|ci)后,注意wi表示消息中的一个字,接下来就是判断整条消息属于某个类别的概率,就要计算p(w0|1)p(w1|1)p(w2|1)的形式,这样如果某个wi为0,这样整个概率都为0,或者都很小连乘后会更小,甚至round off 0。这样就会影响判断,因此把他们转到对数空间中来做运算,对数在机器学习里经常用到,在保持单调的情况下避免因数值运算带来的歧义问题,而且对数可以把乘法转到加法运算,加速了运算。因此上面的代码中把所有的出现次数初始化为1,然后把分母初始为2,接着都是累加,在对数空间中从0还是1开始累加,最后比较大小不会受影响的。
最后贴出分类代码:
def classifyNB(vec2Classify, p0Vec, p1Vec, pClass1):
p1 = sum(vec2Classify * p1Vec) + log(pClass1) #element-wise mult
p0 = sum(vec2Classify * p0Vec) + log(1.0 - pClass1)
if p1 > p0:
return 1
else:
return 0
分类代码也是在对数空间中计算的后验概率,然后通过比较大小来判断消息属于那一类。
总结:
优点:对小量数据很有效,可以处理多类
缺点:很依赖于数据的准备
朴素贝叶斯在概率图模型里被划为判别模型(Discriminative model)
以上内容来至群友博客:http://blog.csdn.net/marvin521
Ps:又见贝叶斯~之前,在machine learning for hacker里面有一篇关于Rstyle的贝叶斯,该算法简单高效,常用于spam检测和文本挖掘,像mahout里面的bayes就是为文本挖掘量身打造的。算法要求属性集是离散的,那么面对连续性的属性时,就要预先采用离散化了,可以结合连续型变量的分布用简单的分桶,最大描述准则(MDL)或者熵等等方法离散。
Machine Learning in Action(3) 朴素贝叶斯算法的更多相关文章
- 《Machine Learning in Action》—— 白话贝叶斯,“恰瓜群众”应该恰好瓜还是恰坏瓜
<Machine Learning in Action>-- 白话贝叶斯,"恰瓜群众"应该恰好瓜还是恰坏瓜 概率论,可以说是在机器学习当中扮演了一个非常重要的角色了.T ...
- 机器学习---用python实现朴素贝叶斯算法(Machine Learning Naive Bayes Algorithm Application)
在<机器学习---朴素贝叶斯分类器(Machine Learning Naive Bayes Classifier)>一文中,我们介绍了朴素贝叶斯分类器的原理.现在,让我们来实践一下. 在 ...
- machine learning for hacker记录(3) 贝叶斯分类器
本章主要介绍了分类算法里面的一种最基本的分类器:朴素贝叶斯算法(NB),算法性能正如英文缩写的一样,很NB,尤其在垃圾邮件检测领域,关于贝叶斯的网上资料也很多,这里推荐那篇刘未鹏写的http://mi ...
- 朴素贝叶斯算法下的情感分析——C#编程实现
这篇文章做了什么 朴素贝叶斯算法是机器学习中非常重要的分类算法,用途十分广泛,如垃圾邮件处理等.而情感分析(Sentiment Analysis)是自然语言处理(Natural Language Pr ...
- 【数据挖掘】朴素贝叶斯算法计算ROC曲线的面积
题记: 近来关于数据挖掘学习过程中,学习到朴素贝叶斯运算ROC曲线.也是本节实验课题,roc曲线的计算原理以及如果统计TP.FP.TN.FN.TPR.FPR.ROC面积等等.往往运用 ...
- 朴素贝叶斯算法的python实现
朴素贝叶斯 算法优缺点 优点:在数据较少的情况下依然有效,可以处理多类别问题 缺点:对输入数据的准备方式敏感 适用数据类型:标称型数据 算法思想: 朴素贝叶斯比如我们想判断一个邮件是不是垃圾邮件,那么 ...
- C#编程实现朴素贝叶斯算法下的情感分析
C#编程实现 这篇文章做了什么 朴素贝叶斯算法是机器学习中非常重要的分类算法,用途十分广泛,如垃圾邮件处理等.而情感分析(Sentiment Analysis)是自然语言处理(Natural Lang ...
- Naive Bayes(朴素贝叶斯算法)[分类算法]
Naïve Bayes(朴素贝叶斯)分类算法的实现 (1) 简介: (2) 算法描述: (3) <?php /* *Naive Bayes朴素贝叶斯算法(分类算法的实现) */ /* *把. ...
- 腾讯公司数据分析岗位的hadoop工作 线性回归 k-means算法 朴素贝叶斯算法 SpringMVC组件 某公司的广告投放系统 KNN算法 社交网络模型 SpringMVC注解方式
腾讯公司数据分析岗位的hadoop工作 线性回归 k-means算法 朴素贝叶斯算法 SpringMVC组件 某公司的广告投放系统 KNN算法 社交网络模型 SpringMVC注解方式 某移动公司实时 ...
随机推荐
- java通过代码控制线程状态,解决线程不安全的问题。
写两个类,Input,output 两个都是使用同步代码块的方式实现线程间的同步 input类,是为变量赋值 output类,是打印变量 由于线程争夺cpu造成数据的不匹配 通过,设立一个 flag ...
- 如何循序渐进向.NET架构师发展
微软的DotNet开发绝对是属于那种入门容易提高难的技术.而要能够成为DotNet架构师没有三年或更长时间的编码积累基本上是不可能的.特别是在大型软件项目中,架构师是项目核心成员,承上启下,因此RUP ...
- AC日记——花店橱窗布置 codevs 1028
题目描述 Description 假设以最美观的方式布置花店的橱窗,有F束花,V个花瓶,我们用美学值(一个整数)表示每束花放入每个花瓶所产生的美学效果.为了取得最佳的美学效果,必须使花的摆放取得最大的 ...
- Java原来如此-反射机制
在Java运行时环境中,对于任意一个类,能知道这个类有哪些属性和方法.对于任意一个对象,能调用它的任意一个方法.这种动态获取类的信息以及动态调用对象的方法的功能来自于Java语言的反射(Reflect ...
- hdu6219(最大空凸包)
题意: 给一些点,求出一个最大的空凸包,这个凸包里没有任何给定点且要求这个凸包面积最大 分析: 枚举凸包左下角的点,然后dp[i][j]表示凸包的最后两条边是j->i和i->O情况下凸包的 ...
- Weblogic内存溢出及常用参数配置
http://www.360doc.com/content/14/0306/14/16134804_358216319.shtml 一.WebLogic内存溢出 最近访问量门户访问量突然增大, ...
- apache一个IP绑定多个域名
用ServerAlias <VirtualHost *:80>ServerAdmin i@kuigg.comDocumentRoot /www/kuigg.comServerName ku ...
- C#文件路径操作总结【转】
http://www.cnblogs.com/zhoufoxcn/archive/2006/10/24/2515874.html 一.获取当前文件的路径 1. System.Diagnostics ...
- Opencv 最小外接矩形合并拼接
前一篇画出了最小外接矩形,但是有时候画出来的矩形由于中间像素干扰或者是其他原因矩形框并不是真正想要的 如图1是一个信号的雨图,被矩形框分割成了多个小框: 需要合并矩形框达到的效果: 主要思想: 扫描两 ...
- openssl之EVP系列之11---EVP_Verify系列函数介绍
openssl之EVP系列之11---EVP_Verify系列函数介绍 ---依据openssl doc/crypto/EVP_VerifyInit.pod翻译和自己的理解写成 (作者 ...