统计学习方法与Python实现(三)——朴素贝叶斯法

统计学习方法与Python实现(三)——朴素贝叶斯法

  iwehdio的博客园:https://www.cnblogs.com/iwehdio/

1、定义

  朴素贝叶斯法是基于贝叶斯定理与特征条件独立假设的分类方法。

  对于给定的训练数据集,首先基于特征条件独立假设学习输入输出的联合概率分布。然后基于此模型,对给定的输入x,利用贝叶斯定理求出后验概率最大的输出y,从而进行决策分类。

  朴素贝叶斯法学习到的是生成数据的机制,属于生成模型。

  设Ω为试验E的样本空间,A为E的事件,B1~Bn为Ω的一个划分,则有全概率公式:

2、学习与分类

  对于训练数据集:

  我们的目的是从训练集中学习到联合概率分布P(X, Y),为此先学习后验概率分布和条件概率分布。

  后验概率分布,即类标签Y的概率分布,条件概率分布即在类标签Y确定的情况下输入特征向量x的分布。

  从中学习后验概率分布:

  从中学习条件概率分布:

    

  条件概率分布的参数是指数级数量的,对其进行参数估计是不可能的。因此,对条件概率分布做独立性假设,认为输入特征向量x的各个分量是独立的,这也是“朴素”的含义。这样做简化了模型,但是也牺牲了分类的准确率。

  条件独立性假设:

  朴素贝叶斯法进行分类时,对于输入特征向量x,通过学习到的模型计算后验概率。主要是之前学习的后验概率和条件概率,带入全概率公式,可得输入x的条件下,输出y取各个值的概率,并且将概率最大的y作为分类结果。

  朴素贝叶斯法分类的基本公式为:

  朴素贝叶斯分类器为:

  分母为定值,则进一步简化可得:

3、分类方法的含义

  一般的分类方法都有损失函数的概念,优化的目标也是最小化损失函数。朴素贝叶斯法直接要求将实例分到后验概率最大的类中有何含义?实际上,这也等价于期望风险即损失函数最小化。

  如果对模型f(X)取0-1损失函数L(Y,f(X)),即分类正确损失L取0,分类错误L取1。则期望风险函数为:

  因为每个输入特征向量x是独立的,因此只需对每个X=x的实例进行极小化。

  即推导得到了后验概率最大化准则。

4、参数学习

  参数学习即确定每个先验概率和条件概率,一般用极大似然估计法。

  先验概率P(Y = ck)的极大似然估计是:

  条件概率(即Y取ck时X的第j个特征取第l个值的概率)的极大似然估计是:

  其中,函数I(.)表示当括号内的条件满足取1,不满足取0。

  朴素贝叶斯算法为:

  a、对于给定的训练数据集,计算先验概率和条件概率。

,  

  b、对于给定的实例x,计算

  c、确定实例x的类

5、贝叶斯估计

  极大似然估计可能会使所要估计的概率为0的情况,这时会导致计算条件概率时分母为0,使分类出现偏差。可以用贝叶斯估计来解决此问题,即在随机变量各个取值的聘书上加一个正数λ。λ取0时为极大似然估计,λ取1时为拉普拉斯平滑。贝叶斯估计下的条件概率为:

  贝叶斯估计下的先验概率为:

6、Python实现

  数据集选择mnist手写数字集,数据集中为0~255的整数,先读入数据并对其进行0-1二值化。并初始化数组记录条件概率和先验概率。

from tensorflow.keras.datasets import mnist
import numpy as np

(train_data, train_label), (test_data, test_label) =     mnist.load_data(r‘E:\code\statistical_learning_method\Data_set\mnist.npz‘)

# 训练集和测试集大小
train_length = 60000
test_length = 10000
size = 28 * 28      # 输入特征向量长度
data_kind = 10      # 分为几类
choice = 2          # 每个向量有几种取值
lam = 1             # 贝叶斯估计中的lamda

# 预处理数据
train_data = train_data[:train_length].reshape(train_length, size)
# 数据二值化
np.place(train_data, train_data > 0, 1)
train_label = np.array(train_label, dtype=‘int8‘)
train_label = train_label[:train_length].reshape(train_length, )

test_data = test_data[:test_length].reshape(test_length, size)
np.place(test_data, test_data > 0, 1)   # 数据二值化
test_label = np.array(test_label, dtype=‘int8‘)
test_label = test_label[:test_length].reshape(test_length, )

# 初始化数组记录条件概率和先验概率
P_con = np.zeros([data_kind, size, choice])
P_pre = np.zeros(data_kind)

  

  然后在训练集上进行学习,计算先验概率和条件概率。

