机器学习算法与实践_03概率论与贝叶斯算法笔记

news2024/11/15 9:19:53

1、概率论基础知识介绍

人工智能项目本质上是一个统计学项目,是通过对 样本 的分析,来评估/估计 总体 的情况,与数学知识相关联

  • 高等数学 ——> 模型优化

  • 概率论与数理统计 ——> 建模思想

  • 线性代数 ——> 高性能计算

在机器学习中,许多算法都是基于概率模型进行构建的,这些模型使用概率来描述数据生成过程,从而能够对数据进行预测和分类,例如:

  • 朴素贝叶斯分类器:基于贝叶斯定理,使用概率来预测数据点的类别
  • 逻辑回归:虽然通常被视为线性分类器,但它本质上是一个概率模型,输出的是数据点属于某个类别的概率
  • 隐马尔可夫模型(HMMs):使用概率来描述状态转换和观测序列

所以,我们需要先了解概率论相关基础知识,为下面理解贝叶斯算法原理打下基础

1.1 概率与频率

在实际操作中,直接计算或得知某个事件的精确概率可能是困难的或不可能的,而频率作为一个可观测、可计算的量,为我们提供了一种近似估计概率的方法

1.1.1 定义

  • 概率(probability,又称或然率、置信度): 是数学中描述某个事件发生的可能性的量度,是一个理论上的度量,它通常是一个介于0和1之间的实数,其中0表示事件几乎不可能发生,1表示事件几乎肯定会发生

  • 频率(frequency): 是实际观测或实验中某一事件发生的次数与总试验次数之比,它是一个经验度量,反映了在一系列试验中事件实际发生的次数

1.1.2 用频率估概率

  • 大数定律:大数定律是概率论中的一个基本定理,它指出当试验次数足够多时,事件发生的频率将趋近于其真实概率,这意味着随着试验次数的增加,频率作为概率的估计会越来越准确

  • 实际应用:在实际应用中,尤其是数据科学和机器学习领域,我们经常使用频率来估计概率,例如:在训练模型时,我们可能使用大量数据来估计某个特征值出现的概率

  • 数据量与估计准确性:数据量越大,频率估计的准确性通常越高,这是因为大数定律保证了频率随试验次数增加而趋于稳定

1.1.3 工程实践中的处理

  • 数据驱动的决策:在工程实践中,尤其是在数据量很大的情况下,我们经常直接使用频率作为概率的替代,这种方法在处理大量数据时尤其有效,因为大数定律确保了估计的稳定性和可靠性

  • 模型训练:在机器学习模型训练中,我们通常使用大量数据来估计模型参数,这些参数的概率分布往往通过频率来估计

  • 统计推断:统计推断中,频率也被用来估计总体参数,例如:样本均值的分布可以用来估计总体均值

1.1.4 注意事项

  • 有限样本偏差:在样本量较小的情况下,频率可能不是概率的良好估计,因为小样本更易受到随机波动的影响

  • 数据质量:数据的质量和代表性也会影响频率估计的准确性,数据集中的偏差或不准确可能导致估计结果不可靠

1.2 概率的基本特性

  • 非负性: 概率的非负性是指任何事件发生的概率都不会是负数,即:

  • 规范性: 概率的规范性(或归一性)是指在一个完整样本空间内所有可能事件的概率之和等于1。这适用于所有可能的事件集合,包括所有可能的单一事件和它们的组合。对于一个包含所有可能结果的样本空间,存在:

    其中:表示样本空间中的第个事件,是事件的总数

  • 单调性:如果事件(即:当事件 A 发生时,事件 B 也同样会发生),那么

  • 可加性:对于两个互斥事件 A 和 B (即:它们不能同时发生),存在:

  • 连续性:对于一系列事件,如果这些事件是互斥的,并且覆盖了整个样本空间,那么对于任意事件包含在这些事件中的概率可以通过极限来定义

1.3 概率的计算方法

1.3.1 离散型变量

(1)特点: 有限个状态,状态之间无大小、程度等概念,状态之间是严格对立的

(2)示例:

  • 鸢尾花有山鸢尾、杂色鸢尾、长鞘鸢尾等不同类型的品种
  • 交通信号灯有红、绿、黄不同的颜色
  • 人类有男、女不同的性别
  • 骰子有1、2、3、4、5、6不同的点数

(3)编码: 连续型变量是指有限个状态,而状态大多数不是数值类型的数据,不易进行处理,所以需要对其进行编码(编码就是为了将非数值型数据转换为机器学习算法可以处理的数值型数据,方便进行处理)

