贝叶斯分类器的python实现

本文介绍了贝叶斯分类器的实现原理,重点讨论了马氏距离在决策函数中的应用以及如何通过特征选择、先验概率估计和数据处理来提高分类性能。实验结果显示,特征向量的选择和预处理对分类效果至关重要,而精确的先验概率和考虑特征相关性的马氏距离有助于减小误差率。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

前言

这篇文章来自最近做的一个小的课程实验,写完了贴出来希望对大家能有帮助。
创作不易,如果有需要引用,希望大家标明原作者。

然后是,养成先赞后看的好习惯,仓库放这里。

实验原理:

  1. 贝叶斯分类器的实现。

    贝叶斯分类器的判决规则来自于贝叶斯决策论,原理在已知信息的基础上进行最小条件风险分类。

    贝叶斯公式表明,在已知一个样本点 ω \omega ω的特征值 x x x,和训练样本的先验概率 P ( ω i ) P(\omega_i) P(ωi)和类条件概率密度函数 p ( x ∣ ω i ) p(x|\omega_i) p(xωi)时,可计算出后验概率 P ( w i ∣ x ) P(w_i |x) P(wix)

P ( ω i ∣ x ) = p ( x ∣ ω i ) ∗ P ( ω i ) p ( x ) P(\omega_i |x)=\cfrac{p(x|\omega_i)*P(\omega_i)}{p(x)}\\ P(ωix)=p(x)p(xωi)P(ωi)
​ 后验概率表征的是当样本点 ω \omega ω的特征值为 x x x时,其属于 ω i \omega_i ωi的可能性大小。

​ 此时,分类行为的误差率 P ( e r r o r ) P(error) P(error)为选择另一半的概率。

​ 对分类行为的概率 P ( ω i ∣ x ) P(\omega_i|x) P(ωix)乘以选择类型的行为 α i \alpha_i αi的损失函数 λ ( α i ∣ ω i ) \lambda(\alpha_i|\omega_i) λ(αiωi)并积分构成条件风险 R ( α i ∣ ω i ) R(\alpha_i|\omega_i) R(αiωi)
R ( α i ∣ x ) = Σ j = 1 c λ ( α i ∣ ω i ) P ( ω i ∣ x ) R(\alpha_i|x)=\Sigma_{j=1}^{c}\lambda(\alpha_i|\omega_i)P(\omega_i|x) R(αix)=Σj=1cλ(αiωi)P(ωix)

​ 条件风险表征的是后验概率条件已知时,采取分类行为对应的行为损失,条件风险越小,可能性越大。

​ 将贝叶斯分类器抽象为以下组成部分:

部分组成
输入多个输入
判决函数多个类别的判别函数
输出分类结果

​ 贝叶斯分类器的核心是判别函数,对应 c c c个类的最小损失函数,用于判决样本点的类别。
g t ( x ) = m a x ( g j ( x ) ) → ω = ω t g_t(x)=max(g_j(x))\rightarrow \omega=\omega_t gt(x)=max(gj(x))ω=ωt
​ 在自然环境中,样本的类条件概率密度函数的似然函数是高斯函数,判决函数为
l n P ( ω i ) g i ( x ) = − 1 2 ( x − μ i ) T Σ i − 1 ( x − μ i ) − d 2 l n 2 π − 1 2 l n ∣ Σ i ∣ + l n P ( ω i ) {lnP(ωi)} g_i(x)=−\cfrac{1}{2}(x−μ_i)^TΣ^{−1}_{i}(x−μ_i)−\cfrac{d}{2}ln2π−\cfrac{1}{2}ln|Σ_i|+lnP(\omega_i) lnP(ωi)gi(x)=21(xμi)TΣi1(xμi)2dln2π21lnΣi+lnP(ωi)

​ 多项式第一项包含马氏距离,表征样本点与类别均值的相似性; d d d表示特征向量的维度,表征待分类样本的维度信息; Σ i \Sigma_i Σi表示类别 i i i的协方差矩阵,表征类别特征值的分散程度, P ( ω i ) P(\omega_i) P(ωi)表示先验概率。

  1. 马氏距离。

    马氏距离在以上判决函数中出现,是一种用于衡量两个样本之间的相似度或差异性的指标。计算马氏距离的原理是,在特征空间中,通过计算两个样本点之间的欧氏距离,然后乘以协方差矩阵的逆矩阵,再次与欧氏距离相乘得到。

m = ( x − μ i ) T Σ i − 1 ( x − μ i ) m = (x - \mu_i)^{T}\Sigma_i^{-1}(x-\mu_i) m=(xμi)TΣi1(xμi)
​ 其中, x x x表示该点的特征向量, μ i \mu_i μi表示该类别的均值向量, Σ i \Sigma_i Σi表示该类的协方差矩阵。

