1. 贝叶斯定理

如果有两个事件,事件A和事件B。已知事件A发生的概率为p(A),事件B发生的概率为P(B),事件A发生的前提下。事件B发生的概率为p(B|A),事件B发生的前提下。事件A发生的概率为p(A|B),事件A和事件B同一时候发生的概率是p(AB)。则有

p(AB)=p(A)p(B|A)=p(B)p(A|B)(1)

依据式(1)能够推出贝叶斯定理为

p(B|A)=p(B)p(A|B)p(A)(2)

给定一个全集{B1,B1,…,Bn},当中Bi与Bj是不相交的,即BiBj=∅。则依据全概率公式。对于一个事件A。会有

p(A)=∑i=1np(Bi)p(A|Bi)(3)

则广义的贝叶斯定理有

p(Bi|A)=p(Bi)p(A|Bi)∑ni=1p(Bi)p(A|Bi)(4)

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)。

那怎样求解出这些后验概率呢?依据贝叶斯定理。有

p(y=yi|x)=p(yi)p(x|yi)p(x)(5)

一般地,朴素贝叶斯方法如果各个特征之间是相互独立的,则式(5)能够写成:

p(y=yi|x)=p(yi)p(x|yi)p(x)=p(yi)∏nj=1p(xj|yi)∏nj=1p(xj)(6)

由于(6)式的分母。对于每个p(y=yi|x)求解都是一样的。所以,在实际操作中。能够省略掉。终于。朴素贝叶斯分类器的判别公式变成例如以下的形式:

y=argmaxyip(yi)p(x|yi)=argmaxyip(yi)∏j=1np(xj|yi)(7)

以下,是怎样通过样本对 p(y) 和 p(x|y) 进行概率预计。

3. 朴素贝叶斯法的參数预计

3.1 极大似然预计

在朴素贝叶斯法中,学习就是意味着预计先验概率p(y) 和 条件概率 p(x|y)。然后依据先验概率和条件概率,去计算新的样本的后验概率 p(y|x)。

当中,预计先验概率和条件概率的方法有非常多,比方极大似然预计,多项式。高斯。伯努利等。

当中,在极大似然预计中,先验概率p(y)的极大似然预计例如以下:

p(y=yi)=样本中yi标签的个数总样本的个数(8)

如果输入样本的第j的特征中全部可能取值的集合是 {aj1,aj2,…,ajsj}。则条件概率p(x(j)|y=yi)的极大似然预计例如以下:

p(x(j)=ajl|y=yi)=在属于yi标签的样本中,第j个特征值等于ajl的个数样本中属于yi标签的个数(9)

样例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)的预计例如以下:

p(y=yi)=样本中yi标签的个数+α样本的总个数+总的类别个数×α(10)

如果输入样本的第j个特征的全部可能取值的集合是 {aj1,aj2,…,ajsj}。则条件概率p(x(j)|y=yi)的预计例如以下:

p(x(j)|y=yi)=在属于yi标签的样本中,第j个特征值等于ajl的个数+α属于yi标签的个数+第j个特征的唯一值个数×α(11)

当中。α是平滑值。当α=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

当输入的特征是连续值的时候,我们无法用上面的方法来预计先验概率和条件概率,能够採用高斯模型。

高斯模型如果特征服从高斯分布。

其特征的似然预计例如以下所看到的:

p(xi|y)=12πσ2y−−−−√exp(−(xi−μy)22σ2y)(12)

当中。