离散型变量的常用编码方法分为Zero index编码和One hot编码这两种

  • ①Zero Index编码: 也称为索引编码或标签编码,是一种将类别变量转换为从0开始的连续整数的方法,每个类别被赋予一个唯一的整数标签。

    特点

    • 简单:实现简单,易于理解和操作。

    • 连续性:编码是连续的,从0开始,但这种连续性并不代表类别之间的任何顺序或等级关系。

    • 大小无内涵:编码的大小没有数学意义,例如,编码为1和编码为4的类别是平等的,它们之间没有内在的比较意义。

应用场景

  • 适用于那些类别之间没有顺序或等级关系的情况。

  • 常用于机器学习模型中,如决策树、随机森林等。

  • ②One Hot编码: 也称为一位有效编码,是一种将类别变量转换为二进制向量的方法,每个类别都分别由一个长度等于类别数的向量表示,并且在此向量中只有一个位置为1,其余位置均为0。

    特点

    • 向量表示:每个类别由一个唯一的二进制向量表示,向量中的1表示该类别的存在。

    • 平等性:所有类别在向量空间中是平等的,没有大小或顺序之分。

    • 无序性:One Hot编码不包含任何类别之间的顺序或等级信息。

应用场景

  • 适用于需要明确区分类别,且类别之间没有顺序或等级关系的情况。

  • 常用于自然语言处理、推荐系统、神经网络等场景。

  • ③示例: 假设有一个数据集,包含三个类别:苹果、香蕉、樱桃,则使用这两种编码方式可以表示如下:

    Zero Index编码

    • 苹果:0

    • 香蕉:1

    • 樱桃:2

One Hot编码

  • 苹果:[1, 0, 0]

  • 香蕉:[0, 1, 0]

  • 樱桃:[0, 0, 1]

(4)计算方法: 先转换为频率,然后数个数

  • 示例:求iris数据集中,三种鸢尾花出现的概率
# 引入load_iris,获取鸢尾花数据集
from sklearn.datasets import load_iris
X, y = load_iris(return_X_y=True)

# 查看所有y值(可以发现分别用0、1、2这三个编码代表了三种鸢尾花类型)
print(y)

# 求概率(可以发现在这个数据集中,三种鸢尾花出现的概率都是1/3,非常均衡,属于一个理想的数据集)
P0 = (y == 0).mean()
P1 = (y == 1).mean()
P2 = (y == 2).mean()

print(f"标签编码为0的鸢尾花出现的概率为:{P0}")
print(f"标签编码为1的鸢尾花出现的概率为:{P1}")
print(f"标签编码为2的鸢尾花出现的概率为:{P2}")

1.3.2 连续型变量

(1)特点: 无限个数值,数值之间有大小、程度等差异,数值之间的内涵是一致的

(2)例如:

  • 一个人的身高是一个连续变量,可以是 1.75 米、1.76 米、1.77 米等
  • 一个人的体重也是一个连续变量,可以有无数个可能的值
  • 气温是一个连续变量,可以是 23.5 度、23.6 度、23.7 度等
  • 商品的价格是一个连续变量,可以有小数点后的值
  • 一个人每天花费在上班通勤上的时间是一个连续变量,可以是 30.5 分钟、31 分钟、31.5 分钟等

(3)编码: 连续型变量通常不需要像离散型变量那样的编码,因为它们已经是数值型,可以直接用于大多数机器学习算法。然而,在某些情况下,对连续型变量进行特定的处理或转换可能是有益的,这些处理包括:

  • 归一化(Normalization):将数据缩放到一个特定的范围,通常是 [0, 1],或者转换为具有零均值和单位方差的形式,这有助于加快学习算法的收敛速度,并提高模型的性能

  • 标准化(Standardization):将数据转换为均值为 0,标准差为 1 的形式,这种方法对于假设数据分布为正态分布的算法(如线性回归、逻辑回归等)尤其重要

  • 离散化(Discretization):将连续变量分割成若干个区间或桶,将其转换为离散型变量,这在某些分类任务中可能有用,尤其是当连续变量的每个区间对预测结果有明显区别时

  • 特征工程:通过数学变换(如对数变换、平方根变换等)来改善模型的性能,或者创建新的特征,这些新特征可能更好地捕捉数据中的模式

  • 异常值处理:识别并处理异常值,因为极端的数值可能会对模型的性能产生负面影响

  • 降维:使用主成分分析(PCA)或其他方法来减少数据的维度,同时尽可能保留原始数据的信息

