【机器学习-监督学习】朴素贝叶斯

news2024/9/19 17:39:07

在这里插入图片描述

【作者主页】Francek Chen
【专栏介绍】 ⌈ ⌈ Python机器学习 ⌋ ⌋ 机器学习是一门人工智能的分支学科,通过算法和模型让计算机从数据中学习,进行模型训练和优化,做出预测、分类和决策支持。Python成为机器学习的首选语言,依赖于强大的开源库如Scikit-learn、TensorFlow和PyTorch。本专栏介绍机器学习的相关算法以及基于Python的算法实现。
【GitCode】专栏资源保存在我的GitCode仓库:https://gitcode.com/Morse_Chen/Python_machine_learning。

文章目录

    • 一、贝叶斯决策论
    • 二、极大似然估计
    • 三、朴素贝叶斯分类器
    • 四、动手实现朴素贝叶斯分类器
    • 五、Sklearn中的朴素贝叶斯
      • (一)实现垃圾短信分类
      • (二)三类朴素贝叶斯模型比较


  贝叶斯分类是一类分类算法的总称,这类算法均以贝叶斯定理为基础,所以统称为贝叶斯分类。朴素贝叶斯是一种贝叶斯分类算法,在许多场合可以与决策树和神经网络分类算法相媲美。图1展示了贝叶斯原理、贝叶斯分类和朴素贝叶斯三者之间的关系。

在这里插入图片描述

图1 贝叶斯原理、贝叶斯分类和朴素贝叶斯的关系

  朴素贝叶斯分类模型是一种简单的构造分类器的方法。朴素贝叶斯分类模型是将问题分为特征向量和决策向量两类,并假设问题的特征向量都是相互独立地作用于决策向量的,即问题的特征之间都是互不相关的。尽管有这样过于简单的假设,但朴素贝叶斯分类模型能指数级降低贝叶斯网络构建的复杂性,同时还能较好地处理训练样本的噪声和无关属性,所以朴素贝叶斯分类模型仍然在很多现实问题中有着高效的应用,例如入侵检测和文本分类等领域。目前许多研究学者也在致力于改善特征变量间的独立性的限制使得朴素贝叶斯分类模型可以应用到更多问题上。

一、贝叶斯决策论

  贝叶斯决策论(Bayesian decision theory)是概率框架下实施决策的基本方法。对分类任务来说,在所有相关概率都己知的理想情形下,贝叶斯决策论考虑如何基于这些概率和误判损失来选择最优的类别标记。下面我们以多分类任务为例来解释其基本原理。

  假设有 N N N种可能的类别标记,即 Y = { c 1 , c 2 ⋯   , c N } \mathcal Y=\{c_1,c_2\cdots,c_N\} Y={c1,c2,cN} λ i j \lambda_{ij} λij是将一个真实标记为 c j c_j cj的样本误分类为 c i c_i ci所产生的损失。基于后验概率 P ( c i ∣ x ) P(c_i|\boldsymbol x) P(cix)可获得将样本 x \boldsymbol x x分类为 c i c_i ci所产生的期望损失(expected loss),即在样本 x \boldsymbol x x上的“条件风险”(conditional risk) R ( c i ∣ x ) = ∑ j = 1 N λ i j P ( c j ∣ x ) R(c_i|\boldsymbol x)=\sum_{j=1}^N\lambda_{ij}P(c_j|\boldsymbol x) R(cix)=j=1NλijP(cjx) 我们的任务是寻找一个判定准则 h : X → Y h:\mathcal X\rightarrow\mathcal Y h:XY 以最小化总体风险 R ( h ) = E x [ R ( h ( x ) ∣ x ) ] R(h)=\mathbb E_{\boldsymbol x}\left[R(h(\boldsymbol x)|\boldsymbol x)\right] R(h)=Ex[R(h(x)x)] 显然,对每个样本 x \boldsymbol x x,若 h h h能最小化条件风险 R ( h ( x ) ∣ x ) R(h(\boldsymbol x)|\boldsymbol x) R(h(x)x),则总体风险 R ( h ) R(h) R(h)也将被最小化。这就产生了贝叶斯判定准则(Bayes decision rule):为最小化总体风险,只需在每个样本上选择那个能使条件风险 R ( c ∣ x ) R(c|\boldsymbol x) R(cx)最小的类别标记,即 h ∗ ( x ) = arg min ⁡ c ∈ Y R ( c ∣ x ) h^*(\boldsymbol x)=\argmin_{c\in\mathcal Y}R(c|\boldsymbol x) h(x)=cYargminR(cx) 此时, h ∗ h^* h称为贝叶斯最优分类器(Bayes optimal classifier),与之对应的总体风险 R ( h ∗ ) R(h^*) R(h)称为贝叶斯风险(Bayes risk)。 1 − R ( h ∗ ) 1-R(h^*) 1R(h) 反映了分类器所能达到的最好性能,即通过机器学习所能产生的模型精度的理论上限。

  具体来说,若目标是最小化分类错误率,则误判损失 λ i j \lambda_{ij} λij可写为
