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 ...
随机推荐
- PAT 1023 组个最小数 (20)(代码+思路)
1023 组个最小数 (20)(20 分) 给定数字0-9各若干个.你可以以任意顺序排列这些数字,但必须全部使用.目标是使得最后得到的数尽可能小(注意0不能做首位).例如:给定两个0,两个1,三个5, ...
- Python-多进程VS多线程
多进程VS多线程 功能: 进程:能够完成多任务,比如,同时运行多个QQ 线程:能够完成多任务,比如一个QQ中的多个聊天窗口 定义 进程:系统进行资源分配和测试的一个独立单位,线程自己基本上不拥有系统资 ...
- Luogu 2467[SDOI2010]地精部落 - DP
Solution 这题真秒啊,我眼瞎没有看到这是个排列 很显然, 有一条性质: 第一个是山峰 和 第一个是山谷的情况是一一对应的, 只需要把每个数 $x$ 变成 $n-x+1$ 然后窝萌定义数组 $ ...
- JSP 9个内置对象
JSP内置对象(隐式对象)是JSP容器为每个页面自动实例化的一组对象,开发者可直接使用,也被称为预定义变量. JSP容器提供了9个内置对象 request // javax.servlet.http. ...
- Spring ApplicationContext(八)事件监听机制
Spring ApplicationContext(八)事件监听机制 本节则重点关注的是 Spring 的事件监听机制,主要是第 8 步:多播器注册:第 10 步:事件注册. public void ...
- PHP redis 群发短信
$redis = new \Redis(); $redis->connect('127.0.0.1', 6379); $list = M('Sms')->field('phone')-&g ...
- openssl pem文件的读取
准备工作 生成私钥文件(里面已包含公钥) openssl genrsa -out private.pem 1024 从私钥文件中提取公钥 openssl rsa -in private.pem -pu ...
- solr之创建core(搜索核心,包括索引和数据)的方法
我的solrhome为D:\solrHome\solr step1:进入solrHome会看到collection1文件夹,创建该文件夹的副本,重命名为product 进入product文件夹,进入d ...
- [Office]Execl取消保护密码
2007版Excel表格中可以按照以下方式建宏: 打开Excel表格中的Excel选项,选择自定义,得到如下画面: 然后在左边侧框栏中选择“查看宏”或者Alt+F11 之后双击或者选择添加按钮,则可 ...
- 关于xp操作系统下使用VC6++编写的上位机软件在win10中运行的问题
将代码拷贝到win10操作系统中,在vs2015环境中重新编译即可. 编译生成的exe出现终止时考虑mscomm控件是否注册. 当win10环境64位操作系统时,将以下四个文件放置于C:\Window ...