机器学习原理到Python代码实现之NaiveBayes【朴素贝叶斯】

Naive Bayes 朴素贝叶斯算法

该文章作为机器学习的第二篇文章,主要介绍的是朴素贝叶斯算法的原理和应用。学习本章内容建议对概率论中的联合概率以及先验概率、后验概率有初步的学习和掌握。

难度系数:⭐⭐⭐

更多相关工作请参考:Github

算法介绍

朴素贝叶斯算法是一种基于概率论的分类算法 ,它假设特征之间是独立的,即特征之间没有关联关系。朴素贝叶斯算法通过计算每个类别的概率来对新的样本进行分类。

算法原理解析

贝叶斯定理

贝叶斯定理是概率论中的核心概念,用于描述当存在新的信息或数据时,如何更新对某一事件或参数的信念。具体来说,它提供了从条件概率和先验概率推导出后验概率的公式。

贝叶斯定理的公式为: P ( A ∣ B ) = ( P ( B ∣ A ) ∗ P ( A ) ) / P ( B ) P(A|B) = (P(B|A) * P(A)) / P(B) P(AB)=(P(BA)P(A))/P(B)。这个公式用于计算在给定事件B发生的情况下,事件A发生的概率,即后验概率。

其中:

  • P ( A ∣ B ) P(A|B) P(AB): 这是我们要求的后验概率,即在事件B已经发生的情况下,事件A发生的概率。
  • P ( B ∣ A ) P(B|A) P(BA): 这是条件概率,表示在事件A发生的情况下,事件B发生的概率。
  • P ( A ) P(A) P(A): 这是事件A的先验概率,即在没有任何额外信息的情况下,事件A发生的概率。
  • P ( B ) P(B) P(B): 这是事件B的先验概率,即在没有任何额外信息的情况下,事件B发生的概率。

贝叶斯定理的公式用于计算后验概率,即根据新的证据或数据,更新对事件A发生的信念。通过使用先验概率和条件概率,贝叶斯定理可以帮助我们在给定新信息的情况下,更准确地估计事件A发生的概率。

接下来是笔者的一些公式推导,在事件相互独立的情况下:

在B事件发生的情况下,A事件发生的概率为:

P ( A ∣ B ) = P ( A ∩ B ) / P ( B ) P(A|B) = P(A \cap B) / P(B) P(AB)=P(AB)/P(B)

在A事件发生的情况下,B事件发生的概率为:

P ( B ∣ A ) = P ( A ∩ B ) / P ( A ) P(B|A) = P(A \cap B) / P(A) P(BA)=P(AB)/P(A)

通过 P ( A ∩ B ) P(A \cap B) P(AB)作为桥梁,化简公式,我们便得到的公式:

P ( A ∣ B ) = ( P ( B ∣ A ) ∗ P ( A ) ) / P ( B ) P(A|B) = (P(B|A) * P(A)) / P(B) P(AB)=(P(BA)P(A))/P(B)

传统版本

朴素贝叶斯算法是一种基于贝叶斯定理与特征条件独立假设的分类方法。这种算法有坚实的数学基础,分类效率相对稳定。从数学角度看,朴素贝叶斯算法主要应用了贝叶斯定理。

朴素贝叶斯算法利用了贝叶斯定理来计算样本属于某个类别的概率。具体来说,对于一个样本 x x x,假设它属于类别 c c c的概率 P ( c ∣ x ) P(c|x) P(cx)可以由以下公式计算:
P ( c ∣ x ) = P ( c ) ∗ P ( x ∣ c ) / P ( x ) P(c|x) = P(c) * P(x|c) / P(x) P(cx)=P(c)P(xc)/P(x)
其中 P ( c ) P(c) P(c)是类别 c c c的先验概率,即该类别在训练集中的比例; P ( x ∣ c ) P(x|c) P(xc)是在类别 c c c的条件下 x x x出现的概率; P ( x ) P(x) P(x) x x x在训练集中的总概率。

朴素贝叶斯算法的核心思想是假设特征之间相互独立,即 P ( x ∣ c ) P(x|c) P(xc)可以分解为各个特征的条件概率的乘积。具体来说,如果 x x x是一个 n n n维特征向量,即 x = ( x 1 , x 2 , . . . , x n ) x=(x1,x2,...,xn) x=(x1,x2,...,xn),那么 P ( x ∣ c ) P(x|c) P(xc)可以表示为:
P ( x ∣ c ) = P ( x 1 ∣ c ) ∗ P ( x 2 ∣ c ) ∗ . . . ∗ P ( x n ∣ c ) P(x|c) = P(x1|c) * P(x2|c) * ... * P(xn|c) P(xc)=P(x1∣c)P(x2∣c)...P(xnc)
其中 P ( x i ∣ c ) P(xi|c) P(xic)是在类别 c c c的条件下特征 x i xi xi出现的概率。

