Naive Bayes 笔记
Naive Bayes (朴素贝叶斯) 属于监督学习算法, 它通过计算测试样本在训练样本各个分类中的概率来确定测试样本所属分类, 取最大概率为其所属分类.
| 优点 | 在数据较少的情况下仍然有效,可以处理多类别问题 |
| 缺点 | 对输入数据的准备方式较为敏感 |
| 适用数据类型 | 标称型 |
基础概念
1. 条件概率
P(A|B) 表示事件B已经发生的前提下, 事件A发生的概率, 即事件B发生下事件A的条件概率。
计算公式为: 
2. 贝叶斯公式
当 P(A|B) 比较容易计算, P(B|A) 比较难以计算时, 可以利用贝叶斯公式.
计算公式为: 
算法描述
1. 算法的核心就是计算 P(Ci|w), 其中 w 是测试样本, Ci 是某一个分类, 即计算 w 属于 Ci 的概率, 哪个概率大, 就属于哪个 Ci; 计算公式为:
2. P(w) 对于一个测试样本是固定值, 所以这里不进行考虑, 只需考虑分母即可. (代码72, 73行)
3. P(Ci) 表示的是测试样本中一个分类的概率, 这个也是可以直接求出来的.(即代码中的 pAbusive)
4. P(w|Ci) 中的 w 在本文中是指一个文档, 它由各个单词 W0, W1, W2...组成, W0, W1, W2...的相互之间是独立的, 所以有以下公式成立: 
5. 如果每次有一篇测试文档 w 进来后, 都把它拆分成 W0, W1, W2.. 再去计算 P(W0|Ci), P(W1|Ci), P(W2|Ci)..., 则会大大降低效率, 所以应该在训练阶段把所有出现过的词语 Wj 在各个 Ci 的概率都 P(Wj|Ci) 计算好, 在测试时直接使用即可.
6. P(Wj|Ci) 的计算, 用 Wj 在 Ci 中出现的次数除以 Ci 中的总单词数即可. (代码第 62, 63 行)
算法流程图