(4)计算方法: 通过对概率密度函数(PDF,Probability Density Function)的积分来求解

(概率密度函数是概率的导数,概率是概率密度函数的积分)

①计算步骤(理论数学):

  • 先找到概率密度函数(在概率论和统计学中,有多种类型的概率密度函数,用于描述不同类型连续型随机变量的概率分布,高斯分布函数就是其中的一种)

  • 再对概率密度函数求积分

高斯分布函数(也称为正态分布函数)是特定形式的一种概率密度函数,它描述了正态分布的变量的概率密度,其公式如下:(其中,μ是均值,可以用mean方法计算得出;σ是标准差,可以用std方法计算得出)

用matplotlib绘制高斯函数的图像:

# 引入numpy,为高斯分布函数提供π、e的值
import numpy as np
# 引入matplotlib的pyplot函数,为绘图做准备
from matplotlib import pyplot as plt
# 如果是用pycharm等后端工具绘图,需要指定图形用户界面工具包
# import matplotlib
# matplotlib.use('TkAgg')  # 设置绘图后端为 TkAgg

# 从-5到5,等差数列,生成100个x均分点
x = np.linspace(start=-5, stop=5, num=100)
# 创建高斯分布函数,设定返回结果为高斯分布函数的方程式
def normal(x, mu=0, sigma=1):
    # np.pi即为圆周率π,np.exp即为数学常数e
    return 1 / (((2 * np.pi) ** 0.5) * sigma) * np.exp(-((x - mu) ** 2) / (2 * (sigma ** 2)))
# 用plot方法折线图,label是图线的标签
plt.plot(x, normal(x, mu=0, sigma=1), label="$\mu=0,\sigma =1$")
plt.plot(x, normal(x, mu=1, sigma=1), label="$\mu=1,\sigma =1$")
plt.plot(x, normal(x, mu=0, sigma=2), label="$\mu=0,\sigma =2$")
# 用grid方法显示图像网格
plt.grid()
# 用legend方法显示图线的标签
plt.legend()
# 用show方法显示图表
plt.show()

绘制出来的图像如下图所示:(在任何一点的概率都是0,但中间的概率明显应该比两边的概率大,所以理论数学的计算是不可行的)

②计算步骤(工程数学):

  • 直接把连续型变量的分布看作是高斯分布

  • 直接拿概率密度函数的值代替概率

  • 示例:根据一天中每个小时的温度,来计算22摄氏度出现的概率

# 引入numpy,创建高斯分布函数,并返回函数的值
import numpy as np
def gauss(x, mu, sigma):
    return 1/(np.sqrt(2*np.pi)*sigma) * np.exp(-(x - mu)**2 / (2*sigma**2))

# 采样一天中24小时的温度数据
temperature = np.array([10, 9, 8, 7, 6, 5, 6, 7, 9, 12, 15, 18, 20, 22, 23, 22, 21, 19, 17, 15, 13, 11, 10, 9])
# 求均值
mu = temperature.mean()
# 求标准差
sigma = temperature.std()
# 求温度为22的概率
P_22 = gauss(x=22, mu=mu, sigma=sigma)
print(f'温度为22的概率为:{P_22}')

2、条件概率与贝叶斯算法基本介绍

2.1 定义

条件概率以贝叶斯定理为理论基础,指的是某事件已发生的前提下,另一事件发生的概率

例如: 假设我在做一道单选题,有A、B、C、D四个选项,但我不知道这道题的答案,只能猜一个选项

一般情况下,我能猜对答案的概率是1/4

此时,如果我已经排除了A、D两个选项,那么会存在以下情况:

  • A、D两项确实是错误答案,应该被排除,则在我已经排除A、D两项的前提下,我从B、C里面再去猜答案,猜对的概率是1/2

  • A、D两项其实有正确答案,不该被排除,则在我已经排除A、D两项的前提下,我从B、C里面再去猜答案,猜对的概率是0

2.2 公式推导

根据贝叶斯定理,B事件发生的前提下,A事件发生的概率为:

同理可得,A事件发生的前提下,B事件发生的概率为:

根据等式的乘法性质,可得:

因此:

进一步可推导出:

其中:

  • P(A∣B) 是后验概率(Posterior Probability),指的是在事件 B 发生的前提下,事件 A 发生的概率。
  • P(B∣A) 是似然概率(Likelihood),指的是在事件 A 发生的前提下,事件 B 发生的概率。
  • P(A) 是先验概率(Prior Probability),指的是在没有考虑任何额外证据或信息之前,某个事件发生的概率
  • P(B) 是边缘概率(Marginal Probability),指的是在考虑所有可能情况下,某个事件发生的总概率

