朴素贝叶斯分类器(Naive Bayes)
1. 贝叶斯定理
如果有两个事件,事件A和事件B。已知事件A发生的概率为p(A),事件B发生的概率为P(B),事件A发生的前提下。事件B发生的概率为p(B|A),事件B发生的前提下。事件A发生的概率为p(A|B),事件A和事件B同一时候发生的概率是p(AB)。则有
依据式(1)能够推出贝叶斯定理为
给定一个全集{B1,B1,…,Bn},当中Bi与Bj是不相交的,即BiBj=∅。则依据全概率公式。对于一个事件A。会有
则广义的贝叶斯定理有
2. 朴素贝叶斯基本原理
给定一组训练数据集{(X1,y1),(X2,y2),(X3,y3),…,(Xm,ym)}。当中,m是样本的个数。每个数据集包括着n个特征,即Xi=(xi1,xi2,…,xin)。类标记集合为{y1,y2,…,yk}。设p(y=yi|X=x)表示输入的X样本为x时,输出的y为yk的概率。
如果如今给定一个新的样本x。要推断其属于哪一类,可分别求解p(y=y1|x),p(y=y2|x),p(y=y3|x),…,p(y=yk|x)的值。哪一个值最大,就属于那一类。即,求解最大的后验概率 argmaxp(y|x)。
那怎样求解出这些后验概率呢?依据贝叶斯定理。有
一般地,朴素贝叶斯方法如果各个特征之间是相互独立的,则式(5)能够写成:
由于(6)式的分母。对于每个p(y=yi|x)求解都是一样的。所以,在实际操作中。能够省略掉。终于。朴素贝叶斯分类器的判别公式变成例如以下的形式:
以下,是怎样通过样本对 p(y) 和 p(x|y) 进行概率预计。
3. 朴素贝叶斯法的參数预计
3.1 极大似然预计
在朴素贝叶斯法中,学习就是意味着预计先验概率p(y) 和 条件概率 p(x|y)。然后依据先验概率和条件概率,去计算新的样本的后验概率 p(y|x)。
当中,预计先验概率和条件概率的方法有非常多,比方极大似然预计,多项式。高斯。伯努利等。
当中,在极大似然预计中,先验概率p(y)的极大似然预计例如以下:
如果输入样本的第j的特征中全部可能取值的集合是 {aj1,aj2,…,ajsj}。则条件概率p(x(j)|y=yi)的极大似然预计例如以下:
样例1
该样例来自李航的《统计学习方法》。
表中X(1)和X(2)为特征,取值的集合各自是A1={1,2,3},A2={S,M,L}。Y为类标记,Y=1,−1。
试求。x=(2,S)的类标记。
数据例如以下所看到的。当中,特征X(2)的取值{S,M,L}分别表示成{0,1,2}。
import numpy as np
import pandas as pd
x1 = np.array([1,1,1,1,1,2,2,2,2,2,3,3,3,3,3])
x2 = np.array([0,1,1,0,0,0,1,1,2,2,2,1,1,2,2])
y = np.array([-1,-1,1,1,-1,-1,-1,1,1,1,1,1,1,1,-1])
dataSet = np.concatenate((x1[:,None],x2[:,None],y[:,None]),axis=1)
df = pd.DataFrame(dataSet,index=np.arange(1,16,1),columns=['X1','X2','y'])
df.T
1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | 11 | 12 | 13 | 14 | 15 | |
---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|
X1 | 1 | 1 | 1 | 1 | 1 | 2 | 2 | 2 | 2 | 2 | 3 | 3 | 3 | 3 | 3 |
X2 | 0 | 1 | 1 | 0 | 0 | 0 | 1 | 1 | 2 | 2 | 2 | 1 | 1 | 2 | 2 |
y | -1 | -1 | 1 | 1 | -1 | -1 | -1 | 1 | 1 | 1 | 1 | 1 | 1 | 1 | -1 |
求解
step1: 求解先验概率
p(y=−1)=615,p(y=1)=915
step2 求解条件概率
(2.1) 特征X1
p(X1=1|y=−1)=36=12。p(X1=2|y=−1)=26=13, p(X1=3|y=−1)=16
p(X1=1|y=1)=29,p(X1=2|y=1)=39=13, p(X1=3|y=1)=49
(2.2) 特征X1
p(X2=0|y=−1)=36=12,p(X2=1|y=−1)=26=13。 p(X2=2|y=−1)=16
p(X2=0|y=1)=19,p(X2=1|y=1)=49=。 p(X2=2|y=1)=49
step3 求解后验概率
p(y=−1)p(X=(2,S)|y=−1)=p(y=−1)p(X1=2|y=−1)p(X2=S|y=−1)=6151312=115
p(y=1)p(X=(2,S)|y=1)=p(y=1)p(X1=2|y=1)p(X2=S|y=1)=9151319=145
由于 115>145, 所以该样本的类标记为 −1
例如以下是python的极大似然预计的朴素贝叶斯代码,代码执行结果跟求解一致。
class MLENB:
"""
Maximum likelihood estimation Naive Bayes
Attributes
----------
class_prior_ : array, shape (n_classes, )
Smoothed empirical probability for each class.
class_count_: array, shape (n_classes,)
number of training samples observed in each class.
MLE_: array, shape(n_classes, n_features)
Maximum likelihood estimation of each feature per class, each of element is a dict
"""
def __init__(self):
pass
def fit(self,X,y):
"""Fit maximum likelihood estimation Naive Bayes according to X, y
Parameters
----------
X : array-like, shape (n_samples, n_features)
Training vectors, where n_samples is the number of samples
and n_features is the number of features.
y : array-like, shape (n_samples,)
Target values.
Returns
-------
self : object
Returns self.
"""
n_samples = X.shape[0]
n_features = X.shape[1]
n_classes = len(set(y))
self.class_count_ = np.empty(n_classes)
self.class_prior_ = np.empty(n_classes)
self.MLE_ = np.empty((n_classes,n_features),dtype=dict)
self.target_unique = np.unique(y)
for i in range(n_classes):
dataX_tu = X[y == self.target_unique[i]]
self.class_prior_[i] = dataX_tu.shape[0] / float(len(y))
self.class_count_[i] = dataX_tu.shape[0]
for j in range(n_features):
feature = dataX_tu[:,j]
feature_unique = np.unique(feature)
fp = {}
for f_item in feature_unique:
fp[f_item] = list(feature).count(f_item) / float(len(feature))
self.MLE_[i,j] = fp
return self
def __predict_likelihood(self,x):
if x.ndim == 1:
x = np.array([x])
n_samples = x.shape[0]
n_features = x.shape[1]
n_classes = len(self.class_count_)
likelihood = []
for x_item in x:
class_p = []
for i in range(n_classes):
p = self.class_prior_[i]
for j in range(n_features):
if x_item[j] in self.MLE_[i,j]:
p *= self.MLE_[i,j][x_item[j]]
else:
p *= 0
class_p.append(p)
likelihood.append(class_p)
return np.array(likelihood)
def predict(self,x):
"""Perform classification on an array of test vectors X.
Parameters
----------
X : array-like, shape = [n_samples, n_features]
Returns
-------
C : array, shape = [n_samples]
Predicted target values for X
"""
likelihood = self.__predict_likelihood(x)
max_index = np.argmax(likelihood, axis=1)
return np.array([self.target_unique[i] for i in max_index])
def predict_proba(self,x):
"""
Return probability estimates for the test vector X.
Parameters
----------
X : array-like, shape = [n_samples, n_features]
Returns
-------
C : array-like, shape = [n_samples, n_classes]
Returns the probability of the samples for each class in
the model. The columns correspond to the classes in sorted
order, as they appear in the attribute `classes_`.
"""
likelihood = self.__predict_likelihood(x)
return np.array([lh / np.sum(lh) for lh in likelihood])
# 測验结果
X = dataSet[:,0:-1]
y = dataSet[:,-1]
mlenb = MLENB()
mlenb.fit(X,y)
print(mlenb.predict(np.array([2,0])))
print(mlenb.predict_proba(np.array([2,0])))
[-1]
[[ 0.75 0.25]]
3.2 Multinomial Naive Bayes
用极大似然预计可能会出现所要预计的概率值为0的情况。
这时会影响到后验概率的计算结果,使分类产生偏差。这时。能够採用多项式模型,对先验概率和条件概率做一些平滑处理。详细公式为:
先验概率p(y)的预计例如以下:
如果输入样本的第j个特征的全部可能取值的集合是 {aj1,aj2,…,ajsj}。则条件概率p(x(j)|y=yi)的预计例如以下:
当中。α是平滑值。当α=1时,是拉普拉斯平滑(Laplace smoothing),当α=0时,退化到极大似然预计。当0<α<1时,称作Lidstone平滑。
有个疑问:多项式朴素贝叶斯与李航《统计学习方法》中说的贝叶斯预计有啥差别?本文的方法是參考李航的贝叶斯预计。
python的多项式朴素贝叶斯的參考代码例如以下:
class MultinomialNB:
"""Naive Bayes classifier for multinomial models
Attributes
----------
class_prior_ : array, shape (n_classes, )
Smoothed empirical probability for each class.
class_count_: array, shape (n_classes,)
number of training samples observed in each class.
bayes_estimation_: array, shape(n_classes, n_features)
bayes estimations of each feature per class, each of element is a dict
"""
def __init__(self, alpha=1.0):
self.alpha_ = 1.0
def fit(self,X,y):
n_samples = X.shape[0]
n_features = X.shape[1]
n_classes = len(set(y))
self.class_count_ = np.empty(n_classes)
self.class_prior_ = np.empty(n_classes)
self.bayes_estimation_ = np.empty((n_classes,n_features),dtype=dict)
self.target_unique = np.unique(y)
for i in range(n_classes):
dataX_tu = X[y == self.target_unique[i]]
self.class_prior_[i] = (dataX_tu.shape[0] + self.alpha_) / (float(len(y)) + n_classes * self.alpha_)
self.class_count_[i] = dataX_tu.shape[0]
for j in range(n_features):
feature = dataX_tu[:,j]
feature_unique = np.unique(feature)
fp = {}
for f_item in feature_unique:
fp[f_item] = (list(feature).count(f_item) + self.alpha_) / (float(len(feature)) + len(feature_unique) * self.alpha_)
self.bayes_estimation_[i,j] = fp
return self
def __predict_likelihood(self,x):
if x.ndim == 1:
x = np.array([x])
n_samples = x.shape[0]
n_features = x.shape[1]
n_classes = len(self.class_count_)
likelihood = []
for x_item in x:
class_p = []
for i in range(n_classes):
p = self.class_prior_[i]
for j in range(n_features):
if x_item[j] in self.bayes_estimation_[i,j]:
p *= self.bayes_estimation_[i,j][x_item[j]]
else:
p *= 0
class_p.append(p)
likelihood.append(class_p)
return np.array(likelihood)
def predict(self,x):
likelihood = self.__predict_likelihood(x)
max_index = np.argmax(likelihood, axis=1)
return np.array([self.target_unique[i] for i in max_index])
def predict_proba(self,x):
likelihood = self.__predict_likelihood(x)
return np.array([lh / np.sum(lh) for lh in likelihood])
# 測验结果
X = dataSet[:,0:-1]
y = dataSet[:,-1]
mnb = MultinomialNB()
mnb.fit(X,y)
print(mnb.predict(np.array([2,0])))
print(mnb.predict_proba(np.array([2,0])))
[-1]
[[ 0.65116279 0.34883721]]
3.3 Gaussian Naive Bayes
当输入的特征是连续值的时候,我们无法用上面的方法来预计先验概率和条件概率,能够採用高斯模型。
高斯模型如果特征服从高斯分布。
其特征的似然预计例如以下所看到的:
当中。
σ2y是第i个特征的方差,μy是第i个特征的均值。
其python代码例如以下:
class GaussianNB:
"""
Attributes
----------
class_prior_ : array, shape (n_classes,)
probability of each class.
class_count_ : array, shape (n_classes,)
number of training samples observed in each class.
theta_ : array, shape (n_classes, n_features)
mean of each feature per class
sigma_ : array, shape (n_classes, n_features)
variance of each feature per class
"""
def __init__(self):
pass
def fit(self, X, y):
n_samples = X.shape[0]
n_features = X.shape[1]
n_classes = len(set(y))
self.theta_ = np.zeros([n_classes,n_features])
self.sigma_ = np.zeros([n_classes,n_features])
self.class_prior = np.zeros(n_classes)
self.class_count = np.zeros(n_classes)
self.target_unique = np.unique(y)
for i in range(n_classes):
dataX_tu = X[y == self.target_unique[i]]
self.class_prior[i] = dataX_tu.shape[0] / float(len(y))
self.class_count[i] = dataX_tu.shape[0]
self.theta_[i,:] = np.mean(dataX_tu,axis=0)
self.sigma_[i,:] = np.var(dataX_tu,axis=0)
return self
def __predict_likelihood(self,x):
if x.ndim == 1:
x = np.array([x])
n_samples = x.shape[0]
likelihood = []
for x_item in x:
gaussian = np.exp(-(x_item-self.theta_)**2 / (2 * self.sigma_)) / np.sqrt(2*np.pi*self.sigma_)
p = np.exp(np.sum(np.log(gaussian),axis=1))
likelihood.append(self.class_prior * p)
return np.array(likelihood)
def predict(self,x):
likelihood = self.__predict_likelihood(x)
max_index = np.argmax(likelihood, axis=1)
return np.array([self.target_unique[i] for i in max_index])
def predict_proba(self,x):
likelihood = self.__predict_likelihood(x)
return np.array([lh / np.sum(lh) for lh in likelihood])
# 測验结果
X = dataSet[:,0:-1]
y = dataSet[:,-1]
gnb = GaussianNB()
gnb.fit(X,y)
print(gnb.predict(np.array([2,0])))
print(gnb.predict_proba(np.array([2,0])))
[-1]
[[ 0.74566865 0.25433135]]
3.4 Bernoulli Naive Bayes
5. Naive Bayes 注意事项
- Works only with categorical predictors, numerical predictors must be categorized or binned before use
- Works with the assumption of predictor independence, and thus cannot detect or account for relationships between the predictors, unlike a decision tree for example.
朴素贝叶斯分类器(Naive Bayes)的更多相关文章
- 数据挖掘十大经典算法(9) 朴素贝叶斯分类器 Naive Bayes
贝叶斯分类器 贝叶斯分类器的分类原理是通过某对象的先验概率,利用贝叶斯公式计算出其后验概率,即该对象属于某一类的概率,选择具有最大后验概率的类作为该对象所属的类.眼下研究较多的贝叶斯分类器主要有四种, ...
- 十大经典数据挖掘算法(9) 朴素贝叶斯分类器 Naive Bayes
贝叶斯分类器 贝叶斯分类分类原则是一个对象的通过先验概率.贝叶斯后验概率公式后计算,也就是说,该对象属于一类的概率.选择具有最大后验概率的类作为对象的类属.现在更多的研究贝叶斯分类器,有四个,每间:N ...
- 朴素贝叶斯分类法 Naive Bayes ---R
朴素贝叶斯算法 [转载时请注明来源]:http://www.cnblogs.com/runner-ljt/ Ljt 勿忘初心 无畏未来 作为一个初学者,水平有限,欢迎交流指正. 朴素贝叶斯分类法 ...
- 机器学习---朴素贝叶斯分类器(Machine Learning Naive Bayes Classifier)
朴素贝叶斯分类器是一组简单快速的分类算法.网上已经有很多文章介绍,比如这篇写得比较好:https://blog.csdn.net/sinat_36246371/article/details/6014 ...
- 朴素贝叶斯分类器的应用 Naive Bayes classifier
一.病人分类的例子 让我从一个例子开始讲起,你会看到贝叶斯分类器很好懂,一点都不难. 某个医院早上收了六个门诊病人,如下表. 症状 职业 疾病 打喷嚏 护士 感冒 打喷嚏 农夫 过敏 头痛 建筑工 ...
- PGM学习之三 朴素贝叶斯分类器(Naive Bayes Classifier)
介绍朴素贝叶斯分类器的文章已经很多了.本文的目的是通过基本概念和微小实例的复述,巩固对于朴素贝叶斯分类器的理解. 一 朴素贝叶斯分类器基础回顾 朴素贝叶斯分类器基于贝叶斯定义,特别适用于输入数据维数较 ...
- 朴素贝叶斯分类器(Naive Bayesian Classifier)
本博客是基于对周志华教授所著的<机器学习>的"第7章 贝叶斯分类器"部分内容的学习笔记. 朴素贝叶斯分类器,顾名思义,是一种分类算法,且借助了贝叶斯定理.另外,它是一种 ...
- 用scikit-learn实现朴素贝叶斯分类器 转
原文:http://segmentfault.com/a/1190000002472791 朴素贝叶斯(Naive Bayes Classifier)是一种「天真」的算法(假定所有特征发生概率是独立的 ...
- 朴素贝叶斯分类器及Python实现
贝叶斯定理 贝叶斯定理是通过对观测值概率分布的主观判断(即先验概率)进行修正的定理,在概率论中具有重要地位. 先验概率分布(边缘概率)是指基于主观判断而非样本分布的概率分布,后验概率(条件概率)是根据 ...
随机推荐
- 解决html5 audio iphone,ipd,safari不能自动播放问题
html audio 在iPhone,ipd,safari浏览器不能播放是有原因滴 (在safri on ios里面明确指出等待用户的交互动作后才能播放media,也就是说如果你没有得到用户的acti ...
- docker查看容器的网络ip
docker inspect -f '{{range .NetworkSettings.Networks}}{{.IPAddress}}{{end}}' container_name_or_id 可直 ...
- 【凯子哥带你学Framework】Activity界面显示全解析(下)
咱们接着上篇继续讲,上篇没看的请戳:[凯子哥带你学Framework]Activity界面显示全解析(上) 如何验证上一个问题 首先,说明一下运行条件: //主题 name="AppThem ...
- [Android Security] APK自我保护 - DEX/APK校验
cp : https://segmentfault.com/a/1190000005105973 DEX校验 classes.dex 是 Android 虚拟机的可执行文件,我们所写的 java 代码 ...
- yolo源码解析(二)
五 读取数据pascal_voc.py文件解析 我们在YOLENet类中定义了两个占位符,一个是输入图片占位符,一个是图片对应的标签占位符,如下: #输入图片占位符 [NONE,image_size, ...
- RV32A指令集
RV32A指令包括两类:AMO(atomic memory operation)指令,Load-Reserved/Store-Conditional指令 Category Fmt RV32I base ...
- Set Matrix Zeroes leetcode java
题目: Given a m x n matrix, if an element is 0, set its entire row and column to 0. Do it in place. cl ...
- 【Javascript设计模式1】-单例模式
<parctical common lisp>的作者曾说,如果你需要一种模式,那一定是哪里出了问题.他所说的问题是指因为语言的天生缺陷,不得不去寻求和总结一种通用的解决方案. 不管是弱类型 ...
- 推文《阿里凑单算法首次公开!基于Graph Embedding的打包购商品挖掘系统解析》笔记
推文<阿里凑单算法首次公开!基于Graph Embedding的打包购商品挖掘系统解析>笔记 从17年5月份开始接触Graph Embedding,学术论文读了很多,但是一直不清楚这技术是 ...
- Java Web 生成临时文件并下载(原)
概述:本文是 java 服务器端生成文件并下载的示例,并不完善,下载之后一般来说还需要删除临时文件. 注意:临时文件存放在 /WEB-INF/tmp 目录下,所以先要把 tmp 目录建起来. pu ...