故事版本

首先,朴素贝叶斯算法是一种基于贝叶斯定理的分类方法。贝叶斯定理是用来计算某个事件发生的概率,基于这个事件已经发生和还没有发生的概率。

为了让你更好地理解,让我们用生活中的一个例子来说明:

假设你有一个朋友,他是个图书管理员。他可以根据一本书的封面来判断这本书是否是儿童书。怎么做到的呢?

  1. 属性选择:他首先会看书的几个关键特征,例如书的颜色、封面的图案和标题等。这些都是他判断的“属性”。
  2. 概率计算:基于他的经验,他知道某种颜色或图案更有可能出现在儿童书中。这就是他基于这些属性计算出的不同类型书籍的概率。
  3. 分类决策:当一本书放在他面前时,他会根据这些属性(颜色、图案等)来判断这本书是否是儿童书。

这就是朴素贝叶斯算法的核心思想:基于已知属性来预测或分类一个事件或对象。

但为什么叫“朴素”呢?因为这种方法有一个前提假设,那就是每个属性之间是相互独立的。这意味着书的不同属性(例如颜色和图案)不会相互影响,也就是说,一个书不会因为它是红色且有一个星星图案就更有可能是儿童书,如果这两个特征在之前的样本中没有同时出现过,这个假设就不成立。但为了简化计算,我们通常会做这个假设。

数学原理

基于离散特征的朴素贝叶斯算法

我们要从数学角度推导如何在具备 N N N个特征的数据集上,通过朴素贝叶斯实现分类。

首先,我们需要了解几个关键概念:

特征:数据集中的每个独立变量。
类别:数据集中的目标变量或分类。
概率:某一事件发生的可能性。
朴素贝叶斯:基于贝叶斯定理和特征独立假设的分类方法。
现在,我们开始推导:

第一步,设数据集有 N N N个特征,记作 ( X 1 , X 2 , . . . , X N ) (X_1, X_2, ..., X_N) (X1,X2,...,XN)

第二步,设目标类别有M种,记作 ( C 1 , C 2 , . . . , C M ) (C_1, C_2, ..., C_M) (C1,C2,...,CM)

第三步,基于贝叶斯定理,对于给定的类别 ( C k ) (C_k) (Ck),一个样本 ( X ) (X) (X) 属于 ( C k ) (C_k) (Ck) 的概率可以表示为:
P ( C k ∣ X 1 , X 2 , . . . , X N ) = P ( C k ) × P ( X 1 ∣ C k ) × P ( X 2 ∣ C k ) × . . . × P ( X N ∣ C k ) P ( X 1 ) × P ( X 2 ) × . . . × P ( X N ) P(C_k | X_1, X_2, ..., X_N) = \frac{P(C_k) \times P(X_1 | C_k) \times P(X_2 | C_k) \times ... \times P(X_N | C_k)}{P(X_1) \times P(X_2) \times ... \times P(X_N)} P(CkX1,X2,...,XN)=P(X1)×P(X2)×...×P(XN)P(Ck)×P(X1Ck)×P(X2Ck)×...×P(XNCk)
其中, P ( C k ) P(C_k) P(Ck) 是类别 C k C_k Ck 的先验概率, P ( X i ∣ C k ) P(X_i | C_k) P(XiCk) 是特征 ( X i ) (X_i) (Xi) 在类别 ( C k ) (C_k) (Ck) 下的条件概率。

第四步,由于我们假设特征之间是独立的,所以:
P ( X ∣ C ) = P ( X 1 ∣ C ) × P ( X 2 ∣ C ) × . . . × P ( X N ∣ C ) P(X | C) = P(X_1 | C) \times P(X_2 | C) \times ... \times P(X_N | C) P(XC)=P(X1C)×P(X2C)×...×P(XNC)
P ( X ) = P ( X 1 ) × P ( X 2 ) × . . . × P ( X N ) P(X) = P(X_1) \times P(X_2) \times ... \times P(X_N) P(X)=P(X1)×P(X2)×...×P(XN)