在上述公式中,将A、B分别替换为机器学习模型中的标签y、特征X,可得:在特征X出现的前提下,标签y出现的概率为

由于条件概率模型通常是处理分类问题的,在分类问题中,同一组特征X,一般只会对应同一个标签y(如:y0、y1、y2...),所以上面公式可进一步推导出:

...

在处理分类问题时,条件概率模型不是非要算出一个具体的概率值,而是通过概率密度函数来比较大小,将概率最大的,视为特征样本的标签

既然是比大小,那么上面的公式应当还能化简,即:由于上面的式子都有除以P(X),所以与其比较除以P(X)之后的大小,不如直接比较不除以P(X)时的大小

例如:因为9>6>3,所以当9、6、3分别除以2之后,这个大小关系依然一致(9/2 > 6/2 > 3/2)

因此,上面的公式可进一步化简得:

...

由于X代表的是一组特征,包含X1,X2,X3,X4,...,Xn,所以可进一步推导得出:

...

因为X1、X2、X3、X4、...、Xn是独立特征,所以可以最终推导得出:

...

2.3 贝叶斯算法

贝叶斯算法是基于贝叶斯定理的一类算法,它提供了一种计算条件概率的方法,即:在已知其他事件发生的情况下,某事件发生的概率

朴素贝叶斯(Naive Bayes)和高斯贝叶斯(Gaussian Naive Bayes)都属于贝叶斯算法,但它们在处理数据和假设数据分布方面有所不同:

(1)朴素贝叶斯(Naive Bayes)

  • 是一种基于贝叶斯定理的简单概率分类器,它假设所有特征之间相互独立
  • 适用于文本分类、垃圾邮件检测等任务
  • 可以用于多种类型的数据分布,如多项式分布、伯努利分布等

(2)高斯贝叶斯(Gaussian Naive Bayes)

  • 是朴素贝叶斯的一个特例,它假设数据特征遵循高斯(正态)分布
  • 通常用于连续数据的特征,因为高斯分布是连续的
  • 在特征值近似正态分布时效果最好

3、高斯贝叶斯算法实践

以鸢尾花的分类任务为例,下面介绍通过高斯贝叶斯算法来进行预测

# 引入load_iris,获取鸢尾花数据集
from sklearn.datasets import load_iris
X,y = load_iris(return_X_y=True)

# 引入train_test_split,将数据集切分为训练集和测试集
from sklearn.model_selection import train_test_split
X_train, X_test, y_train, y_test = train_test_split(X, y, test_size=0.2, random_state=0)

# 在python中,sklearn.naive_bayes是 sklearn 库中的一个模块,它实现了多种朴素贝叶斯分类器
# 在sklearn.naive_bayes中,GaussianNB就是用于实现高斯贝叶斯算法的分类器,所以我们需要先对其进行引入
from sklearn.naive_bayes import GaussianNB

# GaussianNB是一个类,所以应该用面向对象的思想对其进行使用(即:实例化对象)
gnb = GaussianNB()

# 训练模型时,需要将训练集(X_train和y_train)作为参数传入fit方法中
gnb.fit(X=X_train, y=y_train)
# 预测模型时,需要将测试集(X_test)作为参数传入predict方法中
y_pred = gnb.predict(X=X_test)

#将y_test与y_pred进行对比,看有多少个数是相等的,就可以得到预测的准确率
acc = (y_pred == y_test).mean()
print(f"预测的准确率为:{acc}")

4、自定义高斯贝叶斯分类器

在本文第三章节的高斯贝叶斯算法实践中,用的都是sklearn库中的标准模块和函数,为了理解其中的实现原理(贝叶斯公式和高斯函数都有运用),本章节将模仿sklearn,自定义一个高斯贝叶斯分类器

# 引入numpy,为高斯分布函数提供π、e的值,以及提供一些其他的科学计算方法
import numpy as np

