贝叶斯分类器介绍及代码实现

 

一、引言


1.1 背景介绍

   贝叶斯分类器是一种基于贝叶斯定理的分类方法,它利用概率推理来预测样本的类别。它的背景可以追溯到18世纪末期,当时贝叶斯定理被提出,为概率论奠定了基础。随着计算机技术的发展,贝叶斯定理逐渐被应用于统计学和机器学习领域。在机器学习中,贝叶斯分类器被广泛应用于分类问题,如垃圾邮件过滤、情感分析、图像分类、语音识别等。


1.2 贝叶斯分类器的优势

    贝叶斯分类器的主要优势在于它能够利用先验信息来提高分类器的准确性。通过概率推理,贝叶斯分类器可以推断出样本属于某个类别的后验概率,从而更加准确地预测样本的类别。此外,贝叶斯分类器还具有稳健性,即对于一些具有不确定性的样本,贝叶斯分类器能够给出更加可靠的预测结果。

    除了传统的朴素贝叶斯分类器之外,贝叶斯分类器还包括了扩展贝叶斯分类器、贝叶斯网络等其他方法。这些方法在处理复杂的数据和问题时具有更好的表现,如能够处理数据不平衡问题、特征选择和特征缩放等问题。

二、贝叶斯定理与概率论基础


2.1 贝叶斯定理

    贝叶斯分类是以贝叶斯定理为基础的一种分类算法,其主要思想为:先验概率+新的数据=后验概率
   已知某条件概率,如何得到事件交换后的概率;即在已知P(B|A)的情况下求得P(A|B)。条件概率P(B|A)表示事件A已经发生的前提下,事件B发生的概率。其基本求解公式为:P(B|A)=P(AB)/P(A)。

贝叶斯定理:P(A|B)=eq?%5Cfrac%7BP%28B%7CA%29P%28A%29%7D%7BP%28B%29%7D

2.2 条件概率与联合概率

    条件概率是指在一个事件发生的前提下,事件发生的概率。例如,在扔硬币试验中,假设硬币正面朝上的条件下,硬币反面朝上的概率就是条件概率。

   联合概率是指两个或多个事件同时发生的概率。在贝叶斯分类器中,联合概率通常是指多个特征之间相互关联的概率。例如,在垃圾邮件过滤问题中,邮件的主题和正文内容可能存在关联,这些关联就是联合概率。

   全概率公式(Law of Total Probability)描述了一个事件在不同情况下发生的概率。全概率公式通常用于将一个复杂的事件分解成多个简单事件,并通过这些简单事件的概率来计算复杂事件的概率。假设有一组互斥且完备的事件 它们构成了样本空间 的一个划分,它们需要满足互斥性和完备性。

   全概率公式:P(B)=eq?%5Csum_%7Bi%7D%5E%7Bn%7DP%28B%7CAi%29P%28Ai%29

2.3 先验概率与后验概率

    先验概率(Prior Probability)是指在考虑任何特定证据之前,对一个事件发生的信念或估计。先验概率是基于以往的经验、知识或主观判断得到的。在概率论中,先验概率通常用符号 P(H)  来表示,其中H 代表一个假设或事件。先验概率提供了一个事件发生的基础概率度量。

     后验概率(Posterior Probability)是指在考虑了某些特定证据之后,对一个事件发生的信念或估计。后验概率是通过贝叶斯定理结合先验概率和新的证据概率来计算的。在概率论中,后验概率通常用符号 P(H|E)来表示,其中 E代表一组证据。后验概率提供了在观察到特定证据后,事件发生的更新后的概率度量。

     贝叶斯定理提供了一种从先验概率和证据概率推导后验概率的方法。贝叶斯定理的数学表达式如下:

P(H|E) =eq?%5Cfrac%7BP%28E%7CH%29%5Ccdot%20P%28H%29%7D%7BP%28E%29%7D 

