贝叶斯定理
现在假设有两个事件分别为A和B,贝叶斯定理则可以描述在事件A发生的前提下B发生的概率以及在事件B发生的前提下事件A发生的概率之间的关系。有点绕?画个图就能理解了~
现在假设事件A发生的概率为
上述的公式就是贝叶斯公式。推到过程是不是很简单~
朴素贝叶斯概率模型
基本思想
回到分类的问题上,我们想要通过上面的公式解决具体的分类问题。首先,我们根据一般的分类问题将上面公式中提到的A和B具体化一下,我们指示A为样本,其包含样本所有的特征数据。B为分类的类别。为更好的对对应起来,我们用x代指一个样本数据,c代表一个分类类别。那么就有如下的贝叶斯公式:
这个公式的左边描述的是,在我们已知一个数据样本的情况下,其归属类别c的概率。很自然的我们就可以想到,将数据x和类别对应的一一计算,分别计算该样本在被分类到不同类别的概率,找到概率最大的那个类别,就是我们将要分类的类别了。
问题简化
确定解决的方向之后,因为需要实际的解决问题,我们当然希望计算的过程越简单越好,所以我们需要对问题模型进行适当的处理,而又尽量的保持原方法的理论准确率。
简化公式
公式方面,我们观察到P(x)和类别没有关系,也就是说对于任何类别的概率计算,p(x)都是一个常数,并不会影响最终的结果。所以我们可以将其从公式中删除掉,简化后得到下面的公式:
简化模型
从上面简化之后的公式中我们可以看出,其和联合分布其实有点类似
在实际情况中,如果考虑特征之间的关联性。我们通常没有办法直接计算
这样忽略属性之间的相关性在周老师的书中被称之为“属性条件独立性假设(attribute conditional independence assumption)”。基于这样的前提,我们继续使用联系分布公式,以第二个等式为例:
继续分解下去我们可以得到
通过上面最后一个公式,我们可以很方便的计算出在已知一个样本的情况下,其归属于不同类别的概率。
那现在就让我们来编程实现一下吧:
python实现
"""
朴素贝叶斯
基于贝叶斯公式,并添加了属性条件独立性假设。
"""
import numpy as np
from sklearn.datasets import load_iris
iris = load_iris() # 加载数据
y = iris.target
x = iris.data
def naive_bayes(x, y, predict):
unique_y = list(set(y))
label_num = len(unique_y)
sample_num, dim = x.shape
joint_p = [1] * label_num
# 把所有的类别都过一遍,计算P(c)
for (label_index, label) in enumerate(unique_y):
p_c = len(y[y == label]) / sample_num
for (feature_index, x_i) in enumerate(predict):
tmp = x[y == label]
joint_p[label_index] *= len(
[t for t in tmp[:, feature_index] if t == x_i]) / len(tmp)
joint_p[label_index] *= p_c
tmp = joint_p[0]
max_index = 0
for (i, p) in enumerate(joint_p):
if tmp < p:
tmp = p
max_index = i
return unique_y[max_index]
# 测试所用的数据为数据集中最后一个数据,类别为2
out = naive_bayes(x, y, np.array([5.9, 3., 5.1, 1.8]))
print(out)
好了大功告成~希望对大家有帮助~