λ i j = { 0 , if   i = j ; 1 , otherwise \lambda_{ij}=\begin{cases}0,&\text{if} \ \ i=j; \\ 1,&\text{otherwise}\end{cases} λij={0,1,if  i=j;otherwise 此时条件风险 R ( c ∣ x ) = 1 − P ( c ∣ x ) R(c|\boldsymbol x)=1-P(c|\boldsymbol x) R(cx)=1P(cx) 于是,最小化分类错误率的贝叶斯最优分类器为 h ∗ ( x ) = arg max ⁡ c ∈ Y P ( c ∣ x ) h^*(\boldsymbol x)=\argmax_{c\in\mathcal Y}P(c|\boldsymbol x) h(x)=cYargmaxP(cx) 即对每个样本 x \boldsymbol x x,选择能使后验概率 P ( c ∣ x ) P(c|\boldsymbol x) P(cx)最大的类别标记。

  不难看出,欲使用贝叶斯判定准则来最小化决策风险,首先要获得后验概率 P ( c ∣ x ) P(c|\boldsymbol x) P(cx)。然而,在现实任务中这通常难以直接获得。从这个角度来看,机器学习所要实现的是基于有限的训练样本集尽可能准确地估计出后验概率 P ( c ∣ x ) P(c|\boldsymbol x) P(cx)。大体来说,主要有两种策略:给定 x \boldsymbol x x,可通过直接建模 P ( c ∣ x ) P(c|\boldsymbol x) P(cx)来预测 c c c,这样得到的是“判别式模型”(discriminative models);也可先对联合概率分布 P ( x , c ) P(\boldsymbol x,c) P(x,c)建模,然后再由此获得 P ( c ∣ x ) P(c|\boldsymbol x) P(cx),这样得到的是“生成式模型”(generative models)。显然,前面介绍的决策树、BP神经网络、支持向量机等,都可归入判别式模型的范畴。对生成式模型来说,必然考虑 P ( c ∣ x ) = P ( x , c ) P ( x ) P(c|\boldsymbol x)=\frac{P(\boldsymbol x,c)}{P(\boldsymbol x)} P(cx)=P(x)P(x,c)

  基于贝叶斯定理, P ( c ∣ x ) P(c|\boldsymbol x) P(cx)可写为 P ( c ∣ x ) = P ( c ) P ( x ∣ c ) P ( x ) P(c|\boldsymbol x)=\frac{P(c)P(\boldsymbol x|c)}{P(\boldsymbol x)} P(cx)=P(x)P(c)P(xc) 其中, P ( c ) P(c) P(c)是类“先验”(prior)概率; P ( x ∣ c ) P(\boldsymbol x|c) P(xc)是样本 x \boldsymbol x x相对于类标记 c c c类条件概率(class-conditional probability),或称为“似然”(likelihood); P ( x ) P(\boldsymbol x) P(x)是用于归一化的“证据”(evidence)因子。对给定样本 x \boldsymbol x x,证据因子 P ( x ) P(\boldsymbol x) P(x)与类标记无关,因此估计 P ( c ∣ x ) P(c|\boldsymbol x) P(cx)的问题就转化为如何基于训练数据 D D D来估计先验 P ( c ) P(c) P(c)和似然 P ( x ∣ c ) P(\boldsymbol x|c) P(xc)

  类先验概率 P ( c ) P(c) P(c)表达了样本空间中各类样本所占的比例,根据大数定律,当训练集包含充足的独立同分布样本时, P ( c ) P(c) P(c)可通过各类样本出现的频率来进行估计。

  对类条件概率 P ( x ∣ c ) P(\boldsymbol x|c) P(xc)来说,由于它涉及关于 x \boldsymbol x x所有属性的联合概率,直接根据样本出现的频率来估计将会遇到严重的困难。例如,假设样本的 d d d个属性都是二值的,则样本空间将有 2 d 2^d 2d种可能的取值,在现实应用中,这个值往往远大于训练样本数 m m m,也就是说,很多样本取值在训练集中根本没有出现,直接使用频率来估计 P ( x ∣ c ) P(\boldsymbol x|c) P(xc)显然不可行,因为“未被观测到”与“出现概率为零”通常是不同的。

二、极大似然估计

  估计类条件概率的一种常用策略是先假定其具有某种确定的概率分布形式,再基于训练样本对概率分布的参数进行估计。具体地,记关于类别 c c c的类条件概率为 P ( x ∣ c ) P(\boldsymbol x|c) P(xc),假设 P ( x ∣ c ) P(\boldsymbol x|c) P(xc)具有确定的形式并且被参数向量 θ c \boldsymbol\theta_c θc唯一确定,则我们的任务就是利用训练集 D D D估计参数 θ c \boldsymbol\theta_c θc。为明确起见,我们将 P ( x ∣ c ) P(\boldsymbol x|c) P(xc)记为 P ( x ∣ θ c ) P(\boldsymbol x|\boldsymbol\theta_c) P(xθc)

  事实上,概率模型的训练过程就是参数估计(parameter estimation)过程。对于参数估计,统计学界的两个学派分别提供了不同的解决方案:频率主义学派(Frequentist)认为参数虽然未知,但却是客观存在的固定值,因此,可通过优化似然函数等准则来确定参数值;贝叶斯学派(Bayesian)则认为参数是未观察到的随机变量,其本身也可有分布,因此,可假定参数服从一个先验分布,然后基于观测到的数据来计算参数的后验分布。本节介绍源自频率主义学派的极大似然估计(Maximum Likelihood Estimation,简称MLE),这是根据数据采样来估计概率分布参数的经典方法。

  令 D c D_c Dc表示训练集 D D D中第 c c c类样本组成的集合,假设这些样本是独立同分布的,则参数 θ c \boldsymbol\theta_c θc对于数据集 D c D_c Dc的似然是 P ( D c ∣ θ c ) = ∏ x ∈ D c P ( x ∣ θ c ) P(D_c|\boldsymbol\theta_c)=\prod_{\boldsymbol x\in D_c}P(\boldsymbol x|\boldsymbol\theta_c) P(Dcθc)=xDcP(xθc) θ c \boldsymbol\theta_c θc进行极大似然估计,就是去寻找能最大化似然 P ( D c ∣ θ c ) P(D_c|\boldsymbol\theta_c) P(Dcθc)的参数值 θ ^ c \hat{\boldsymbol\theta}_c θ^c。直观上看,极大似然估计是试图在 θ c \boldsymbol\theta_c θc所有可能的取值中,找到一个能使数据出现的“可能性”最大的值。

  上式中的连乘操作易造成下溢,通常使用对数似然(log-likelihood)
L L ( θ c ) = log ⁡ P ( D c ∣ θ c ) = ∑ x ∈ D c log ⁡ P ( x ∣ θ c ) \begin{aligned} LL(\boldsymbol\theta_c) &= \log P(D_c|\boldsymbol\theta_c) \\[1ex] &= \sum_{\boldsymbol x\in D_c}\log P(\boldsymbol x|\boldsymbol\theta_c) \end{aligned} LL(θc)=logP(Dcθc)=xDclogP(xθc) 此时参数 θ c \boldsymbol\theta_c θc的极大似然估计 θ ^ c \hat{\boldsymbol\theta}_c θ^c θ ^ c = arg max ⁡ θ c L L ( θ c ) \hat{\boldsymbol\theta}_c=\argmax_{\boldsymbol\theta_c}LL(\boldsymbol\theta_c) θ^c=θcargmaxLL(θc)

  例如,在连续属性情形下,假设概率密度函数 p ( x ∣ c ) ∼ N ( μ c , σ c 2 ) p(\boldsymbol x|c)\sim \mathcal N(\boldsymbol\mu_c,\boldsymbol\sigma^2_c) p(xc)N(μc,σc2),则参数 μ c \boldsymbol\mu_c μc σ c 2 \boldsymbol\sigma^2_c σc2的极大似然估计为
μ ^ c = 1 ∣ D c ∣ ∑ x ∈ D c x σ ^ c 2 = 1 ∣ D c ∣ ∑ x ∈ D c ( x − μ ^ c ) ( x − μ ^ c ) T \begin{aligned} \hat{\boldsymbol\mu}_c &= \frac{1}{|D_c|}\sum_{\boldsymbol x\in D_c}\boldsymbol x \\[1ex] \hat{\boldsymbol\sigma}^2_c &= \frac{1}{|D_c|}\sum_{\boldsymbol x\in D_c}(\boldsymbol x-\hat{\boldsymbol\mu}_c)(\boldsymbol x-\hat{\boldsymbol\mu}_c)^{\mathrm T} \end{aligned} μ^cσ^c2=Dc1xDcx=Dc1xDc(xμ^c)(xμ^c)T 也就是说,通过极大似然法得到的正态分布均值就是样本均值,方差就是 ( x − μ ^ c ) ( x − μ ^ c ) T (\boldsymbol x-\hat{\boldsymbol\mu}_c)(\boldsymbol x-\hat{\boldsymbol\mu}_c)^{\mathrm T} (xμ^c)(xμ^c)T 的均值,这显然是一个符合直觉的结果。在离散属性情形下,也可通过类似的方式估计类条件概率。

  需注意的是,这种参数化的方法虽能使类条件概率估计变得相对简单,但估计结果的准确性严重依赖于所假设的概率分布形式是否符合潜在的真实数据分布。在现实应用中,欲做出能较好地接近潜在真实分布的假设,往往需在一定程度上利用关于应用任务本身的经验知识,否则若仅凭“猜测”来假设概率分布形式,很可能产生误导性的结果。

三、朴素贝叶斯分类器

  不难发现,基于贝叶斯公式 P ( c ∣ x ) = P ( c ) P ( x ∣ c ) P ( x ) \begin{aligned}P(c|\boldsymbol x)=\frac{P(c)P(\boldsymbol x|c)}{P(\boldsymbol x)}\end{aligned} P(cx)=P(x)P(c)P(xc) 来估计后验概率 P ( c ∣ x ) P(c|\boldsymbol x) P(cx)的主要用难在于:类条件概率 P ( x ∣ c ) P(\boldsymbol x|c) P(xc)是所有属性上的联合概率,难以从有限的训练样本直接估计而得。为避开这个障碍,朴素贝叶斯分类器(naïve Bayes classifier)采用了“属性条件独立性假设”(attribute conditional independence assumption):对已知类别,假设所有属性相互独立。换言之,假设每个属性独立地对分类结果发生影响。

  基于属性条件独立性假设,后验概率公式 P ( c ∣ x ) = P ( c ) P ( x ∣ c ) P ( x ) \begin{aligned}P(c|\boldsymbol x)=\frac{P(c)P(\boldsymbol x|c)}{P(\boldsymbol x)}\end{aligned} P(cx)=P(x)P(c)P(xc) 可重写为 P ( c ∣ x ) = P ( c ) P ( x ∣ c ) P ( x ) = P ( c ) P ( x ) ∏ i = 1 d P ( x i ∣ c ) P(c|\boldsymbol x)=\frac{P(c)P(\boldsymbol x|c)}{P(\boldsymbol x)}=\frac{P(c)}{P(\boldsymbol x)}\prod_{i=1}^dP(x_i|c) P(cx)=P(x)P(c)P(xc)=P(x)P(c)i=1dP(xic) 其中 d d d为属性数目, x i x_i xi x \boldsymbol x x在第 i i i个属性上的取值。

  由于对所有类别来说 P ( x ) P(\boldsymbol x) P(x)相同,因此基于公式 h ∗ ( x ) = arg max ⁡ c ∈ Y P ( c ∣ x ) h^*(\boldsymbol x)=\argmax\limits_{c\in\mathcal Y}P(c|\boldsymbol x) h(x)=cYargmaxP(cx) 的贝叶斯判定准则有 h n b ( x ) = arg max ⁡ c ∈ Y P ( c ) ∏ i = 1 d P ( x i ∣ c ) h_{nb}(\boldsymbol x)=\argmax_{c\in\mathcal Y}P(c)\prod_{i=1}^dP(x_i|c) hnb(x)=cYargmaxP(c)i=1dP(xic) 这就是朴素贝叶斯分类器的表达式。

  显然,朴素贝叶斯分类器的训练过程就是基于训练集 D D D来估计类先验概率 P ( c ) P(c) P(c),并为每个属性估计条件概率 P ( x i ∣ c ) P(x_i|c) P(xic)

  令 D c D_c Dc表示训练集 D D D中第 c c c类样本组成的集合,若有充足的独立同分布样本,则可容易地估计出类先验概率 P ( c ) = ∣ D c ∣ ∣ D ∣ P(c)=\frac{|D_c|}{|D|} P(c)=DDc 对离散属性而言,令 D c , x i D_{c,x_i} Dc,xi表示 D c D_c Dc中在第 i i i个属性上取值为 x i x_i xi的样本组成的集合,则条件概率 P ( x i ∣ c ) P(x_i|c) P(xic)可估计为 P ( x i ∣ c ) = ∣ D c , x i ∣ ∣ D c ∣ P(x_i|c)=\frac{|D_{c,x_i}|}{|D_c|} P(xic)=DcDc,xi 对连续属性可考虑概率密度函数,假定 p ( x i ∣ c ) ∼ N ( μ c , i , σ c , i 2 ) p(x_i|c)\sim \mathcal N(\mu_{c,i},\sigma^2_{c,i}) p(xic)N(μc,i,σc,i2),其中 μ c , i \mu_{c,i} μc,i σ c , i 2 \sigma^2_{c,i} σc,i2分别是第 c c c类样本在第 i i i个属性上取值的均值和方差,则有 p ( x i ∣ c ) = 1 2 π σ c , i e − ( x i − μ c , i ) 2 2 σ c , i 2 p(x_i|c)=\frac{1}{\sqrt{2\pi}\sigma_{c,i}}\text{e}^{-\frac{(x_i-\mu_{c,i})^2}{2\sigma_{c,i}^2}} p(xic)=2π σc,i1e2σc,i2(xiμc,i)2 上式也被称为高斯朴素贝叶斯。特征的可能性(即概率)假设为高斯分布。

  为了避免其他属性携带的信息被训练集中未出现的属性值“抹去”,在估计概率值时通常要进行“平滑”(smoothing),常用拉普拉斯修正(Laplacian correction)。具体来说,令 N N N表示训练集 D D D中可能的类别数, N i N_i Ni表示第 i i i个属性可能的取值数,则对类先验概率 P ( c ) = ∣ D c ∣ ∣ D ∣ \begin{aligned}P(c)=\frac{|D_c|}{|D|}\end{aligned} P(c)=DDc 和条件概率 P ( x i ∣ c ) = ∣ D c , x i ∣ ∣ D c ∣ \begin{aligned}P(x_i|c)=\frac{|D_{c,x_i}|}{|D_c|}\end{aligned} P(xic)=DcDc,xi 分别修正,形成多项分布朴素贝叶斯
P ^ ( c ) = ∣ D c ∣ + 1 ∣ D ∣ + N P ^ ( x i ∣ c ) = ∣ D c , x i ∣ + 1 ∣ D c ∣ + N i \begin{aligned} \hat P(c) &= \frac{|D_c|+1}{|D|+N} \\[2ex] \hat P(x_i|c) &= \frac{|D_{c,x_i}|+1}{|D_c|+N_i} \end{aligned} P^(c)P^(xic)=D+NDc+1=Dc+NiDc,xi+1 显然,拉普拉斯修正避免了因训练集样本不充分而导致概率估值为零的问题,并且在训练集变大时,修正过程所引入的先验(prior)的影响也会逐渐变得可忽略,使得估值渐趋向于实际概率值。

  在现实任务中朴素贝叶斯分类器有多种使用方式。例如,若任务对预测速度要求较高,则对给定训练集,可将朴素贝叶斯分类器涉及的所有概率估值事先计算好存储起来,这样在进行预测时只需“查表”即可进行判别;若任务数据更替频繁,则可采用“懒惰学习”(lazy learning)方式,先不进行任何训练,待收到预测请求时再根据当前数据集进行概率估值;若数据不断增加,则可在现有估值基础上,仅对新增样本的属性值所涉及的概率估值进行计数修正即可实现增量学习。

  根据分析,朴素贝叶斯分类流程如图2所示。

在这里插入图片描述

图2 朴素贝叶斯分类流程

四、动手实现朴素贝叶斯分类器

  手机与电脑的普及使得我们每个人每天都可以接收大量的信息,然而其中不乏有一些垃圾信息可能浪费我们的注意力和时间,因此找到一种方法过滤垃圾信息是有必要的。可以通过对收到的信息进行分类来过滤垃圾信息,那么垃圾信息识别问题就变为了一个分类问题。解决分类问题的算法有很多,如逻辑回归、决策树和随机森林等。然而垃圾信息识别过程中不得不处理文本信息,相应的算法必须具备处理文本的能力。“贝叶斯推断”是处理这类问题的一个很好的方法,一方面其分类效果相对突出,另一方面这种方法具有自学习的能力,能够在不断的分类过程中提升子集的准确率。

  使用朴素贝叶斯法训练垃圾邮件分类的过程:(1)解析训练集种所有邮件并提取每一个词;(2)统计每一个词出现在正常邮件和垃圾邮件的词频。可以根据这个初步统计结果实现一个垃圾信息的鉴别器。对于一个新的样本输入,就可以提取每一个词然后计算其属于两个类别的概率。

  先读取数据,然后统计正常邮件和垃圾邮件数目,并给每个数据加上标签。

import numpy as np
import re
import math

def getDateSet(dataPath=""r"./SMSSpamCollection"):
    with open(dataPath, encoding='utf-8') as f:
        txt_data = f.readlines()
    # 所有邮件
    data = []
    # 标签
    classTag = []
    # 垃圾邮件
    spam_data_num = 0
    # 正常邮件
    ham_data_num = 0
    for line in txt_data:
        line_split = line.strip("\n").split('\t')
        if line_split[0] == "ham":
            data.append(line_split[1])
            spam_data_num += 1
            classTag.append(1)
        elif line_split[0] == "spam":
            data.append(line_split[1])
            ham_data_num += 1
            classTag.append(0)
    print("数据集大小为{}, 其中垃圾邮件数量为{},正常邮件数量为{}".format(len(data), spam_data_num, ham_data_num))
    return data, classTag

  为了方便实现和使用朴素贝叶斯分类,定义了一个NaiveBayes类封装相关属性和方法。首先是构造函数__init__;接着,由于最开始加载数据时没有将邮件内容拆分成一个个单词,故在训练模型之前要对读入的数据进行预处理;然后,训练过程分为了三个子过程:包括fitbuild_word_setword_count三个函数,首先是fit函数,其作为最外层的函数读入一整行的数据以及该行数据的标签,然后使用data_preprocess函数将一整行输入分割为单词,将分割得到的单词组以及对应的标签送入build_word_set函数中,在build_word_set函数中,使用for循环不断更新构造函数中初始化过的正常短信和垃圾短信的次数、总词频数、正常短信和垃圾短信的单词列表;最后,测试集上的预测模块分为两个函数,总接口为predict,其接受多条短信作为输入;predict_one函数实现了对一条短信进行预测的功能。

class NaiveBayes:
    def __init__(self):
        self.__ham_count = 0  # 正常短信数量
        self.__spam_count = 0  # 垃圾短信数量

        self.__ham_words_count = 0  # 正常短信单词总数
        self.__spam_words_count = 0  # 垃圾短信单词总数

        self.__ham_words = list()  # 正常短信单词列表
        self.__spam_words = list()  # 垃圾短信单词列表

        # 训练集中不重复单词集合
        self.__word_dictionary_set = set()
        self.__word_dictionary_size = 0

        self.__ham_map = dict()  # 正常短信的词频统计
        self.__spam_map = dict()  # 垃圾短信的词频统计

        self.__ham_probability = 0.0
        self.__spam_probability = 0.0

    # 输入为一封邮件的内容
    def data_preprocess(self, sentence):
        # 将输入转换为小写并将特殊字符替换为空格
        temp_info = re.sub('\W', ' ', sentence.lower())
        # 根据空格将其分割为一个一个单词
        words = re.split(r'\s+', temp_info)
        # 返回长度大于等于3的所有单词
        return list(filter(lambda x: len(x) >= 3, words))

    def fit(self, X_train, y_train):
        words_line = []
        for sentence in X_train:
            words_line.append(self.data_preprocess(sentence))
        self.build_word_set(words_line, y_train)
        self.word_count()

    def build_word_set(self, X_train, y_train):
        for words, y in zip(X_train, y_train):
            if y == 0:
                # 正常短信
                self.__ham_count += 1
                self.__ham_words_count += len(words)
                for word in words:
                    self.__ham_words.append(word)
                    self.__word_dictionary_set.add(word)
            if y == 1:
                # 垃圾短信
                self.__spam_count += 1
                self.__spam_words_count += len(words)
                for word in words:
                    self.__spam_words.append(word)
                    self.__word_dictionary_set.add(word)

        self.__word_dictionary_size = len(self.__word_dictionary_set)

    def word_count(self):
        # 不同类别下的词频统计
        for word in self.__ham_words:
            self.__ham_map[word] = self.__ham_map.setdefault(word, 0) + 1

        for word in self.__spam_words:
            self.__spam_map[word] = self.__spam_map.setdefault(word, 0) + 1

        # 非垃圾短信的概率
        self.__ham_probability = self.__ham_count / (self.__ham_count + self.__spam_count)
        # 垃圾短信的概率
        self.__spam_probability = self.__spam_count / (self.__ham_count + self.__spam_count)
        print("正常短信词频:{}".format(self.__ham_map))
        print("垃圾短信词频:{}".format(self.__spam_map))

    def predict(self, X_test):
        return [self.predict_one(sentence) for sentence in X_test]

    def predict_one(self, sentence):
        ham_pro = 0
        spam_pro = 0
        words = self.data_preprocess(sentence)
        for word in words:
            ham_pro += math.log(
                (self.__ham_map.get(word, 0) + 1) / (self.__ham_count + self.__word_dictionary_size))

            spam_pro += math.log(
                (self.__spam_map.get(word, 0) + 1) / (self.__spam_count + self.__word_dictionary_size))

        ham_pro += math.log(self.__ham_probability)
        spam_pro += math.log(self.__spam_probability)
        return int(spam_pro >= ham_pro)

  最后,运行主函数,在训练集上训练模型,在测试集上得到预测结果,并完成模型评价。

from sklearn.metrics import recall_score
from sklearn.metrics import precision_score
from sklearn.metrics import classification_report
from sklearn.metrics import accuracy_score
if __name__ == "__main__":
    # 加载数据集
    data, classTag = getDateSet()
    # 设置训练集大小
    train_size = 3000
    # 训练集
    train_X = data[:train_size]
    train_y = classTag[:train_size]
    # 测试集
    test_X = data[train_size:]
    test_y = classTag[train_size:]
    # 在训练集上训练模型
    nb_model = NaiveBayes()
    nb_model.fit(train_X, train_y)
    # 在测试集上得到预测结果
    pre_y = nb_model.predict(test_X)

    # 模型评价
    accuracy_score_value = accuracy_score(test_y, pre_y)
    recall_score_value = recall_score(test_y, pre_y)
    precision_score_value = precision_score(test_y, pre_y)
    classification_report_value = classification_report(test_y, pre_y)
    print("准确率:", accuracy_score_value)
    print("召回率:", recall_score_value)
    print("精确率:", precision_score_value)
    print(classification_report_value)

在这里插入图片描述
……

在这里插入图片描述

五、Sklearn中的朴素贝叶斯

在这里插入图片描述

图3 sklearn朴素贝叶斯

Sklearn的naive_bayes模块中提供了3种朴素贝叶斯分类算法:

  1. 高斯朴素贝叶斯GaussianNB):特征变量是连续变量,符合高斯分布,比如说人的身高,物体的长度。
  2. 多项式朴素贝叶斯MultinomialNB):特征变量是离散变量,符合多项式分布。例如在文档分类中特征变量体现在一个单词出现的次数,或者是单词的TF-IDF值等。
  3. 伯努利朴素贝叶斯BernoulliNB):特征变量是布尔变量,符合 0/1 分布,例如在文档分类中特征是单词是否出现。