第五步,将第四步的结论代入第三步的公式,得到:
P ( C k ∣ X ) = P ( C k ) × P ( X ∣ C k ) P ( C 1 ) × P ( X ∣ C 1 ) + P ( C 2 ) × P ( X ∣ C 2 ) + . . . + P ( C M ) × P ( X ∣ C M ) P(C_k | X) = \frac{P(C_k) \times P(X | C_k)}{P(C_1) \times P(X | C_1) + P(C_2) \times P(X | C_2) + ... + P(C_M) \times P(X | C_M)} P(CkX)=P(C1)×P(XC1)+P(C2)×P(XC2)+...+P(CM)×P(XCM)P(Ck)×P(XCk)
第六步,由于我们通常无法得知真实的概率值,因此需要使用已知的训练数据集来估计这些概率。具体来说,对于类别 ( C k ) (C_k) (Ck) 和特征 ( X i ) (X_i) (Xi),我们有:
P ( C k ) = 样本中属于 C k 的样本数 总样本数 P(C_k) = \frac{\text{样本中属于} C_k \text{的样本数}}{\text{总样本数}} P(Ck)=总样本数样本中属于Ck的样本数
P ( X i ∣ C k ) = 属于 C k 且具有 X i 的样本数 属于 C k 的样本数 P(X_i | C_k) = \frac{\text{属于} C_k \text{且具有} X_i \text{的样本数}}{\text{属于} C_k \text{的样本数}} P(XiCk)=属于Ck的样本数属于Ck且具有Xi的样本数
第七步,最后,为了得到每个类别被选中的概率,我们将每个类别的概率除以所有类别的概率之和。即:
P ( C k ∣ X ) = P ( C k ) P ( C 1 ) + P ( C 2 ) + . . . + P ( C M ) × P ( X ∣ C k ) P(C_k | X) = \frac{P(C_k)}{P(C_1) + P(C_2) + ... + P(C_M)} \times P(X | C_k) P(CkX)=P(C1)+P(C2)+...+P(CM)P(Ck)×P(XCk)
这就是朴素贝叶斯分类器的数学推导过程。通过这个过程,我们可以使用已知的训练数据集来估计每个类别的概率和每个特征在每个类别下的条件概率,然后使用这些估计值来预测新的未知样本的类别。

基于连续特征的朴素贝叶斯算法

对于连续特征,朴素贝叶斯分类器可以采用两种方式进行处理。第一种方法是将连续的数据离散化,然后用相应的离散区间替换连续数值。然而,这种方法对于划分离散区间的粒度要求较高,不能太细,也不能太粗。

第二种方法是假设连续数据服从某个概率分布,使用训练数据估计分布参数。通常我们用高斯分布(正态分布)来表示连续数据的类条件概率分布。具体来说,我们可以计算每个特征在每个类别中的均值和标准差,然后使用这些参数来评估给定特征值在该类别中的概率。这种方法在计算后验概率时更加准确。

如果数据是连续的并且特征之间存在顺序关系(例如身高、体重、脚掌长度等),可以假设这些特征服从正态分布,并通过计算训练样本中各个类别中此特征的均值和标准差来得到正态分布的密度函数。然后使用该密度函数来评估给定特征值的概率。

数据集介绍

鸢尾花(Iris)数据集是一个常用的分类实验数据集,由Fisher在1936年收集整理。该数据集包含150个样本,每个样本有四个属性:花萼长度、花萼宽度、花瓣长度和花瓣宽度,这四个属性用于预测鸢尾花属于Setosa、Versicolour或Virginica三个种类中的哪一类。

鸢尾花数据集的特点是具有多重变量,即每个样本都有多个特征,这使得它成为进行多元分类任务的一个理想选择。通过分析这些特征,可以了解不同鸢尾花品种之间的差异,并建立分类器来自动识别未知样本的种类。

鸢尾花数据集的来源是实际的鸢尾花测量数据,因此它具有实际背景和应用价值。这个数据集经常被用于机器学习和数据挖掘算法的实验和验证,因为它提供了多变量分析的一种有效方式。

在本次朴素贝叶斯分类中,我们计划采用这个数据集作为我们的实验对象。

代码实现

# 准备好我们需要使用的第三方包
import os
import numpy as np
import pandas as pd
from scipy.stats import norm
import matplotlib.pyplot as plt
from matplotlib.colors import ListedColormap

数据分析

首先,我们加载数据集,并展示一下数据的格式:

column_names=['SepalLength','SepalWidth','PetalLength', 'PetalWidth','Species']
train_dataset = pd.read_csv('dataset\\iris_training.csv', header=0, names=column_names)
test_dataset = pd.read_csv('dataset\\iris_test.csv', header=0, names=column_names)
train_dataset.info()
train_dataset.head()
<class 'pandas.core.frame.DataFrame'>
RangeIndex: 120 entries, 0 to 119
Data columns (total 5 columns):#   Column       Non-Null Count  Dtype  
---  ------       --------------  -----  0   SepalLength  120 non-null    float641   SepalWidth   120 non-null    float642   PetalLength  120 non-null    float643   PetalWidth   120 non-null    float644   Species      120 non-null    int64  
dtypes: float64(4), int64(1)
memory usage: 4.8 KB
SepalLengthSepalWidthPetalLengthPetalWidthSpecies
06.42.85.62.22
15.02.33.31.01
24.92.54.51.72
34.93.11.50.10
45.73.81.70.30