# 定义一个MyGaussianNB类,实现高斯贝叶斯算法的fit和predict方法
class MyGaussianNB(object):
    """
        自定义高斯贝叶斯分类算法
    """
    def __init__(self):
        """
            初始化方法
        """
        pass

    def _gauss(self, x, mu, sigma):
        """
            定义一个内部方法,返回高斯分布函数值
        """
        return 1 / (((2 * np.pi) ** 0.5) * sigma) * np.exp(-((x - mu) ** 2) / (2 * (sigma ** 2)))

    def fit(self, X_train, y_train):
        """
            训练过程(高斯贝叶斯算法不是懒惰学习的方式,有训练过程)
            训练逻辑:
                Step1:将训练集中所有的y标签去重,得到总共有多少个y标签(比如鸢尾花标准数据集中有3个y标签)
                Step2:将训练集中的X样本按照这3个标签做切分,划分出每一类标签对应的所有X样本
                Step3:对于每一类标签的所有X样本,求出每一列特征的均值和标准差
                    标签值为0对应的所有X样本,第1列特征的均值和标准差、第2列特征的均值和标准差、第3列特征的均值和标准差、第4列特征的均值和标准差
                    标签值为1对应的所有X样本,第1列特征的均值和标准差、第2列特征的均值和标准差、第3列特征的均值和标准差、第4列特征的均值和标准差
                    标签值为2对应的所有X样本,第1列特征的均值和标准差、第2列特征的均值和标准差、第3列特征的均值和标准差、第4列特征的均值和标准差
                最终得到的结果示例:
                # [[{'mean': 5.02051282051282, 'std': 0.3596148132908301}, {'mean': 3.4025641025641025, 'std': 0.37654786836856813}, {'mean': 1.4615384615384615, 'std': 0.14253273958653637}, {'mean': 0.24102564102564095, 'std': 0.10553392629362397}], 
                #  [{'mean': 5.886486486486486, 'std': 0.513684182165048}, {'mean': 2.7621621621621624, 'std': 0.32244953625825373}, {'mean': 4.216216216216216, 'std': 0.4795907678447316}, {'mean': 1.324324324324324, 'std': 0.2018902637511686}], 
                #  [{'mean': 6.638636363636365, 'std': 0.6238501820042829}, {'mean': 2.9886363636363638, 'std': 0.328367801745452}, {'mean': 5.5659090909090905, 'std': 0.5426966262094999}, {'mean': 2.0318181818181817, 'std': 0.2538545819171491}]]                    
        """
        self.X_train = X_train
        self.y_train = y_train

        #找出训练集 y_train 中有多少个不重复的类别标签,并将其存储在 self.classes 中
        self.classes = np.unique(y_train)   

        # 定义一个空列表,存放每个标签对应的四列X特征数据中,每一列X特征数据的均值和标准差
        self.parameters = []

        # 对 self.classes 中的类别进行遍历,并将索引和对应的元素值分别赋给变量 i 和 y_now
        for i, y_now in enumerate(self.classes):
            # X_train[y_train == y_now],是将训练集中的 y 标签分别于当前循环中的标签做对比,找到有哪些组X是对应此标签的
            X_classes = X_train[y_train == y_now]
            # 往self.parameters中添加一个空列表,用于存放当前标签对应的所有训练集X样本中每一列特征的均值和标准差数据
            self.parameters.append([])

            # X_classes.T是将X_classes进行转置,方便求其每一列的均值和标准差
            # 假设X_classes=[[5.2 3.5 1.5 0.2]
            #               [5.7 3.8 1.7 0.3]
            #               [4.7 3.2 1.3 0.2]
            #               [5.  3.5 1.6 0.6]
            #               [5.4 3.7 1.5 0.2]
            #               [4.8 3.1 1.6 0.2]
            #               [5.3 3.7 1.5 0.2]
            #               [4.3 3.  1.1 0.1]
            #               [5.4 3.4 1.7 0.2]
            #               [5.7 4.4 1.5 0.4]
            #               [4.6 3.1 1.5 0.2]
            #               [4.6 3.4 1.4 0.3]
            #               [4.8 3.  1.4 0.1]
            #               [5.1 3.8 1.6 0.2]
            #               [4.8 3.4 1.6 0.2]
            #               [4.5 2.3 1.3 0.3]
            #               [4.9 3.  1.4 0.2]
            #               [4.4 3.2 1.3 0.2]]
            # 则X_classes.T=[[5.2 5.7 4.7 5.  5.4 4.8 5.3 4.3 5.4 5.7 4.6 4.6 4.8 5.1 4.8 4.5 4.9 4.4]
            #               [3.5 3.8 3.2 3.5 3.7 3.1 3.7 3.  3.4 4.4 3.1 3.4 3.  3.8 3.4 2.3 3.  3.2]
            #               [1.5 1.7 1.3 1.6 1.5 1.6 1.5 1.1 1.7 1.5 1.5 1.4 1.4 1.6 1.6 1.3 1.4 1.3]
            #               [0.2 0.3 0.2 0.6 0.2 0.2 0.2 0.1 0.2 0.4 0.2 0.3 0.1 0.2 0.2 0.3 0.2 0.2]]
            # 转置之后,遍历获取的就是每一个特征列的数据,需要分别求其均值和标准差,并添加到self.parameters中
            for col in X_classes.T:
                parameters = {"mean": col.mean(), "std": col.std()}
                self.parameters[i].append(parameters)

    def predict(self, X_test):
        """
            推理过程(此处是重点)
        """
        # 大致流程:
        # Step1:将测试数据集中的每一个特征值都与分别于训练数据集中每一列特征值的均值和标准差一一对应,求得当前测试数据对于每一类标签的概率密度函数值
        # Step2:取概率密度函数最大的值对应的标签值,作为当前测试数据预测出来的标签

        # 具体实现:
        # 1、定义一个列表,用于接收每个测试集预测出来的标签值
        results = []

        # 2、循环遍历测试集中的每一个样本,分别求其对应的标签值,并存放值results中
        for x_test in X_test:
            # 定义一个空列表,用于存放每个P(y_train_i|x_test_j)的概率结果
            posteriors = []

            # 对 self.classes 中的类别进行遍历,并将索引和对应的元素值分别赋给变量 i 和 y_now
            for i, y_now in enumerate(self.classes):
                # 计算先验概率P(y_train_i)
                prior = (self.y_train == y_now).mean()
                # 重置似然概率
                likelihood = 1
                # self.parameters=[[{'mean': 5.02051282051282, 'std': 0.3596148132908301}, {'mean': 3.4025641025641025, 'std': 0.37654786836856813}, {'mean': 1.4615384615384615, 'std': 0.14253273958653637}, {'mean': 0.24102564102564095, 'std': 0.10553392629362397}], 
                #                  [{'mean': 5.886486486486486, 'std': 0.513684182165048}, {'mean': 2.7621621621621624, 'std': 0.32244953625825373}, {'mean': 4.216216216216216, 'std': 0.4795907678447316}, {'mean': 1.324324324324324, 'std': 0.2018902637511686}], 
                #                  [{'mean': 6.638636363636365, 'std': 0.6238501820042829}, {'mean': 2.9886363636363638, 'std': 0.328367801745452}, {'mean': 5.5659090909090905, 'std': 0.5426966262094999}, {'mean': 2.0318181818181817, 'std': 0.2538545819171491}]]
                # 以i=0为例:
                # i=0 ==> self.parameters[i]=[{'mean': 5.02051282051282, 'std': 0.3596148132908301}, {'mean': 3.4025641025641025, 'std': 0.37654786836856813}, {'mean': 1.4615384615384615, 'std': 0.14253273958653637}, {'mean': 0.24102564102564095, 'std': 0.10553392629362397}]
                #     ==> j=0,param={'mean': 5.02051282051282, 'std': 0.3596148132908301},x_test[j]="测试集中第1列特征x的数据"
                #         j=1,param={'mean': 3.4025641025641025, 'std': 0.37654786836856813},x_test[j]="测试集中第2列特征x的数据"
                #         j=2,param={'mean': 1.4615384615384615, 'std': 0.14253273958653637},x_test[j]="测试集中第3列特征x的数据"
                #         j=3,param={'mean': 0.24102564102564095, 'std': 0.10553392629362397},x_test[j]="测试集中第4列特征x的数据"
                for j, param in enumerate(self.parameters[i]):
                    # 计算似然概率:P(x_test_1|y_train_i) · P(x_test_2|y_train_i) · P(x_test_3|y_train_i) · P(x_test_4|y_train_i)
                    likelihood *= self._gauss(x_test[j], param["mean"], param["std"])

                # 计算后验概率,P(x_test_1|y_train_i) · P(x_test_2|y_train_i) · P(x_test_3|y_train_i) · P(x_test_4|y_train_i) · P(y_train_i)
                posterior =  likelihood * prior
                # 将计算得到的概率都添加到posteriors列表中
                posteriors.append(posterior)

            # np.argmax是 NumPy 库中的一个函数,用于返回数组中最大值的索引
            # 由于每个概率的索引正好对应一个y标签,所以,可通过最大概率值的索引,从self.classes中获取到索引对应的标签值,作为预测值(y_pred),并添加到results结果集中
            results.append(self.classes[np.argmax(posteriors)])

        # 返回每个样本对应的标签值,方便后续与实际值之间做分析
        return results