使用scikit-learn库中naive_bayes模块的GaussianNB类可以构建高斯朴素贝叶斯分类模型,其语法格式和参数说明如下。

sklearn.naive_bayes.GaussianNB(*, priors=None, var_smoothing=1e-9)

参数名称参数说明
priors接收array。表示先验概率大小,若没有给定,则模型根据样本数据计算(利用极大似然法)。默认为None。
var_smoothing浮点数,添加到每个特征的方差以防止除零错误。默认值是1e-9。

使用scikit-learn库中naive_bayes模块的MultinomialNB类可以实现多项式朴素贝叶斯分类,其语法格式和参数说明如下。

sklearn.naive_bayes.MultinomialNB(*, alpha=1.0, force_alpha=True, fit_prior=True, class_prior=None)

参数名称参数说明
alphafloat,默认1.0,添加拉普拉斯平滑参数以防止零概率。
force_alphabool,如果为True,将强制alpha为非负值。默认为True。
fit_priorbool,默认True,表示是否学习先验概率。如果为False,将使用class_prior中提供的先验概率。
class_prior数组形状为 (n_classes,) 或 None。类别的先验概率。如果为None,则使用fit_prior来确定类先验概率。

使用scikit-learn库中naive_bayes模块的BernoulliNB类可以实现伯努利朴素贝叶斯,其语法格式和参数说明如下。