接下来,我们可以对每个维度的特征进行统计分析,例如计算每个维度的均值、标准差、最大值、最小值等。并通过作图的方式来展示特征与类别之间的关系:

def feature_analysis(X, Y):"""输入特征X与类别标签Y,分析特征的均值、标准差、最大值、最小值,并绘制散点图来表示每个维度特征与类别之间的关系存在四个特征,故制作一个画布,绘制一张2x2的子图来展示每个特征Args:X (pd.DataFrame): 输入的特征数据Y (pd.DataFrame): 特征对应的标签"""# 设置颜色及子图的大小color = ListedColormap(['red', 'green', 'blue'])fig, axes = plt.subplots(nrows=2, ncols=2, figsize=(10, 10))data_info = {}# 遍历每个特征for i, feature in enumerate(X.columns):data_info[feature] = {"mean": X[feature].mean(),"std": X[feature].std(),"min": X[feature].min(),"max": X[feature].max()}# 绘制散点图来表示每个维度特征与类别之间的关系存在四个特征axes[i // 2, i % 2].scatter(X[feature], Y, c=Y, cmap=color)axes[i // 2, i % 2].set_title(feature)axes[i // 2, i % 2].set_xlabel(feature)axes[i // 2, i % 2].set_ylabel('Species')plt.tight_layout()plt.show()# 绘制两两特征之间的散点图fig, axes = plt.subplots(nrows=4, ncols=3, figsize=(12, 9))for i, feature_x in enumerate(X.columns):for j, feature_y in enumerate(X.columns):if i != j:y = i if i < j else i-1axes[j, y].scatter(X[feature_x], X[feature_y], c=Y, cmap=color)axes[j, y].set_title(feature_x + ' vs ' + feature_y)axes[j, y].set_xlabel(feature_x)axes[j, y].set_ylabel(feature_y)plt.tight_layout()plt.show()for key, value in data_info.items():print("[%12s] mean:%7.5f std:%7.5f max:%7.5f min:%7.5f" % (key, value['mean'], value['std'], value['max'], value['min']))feature_analysis(train_dataset.iloc[:, :-1], train_dataset.iloc[:, -1])

在这里插入图片描述
在这里插入图片描述

[ SepalLength] mean:5.84500 std:0.86858 max:7.90000 min:4.40000
[  SepalWidth] mean:3.06500 std:0.42716 max:4.40000 min:2.00000
[ PetalLength] mean:3.73917 std:1.82210 max:6.90000 min:1.00000
[  PetalWidth] mean:1.19667 std:0.78204 max:2.50000 min:0.10000

从展示的图像中我们可以看到不同特征与类别之间的关系。也可以看出两两特征在组合后所呈现的特征关系,这些都与我们后续的朴素贝叶斯算法有关系。

构建朴素贝叶斯算法

我们将继续从自己构建和调用sklearn两种模式来为大家呈现这个算法的实现。

基础实现

朴素贝叶斯算法在自我实现的时候需要考虑到,我们在构建NaiveBayes模型的时候,需要考虑到有以下的功能:

  1. 算法的训练
  2. 算法的预测
  3. 算法的评估

接下来,我们开始构建属于我们自己的朴素贝叶斯算法:

class NaiveBayes:def __init__(self):self.class_prob = Noneself.class_cond_prob = Noneself.discretization = Noneself.n_classes = None# 该函数将输入某一个维度的连续特征,将返回服从高斯分布的特征参数def gaussian_process(self, feature):# feature是pd.DataFramemean = feature.mean()std = feature.std()return mean, std# 该函数将输入某一个维度的连续特征,将返回划分区域的area个区域,同时需要考虑到在feature分布外的数据[-inf, inf]def zoning_process(self, feature, area=5):# feature是pd.DataFramemin_value = feature.min() - 0.01max_value = feature.max() + 0.01step = (max_value - min_value) / (area - 2)# 划分区域zones = []for i in range(area):if i == 0:zones.append([float("-inf"), min_value])elif i == area-1:zones.append([max_value, float("inf")])else:zones.append([min_value + (i-1) * step, min_value + i * step])return zones# 模型的训练def fit(self, X, Y, discretization=False, area=0):# X是pd.DataFrame,Y是pd.Seriesself.discretization = discretization# 计算class_probself.class_prob = Y.value_counts(normalize=True).to_dict()self.n_classes = len(self.class_prob.keys())# 计算class_meanself.class_cond_prob = {}for i in self.class_prob.keys():self.class_cond_prob[i] = {}for j, feature_name in enumerate(X.columns):if discretization and X[feature_name].dtype == "float64":# 通过self.zoning的方法,将特征转换成离散的片段# self.zoning的返回是Nx2的列表,代表区间的最小值和最大值zones = self.zoning_process(X[feature_name], area)self.class_cond_prob[i][feature_name] = {"type": "zoning", "zoning": {}}for k, zone in enumerate(zones):zone = tuple(zone)self.class_cond_prob[i][feature_name]["zoning"][zone] = 0# 筛选出Y中符合i的下标以及对应的X中的特征index = (Y == i) & (X[feature_name] >= zone[0]) & (X[feature_name] < zone[1])self.class_cond_prob[i][feature_name]["zoning"][zone] = X[feature_name][index].shape[0] / (Y == i).sum()elif not discretization and X[feature_name].dtype == "float64":# 通过self.gaussian_process函数获得特征的均值和方法,获得高斯分布的特性index = (Y == i)mean, std = self.gaussian_process(X[feature_name][index])self.class_cond_prob[i][feature_name] = {"type": "gaussian", "mean": mean, "std": std}else:# 特征本身就是离散的self.class_cond_prob[i][feature_name] = {"type": "discrete"}for value in X[feature_name].unique():self.class_cond_prob[i][feature_name][value] = 0index = (Y == i) & (X[feature_name] == value)self.class_cond_prob[i][feature_name][value] = X[feature_name][index].shape[0] / (Y == i).sum()def predict(self, X):# 通过朴素贝叶斯的方法预测结果# X是pd.DataFrameprediction = []for i in range(X.shape[0]):prob = np.ones(self.n_classes)for j in range(self.n_classes):for feature_name in X.columns:if feature_name not in self.class_cond_prob[j]:continueif self.class_cond_prob[j][feature_name]["type"] == "discrete":prob[j] *= self.class_cond_prob[j][feature_name][X.iloc[i, :][feature_name]]elif self.class_cond_prob[j][feature_name]["type"] == "zoning":for area, sub_prob in self.class_cond_prob[j][feature_name]["zoning"].items():if X.iloc[i, :][feature_name] >= area[0] and X.iloc[i, :][feature_name] < area[1]:prob[j] *= sub_probelif self.class_cond_prob[j][feature_name]["type"] == "gaussian":mean = self.class_cond_prob[j][feature_name]["mean"]std = self.class_cond_prob[j][feature_name]["std"]prob[j] *= norm.pdf(X.iloc[i, :][feature_name], mean, std)prediction.append(np.argmax(prob))return pd.DataFrame(prediction)def score(self, pred, target):assert len(pred) == len(target), "The length of predictions and targets must be equal."# 计算pred 和 target 中相同元素的个数return (pred == target).sum() / len(pred)

以上是我们复现的朴素贝叶斯算法的代码,对于特征,我们提供了三种模式,其中对于离散特征,我们仅需要
将其映射到对应的类别即可;对于连续特征,我们提供了两种模式分别是gaussian_processzoning_process

  1. 对于zoning_process,我们将连续特征划分为不同的区间,然后在每个区间内使用不同的概率分布来建模。
  2. 对于gaussian_process,我们使用高斯分布来建模模拟概率分布。

以下是我们调用自己实现的朴素贝叶斯方法的流程:

naivebayes = NaiveBayes()
train_X, train_Y = train_dataset.iloc[:, :-1], train_dataset.iloc[:, -1]# 采用zoning_process,划分5区间的朴素贝叶斯
naivebayes.fit(train_X, train_Y, discretization=True, area=4)
pred = naivebayes.predict(test_dataset.iloc[:, :-1])
score = naivebayes.score(pred.iloc[:, 0], test_dataset.iloc[:, -1])print("zoning_process area:4 acc:", score)# 采用zoning_process,划分5区间的朴素贝叶斯
naivebayes.fit(train_X, train_Y, discretization=True, area=8)
pred = naivebayes.predict(test_dataset.iloc[:, :-1])
score = naivebayes.score(pred.iloc[:, 0], test_dataset.iloc[:, -1])print("zoning_process area:8 acc:", score)# 采用zoning_process,划分5区间的朴素贝叶斯
naivebayes.fit(train_X, train_Y, discretization=True, area=12)
pred = naivebayes.predict(test_dataset.iloc[:, :-1])
score = naivebayes.score(pred.iloc[:, 0], test_dataset.iloc[:, -1])print("zoning_process area:12 acc:", score)# 采用gaussian_process方法处理
naivebayes.fit(train_X, train_Y, discretization=False)
pred = naivebayes.predict(test_dataset.iloc[:, :-1])
score = naivebayes.score(pred.iloc[:, 0], test_dataset.iloc[:, -1])print("gaussian_process acc:", score)
zoning_process area:4 acc: 0.7
zoning_process area:8 acc: 1.0
zoning_process area:12 acc: 0.9
gaussian_process acc: 0.9666666666666667