其中:

        P(H|E)是在证据 E 发生的条件下,假设H发生的后验概率;
        P(E|H)是在假设 H发生的条件下,证据E发生的条件概率,也称为似然概率;
        P(H)是假设H发生的先验概率;
        P(E)是证据E发生的边缘概率,即在没有任何先验信息的情况下,证据E发生的概率。

     在实际应用中,先验概率和后验概率的差异可以这样理解:先验概率是你对一个事件发生之前所持有的信念,而后验概率是在你获得新的证据后,对你的信念进行修正后的概率。后验概率更接近于我们在实际生活中所说的“概率”,因为它考虑了所有的相关信息。

三、朴素贝叶斯分类器


3.1 朴素贝叶斯分类器的原理

    朴素贝叶斯分类器是一种基于贝叶斯定理和特征间独立假设的分类方法。它是一种有监督的学习算法,能够利用训练数据集学习一个分类规则,并据此对新的样本进行分类。

    朴素贝叶斯分类器的工作原理是基于贝叶斯定理和特征之间独立假设的。在给定样本的情况下,每个类别被赋予一个概率,这个概率是由样本的特征数据计算得出的。假设有n个特征,每个特征在各个类别中的表现有所不同,因此,对于一个给定的样本,各个类别被赋予不同的概率。朴素贝叶斯假设这些特征之间是相互独立的,因此可以简化计算过程。

    在垃圾邮件过滤系统中,朴素贝叶斯分类器可以用来识别垃圾邮件。通过对正常邮件进行训练,分类器可以学习到正常邮件的特征,并将其应用于对新邮件的分类。如果新邮件具有与训练数据集中的正常邮件相似的特征,则分类器将其分类为正常邮件;否则,将其分类为垃圾邮件。

3.2 特征条件独立假设

    特征条件独立假设是朴素贝叶斯分类器的关键假设之一,它是指在给定类别的情况下,特征之间相互独立。这意味着每个特征对于分类的贡献是相互独立的,即给定类别的情况下,特征之间的存在或取值不会相互影响。

    具体来说,假设有一个包含n个特征的样本,分别记作 X_1, X_2, ..., X_n,以及一个目标类别 C_k。特征条件独立假设可以表示为:

d22230450b7247df9a7fb7b96fcaab4a.jpeg

      这意味着在给定类别 C_k的情况下,每个特征的出现与其他特征的出现是独立的。换句话说,特征之间的联合概率可以简化为各个特征的条件概率的乘积。

     在实际应用中,朴素贝叶斯分类器通常假设特征条件独立性,以简化计算过程,并使得模型具有更好的效果。虽然这个假设在现实世界中并不总是成立,但在很多情况下,朴素贝叶斯分类器仍然能够取得良好的分类结果,尤其是在特征之间相关性较低的情况下。

3.3 朴素贝叶斯分类器的构建过程

朴素贝叶斯分类器的构建过程涉及以下步骤:

  • 数据准备:

   - 收集样本数据集:首先需要收集包含特征和类别标签的样本数据集,这些样本数据应该是已经标记好的,并且涵盖了不同类别的情况。
   - 数据预处理:对数据进行预处理,包括去除噪声、处理缺失值、进行特征选择等。确保数据的质量和完整性对于构建准确的分类器至关重要。

  • 特征提取与选择:

   - 根据问题需求和数据特点,选择合适的特征作为分类器的输入。这可能涉及到特征提取、特征转换或特征工程等步骤,以便将原始数据转化为分类器可以处理的格式。

  • 计算先验概率:

   - 对于每个类别C_k,计算其先验概率P(C_k),即在没有任何特征信息的情况下,每个类别出现的概率。通常通过计算训练数据集中每个类别出现的频率来估计先验概率。

  • 计算条件概率:

   - 对于每个特征 X_i,计算在给定类别 C_k的情况下,该特征的条件概率P(X_i | C_k)。这个步骤可能需要根据特征的类型(离散型或连续型)采用不同的方法进行计算。

  • 构建分类器模型:

   - 根据贝叶斯定理和特征条件独立假设,利用先验概率和条件概率构建朴素贝叶斯分类器模型。具体地,对于一个新的样本,通过计算每个类别的后验概率,选择具有最高后验概率的类别作为预测结果。

  • 模型评估与优化:

   - 使用测试数据集对构建的朴素贝叶斯分类器进行评估,以验证其分类性能。常用的评估指标包括准确率、精确率、召回率、F1 值等。
   - 根据评估结果对模型进行优化,可能包括调整特征选择、调整模型参数、处理过拟合或欠拟合等。

