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

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即为数学常数ereturn 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):"""初始化方法"""passdef _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_trainself.y_train = y_train#找出训练集 y_train 中有多少个不重复的类别标签,并将其存储在 self.classes 中self.classes = np.unique(y_train)   # 定义一个空列表,存放每个标签对应的四列X特征数据中,每一列X特征数据的均值和标准差self.parameters = []# 对 self.classes 中的类别进行遍历,并将索引和对应的元素值分别赋给变量 i 和 y_nowfor 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_nowfor 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.xdnf.cn/news/145076.html

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

相关文章

MySQL篇(窗口函数/公用表达式(CTE))(持续更新迭代)

目录 讲解一:窗口函数 一、简介 二、常见操作 1. sumgroup by常规的聚合函数操作 2. sum窗口函数的聚合操作 三、基本语法 1. Function(arg1,..., argn) 1.1. 聚合函数 sum函数:求和 min函数 :最小值 1.2. 排序函数 1.3. 跨行函数…

2024年港澳台华侨生联考分数线继续更新来啦

导读 在最近的一系列分享中,我们和大家一同分享了2024年港澳台华侨生联考的分数线。今天我们继续和大家一起分享一些2024年港澳台联考的高校录取分数线吧! 首都师范大学 首都师范大学和首都医科大学作为被低估的两所高校,这两年的分数线也是…

数据结构之二叉树(1)

数据结构之二叉树(1) 一、树 1、树的概念与结构 (1)树是一种非线性的数据结构,由n(n>0)个有限结点组成一个具有层次关系的集合。 (2)树有一个特殊的结点,叫做根结点&#xff…

【记录】C++学习路线

一、记录心得: 目前自己的状况是刚上大三,学校是双非一本,教的主流方向是 J A V A JAVA JAVA开发方向,还有就是嵌入式方向,这两个方向自己都不是很感兴趣,所以从大一开始就自学 C C C,加入 A…

图的应用(拓扑排序)

自己设计一个不少于6个结点的带权有向无环图,并画出其邻接矩阵的样子 用一维数组将你设计的有向无环图的邻接矩阵进行压缩存储 文字描述:基于你压缩存储的数组,如何判断结点 i、j 之间是否有边? 基于你设计的带权有向无环图&#…

flash_attention简要笔记

优化效果 原来,attention部分的计算量和中间激活占用显存的复杂度都是 O ( N 2 ) O(N^2) O(N2) 计算量部分原来QK矩阵乘和attn_scoreV矩阵乘的计算量,复杂度都是 O ( N 2 ) O(N^2) O(N2);中间激活因为中间有一个attn_score,所以复…

基于yolov8的战斗机类型识别检测系统python源码+onnx模型+评估指标曲线+精美GUI界面

【算法介绍】 YOLOv8是Ultralytics公司推出的最新一代对象检测模型,它在目标检测领域展现了前所未有的先进性能。基于YOLOv8的战斗机类型识别检测系统,通过结合深度学习技术和卷积神经网络(CNN),实现了对战斗机图像的…

八股文-多线程、并发

八股文-多线程、并发 最近学到了一种方法,可以用于简历项目经验编写以及面试题目的回答 STAR法则:在什么背景下,你需要解决什么问题,你做了啥,得到了什么结果 情境(Situation): 描…

软件测试分类篇(上)

目录 引言: 一、为什么要对软件测试进行分类 二、按照测试目标分类 1. 界面测试 2. 功能测试 3. 性能测试 4. 可靠性测试 5. 安全性测试 6. 易用性测试 三、按照执行方式分类 1. 静态测试 2. 动态测试 四、按照测试方法分类 1. 白盒测试 2. 黑盒测试 …

HTTP 教程

HTTP/HTTPS 简介 HTTP(Hypertext Transfer Protocol,超文本传输协议)和 HTTPS(Hypertext Transfer Protocol Secure,超文本传输安全协议)是用于在网络中传输信息的两种主要协议。它们定义了客户端和服务器…

10.1 溪降技术:通讯

目录 10.1 通讯概述观看视频课程电子书:通讯视觉信号想象一下…… 声音信号总结 10.1 通讯 概述 两名队友讨论下一个跳点 溪降是一项团队活动,需要团队成员之间良好的沟通。由于溪降所处的环境特性,往往使得声音通讯变得困难。环境可能非常嘈…

自动化测试常用函数

目录 一、元素的定位 1、cssSelector 2、xpath (1)xpath 语法 1、获取HTML页面所有的节点 2、获取HTML页面指定的节点 3、获取一个节点中的直接子节点 4、获取一个节点的父节点 5、实现节点属性的匹配 6、使用指定索引的方式获取对应的节点内容…

欧美海外仓系统有哪些服务商选择?

在跨境电商的全球化浪潮中,欧美市场以其成熟的电商生态和庞大的消费群体,成为了众多跨境卖家竞相争夺的高地。为了提升物流效率、降低成本并增强客户体验,海外仓成为了不可或缺的一环。而海外仓系统的选择,则直接关系到仓库的运营…

排序-----选择排序

首先介绍几种排序的分类: 选择排序是每次都遍历,标记出最小的元素,然后把它放在前面。 本文介绍优化后的版本:每次遍历标记出最小的和最大的元素,分别放到前面和后面。(注意这里是找到对应的下标&#xff0…

数据结构与算法——Java实现 6.递归

要学会试着安静下来 —— 24.9.17 一、递归的定义 计算机科学中,递归是一种解决计算问题的方法,其中解决方案取决于同一类问题的更小子集 说明: ① 自己调用自己,如果说每个函数对应着一种解决方案,自己调用自己意味着解决方案是…

2024/9/20 使用QT实现扫雷游戏

有三种难度初级6x6 中级10x10 高级16x16 完成游戏 游戏失败后&#xff0c;无法再次完成游戏&#xff0c;只能重新开始一局 对Qpushbutton进行重写 mybutton.h #ifndef MYBUTTON_H #define MYBUTTON_H #include <QObject> #include <QWidget> #include <QPus…

jdk版本更换以及遇到的问题略谈(以jdk1.8和jdk11为例)

目录 在我看来 遇到的问题 原因以及解决方法 方法一&#xff1a;禁止误改误删 方法二&#xff1a;bat文件驱动运行 方法三&#xff1a;cmd命令 方法四&#xff1a;修改注册表&#xff08;不推荐&#xff09; 最近在进行漏洞复现&#xff08;shiro550&#xff09;的时候&…

DAY20信息打点-红蓝队自动化项目资产侦察武器库部署企查产权网络空间

2.自动化-网络空间-AsamF 1.去GitHub上下载项目之后使用CMD打开 2.输入命令AsamF_windows_amd64.exe -v生成配置文件 3.AsamF会在~/.config/asamf/目录下生成config.json文件 C:\Users\Acer\.config\asamf 5.根据文档输入命令去查询所需信息&#xff08;已经没有用了&#x…

jeecg自定义sql查询,并使用高级查询的参数

jeecg框架的高级查询界面如下 后台代码&#xff1a; controller层&#xff1a; GetMapping(value "/list")public Result<IPage<Receiver>> queryPageList(Receiver receiver,RequestParam(name"pageNo", defaultValue"1") Integ…

进程和线程问题解答

线程和进程的概念、区别 进程是操作系统进行资源分配的基本单位&#xff0c;拥有独立的地址空间&#xff0c;包括代码、数据、堆、栈等。进程间的切换开销较大。 线程是进程中的一个执行单元&#xff0c;是系统中最小的执行单位&#xff0c;共享进程的资源&#xff0c;如代码…