由实验结果可知,并不是说划分区间的越多,分类的准确率越高。在采用划分区域方法的时候选择合适的区域数,比如在划分5区间的朴素贝叶斯中,选择8个区域数,分类的准确率最高。同时,在采用高斯分布方法处理数据的时候,分类的准确率会较高,但也不一定完全优于划分区域的方法。

sklearn调用朴素贝叶斯

接下来我们演示一下朴素贝叶斯在sklearn中的使用。

from sklearn.naive_bayes  import GaussianNB
clf = GaussianNB()
clf.fit(train_X, train_Y)
pred = clf.predict(test_dataset.iloc[:, :-1])
score = clf.score(test_dataset.iloc[:, :-1], test_dataset.iloc[:, -1])
print("Accuracy:", score)
Accuracy: 0.9666666666666667

需要注意的是,朴素贝叶斯的算法强调了每个特征之间是相互独立的,但现实中,特征之间可能存在一定的关联关系。故在使用时需要注意。

高阶实验

最后我们这里提供了一个全新的数据集Mobile_phone_price_range_estimate;相较于之前的数据集,这个数据集的属性更多,并且属性之间存在一定的关联关系。该数据集主要作用是用来对比朴素贝叶斯和其他算法的性能的,为大家对算法侧重有一定的理解。

train_dataset = pd.read_csv('dataset\\Mobile_phone_price_range_estimate_train.csv')
test_dataset = pd.read_csv('dataset\\Mobile_phone_price_range_estimate_test.csv')naivebayes = NaiveBayes()train_X, train_Y = train_dataset.iloc[:, 1:-1], train_dataset.iloc[:, -1]
# 采用zoning_process,划分5区间的朴素贝叶斯
naivebayes.fit(train_X, train_Y, discretization=True, area=4)
pred = naivebayes.predict(test_dataset.iloc[:, 1:-1])
score = naivebayes.score(pred.iloc[:, 0], test_dataset.iloc[:, -1])print("zoning_process area:4 acc:", score)# 采用zoning_process,划分8区间的朴素贝叶斯
naivebayes.fit(train_X, train_Y, discretization=True, area=8)
pred = naivebayes.predict(test_dataset.iloc[:, 1:-1])
score = naivebayes.score(pred.iloc[:, 0], test_dataset.iloc[:, -1])print("zoning_process area:8 acc:", score)# 采用zoning_process,划分12区间的朴素贝叶斯
naivebayes.fit(train_X, train_Y, discretization=True, area=12)
pred = naivebayes.predict(test_dataset.iloc[:, 1:-1])
score = naivebayes.score(pred.iloc[:, 0], test_dataset.iloc[:, -1])print("zoning_process area:12 acc:", score)# 采用gaussian_process方法处理
naivebayes.fit(train_X, train_Y, discretization=False)
pred = naivebayes.predict(test_dataset.iloc[:, 1:-1])
score = naivebayes.score(pred.iloc[:, 0], test_dataset.iloc[:, -1])print("gaussian_process acc:", score)
zoning_process area:4 acc: 0.5375
zoning_process area:8 acc: 0.7275
zoning_process area:12 acc: 0.715
gaussian_process acc: 0.7725

总结

朴素贝叶斯算法是一种基于贝叶斯定理的分类方法,其核心思想是利用已知的一组条件独立假设,将复杂的联合概率分布简化,从而更高效地进行分类。该算法在许多领域都有广泛的应用,如文本分类、垃圾邮件过滤、情感分析等。

朴素贝叶斯算法的主要优点包括:

  1. 简单易理解: 朴素贝叶斯算法基于贝叶斯定理,因此其原理相对简单,容易理解。
  2. 高效: 由于该算法使用了条件独立假设,因此在计算概率时可以大大减少计算量,特别是当特征数量很大时,其效率更高。
  3. 对缺失值不敏感: 由于使用了条件独立假设,朴素贝叶斯算法对特征之间的相关性要求不高,因此对缺失值不敏感。
  4. 可扩展性强: 对于大量数据集,朴素贝叶斯算法可以很容易地进行扩展和改进。