σ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 注意事项

  1. Works only with categorical predictors, numerical predictors must be categorized or binned before use
  2. 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)的更多相关文章

  1. 数据挖掘十大经典算法(9) 朴素贝叶斯分类器 Naive Bayes

    贝叶斯分类器 贝叶斯分类器的分类原理是通过某对象的先验概率,利用贝叶斯公式计算出其后验概率,即该对象属于某一类的概率,选择具有最大后验概率的类作为该对象所属的类.眼下研究较多的贝叶斯分类器主要有四种, ...

  2. 十大经典数据挖掘算法(9) 朴素贝叶斯分类器 Naive Bayes

    贝叶斯分类器 贝叶斯分类分类原则是一个对象的通过先验概率.贝叶斯后验概率公式后计算,也就是说,该对象属于一类的概率.选择具有最大后验概率的类作为对象的类属.现在更多的研究贝叶斯分类器,有四个,每间:N ...

  3. 朴素贝叶斯分类法 Naive Bayes ---R

    朴素贝叶斯算法 [转载时请注明来源]:http://www.cnblogs.com/runner-ljt/ Ljt   勿忘初心  无畏未来 作为一个初学者,水平有限,欢迎交流指正. 朴素贝叶斯分类法 ...

  4. 机器学习---朴素贝叶斯分类器(Machine Learning Naive Bayes Classifier)

    朴素贝叶斯分类器是一组简单快速的分类算法.网上已经有很多文章介绍,比如这篇写得比较好:https://blog.csdn.net/sinat_36246371/article/details/6014 ...

  5. 朴素贝叶斯分类器的应用 Naive Bayes classifier

    一.病人分类的例子 让我从一个例子开始讲起,你会看到贝叶斯分类器很好懂,一点都不难. 某个医院早上收了六个门诊病人,如下表. 症状 职业 疾病 打喷嚏 护士 感冒  打喷嚏 农夫 过敏  头痛 建筑工 ...

  6. PGM学习之三 朴素贝叶斯分类器(Naive Bayes Classifier)

    介绍朴素贝叶斯分类器的文章已经很多了.本文的目的是通过基本概念和微小实例的复述,巩固对于朴素贝叶斯分类器的理解. 一 朴素贝叶斯分类器基础回顾 朴素贝叶斯分类器基于贝叶斯定义,特别适用于输入数据维数较 ...

  7. 朴素贝叶斯分类器(Naive Bayesian Classifier)

    本博客是基于对周志华教授所著的<机器学习>的"第7章 贝叶斯分类器"部分内容的学习笔记. 朴素贝叶斯分类器,顾名思义,是一种分类算法,且借助了贝叶斯定理.另外,它是一种 ...

  8. 用scikit-learn实现朴素贝叶斯分类器 转

    原文:http://segmentfault.com/a/1190000002472791 朴素贝叶斯(Naive Bayes Classifier)是一种「天真」的算法(假定所有特征发生概率是独立的 ...

  9. 朴素贝叶斯分类器及Python实现

    贝叶斯定理 贝叶斯定理是通过对观测值概率分布的主观判断(即先验概率)进行修正的定理,在概率论中具有重要地位. 先验概率分布(边缘概率)是指基于主观判断而非样本分布的概率分布,后验概率(条件概率)是根据 ...

随机推荐

  1. jQuery Ajax方式上传文件实现暂停或取消上传

    未上传时要实现取消,很简单... 但如果用户点击了上传,并加载了进度信息... 2017-05-04再次改进.在上传过程中用户可以按 Esc 来取消上传(取消当前上传,或者是全部上传)... 也可以在 ...

  2. 服务器配置多版本CUDA、CUdnn(不同Linux账户使用不同CUDA、CUdnn版本)

    一.由于实验室大家使用的CUDA.CUdnn不同,所以需要在同一台服务器安装多个版本,而且要不引起冲突,方法如下: 1.一般来说CUDA安装在 /usr/local 目录下(当然你可以通过“echo ...

  3. RocketMQ logback使用实践

    logback_broker.xml <?xml version="1.0" encoding="UTF-8"?> <!-- Licensed ...

  4. @几种OutOfMemory异常

    Java虚拟机运行时数据区 在Java虚拟机规范的描述中,除了程序计数器之外,虚拟机内存的其他几个运行时区域都会发生OutOfMemory异常的可能. 我们可以在IDE(如IDEA)中设置虚拟机启动参 ...

  5. POJ 1451 T9 (字典树好题)

    背景:为了方便九宫格手机用户发短信,希望在用户按键时,根据提供的字典(给出字符串和频数),给出各个阶段最有可能要打的单词. 题意: 首先给出的是字典,每个单词有一个出现频率.然后给出的是询问,每个询问 ...

  6. QT国际化(中英转换)

    转载:https://blog.csdn.net/u012528526/article/details/54707233 QT国际化(中英转换) 我们都知道在安卓中,想做国际化很简单,只需要建立对应的 ...

  7. [转]使用HackCube-Special分析胎压传感器信号

    胎压无线传感器安全检测 我们团队之前也有用USRP和GNUradio对其他的胎压设备进行的安全检测,我不使用这套环境的原因是软件无线电的设备和笔记本已经算体积不小的一套设备,通常测试环境都在户外,在这 ...

  8. Palindrome Number leetcode java

    题目: Determine whether an integer is a palindrome. Do this without extra space. click to show spoiler ...

  9. Proguard使用最新,最全教程,亲自试验

    最近公司有一个项目,是外包项目,由于对方也有技术人员,出于技术上的保密,需要对class文件进行二次处理,于是网上找了好久,只发现Proguard是用的最广泛而且网上资料最多的.由于不是纯JAVA项目 ...

  10. mysql启动报错cannot allocate memory for the buffer pool处理

    今天启动mysql服务器时失败了.去/var/log/mysql/查看error.log,报错信息如下: 160123 22:29:26 InnoDB: Initializing buffer poo ...