sklearn.naive_bayes.BernoulliNB(*, alpha=1.0, force_alpha=True, binarize=0.0, fit_prior=True, class_prior=None)

参数名称参数说明
alphafloat,平滑参数。默认为 1.0,用于拉普拉斯平滑以防止零概率。
force_alphabool,如果为True,将强制alpha为非负值。默认为True。
binarizefloat,用于将特征值二值化。所有大于binarize的值将被设置为1,其余为0。默认为0.0。
fit_priorbool。如果为True,模型将学习类别的先验概率;如果为False,将使用class_prior中提供的先验概率。默认为True。
class_prior数组形状为 (n_classes,) 或 None。类别的先验概率。如果为None,则使用fit_prior来确定类先验概率。

(一)实现垃圾短信分类

  本节以一个例子来阐述Sklearn中的朴素贝叶斯分类器在垃圾短信分类中的应用。SMSSpamCollection是一个垃圾短信分类数据集,包含了5574条短信,其中有747条垃圾短信。数据集以纯文本的形式存储,其中每行对应于一条短信。每行的第一个单词是spamham,表示该行的短信是不是垃圾短信。随后记录了短信的内容,内容和标签之间以制表符分隔。该数据集没有收录进sklearn.datasets,所以我们需要自行加载。

# 打开文件,指定路径和编码方式
try:
    with open('./SMSSpamCollection', 'r', encoding='utf8') as f:
        # 读取文件中的每一行,并按制表符分隔
        sms = [line.strip().split('\t') for line in f]
    
    # 将列表中的每个元素拆分为两个部分:标签(y)和内容(X)
    y, X = zip(*sms)