然而,朴素贝叶斯算法也存在一些局限性:

  1. 对特征独立性假设的限制: 朴素贝叶斯算法的核心在于假设特征之间是独立的,但在实际应用中,这个假设往往不成立。这可能导致算法的性能受到限制。
  2. 对参数的依赖性: 朴素贝叶斯算法的性能高度依赖于参数的选择,如平滑参数的选择等。选择合适的参数值对于获得最佳分类效果至关重要。
  3. 对连续型特征的处理能力有限: 对于连续型特征,朴素贝叶斯算法通常采用离散化或分段的方式进行处理,这可能影响分类的准确性。

尽管存在这些局限性,朴素贝叶斯算法仍然是一种非常有价值的分类方法。在实际应用中,根据具体问题和数据集的特点,可以选择不同的朴素贝叶斯模型(如多项式朴素贝叶斯、伯努利朴素贝叶斯或高斯朴素贝叶斯)进行分类。同时,可以通过调整参数、特征选择和交叉验证等方法来提高算法的性能和准确性。

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

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

相关文章

为什么流不关闭会导致内存泄漏

引言 经常有人告诉你流用完要记得关&#xff0c;不然会导致内存泄漏&#xff0c;但你是否考虑过下面这些问题: 为什么流不关会导致内存泄漏&#xff1f;JVM不是有垃圾回收机制吗&#xff1f;这些引用我用完不就变垃圾了为什么不会被回收呢&#xff1f;流未关闭除了导致内存泄…

node的下载、安装、配置

下载&#xff1a; 官网下载&#xff1a;Node.js 左右两个都可以&#xff1a; 安装&#xff1a; 打开cmd&#xff1a; 输入以下指令&#xff0c;如果出现版本号说明安装成功 node -v npm -v 配置&#xff1a; 1、新建文件夹&#xff1a;node_cache和node_global作为npm“缓…

前端实现搜索功能

最近遇到一个需求,用户在输入框输入关键字之后,点击搜索按钮后进行搜索,如下图,选中的数据在下面,上面展现的是搜索后的数据,现在选中了2条数据: 当用户输入KET后点击搜索,搜出的结果有16条,勾选全选选中后,将选中的16条的数据加到之前已选的2条数据里,于是此时已选…

重磅!大模型框架 LangChain 首个稳定版本终于来了!

著名的大模型智能体工具&#xff0c;现在有大版本更新了。 不知不觉&#xff0c;LangChain 已经问世一年了。作为一个开源框架&#xff0c;LangChain 提供了构建基于大模型的 AI 应用所需的模块和工具&#xff0c;大大降低了 AI 应用开发的门槛&#xff0c;使得任何人都可以基于…

oracle角色管理

常用角色 CONNECT,RESOURCE,DBA,EXP_FULL_DATABASE,IMP_FULL_DATABASE 1角色可以自定义&#xff0c;语法与创建用户一样 CREATE role role1 IDENTIFIED by 123; 2授权权限给角色 --自定义角色 CREATE role role1 IDENTIFIED by 123; --授权权限给角色 GRANT create view, …

AI人工智能从业人员《自然语言及语音处理设计开发工程师》证书专项培训(第二期)通知!

工业和信息化部电子工业标准化研究院联合北京龙腾亚太教育咨询有限公司和北京龙腾智元信息技术有限公司于2024年1月成功在京举办AI人工智能从业人员《自然语言及语音处理设计开发工程师》证书专项培训第一期课程&#xff0c;所有学员成功通过考试。介于学员的良好反应&#xff…

设置flex布局的元素,其子元素宽度和超过其本身时,其宽度值未被撑起问题

如图父元素main-content设置了display:flex. 里面包含了不确定个数的子元素&#xff0c;子元素样式为&#xff1a; flex: 1; min-width: 240px;现在想获取父元素的宽度&#xff0c;发现无论子元素的个数为多少&#xff0c;父元素的宽度都是一样的大小&#xff0c;并没有被子元…

Docker与微服务实战(基础篇)

Docker与微服务实战&#xff08;基础篇&#xff09; 1、Docker简介2、Docker安装步骤1.Centos7及以上的版本2.卸载旧版本3.yum安装gcc相关4.安装需要的软件包5.设置stable镜像仓库【国内aliyun】6.更新yum软件包索引--以后安装更快捷7.安装Docker-Ce8.启动Docker9.测试10.卸载1…

Socket closed 异常解决方案:如何解决 JMeter 压测中的问题

问题描述 JMeter 压测时会报 java.net.SocketException: Socket closed java.net.SocketException: Socket closed at java.net.PlainSocketImpl.socketConnect(Native Method) at java.net.AbstractPlainSocketImpl.doConnect(AbstractPlainSocketImpl.java:350) at java.ne…

Temu、Shopee、Lazada等跨境流量如何提升?买家号如何批量养号?