# -*- coding: utf- -*
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']]
# 这里分别指明 postingList 中的各个项是否为侮辱性语言
# 表示不是侮辱性语言, 表示是
classVec = [,,,,,]
return postingList,classVec # 把 dataSet 中的单词存到 list 中, 同时去除所有重复单词
def createVocabList(dataSet):
vocabSet = set([]) #create empty set
for document in dataSet:
vocabSet = vocabSet | set(document) #union of the two sets
return list(vocabSet) # 将 inputSet 转成向量, 即一个长度为 len(vocabList) 的向量
# 与 inputSet 中单词相同处为 , 其余为
def setOfWords2Vec(vocabList, inputSet):
returnVec = []*len(vocabList)
for word in inputSet:
if word in vocabList:
returnVec[vocabList.index(word)] =
else: print "the word: %s is not in my Vocabulary!" % word
return returnVec # 朴素贝叶斯核心训练函数, 训练结果为所有单词在各个分类中的概率即 P(w|Ci)
# 本函数最后得到两个长度为 N 的数组, N 为 trainMatrix 的列数, 即所有文档中的中单词数
# p1Vect/p0Vect 即为任意文档属于侮辱性/非侮辱性文档时, 各个单词出现的概率,即为 P(w|Ci)
# 返回的 pAbusive 为侮辱性语句占总语句的百分比, 即 P(Ci)
def trainNB0(trainMatrix,trainCategory):
numTrainDocs = len(trainMatrix) # 行数
numWords = len(trainMatrix[]) # 列数 # 因为 trainCategory 中为 的是侮辱性, 为 的不是, 所以求 sum 后就是侮辱性的个数
# 再除以总的集合数, 就行到侮辱性所占百分比
pAbusive = sum(trainCategory)/float(numTrainDocs) # p1Num/p0Num 为所有侮辱性/非侮辱性语句对应向量的和
# p1Denom/p0Denom 为所有侮辱性/非侮辱性语句中包含的单词数
p0Num = ones(numWords); p1Num = ones(numWords) # 全为 , 避免乘
p0Denom = 2.0; p1Denom = 2.0 # change to 2.0 for i in range(numTrainDocs):
if trainCategory[i] == :
p1Num += trainMatrix[i]
p1Denom += sum(trainMatrix[i])
else:
p0Num += trainMatrix[i]
p0Denom += sum(trainMatrix[i]) p1Vect = log(p1Num/p1Denom) # 求对数, 避免极小数相乘, 最后得0
p0Vect = log(p0Num/p0Denom) # change to log()
return p0Vect,p1Vect,pAbusive # 对 vec2Classify 进行分类, 看它是属于 p1Vec 还是 p0Vec
def classifyNB(vec2Classify, p0Vec, p1Vec, pClass1):
# log 求加, 实际上就是贝叶斯公式分子中的求乘
# 因为 vec2Classify 对于出现的单词为 , 未出现的单词为
# 所以两者相乘实际上就是 P(w|Ci)
p1 = sum(vec2Classify * p1Vec) + log(pClass1) #element-wise mult
p0 = sum(vec2Classify * p0Vec) + log(1.0 - pClass1)
if p1 > p0:
return
else:
return # 另一种 inputSet 生成向量方法(与 setOfWords2Vec)
# 这里是每个单词出现一次, 就在相应位置 +
# setOfWords2Vec 是对于出现过的单词, 设置相应位置为
def bagOfWords2VecMN(vocabList, inputSet):
returnVec = []*len(vocabList)
for word in inputSet:
if word in vocabList:
returnVec[vocabList.index(word)] +=
return returnVec # 测试朴素贝叶斯
def testingNB():
# 加载数据并进行向量化
# 每个 list0Posts 中的项都生成一个向量, 最后 trainMat 是一个矩阵
listOPosts,listClasses = loadDataSet()
myVocabList = createVocabList(listOPosts)
trainMat=[]
for postinDoc in listOPosts:
trainMat.append(setOfWords2Vec(myVocabList, postinDoc)) # 训练
p0V,p1V,pAb = trainNB0(array(trainMat),array(listClasses)) # 测试 , 结果应为 非侮辱
testEntry = ['love', 'my', 'dalmation']
thisDoc = array(setOfWords2Vec(myVocabList, testEntry))
print testEntry,'classified as: ',classifyNB(thisDoc,p0V,p1V,pAb) # 测试 , 结果应为 侮辱
testEntry = ['stupid', 'garbage']
thisDoc = array(setOfWords2Vec(myVocabList, testEntry))
print testEntry,'classified as: ',classifyNB(thisDoc,p0V,p1V,pAb) # 按空格拆分字符串, 只取长度大于 的单词
def textParse(bigString): #input is big string, #output is word list
import re
listOfTokens = re.split(r'\W*', bigString)
return [tok.lower() for tok in listOfTokens if len(tok) > ] if __name__ == "__main__":
testingNB()
说明
本文为《Machine Leaning in Action》第四章(Classifying with probability theory: naïve Bayes)读书笔记, 代码稍作修改及注释.
好文参考
1.《算法杂货铺——分类算法之朴素贝叶斯分类(Naive Bayesian classification)》
转载 http://my.oschina.net/zenglingfan/blog/177517
Naive Bayes 笔记的更多相关文章
- 学习笔记之Naive Bayes Classifier
Naive Bayes classifier - Wikipedia https://en.wikipedia.org/wiki/Naive_Bayes_classifier In machine l ...
- 朴素贝叶斯算法(Naive Bayes)
朴素贝叶斯算法(Naive Bayes) 阅读目录 一.病人分类的例子 二.朴素贝叶斯分类器的公式 三.账号分类的例子 四.性别分类的例子 生活中很多场合需要用到分类,比如新闻分类.病人分类等等. 本 ...
- [Scikit-learn] 1.9 Naive Bayes
Ref: http://scikit-learn.org/stable/modules/naive_bayes.html 1.9.1. Gaussian Naive Bayes 原理可参考:统计学习笔 ...
- [Machine Learning & Algorithm] 朴素贝叶斯算法(Naive Bayes)
生活中很多场合需要用到分类,比如新闻分类.病人分类等等. 本文介绍朴素贝叶斯分类器(Naive Bayes classifier),它是一种简单有效的常用分类算法. 一.病人分类的例子 让我从一个例子 ...
- Spark MLlib 之 Naive Bayes
1.前言: Naive Bayes(朴素贝叶斯)是一个简单的多类分类算法,该算法的前提是假设各特征之间是相互独立的.Naive Bayes 训练主要是为每一个特征,在给定的标签的条件下,计算每个特征在 ...
- Microsoft Naive Bayes 算法——三国人物身份划分
Microsoft朴素贝叶斯是SSAS中最简单的算法,通常用作理解数据基本分组的起点.这类处理的一般特征就是分类.这个算法之所以称为“朴素”,是因为所有属性的重要性是一样的,没有谁比谁更高.贝叶斯之名 ...
- Naive Bayes理论与实践
Naive Bayes: 简单有效的常用分类算法,典型用途:垃圾邮件分类 假设:给定目标值时属性之间相互条件独立 同样,先验概率的贝叶斯估计是 优点: 1. 无监督学习的一种,实现简单,没有迭代,学习 ...
- [ML] Naive Bayes for Text Classification
TF-IDF Algorithm From http://www.ruanyifeng.com/blog/2013/03/tf-idf.html Chapter 1, 知道了"词频" ...
- 朴素贝叶斯方法(Naive Bayes Method)
朴素贝叶斯是一种很简单的分类方法,之所以称之为朴素,是因为它有着非常强的前提条件-其所有特征都是相互独立的,是一种典型的生成学习算法.所谓生成学习算法,是指由训练数据学习联合概率分布P(X,Y ...
随机推荐
- 796B Find The Bone
B. Find The Bone time limit per test 2 seconds memory limit per test 256 megabytes input standard in ...
- geoserver 发布无坐标png
1.geoserver 安装一些插件的时候,直接去http://docs.geoserver.org/ 官网,选择自己geoserver对应的版本的插件就可以了. 2.geoserver 发布自身带有 ...
- VS“当前上下文中不存在名称“ViewBag”,当前上下文不存在名称“model””-已解决
自己的项目出现了错误提示,却能编译成功,但是有点强迫症,总是想解决这个错误. 上网找了一堆,都是删除缓存等一些方法,但是没有多大用处,我觉得还是版本号不对,没有引用进来相应的配置,所以配置下了Conf ...
- MyBatis Generator中文文档
MyBatis Generator中文文档 MyBatis Generator中文文档地址: http://mbg.cndocs.tk/ 该中文文档由于尽可能和原文内容一致,所以有些地方如果不熟悉,看 ...
- java进行3DES加解密
import javax.crypto.Cipher; import javax.crypto.spec.IvParameterSpec; import javax.crypto.spec.Secre ...
- one or more
想到以后如果一直都是这样,那么以后的生活是多么多么可怕啊. 感觉毫无期盼.没有意义. 如果变得理所当然那是多么多么让人害怕的事,吓得让人发抖. 所以在以后漫长的岁月里,还是一个人吧 如果相互看不惯,感 ...
- linux_制作本地yum源
新建文件夹 mkdir /root/guazai 并将本地磁盘挂载到当前文件夹 mount -o loop /dev/cdrom /root/guazai/ 新建文件夹 mkdir /mnt/loca ...
- kbmMW均衡负载与容灾(2)(转载红鱼儿)
集中式均衡负载 为实现集中式均衡负载方案,需要实现两个不同的应用服务器,一个是只包含均衡负载组件再无其他内容的应用服务器,可称之为均衡负载应用服务器,下文简称LB Server,另外一个就是包含一个或 ...
- jsp里面不能使用${pageContext.request.contextPath}解决方案
1.在jsp中使用${pageContext.request.contextPath}获取相对路径,可是最后路径变为:http://localhost:8080/oneself/$%7BpageCon ...
- Codeforces 1107 简要题解
文章目录 A题 B题 C题 D题 E题 F题 G题 传送门 A题 传送门 题意简述:问你能不能把一个数字串切成若干块,使得切出来的kkk个数k≤2k\le2k≤2满足a1<a2<...&l ...