except FileNotFoundError:
    # 如果文件未找到,打印错误信息
    print("文件未找到,请检查路径。")
except Exception as e:
    # 捕捉其他异常并打印错误信息
    print(f"发生错误: {e}")

  加载完成后,Xy分别是长为5574的字符串列表。其中y的每个元素只可能是spamham,分别表示垃圾短信和正常短信。X的每个元素表示对应短信的内容。在训练贝叶斯分类器以前,需要首先将Xy转换成适于训练的数值表示形式,这个过程称为特征提取。

from sklearn.feature_extraction.text import CountVectorizer as CV
from sklearn.model_selection import train_test_split

# 将标签转换为布尔值'spam'为True,其它为False
y = [label == 'spam' for label in y]

# 将数据集拆分为训练集和测试集,默认测试集占比为25%
X_train, X_test, y_train, y_test = train_test_split(X, y)

# 初始化CountVectorizer,并设置token_pattern只匹配长度为2或更多字母的单词
counter = CV(token_pattern='[a-zA-Z]{2,}')

# 在训练集上拟合CountVectorizer,并将文本转换为特征矩阵
X_train = counter.fit_transform(X_train)

# 使用训练好的CountVectorizer将测试集文本转换为特征矩阵
X_test = counter.transform(X_test)

  特征提取的结果存储在(X_train, y_train)以及(X_test, y_test)中。其中X_trainX_test分别是4180×6595和1394×6595的稀疏矩阵。不难看出,两个矩阵的行数之和等于5574,也就是完整数据集的大小。因此两个矩阵的每行应该代表一个样例,那么每列代表什么呢?查看countervocabulary_属性就会发现,其大小恰好是6595,也就是所有短信中出现过的不同单词的个数。例如短信“Go until jurong point, go”中一共有5个单词,但是由于go出现了两次,所以不同单词的个数只有4个。X_trainX_test中的第(i,j)个元素就表示第j个单词在第i条短信中出现的次数。

  最后就是朴素贝叶斯分类器的构造与训练,代码如下所示。我们首先基于训练集训练朴素贝叶斯分类器,然后分别在训练集和测试集上进行测试。