现在在temu、Lazada、shopee等跨境电商平台开店的商家越来越多。如果商家想让商店的产品得到更多的展示&#xff0c;流量是必不可少的&#xff0c;平台的流量入口主要有几个板块。 让我们谈谈temu、Lazada、shopee搜索流量如何提升&#xff0c;有什么方法。 有两种方法可以在短…

usb转32串口方案

方案结构图 使用usb hub芯片扩展4路usb然后再一分八路串口 USB hub 选择hub芯片注意事项&#xff1a; 目前市场上多数的USB 2.0 Hub芯片,只有内建一个Transaction Translators(STT)&#xff0c;因此 当Hub接收到如Full Speed的装置进入时&#xff0c;12Mbps的「单一」信道…

使用Moonbuilders Academy平台,学习DApp开发

Moonbeam团队于2022年宣布开放Moonbuilders Academy。这是一套以开发为中心的异步学习课程&#xff0c;用于学习如何在Moonbeam上构建跨链DApp。 如何从官网进入平台&#xff1f; 点击http://moonbeam.network 鼠标移动至 “Builders”&#xff0c;在Resources下方选择“Moo…

2024腾讯爱奇艺首发片单,谁能率先拿下开年爆款?

刚进入2024年&#xff0c;头部长视频平台就开启了新一轮“内卷”。 腾讯和爱奇艺不约而同地在2024年的第一天发布了新剧片单&#xff0c;多部高质量精品大剧蓄势待发&#xff0c;点燃了观众和市场的期待。 2023年之争已经落下帷幕&#xff0c;爱奇艺凭借大爆剧《狂飙》拔得头…

Next City 数都上海应用创新大赛结果公布,子虔科技获奖

12月16日&#xff0c;以“应变求机 以数谋新”为主题的上海城市数字化转型体验周举办。作为上海城市数字化转型年终重磅活动&#xff0c;上海市人民政府副秘书长庄木弟&#xff0c;市经济和信息化工作党委书记程鹏&#xff0c;杨浦区委副书记、区长周海鹰&#xff0c;市经济和信…

Apache ActiveMQ 远程代码执行漏洞分析

漏洞简介 Apache ActiveMQ官方发布新版本&#xff0c;修复了一个远程代码执行漏洞&#xff0c;攻击者可构造恶意请求通过Apache ActiveMQ的61616端口发送恶意数据导致远程代码执行&#xff0c;从而完全控制Apache ActiveMQ服务器。 影响版本 Apache ActiveMQ 5.18.0 before …

统信UOS虚拟机安装VirtualBox扩展使用USB功能

为什么要安装VirtualBox扩展包&#xff1f; 安装 Oracle VM VirtualBox 扩展包的原因是&#xff0c;它提供了对 USB 2.0、USB 3.0、远程桌面协议 VRDP&#xff08;VirtualBox Remote Desktop Protocol&#xff09;等实用功能的支持&#xff0c;以增强 VirtualBox 的功能。这些…

HarmonyOS 应用开发学习笔记 ets组件生命周期

HarmoryOS Ability页面的生命周期 Component自定义组件 ets组件生命周期官放文档 本文讲解 ets组件的生命周期&#xff0c;在此之前大家可以先去了解Ability的生命周期&#xff0c;这两个生命周期有有一定的关联性 在开始之前&#xff0c;我们先明确自定义组件和页面的关系&…

RPA财务机器人在厦门市海沧医院财务管理流程优化汇总的应用

目前国内外研究人员对于RPA机器人在财务管理流程优化领域中的应用研究层出不穷&#xff0c;但现有研究成果主要集中在财务业务单一领域&#xff0c;缺乏财务管理整体流程一体化管控的研究。RPA机器人的功能绝非单一的财务业务处理&#xff0c;无论从自身技术发展&#xff0c;或…

常见的Latex公式所用到的内容汇总

行内公式 f ( x ) a b f(x)ab f(x)ab 左右各加一个$&#xff0c;即为行内公式 $ f(x) ab $行间公式 $$ f(x) ab $$f ( x ) a b f(x)ab f(x)ab 手动编号 $$ f(x) a - b \tag{1.1} $$f ( x ) a − b (1.1) f(x)a-b \tag{1.1} f(x)a−b(1.1) 简单运算 -*/以及阿拉伯…

为什么大型服务器要用 Linux 系统?

为什么大型服务器要用 Linux 系统&#xff1f; 在开始前我有一些资料&#xff0c;是我根据网友给的问题精心整理了一份「Linux的资料从专业入门到高级教程」&#xff0c; 点个关注在评论区回复“888”之后私信回复“888”&#xff0c;全部无偿共享给大家&#xff01;&#xff…