使用自定义的高斯贝叶斯分类器处理【鸢尾花(iris)识别】任务:

# 引入load_iris,获取鸢尾花数据集
from sklearn.datasets import load_iris
X,y = load_iris(return_X_y=True)

# 引入train_test_split,将数据集切分为训练集和测试集
from sklearn.model_selection import train_test_split
X_train, X_test, y_train, y_test = train_test_split(X, y, test_size=0.2, random_state=0)

# 调用自定义的高斯贝叶斯分类器,分别传入训练集和测试集
mygnb = MyGaussianNB()
mygnb.fit(X_train=X_train, y_train=y_train)
y_pred = mygnb.predict(X_test=X_test)

# 比较测试集的标签值和预测出来的标签值,计算预测的准确率
acc = (y_pred == y_test).mean()
print(f"预测的准确率为:{acc}")

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/2150925.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

EI-BISYNCH协议,欧陆2000系列设备读取数据

EI-Bisynch是一种基于ANSI X3.28-2.5 A4标准的专有协议,用于消息框架。尽管其名称中包含“Bisynch”,但它实际上是一种基于ASCII的异步协议。数据通过7位数据位、偶校验和1个停止位进行传输。 4.1 术语解释 4.1.1 地址 每个仪器都有一个可配置的地址&…