from sklearn.naive_bayes import MultinomialNB as NB

# 初始化MultinomialNB分类器
model = NB()

# 使用训练数据拟合模型
model.fit(X_train, y_train)

# 计算并打印训练集上的准确率
train_score = model.score(X_train, y_train)
print("train score:", train_score)

# 计算并打印测试集上的准确率
test_score = model.score(X_test, y_test)
print("test score:", test_score)

在这里插入图片描述

  测试结果显示,模型在训练集上的分类准确率达到0.991,在测试集上的分类准确率为0.986。可见朴素贝叶斯分类器达到了良好的分类效果。

  朴素贝叶斯分类器假设样本特征之间相互独立。这一假设非常强,以至于几乎不可能满足。但是在实际应用中,朴素贝叶斯分类器往往表现良好,特别是在垃圾邮件过滤、信息检索等场景下。

(二)三类朴素贝叶斯模型比较

  下面,通过代码和决策可视化对以上三种朴素贝叶斯模型进行比较。这里用到了sklearn库中的一个手动设置的分类数据集make_blobs

  首先函数生成数据为300个、特征为2、类别为7的数据集,然后利用三种朴素贝叶斯算法观察其精度。

# 导入必要的库
from sklearn.datasets import make_blobs
from sklearn.model_selection import train_test_split
from sklearn.naive_bayes import GaussianNB  # 高斯朴素贝叶斯分类器
import numpy as np
import matplotlib.pyplot as plt

# 生成示例数据
X, y = make_blobs(n_samples=300, centers=7, random_state=3)

# 将数据集拆分为训练集和测试集
X_train, X_test, y_train, y_test = train_test_split(X, y, random_state=3)

# 初始化并训练高斯朴素贝叶斯模型
bayes = GaussianNB()
bayes.fit(X_train, y_train)

# 计算并输出训练集和测试集的准确率
train_score = bayes.score(X_train, y_train)
test_score = bayes.score(X_test, y_test)
print("train predict = {}".format(train_score))
print("test predict = {}".format(test_score))

# 绘制决策边界
x_min, x_max = X[:,0].min() - 1, X[:,0].max() + 1
y_min, y_max = X[:,1].min() - 1, X[:,1].max() + 1

# 创建网格以绘制决策边界
xx, yy = np.meshgrid(np.arange(x_min, x_max, 0.02), np.arange(y_min, y_max, 0.02))
z = bayes.predict(np.c_[(xx.ravel(), yy.ravel())]).reshape(xx.shape)

# 绘制决策边界及数据点
plt.pcolormesh(xx, yy, z, cmap=plt.cm.Pastel1, alpha=0.3)
plt.scatter(X_train[:,0], X_train[:,1], c=y_train, cmap=plt.cm.cool, marker='.', edgecolors='k', label='train')
plt.scatter(X_test[:,0], X_test[:,1], c=y_test, cmap=plt.cm.cool, marker='^', edgecolors='k', label='test')
plt.xlim(xx.min(), xx.max())
plt.ylim(yy.min(), yy.max())
plt.title('GaussianNB Decision Boundary')
plt.legend()
plt.show()

在这里插入图片描述

# 导入必要的库和模块
from sklearn.datasets import make_blobs  # 生成示例数据
from sklearn.model_selection import train_test_split  # 切分数据集
from sklearn.naive_bayes import BernoulliNB  # 伯努利朴素贝叶斯分类器
import numpy as np  # 数值计算
import matplotlib.pyplot as plt  # 绘图库

# 生成示例数据
X, y = make_blobs(n_samples=300, centers=7, random_state=3)

# 切分数据集为训练集和测试集
X_train, X_test, y_train, y_test = train_test_split(X, y, random_state=3)

# 初始化并训练伯努利朴素贝叶斯模型
bayes = BernoulliNB()
bayes.fit(X_train, y_train)