# 计算先验概率
def compute_P_pre(label, P_init, lamda=1):

    pre = P_init
    for la in label:
        pre[int(la)] += 1

    pre += lamda

    return pre / (label.shape[0] + pre.shape[0] * lamda)

# 计算条件概率
def compute_P_con(data, label, P_init, lamda=1):

    con = P_init
    summ = np.zeros(P_init.shape[0])
    for index, value in enumerate(data):
        for jndex, dalue in enumerate(value):
            con[int(label[index]), jndex, int(dalue)] += 1
        summ[int(label[index])] += 1

    con += lamda
    summ += lamda * 2

    for index, value in enumerate(con):
        con[index] /= summ[index]

    return con

  最后,在测试集上进行测试。

# 进行测试
def Bayes_divide(pre, con, test, label):

    acc = 0
    ans = np.full(test.shape[0], -1)
    P_div = np.ones([test.shape[0], pre.shape[0]])
    for index, value in enumerate(test):
        for times in range(pre.shape[0]):
            for jndex, dalue in enumerate(value):
                P_div[index, times] *= con[times, jndex, int(dalue)]
            P_div[index, times] *= pre[times]

    for index, temp in enumerate(P_div):
        ans[index] = temp.argmax()
        if ans[index] == label[index]:
            acc += 1

    return acc / label.shape[0], ans

P_pre = compute_P_pre(train_label, P_pre, lamda=lam)
P_con = compute_P_con(train_data, train_label, P_con, lamda=lam)
acc, ans = Bayes_divide(P_pre, P_con, test_data, test_label)
print(‘acc‘, acc)

  lam=1时的测试结果为acc=0.8413。

  更改lam的值,lam=0时,acc=0.8410;lam=2时,acc=0.8411;lam=5时,acc=0.8407;lam=10时,acc=0.8399。总的而言影响不大。

7、生成模型

  因为朴素贝叶斯方法是生成模型,所以可以通过训练好的模型生成出模型学习到的特征,也就是生成模型认为最像某个数字的图像。最简单的思想就是,因为我们假设输入特征向量x的各个维度的值是独立的,所以可以输入一个初始向量,然后比较每个维度上取0或1时,模型输出的概率大小,然后将各个维度的值置为更大的概率所对应的值。代码实现如下:

from skimage import io
import matplotlib.pyplot as plt

# 测试输入数据被识别为goal的概率
def test(data0, goal, pre, con):

    P_gene = 1
    for index, value in enumerate(data0):
        P_gene *= con[goal, index, int(value)]
    P_gene *= pre[goal]

    return P_gene

# 初始化输入为全0向量
gene = np.zeros([data_kind, size])
for goals, sim in enumerate(gene):
    temp = sim
    # 遍历向量
    for index in range(sim.shape[0]):
        ans1 = test(temp, goals, P_pre, P_con)
        temp[index] = 1
        ans2 = test(temp, goals, P_pre, P_con)
        if ans1 > ans2:
            temp[index] = 0

# 画出生成的图像
for i in range(gene[:10].shape[0]):
    draw = gene[i][:, np.newaxis]
    draw = draw.reshape([28, 28])
    plt.subplot(1, 10, i+1)
    plt.axis(‘off‘)
    io.imshow(draw)
plt.tight_layout()

  

  最后的输出结果为:

参考:李航 《统计学习方法(第二版)》

iwehdio的博客园:https://www.cnblogs.com/iwehdio/

原文地址:https://www.cnblogs.com/iwehdio/p/12043821.html

时间: 2024-08-24 00:31:33

统计学习方法与Python实现(三)——朴素贝叶斯法的相关文章

统计学习方法 李航---第4章 朴素贝叶斯法

第4章 朴素贝叶斯法 朴素贝叶斯 (naive Bayes) 法是基于贝叶斯定理与特征条件独立假设的分类方法.对于给定的训练数据集,首先基于特征条件独立假设学习输入/输出的联合概率分布:然后基于此模型,对给定的输入x,利用贝叶斯定理求出后验概率最大的输出Y. 4.1 朴素贝叶斯法的学习与分类 基本方法 朴素贝叶斯法通过训练数据集学习X和Y的联合概率分布 P(X,Y). 具体地,学习以 下先验概率分布及条件概率分布. 先验概率分布 条件概率分布 条件概率分布有指数级数量的参数,其估计实际是不可行的

统计学习方法——朴素贝叶斯法、先验概率、后验概率

