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 笔记的更多相关文章

  1. 学习笔记之Naive Bayes Classifier

    Naive Bayes classifier - Wikipedia https://en.wikipedia.org/wiki/Naive_Bayes_classifier In machine l ...

  2. 朴素贝叶斯算法(Naive Bayes)

    朴素贝叶斯算法(Naive Bayes) 阅读目录 一.病人分类的例子 二.朴素贝叶斯分类器的公式 三.账号分类的例子 四.性别分类的例子 生活中很多场合需要用到分类,比如新闻分类.病人分类等等. 本 ...

  3. [Scikit-learn] 1.9 Naive Bayes

    Ref: http://scikit-learn.org/stable/modules/naive_bayes.html 1.9.1. Gaussian Naive Bayes 原理可参考:统计学习笔 ...

  4. [Machine Learning & Algorithm] 朴素贝叶斯算法(Naive Bayes)

    生活中很多场合需要用到分类,比如新闻分类.病人分类等等. 本文介绍朴素贝叶斯分类器(Naive Bayes classifier),它是一种简单有效的常用分类算法. 一.病人分类的例子 让我从一个例子 ...

  5. Spark MLlib 之 Naive Bayes

    1.前言: Naive Bayes(朴素贝叶斯)是一个简单的多类分类算法,该算法的前提是假设各特征之间是相互独立的.Naive Bayes 训练主要是为每一个特征,在给定的标签的条件下,计算每个特征在 ...

  6. Microsoft Naive Bayes 算法——三国人物身份划分

    Microsoft朴素贝叶斯是SSAS中最简单的算法,通常用作理解数据基本分组的起点.这类处理的一般特征就是分类.这个算法之所以称为“朴素”,是因为所有属性的重要性是一样的,没有谁比谁更高.贝叶斯之名 ...

  7. Naive Bayes理论与实践

    Naive Bayes: 简单有效的常用分类算法,典型用途:垃圾邮件分类 假设:给定目标值时属性之间相互条件独立 同样,先验概率的贝叶斯估计是 优点: 1. 无监督学习的一种,实现简单,没有迭代,学习 ...

  8. [ML] Naive Bayes for Text Classification

    TF-IDF Algorithm From http://www.ruanyifeng.com/blog/2013/03/tf-idf.html Chapter 1, 知道了"词频" ...

  9. 朴素贝叶斯方法(Naive Bayes Method)

        朴素贝叶斯是一种很简单的分类方法,之所以称之为朴素,是因为它有着非常强的前提条件-其所有特征都是相互独立的,是一种典型的生成学习算法.所谓生成学习算法,是指由训练数据学习联合概率分布P(X,Y ...

随机推荐

  1. nginx默认配置和默认站点启动

    1.nginx的配置文件nginx.conf cd /etc/nginx/ vim nginx.conf 打开后的文件为: user nginx;worker_processes 1; error_l ...

  2. hdu 5692(dfs+线段树) Snacks

    题目http://acm.hdu.edu.cn/showproblem.php?pid=5692 题目说每个点至多经过一次,那么就是只能一条路线走到底的意思,看到这题的格式, 多个询问多个更新, 自然 ...

  3. 大数java(pow)

    Problems involving the computation of exact values of very large magnitude and precision are common. ...

  4. git clone时出现:"diffie-hellman-group1-sha1 "

    解决办法1:在用户配置目录下添加一个ssh配置文件 vim /root/.ssh/config  内容如下: Host * KexAlgorithms +diffie-hellman-group1-s ...

  5. 洛谷3084 [USACO13OPEN]照片Photo

    原题链接 神仙\(DP\)啊... 题解请移步隔壁大佬的博客\(QAQ\) #include<cstdio> using namespace std; const int N = 2e5 ...

  6. 进化树(phylogenetic trees)

    构建进化树的工具有: muscle mega 进化树的可视化: 本地可视化软件 Figtree (网址:http://tree.bio.ed.ac.uk/software/figtree/) 该软件是 ...

  7. [Chrome Headless + Python] 截长图 (Take Full-page Screenshot)

    # -*- coding: utf-8 -*- import time import os from selenium import webdriver from selenium.webdriver ...

  8. Shortest Unsorted Continuous Subarray LT581

    Given an integer array, you need to find one continuous subarray that if you only sort this subarray ...

  9. Java SE EE ME用处

    Java SE: 又称J2SE,开发部署桌面应用程序: Java EE:又称J2EE,开发网站 Java ME:是做手机APP开发 EE在SE基础上构建,提供web服务.组件模型.管理和通信API

  10. 编译sgbm_ros中遇到的问题

    出现的问题 这个会报错 1.解决方法是在文件sudo gedit /usr/local/cuda/include/crt/common_functions.h中注释掉如下 #define __CUDA ...