# 计算并输出训练集和测试集的准确率
train_score = bayes.score(X_train, y_train)
test_score = bayes.score(X_test, y_test)
print("train predict = {}".format(train_score))
print("test predict = {}".format(test_score))

# 绘制决策边界
x_min, x_max = X[:,0].min() - 1, X[:,0].max() + 1
y_min, y_max = X[:,1].min() - 1, X[:,1].max() + 1

# 创建网格以绘制决策边界
xx, yy = np.meshgrid(np.arange(x_min, x_max, 0.02), np.arange(y_min, y_max, 0.02))
z = bayes.predict(np.c_[xx.ravel(), yy.ravel()]).reshape(xx.shape)

# 绘制决策边界及数据点
plt.pcolormesh(xx, yy, z, cmap=plt.cm.Pastel1, alpha=0.3)  # 决策边界的颜色
plt.scatter(X_train[:,0], X_train[:,1], c=y_train, cmap=plt.cm.cool, marker='.', edgecolors='k', label='train')
plt.scatter(X_test[:,0], X_test[:,1], c=y_test, cmap=plt.cm.cool, marker='^', edgecolors='k', label='test')
plt.xlim(xx.min(), xx.max())
plt.ylim(yy.min(), yy.max())
plt.title('BernoulliNB Decision Boundary')
plt.legend()
plt.show()

在这里插入图片描述

  因为多项式朴素贝叶斯只适用于处理非负离散数值,所以在下面对数据进行了归一化。

# 导入必要的库和模块
from sklearn.datasets import make_blobs  # 生成示例数据
from sklearn.model_selection import train_test_split  # 切分数据集
from sklearn.naive_bayes import MultinomialNB  # 多项式朴素贝叶斯分类器
import numpy as np  # 数值计算
import matplotlib.pyplot as plt  # 绘图库
from sklearn.preprocessing import MinMaxScaler  # 数据标准化

# 生成示例数据
X, y = make_blobs(n_samples=300, centers=7, random_state=3)

# 切分数据集为训练集和测试集
X_train, X_test, y_train, y_test = train_test_split(X, y, random_state=3)

# 初始化数据标准化器并应用于训练集和测试集
scaler = MinMaxScaler()
scaler.fit(X_train)  # 计算训练集的缩放参数
X_train_scaler = scaler.transform(X_train)  # 规范化训练集
X_test_scaler = scaler.transform(X_test)  # 规范化测试集

# 初始化并训练多项式朴素贝叶斯模型
bayes = MultinomialNB()
bayes.fit(X_train_scaler, y_train)

# 计算并输出训练集和测试集的准确率
train_score = bayes.score(X_train_scaler, y_train)
test_score = bayes.score(X_test_scaler, y_test)
print("train predict = {}".format(train_score))
print("test predict = {}".format(test_score))

# 绘制决策边界
x_min, x_max = X[:,0].min() - 1, X[:,0].max() + 1
y_min, y_max = X[:,1].min() - 1, X[:,1].max() + 1

# 创建网格以绘制决策边界
xx, yy = np.meshgrid(np.arange(x_min, x_max, 0.02), np.arange(y_min, y_max, 0.02))
z = bayes.predict(np.c_[xx.ravel(), yy.ravel()]).reshape(xx.shape)

# 绘制决策边界及数据点
plt.pcolormesh(xx, yy, z, cmap=plt.cm.Pastel1, alpha=0.3)  # 决策边界的颜色
plt.scatter(X_train[:,0], X_train[:,1], c=y_train, cmap=plt.cm.cool, marker='.', edgecolors='k', label='train')
plt.scatter(X_test[:,0], X_test[:,1], c=y_test, cmap=plt.cm.cool, marker='^', edgecolors='k', label='test')
plt.xlim(xx.min(), xx.max())
plt.ylim(yy.min(), yy.max())
plt.title('MultinomialNB Decision Boundary')
plt.legend()
plt.show()

在这里插入图片描述

  因为有的算法不适用该数据集的缘故,可以看到评分越来越低。通过决策可视化观察其决策边界。伯努利朴素贝叶斯主要解决的是二项分布,多项式朴素贝叶斯多用于转化为对文本的处理,所以效果不是很好。

优点
(1)朴素贝叶斯算法分类效率稳定,不仅能处理二分类还能处理多分类,适用于小规模数据,而且还能做增量式训练,即数据量过多超出内存时,我们可以分批的去增量训练。
(2)对缺失数据不太敏感,算法也比较简单,常用于文本分类。
(3)当属性相关性较小时,朴素贝叶斯性能最好。

缺点
(1)在属性个数比较多或者属性之间相关性较大时,分类效果不好,往往无法预测精确的数据。
(2)需要知道先验概率,且先验概率很多时候取决于假设,因此在某些时候会由于假设的先验模型的原因导致预测效果不佳。
(3)由于我们是通过先验和数据来决定后验的概率从而决定分类,所以分类决策存在一定的错误率,并且对输入数据的表达形式很敏感。

:以上文中的数据集及相关资源下载地址:
链接:https://pan.quark.cn/s/79b02e018c98
提取码:cWr9

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

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

相关文章

数据中台建设(七)——数据体系建设

数据体系建设 数据中台是企业数据汇集地,但并不是简单的数据堆积,而是进行分层建模,数据体系建设最终呈现一套完整、规范、准确的数据。数据体系建设就是大数据中数据仓库建设。如下图: 贴源数据层ODS(Operational Data Store)…

python的数据类型详解

python基础 认识python基本类型python的注释风格有三种(也可以说是两种)python的对齐方式python的多行语句折断字符串类型的“计算”列表的常见用法元组的常见用法集合set的常见用法字典的常见用法bytes类型python的输入输出python中的引用 认识python基…

基于环境音频和振动数据的人类活动识别

这篇论文的标题是《Recognition of human activities based on ambient audio and vibration data》,作者是 Marcel Koch 等人,发表在 IEEE Access 期刊上。论文提出了一种基于环境音频和振动数据的分布式多传感器系统,用于识别人类活动。以下…

窗口框架frame(HTML前端)

一.窗口框架 作用&#xff1a;将网页分割为多个HTML页面&#xff0c;即将窗口分为多个小窗口&#xff0c;每个小窗口可以显示不同的页面&#xff0c;但是在浏览器中是一个完整的页面 基本语法 <frameset cols"" row""></frameset><frame…

好的知识竞赛策划公司哪里去找