Leetcode面试经典150题-172.阶乘后的零

给定一个整数 n ,返回 n! 结果中尾随零的数量。 提示 n! n * (n - 1) * (n - 2) * ... * 3 * 2 * 1 示例 1: 输入:n 3 输出:0 解释:3! 6 ,不含尾随 0示例 2: 输入:n 5 输出&a…

linux之mysql安装

1:mysql安装包下载 下载地址 可私信我直接获取安装包 2:linux下wget命令下载 下载地址 wget https://dev.mysql.com/get/Downloads/MySQL-5.7/mysql-5.7.24-linux-glibc2.12-x86_64.tar.gz3:手动安装 将自己的安装包上传到对应的位置 解压 压缩包 使用命令 tar -zxvf mysql-5.7…

chorme浏览器 您的连接不是私密连接

‌当浏览器显示“您的连接不是私密连接,攻击者可能会试图从 localhost 窃取您的信息(例如:密码、消息或信用卡信息)”的警告时,这通常意味着您正在尝试访问的网站的安全证书存在问题,可能是因为它使用的是自…

Windows安装启动:stable-diffusion-webui,AIGC大模型文生图、文生视频,Python

Windows安装启动:stable-diffusion-webui,AIGC大模型文生图、文生视频,Python stable-diffusion-webui是github上的AIGC开源项目,地址: https://github.com/AUTOMATIC1111/stable-diffusion-webuihttps://github.com/AUTOMATIC1…

移动技术开发:简单文本编辑器

1 实验名称 简单文本编辑器 2 实验目的 掌握基本布局管理器的使用方法和基本控件的使用方法&#xff0c;以及事件监听处理的使用方法 3 实验源代码 布局文件代码&#xff1a; <?xml version"1.0" encoding"utf-8"?> <LinearLayout xmlns:an…

图片压缩格式自适应,真的很省流量!

导语 图片&#xff0c;作为信息传递的重要载体&#xff0c;其格式日益多样化。不管是 PC 端还是移动端&#xff0c;图片一直都是流量消耗的大户。在互联网的应用中&#xff0c;用户会上传大量的图片&#xff0c;而且访问频繁&#xff0c;如果这些图片都以传统方式存在服务器磁盘…

用AI制作专属欧美漫画头像!FLUX大模型-漫画情侣lora应用教程

​ ​ 新上线了一个漫画风格的lora《漫画情侣&#xff08;欧美黄金时代风&#xff09;v1.0》 感兴趣的朋友可以去下载使用&#xff0c;下载是免费的。 下面跟大家说一下这个lora的特点、使用方法以及这个lora的延伸应用&#xff1a;欧美漫画头像制作 lora风格特点 欧美漫画/人…

Leetcode面试经典150题-97.交错字符串

给定三个字符串 s1、s2、s3&#xff0c;请你帮忙验证 s3 是否是由 s1 和 s2 交错 组成的。 两个字符串 s 和 t 交错 的定义与过程如下&#xff0c;其中每个字符串都会被分割成若干 非空 子字符串 &#xff1a; s s1 s2 ... snt t1 t2 ... tm|n - m| < 1交错 是…