​ 马氏距离的实际意义是,马氏距离越小,说明所计算的样本点特征向量和类别均值相似度越高。马氏距离为零时,表明样本点与类别均值重合。

​ 在判别函数中使用马氏距离的好处是:首先,考虑了特征值之间的相关性,协方差矩阵的马氏距离通过协方差矩阵的逆矩阵进行加权,使分类器能根据训练数据自适应调整特征值的权值,其次,使用马氏距离降低特征维度,简化了计算模型。

代码实现

实验步骤

  1. 将已知的数据集输入对分类器进行训练,训练判决函数;

  2. 对新的样本点类别进行预测分类;

  3. 计算样本的经验训练误差;

  4. 调整先验概率,计算新的样本点到类别均值向量的马氏距离;

  5. 调整先验概率,对新的样本点进行分类。

实验代码

class BYES:

    # 构造函数
    # d         特征向量的维度
    # prior     先验概率
    # tra_data  训练数据
    # tar_lab   训练标签
    def __init__(self,d , prior, tra_data, tra_lab):

        self.d = d  # 特征值维度
        self.prior = prior  # 先验概率
        self.means = []  # 均值
        self.covariances = []  # 协方差矩阵
        self.cal_cov(tra_data, tra_lab)
        
        
    # 均值 and 协方差
    # tra_data  训练数据
    # tar_lab   训练标签
    def cal_cov(self, tra_data, tra_lab):
        for i in range(len(self.prior)):  # 遍历所有类别
            samples = [data for label, data in zip(tra_lab, tra_data) if label == i]
            samples = np.array(samples)  # 将样本转换成 numpy 数组

            mean = np.mean(samples, axis=0)  # 计算样本点的均值
            cov = np.dot((samples - mean).T, (samples - mean)) / (samples.shape[0] - 1)  # 计算样本点的协方差
            self.means.append(mean)
            self.covariances.append(cov)
            
            
    # 计算马氏距离
    def m_distance(self, x):
        m_dits = []
        for i in range(len(self.means)):
            mean = self.means[i]
            cov = self.covariances[i]
            diff = np.array(x) - mean  # 计算样本点与均值点的差异
            if len(diff.shape) == 1:
                diff = diff[:, np.newaxis]  # 将一维数据转换成列向量
            m_dit = np.dot(np.dot(diff.T, np.linalg.inv(cov)), diff)  # 马氏距离
            m_dit = m_dit.item()
            m_dits.append(m_dit)
        return m_dits
    
    
	# 判别函数
    def judge(self, x):  # x 样本点
        gs = []  # 存储判别函数的值
        m_dits = self.m_distance(x)  # 马氏距离
        for mean, m_dit, cov, prior in zip(self.means, m_dits, self.covariances, self.prior):  # 遍历
            det = np.linalg.det(cov)
            g = - 0.5 * m_dit - 0.5 * self.d * math.log(np.pi) - 0.5 * math.log(det) + math.log(prior)  # 计算判别函数的值
            gs.append(g)
        result = gs.index(max(gs))  # 获取最大值的索引
        return result
    
    
	# 预测函数
    def predict(self, test_data):  # test_data 测试样本
        pre_results = []
        for x in test_data:  # 遍历测试样本
            pre_result = self.judge(x)  # 获取判别结果
            pre_results.append(pre_result)
        print("预测结果", pre_results)
        return pre_results
    

    # 计算误差率
    def cal_error(self,test_data,test_lab):
        pre_results = self.predict(test_data)  # 获取预测结果
        count = 0
        for i, j in zip(pre_results, test_lab):
            if i != j:
                count += 1  # 比较预测结果与测试标签
        error = float(count / len(test_lab))  # 计算误差率
        print(error)
        return error

实验结论

结果太多,这里就浅贴几张,多的不放上来了,大家可以自己尝试一下。
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述

下面部分是分析总结的实验结论:

  1. 贝叶斯分类器对特征向量的选择是敏感的,为了获得更有效的分类结果,可以对训练样本进行的特征向量进行适当选择和预处理,这可以明显提高贝叶斯分类器的性能,得到更小的分类误差,降低分类偏差带来的损失。

  2. 贝叶斯分类器并不是特征向量维度越高越有效。在实际训练时,应该通过测试进行验证,而不是依靠直觉推测。

  3. 先验概率的估计对贝叶斯分类器非常重要的,在实际训练过程中应当通过技术手段,尽可能获得精确的先验概率估计,有效提高贝叶斯分类结果的正确性。

  4. 马氏距离对贝叶斯分类器的贡献,是考虑了特征向量之间的相关性,通过权值调整,有效降低了预测结果的误差率。因此选择更有效的数据处理方式,可以降低分类的误差率,提高分类性能。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值