活动不管多大&#xff0c;都败在策划公司手中&#xff01;要找到好的策划公司&#xff0c;可以考虑以下几个途径&#xff1a; 1.搜索引擎&#xff1a; 通过搜索引擎&#xff0c;可以找到行业内有实力的优秀策划公司。尽管有些公司是打广告&#xff0c;那总比没钱打广告的公司…

Codes 开源研发项目管理平台——敏捷测试管理创新解决方案

前言 Codes 是国内首款重新定义 SaaS 模式的开源项目管理平台&#xff0c;支持云端认证、本地部署、全部功能开放&#xff0c;并且对30人以下团队免费。它通过整合迭代、看板、度量和自动化等功能&#xff0c;简化测试协同工作&#xff0c;使敏捷测试更易于实施。并提供低成本的…

C#与Python脚本使用共享内存通信

实现的功能&#xff1a; C#中读取一张图像&#xff0c;通过共享内存传给python脚本进行处理后将图像进行存储&#xff0c;C#读取处理过后的图像。 C#与python通信有好几种&#xff0c;为什么选择共享内存&#xff1f; 处理图像的速度需求是1秒钟处理5张以上&#xff0c;通过…

《中文Python穿云箭量化平台二次开发技术11》股票基本信息获取分析及应用示例【前十大股东占股比例提取及分析】

《中文Python穿云箭量化平台二次开发技术11》股票基本信息获取分析及应用示例【前十大股东占股比例提取及分析】 《中文Python穿云箭量化平台》是纯Python开发的量化平台&#xff0c;因此其中很多Python模块&#xff0c;我们可以自己设计新的量化工具&#xff0c;例如自己新的行…

1----安卓机型修复串码 开启端口 檫除基带 支持高通与MTK机型工具预览与操作解析

在玩机过程中。很多玩家会碰到各种各样的故障 。其中最多的就在于基带 串码类。由于目前的安卓机型必须修改或者写入串码等参数必须开启端口。而一些初级玩友不太了解开启参数端口的步骤。这个工具很简单的为安卓机型开启端口。并且操作相对简单。 此工具基本功能 1-----可以…

linux入门到实操-4 linux系统网络配置、连接测试、网络连接模式、修改静态IP、配置主机名

教程来源&#xff1a;B站视频BV1WY4y1H7d3 3天搞定Linux&#xff0c;1天搞定Shell&#xff0c;清华学神带你通关_哔哩哔哩_bilibili 整理汇总的课程内容笔记和课程资料&#xff08;包含课程同版本linux系统文件等内容&#xff09;&#xff0c;供大家学习交流下载&#xff1a;…

第15-03章:类的加载与ClassLoader的理解

3、类的加载与ClassLoader的理解 5.1.类加载(ClassLoad)的理解: a.类加载器的作用: 1.将class文件字节码内容加载到内存中&#xff0c;并将这些静态数据转换成方法区的运行时数据结构&#xff0c;然后在堆中生成一个代表这个类的java.lang.Class对象&#xff0c;作为方法区中…

一步迅速了解Linux

1&#xff0c;什么是LInux&#xff1f; Linux 是一个开源的操作系统(管理计算机硬件资源,人物调度)支持多用户,支持网络,支持多线程. 2&#xff0c;Linux特指什么&#xff1f; linux一词,特指的是linux内核 即最操作系统最核心的那一部分功能.负责管理 计算机的硬件资源&…

AIP接口调用

在当今数字化时代&#xff0c;API接口调用已成为连接不同软件和系统的重要手段。特别是在与淘宝这样的大型电商平台进行数据交互时&#xff0c;AIP&#xff08;人工智能平台&#xff09;接口的作用尤为显著。通过AIP接口&#xff0c;开发者可以访问和利用淘宝庞大的商品数据库&…

k8s介绍及部署

目录 一 Kubernetes 简介及部署方法 1.1 应用部署方式演变 1.2 容器编排应用 1.3 kubernetes 简介 1.4 K8S的设计架构 1.4.1 K8S各个组件用途 1.4.2 K8S 各组件之间的调用关系 1.4.3 K8S 的 常用名词感念 1.4.4 k8S的分层架构 二 K8S集群环境搭建 2.1 k8s中容器的管…

[苍穹外卖]-12Apache POI入门与实战

工作台 需求分析: 工作台是系统运营的数据看板, 并提供快捷操作入口, 可以有效提高商家的工作效率 营业额: 已完成订单的总金额有效订单: 已经完成订单的数量订单完成率: 有效订单数/总订单数*100%平均客单价: 营业额/有效订单数新增用户: 新增的用户数量 接口设计: 一个接口返…

RabbitMQ(高阶使用)死信队列

文章内容是学习过程中的知识总结&#xff0c;如有纰漏&#xff0c;欢迎指正 文章目录 一、什么是死信队列&#xff1f; 二、死信队列使用场景 三、死信队列如何使用 四、打车超时处理 1.打车超时实现 以下是本篇文章正文内容 一、什么是死信队列&#xff1f; 先从概念解释上搞…

嵌入式通信原理—SPI总线通信原理与应用

文章目录 SPI 简介基本原理工作模式特点 SPI寻址方式1. 片选&#xff08;Chip Select, CS&#xff09;2. 多从设备通信3. 菊花链&#xff08;Daisy-Chain&#xff09;模式4. 地址寄存器&#xff08;应用层&#xff09; SPI通信过程时钟信号生成&#xff08;SCLK&#xff09;数据…

supermap Iclient3d for cesium加载地形并夸大地形

先看效果图 这是没有夸张之前的都江堰 这是夸大五倍后的都江堰 下面展示代码 主要就是加载supermaponline的skt地形然后夸大 <template><div class"PartOneBox"><div id"cesiumContainer"></div></div> </template>…

华为eNSP使用详解

eNSP&#xff08;Enterprise Network Simulation Platform&#xff09;是华为提供的一款网络仿真平台&#xff0c;它允许用户在没有真实设备的情况下进行网络实验和学习网络技术。eNSP可以模拟各种网络设备&#xff0c;如交换机、路由器、防火墙等&#xff0c;并支持创建多种网…

【mechine learning-十-grading descent梯度下降实现】

grading descent 梯度下降参数更新方法 --导数和学习率 从导数项直观理解梯度下降 grading descent 算法就是更新参数&#xff0c;今天来学习下如何更新w和b 梯度下降 还是以线性回归的均方差损失函数如下为例&#xff1a; 损失函数的可视化图如下 &#xff1a; 横轴和纵轴分…