C++入门基础知识八

1.介绍new与delete 1.malloc和free是函数&#xff0c;new和delete是操作符 2.malloc申请的空间不会初始化&#xff0c;new可以初始化 3.malloc申请空间失败时&#xff0c;返回的是NULL&#xff0c;因此必须判空&#xff0c;new不需要&#xff0c;但是new需要捕获异常 4.申请…

【例题】lanqiao4403 希尔排序模板题

插入排序每次只能将数据移动一位。 已知插入排序代码为&#xff1a; def insert_sort(a):for i in range(1,len(a)):ji-1while j>0 and a[j]>a[i]:a[j1]a[j]j-1a[j1]a[i]return a希尔排序在插入排序的基础上&#xff0c;将数据移动n/2,n/4,…,1位。 for i in range(ga…

某东不固定大小旋转验证码识别

注意,本文只提供学习的思路,严禁违反法律以及破坏信息系统等行为,本文只提供思路 如有侵犯,请联系作者下架 旋转验证码基本是旋转小图到一定的角度去匹配大图的,通常的旋转验证码,中间缺口图部分大小固定,但是在某东上,大小不固定,部分数据集如下: 结合之前的旋转验证…

09.20 C++对C的扩充以及C++中的封装、SeqList

SeqList.h #ifndef SEQLIST_H #define SEQLIST_H#include <iostream> #include<memory.h> #include<stdlib.h> #include<string.h>using namespace std;//typedef int datatype; //类型重命名 using datatype int;//封装一个顺序表 class Seq…

.ipynb 图解介绍,轻松入门,提升效率

目录 01 使用jupyter遇到的问题1.1 Python requires ipykernel installed or requires an update 1.1.1 查询所有内核 1.1.2 选择对应的Python版本 02 理解jupyter规则 2.1 系统命令 01 使用jupyter遇到的问题 1.1 Python requires ipykernel installed or requires an up…

MyBatis 基本操作 - XML版

目录 配置xml文件 一&#xff0c;查询 - Select 1.1 全列查询 1.2 赋值问题 二&#xff0c;新增 - insert 2.1 使用对象插入 2.2 获取主键 三&#xff0c;删除 - delete 四&#xff0c;修改 - update 配置xml文件 <?xml version"1.0" encoding"U…

全国自闭症寄宿学校:为孩子提供全方位关怀

在自闭症儿童教育的广阔领域中&#xff0c;全国范围内的寄宿学校如同一座座灯塔&#xff0c;照亮了这些特殊孩子前行的道路。它们不仅提供了专业的教育服务&#xff0c;更以无微不至的关怀&#xff0c;为孩子们构建了一个温暖的家。在广州这座充满温情的城市&#xff0c;星贝育…

【Verilog学习日常】—牛客网刷题—Verilog快速入门—VL20

数据选择器实现逻辑电路 描述 请使用此4选1数据选择器和必要的逻辑门实现下列表达式。 数据选择器的逻辑符号如下图&#xff1a; 数据选择器代码如下&#xff0c;可在本题答案中添加并例化此数据选择器。 module data_sel(input S0 ,input S1 …

2024.9.20 Python模式识别新国大EE5907,PCA主成分分析,LDA线性判别分析,GMM聚类分类,SVM支持向量机

1.PCA 主成分分析用于特征提取、可视化和分类 根据要求&#xff0c;我在第一个代码框中完成了从指定路径提取图像数据&#xff0c;将其转换为灰度图像并将其展平。在这里&#xff0c;我将数字 88 设置为我的照片的标签&#xff0c;然后将所有 10 张照片传入代码。然后我定义了…

java之杨辉三角问题

给定一个非负整数 numRows&#xff0c;生成「杨辉三角」的前 numRows 行。 在「杨辉三角」中&#xff0c;每个数是它左上方和右上方的数的和。 如何实现呢&#xff1f; 思路&#xff1a;首先&#xff0c;我们可以将杨辉三角视作i行j列的二维数组。除了第一行和第二行之外&am…

✨机器学习笔记(五)—— 神经网络,前向传播,TensorFlow

Course2-Week1: https://github.com/kaieye/2022-Machine-Learning-Specialization/tree/main/Advanced%20Learning%20Algorithms/week1机器学习笔记&#xff08;五&#xff09; 1️⃣神经网络&#xff08;Neural Network&#xff09;2️⃣前向传播&#xff08;Forward propaga…