朴素贝叶斯法,就是使用贝叶斯公式的学习方法,朴素就是它假设输入变量(向量)的各个分量之间是相互独立的.所以对于分量之间不独立的分布,如果使用它学习和预测效果就不会很好. 简化策略 它是目标是通过训练数据集学习联合概率分布$P(X, Y)$用来预测.书上说,具体是先学习到先验概率分布以及条件概率分布,分别如下:(但我认为,直接学习$P(X, Y)$就行了,它要多此一举算出这两个再乘起来变成$P(X, Y)$,但其实计算量差不多,可能这样更好理解吧) $P(Y = c_k), k = 1, 2, 3

朴素贝叶斯法-后验概率最大化

接着上一篇的继续来写. 朴素贝叶斯法分类时,对给定的输入x,通过学习得到的模型计算后验概率分布P(Y=ck|X=x),然后将后验概率最大的类作为x的类输出.后验概率计算根据贝叶斯定理进行: P(Y=ck|X=x)=P(X=x|Y=ck)*P(Y=ck)/(sum (k) P(X=x|Y=ck)*P(Y=ck)) 最后化简成:y=arg max(ck)P(Y=ck)联乘P(X(j)=x(j)|Y=ck).

【资源分享】今日学习打卡--朴素贝叶斯法 (naive bayes classifier)

今日学习打卡,是一个非常简单的模型,朴素贝叶斯法(naive bayes classifier) 总得来说就是贝叶斯 + naive 通过,贝叶斯来计算事件发生概率: 然后,naive就是假设各个因素之间相互独立,互不影响. 在现实生活中,因素经常是有内在联系的.如:是否今天下雨,考虑因素有:气压,湿度,温度.实际上这些因素是有内在联系的,但是模型中假设它们相互独立,所以称为naive.这样,在计算中相当简单,且往往预测结果还算不错的. 链接: https://pan.baidu.com/s/1

4.朴素贝叶斯法

朴素贝叶斯(naive Bayes) 法是基于贝叶斯定理与特征条件独立假设的分类方法.对于给定的训练数据集, 首先基于特征条件独立假设学习输入/输出的联合概率分布: 然后基于此模型, 对给定的输入x, 利用贝叶斯定理求出后验概率最大的输出y. 朴素贝叶斯法实现简单, 学习与预测的效率都很高, 是一种常用的方法. 1. 朴素贝叶斯法的学习与分类基本方法训练数据集: 由X和Y的联合概率分布P(X,Y)独立同分布产生朴素贝叶斯通过训练数据集学习联合概率分布P(X,Y) ,      即先验概率分布:

吴裕雄--天生自然python机器学习:朴素贝叶斯算法

分类器有时会产生错误结果,这时可以要求分类器给出一个最优的类别猜测结果,同 时给出这个猜测的概率估计值. 概率论是许多机器学习算法的基础 在计算 特征值取某个值的概率时涉及了一些概率知识,在那里我们先统计特征在数据集中取某个特定值 的次数,然后除以数据集的实例总数,就得到了特征取该值的概率. 首先从一个最简单的概率分类器开始,然后给 出一些假设来学习朴素贝叶斯分类器.我们称之为“朴素”,是因为整个形式化过程只做最原始.最简单的假设. 基于贝叶斯决策理论的分类方法 朴素贝叶斯是贝叶斯决策理论的一部

朴素贝叶斯法

统计学习四:1.朴素贝叶斯

全文引用自<统计学习方法>(李航) 朴素贝叶斯(naive Bayes)法 是以贝叶斯定理为基础的一中分类方法,它的前提条件是假设特征条件相互独立.对于给定的训练集,它首先基于特征条件假设的前提条件,去学习输入与输出的条件概率分布,然后根据此分布模型,对给定的输入x,利用贝叶斯定理求出后验概率最大的输出y. 1.朴素贝叶斯的学习与分类 1.1 基本方法 假设输入空间\(X \subseteq R^n\)为n维向量的集合,输入空间为类标记集合\(Y=\{c_1,c_2,\cdots,c_K\}\

初识分类算法(3)-----朴素贝叶斯算法

1. 例子引入:如上篇的play or not 例子. 未知分类的样本:D:<A=sunny, B=cool, C=high ,D=strong>,  是 or 否? 我们要判断该样本的分类,即比较该样本属于是的概率大还是否的概率大 P(是/否|A=sunny, B=cool, C=high ,D=strong) P(是|A=sunny, B=cool, C=high ,D=strong)=P(是,(A=sunny, B=cool, C=high ,D=strong))/P(A=sunny,