3.4 参数估计方法:极大似然估计与贝叶斯估计

     在贝叶斯分类器中,参数估计是关键步骤之一,它涉及到估计模型中的参数,如先验概率和条件概率。在实际应用中,常用的参数估计方法有极大似然估计(Maximum Likelihood Estimation, MLE)和贝叶斯估计(Bayesian Estimation)。

     极大似然估计(MLE)是一种基于最大似然原理的参数估计方法。它的基本思想是找到一组参数,使得给定参数下观察到的数据出现的概率最大。具体来说,对于一个含有未知参数的概率模型,极大似然估计通过最大化数据出现的似然函数来估计参数。

     贝叶斯估计(Bayesian Estimation)是一种基于贝叶斯定理的参数估计方法。它的基本思想是将参数视为随机变量,并利用贝叶斯定理来计算参数的后验概率分布。贝叶斯估计不仅考虑了数据对参数的影响,还考虑了先验信息对参数的影响。因此,贝叶斯估计可以提供参数的完整概率分布,而不仅仅是参数的点估计。

五、贝叶斯分类器的实现
本例使用高斯朴素贝叶斯分类器对iris数据集进行花分类,具体代码如下:

  1. load_data:加载数据。此方法的目的是为了将一个已知的鸢尾花数据集分成训练集和测试集,用于机器学习或深度学习的模型训练。首先加载数据,然后将数据分为特征和目标,最后将数据集分为训练集和测试集。这个函数可以被视为一个通用的数据处理函数,它可以在任何需要分割数据为训练集和测试集的场景中使用。
    ​
    # 定义一个方法load_data,该方法用于加载数据
    def load_data(self):
    
        # 使用datasets模块中的load_iris函数加载iris数据集,这是一个常用的小型数据集,包含了三种不同种类的鸢尾花的花瓣和萼片的长度和宽度
        data = datasets.load_iris()
    
        # 将数据集的目标值保存为iris_target
        iris_target = data.target
    
        # 将数据集的特征数据转化为pandas DataFrame格式,列名由数据集的特征名称给出
        iris_features = pd.DataFrame(data=data.data, columns=data.feature_names)
    
        # 使用train_test_split函数将数据集分割为训练集和测试集,测试集的比例为30%
        train_x, test_x, train_y, test_y = train_test_split(iris_features, iris_target, test_size=0.3, random_state=123)
    
        # 返回训练集的特征(train_x),测试集的特征(test_x),训练集的目标(train_y)和测试集的目标(test_y)
        return train_x, test_x, train_y, test_y
    
    ​

     

  2. train_model:训练一个高斯朴素叶贝斯模型。这个方法接受两个参数:`train_x`(特征数据)和`train_y`(目标标签)。它使用高斯朴素贝叶斯模型对训练数据进行训练,并返回训练好的分类器实例。这样,调用这个方法的人就可以使用训练好的分类器来对新的数据进行分类了。
    # 定义一个方法 train_model,该方法用于训练一个高斯朴素贝叶斯模型
    def train_model(self, train_x, train_y):
    
        # 创建一个高斯朴素贝叶斯分类器实例
        clf = GaussianNB()
    
        # 使用训练数据(特征和标签)来训练分类器
        clf.fit(train_x, train_y)
    
        # 返回训练好的分类器实例
        return clf
    
     
  3. proba_data:计算模型在测试集上的预测概率并评估性能。这个方法接受三个参数:`clf`(已训练好的分类器实例)、`test_x`(测试集特征数据)和`test_y`(测试集目标标签)。该方法使用分类器对测试集进行预测,并计算准确率。然后,它创建两个DataFrame,将真实标签、预测标签和概率进行组合。最后,它打印出测试集的准确率和部分预测结果,并返回准确率和预测结果DataFrame。
    # 定义一个方法 proba_data,该方法用于计算模型在测试集上的预测概率并评估性能
    def proba_data(self, clf, test_x, test_y):
    
        # 使用分类器对测试集进行预测
        y_predict = clf.predict(test_x)
    
        # 使用分类器预测测试集样本的类别概率
        y_proba = clf.predict_proba(test_x)
    
        # 计算模型在测试集上的准确率
        accuracy = metrics.accuracy_score(test_y, y_predict) * 100
    
        # 创建两个DataFrame,分别保存真实标签、预测标签和预测概率
        tot1 = pd.DataFrame([test_y, y_predict]).T
        tot2 = pd.DataFrame(y_proba).applymap(lambda x: '%.2f' % x)
    
        # 合并两个DataFrame,根据索引进行合并
        tot = pd.merge(tot1, tot2, left_index=True, right_index=True)
    
        # 为DataFrame添加列名
        tot.columns=['y_true', 'y_predict', 'predict_0', 'predict_1', 'predict_2']
    
        # 打印测试集的准确率和预测结果
        print('The accuracy of Testset is: %d%%' % (accuracy))
        print('The result of predict is: \n', tot.head())
    
        # 返回准确率和预测结果DataFrame
        return accuracy, tot
    

     

  4. exc_p:运行整个流程。这个方法执行了整个流程:首先,它调用 `load_data()` 方法来加载数据并获取训练集和测试集。接下来,它调用 `train_model()` 方法使用训练数据训练模型并得到训练好的分类器。最后,它调用 `proba_data()` 方法使用训练好的模型进行预测,并返回预测结果和性能评估。这个方法用于组织并调用其他方法,实现了一个完整的训练和预测流程。
    # 定义一个方法 exc_p,该方法用于执行整个流程:加载数据、训练模型和计算预测结果
    def exc_p(self):
    
        # 加载数据,获取训练集和测试集
        train_x, test_x, train_y, test_y = self.load_data()
    
        # 使用训练数据训练模型,得到训练好的分类器
        clf = self.train_model(train_x, train_y)
    
        # 使用训练好的模型进行预测,得到预测结果和性能评估
        res = self.proba_data(clf, test_x, test_y)
    
        # 返回预测结果
        return res
    

    完整代码:

    # -*- coding: utf-8 -*-
    import numpy as np
    import pandas as pd
    from sklearn import metrics
    from sklearn.naive_bayes import GaussianNB
    from sklearn.model_selection import train_test_split
    from sklearn import datasets
    
    class bayes_model():
        def __int__(self):
            pass
        def load_data(self):
            data = datasets.load_iris()
            iris_target = data.target
            iris_features = pd.DataFrame(data=data.data, columns=data.feature_names)
            train_x, test_x, train_y, test_y = train_test_split(iris_features, iris_target, test_size=0.3, random_state=123)
            return train_x, test_x, train_y, test_y
        def train_model(self, train_x, train_y):
            clf = GaussianNB()
            clf.fit(train_x, train_y)
            return clf
        def proba_data(self, clf, test_x, test_y):
            y_predict = clf.predict(test_x)
            y_proba = clf.predict_proba(test_x)
            accuracy = metrics.accuracy_score(test_y, y_predict) * 100
            tot1 = pd.DataFrame([test_y, y_predict]).T
            tot2 = pd.DataFrame(y_proba).applymap(lambda x: '%.2f' % x)
            tot = pd.merge(tot1, tot2, left_index=True, right_index=True)
            tot.columns=['y_true', 'y_predict', 'predict_0', 'predict_1', 'predict_2']
            print('The accuracy of Testset is: %d%%' % (accuracy))
            print('The result of predict is: \n', tot.head())
            return accuracy, tot
        def exc_p(self):
            train_x, test_x, train_y, test_y = self.load_data()
            clf = self.train_model(train_x, train_y)
            res = self.proba_data(clf, test_x, test_y)
            return res
    
    if __name__ == '__main__':
        bayes_model().exc_p()
    

     

 

  • 23
    点赞
  • 14
    收藏
    觉得还不错? 一键收藏
  • 1
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值