Python朴素贝叶斯算法代码

2025年1月5日 | 17 分钟阅读

假设您是一名产品经理,希望将客户评价分为好评和差评两类。或者作为贷款经理,您希望识别哪些贷款申请人是安全的,哪些是危险的?作为一名医疗分析师,您希望预测哪些人会患糖尿病。在所有情况下,都存在对评论、贷款申请和患者进行分类的问题。

朴素贝叶斯是最简单、最快速的分类技术,适用于处理大量数据。许多应用程序,包括垃圾邮件过滤、文本分类、情感分析和推荐系统,都成功地使用了朴素贝叶斯分类器。它应用贝叶斯概率定理进行类别预测。

分类工作流程

进行分类时,第一步是理解问题,找到潜在特征,并给它们分配标签。特征是那些影响标签结果的特性或品质。例如,银行管理层会了解客户的就业、收入、年龄、位置、过往贷款记录、交易记录和信用评分,以进行贷款发放。这些特性被称为帮助模型对客户进行分类的特征。

分类过程由学习阶段和评估阶段组成。分类器在学习阶段使用给定的数据集训练其模型,并在评估阶段评估性能。性能根据准确度、误差、精确度和召回率等多种因素进行评估。

Python Code for Naive Bayes Algorithm

什么是朴素贝叶斯分类器?

朴素贝叶斯是一种基于贝叶斯定理的统计分类方法。它是最简单的监督学习方法之一。朴素贝叶斯分类器是一种快速、准确、可靠的方法。在大型数据集上,朴素贝叶斯分类器执行速度快且准确。

朴素贝叶斯分类器假设单个特征对类别的影响与其他特征的影响无关。例如,贷款申请人的适用性取决于他们的收入、贷款和交易历史、年龄和地理位置等因素。这些特征仍然被单独考虑,尽管它们是相互关联的。这种假设被认为是朴素的,因为它使计算更容易。这种假设被称为“类别条件独立性”。

Python Code for Naive Bayes Algorithm
  • P(h):在所有可用信息下,假设 h 正确的可能性。这被称为 h 的先验概率。
  • P(D):数据发生的可能性,独立于假设。这被称为先验概率。
  • P(h|D):在给定数据 D 的情况下,假设 h 发生的可能性。这被称为“后验概率”。
  • P(D|h):如果假设 h 为真,数据 d 存在的可能性。这被称为“后验概率”。

朴素贝叶斯分类器如何运作?

让我们用一个例子更好地理解朴素贝叶斯的工作原理。以玩体育和天气为例。您应该确定参与体育的可能性。您现在应该根据天气对参与者是否会玩进行分类。

第一种方法(在单个特征的情况下):朴素贝叶斯分类器执行以下计算来确定事件的可能性

在步骤 2 中确定每个类别中每个特征的可能性概率。在步骤 3 中确定给定类别标签的先验概率。将这些值输入贝叶斯公式并计算后验概率。

步骤 4:确定输入属于较高概率类别时,哪个类别的可能性更大。

频率表和似然表这两个表可以简化先验和后验概率的计算。可以使用其中任何一个表来计算先验和后验概率。频率表列出了每个特征的标签频率。显示了两个概率表。似然表 1 显示了标签的先验概率,而似然表 2 显示了后验概率。

Python Code for Naive Bayes Algorithm

您想确定在多云天气下玩耍的可能性。

参与的可能性

P(是 | 阴天) 等于 P(是 | 阴天)。P (是) / P (阴天) .....................(1)

确定先验概率

P(阴天) = 4/14 = 0.29

P(是) = 9/14 = 0.64

首先,确定后验概率。

P(阴天 | 是) = 4/9 = 0.44

使用先验和后验概率填写方程 (1)。P (是 | 阴天) = 0.44 * 0.64 / 0.29 = 0.98 (更高)。

同样,您可以确定不参与的可能性

不参与的几率:P(否 | 阴天) = P(否 | 阴天)。P(否) / P (阴天)..........(2)

确定先验概率

P(阴天) = 4/14 = 0.29 P(否) = 5/14 = 0.36

首先,确定后验概率。

P(阴天 | 否) = 0/9 = 0。

1. 将过去和未来的概率包含在方程 (2) 中。

P (否 | 阴天) 等于 0*0.36/0.29,即零。

“是”类别的可能性更大。因此,您可以评估如果天气多云,参与者是否会参与这项运动。

第二种方法(当存在多个特征时)

Python Code for Naive Bayes Algorithm

您想确定在多云和温暖的天气下玩耍的可能性。

参与的可能性

P(天气=阴天, 温度=温和 | 玩= 是) = (玩= 是 | 天气= 阴天, 温度=温和)P(玩=是) (1) P(玩=是, 天气=阴天, 温度=温和)=P(阴天 |是) P(温和 |是)..........(2)

  1. 确定先验概率:P(是) = 9/14 = 0.64
  2. 确定先验概率:P(阴天 | 是) = 4/9 = 0.44 P(温和 |是) = 4/9 等于 0.44。
  3. 将后验概率输入方程 (2),如下所示:P(天气=阴天, 温度=温和 | 玩= 是) = 0.44 * 0.44 = 0.1936(更高)。
  4. 使用先验和后验概率填写方程 (1):P(玩=是 | 天气=阴天, 温度=温和) = 0.1936*0.64 = 0.124

同样,您可以确定不参与的可能性

不参与的可能性

P(天气=阴天, 温度=温和 | 玩= 否) = (玩= 否 | 天气= 阴天, 温度=温和)P(玩=否)... (3)

天气:阴天,温和,玩:否,P(天气:阴天 | 玩:否) P(温度=低 | 玩=无) ………..(4)

  1. 确定先验概率:P(否) = 5/14 = 0.36
  2. 确定后验概率。例如,P(天气=阴天 | 玩=否) = 0/9 = 0,P(温度=温和 | 玩=否) = 2/5 = 0.4
  3. 将后验概率输入以下方程:P(天气=阴天, 温度=温和 | 玩=否) = 0 * 0.4 = 0。
  4. 使用先验和后验概率填写方程 (3)。P(玩= 否 | 天气= 阴天, 温度:温和) = 0*0.36 = 0。

“是”类别的可能性更大。因此,可以得出结论,当天空阴沉时,运动员将参加他们的运动。

朴素贝叶斯分类器

使用合成数据集在 Scikit-Learn 中构建

在第一个示例中,我们将使用 scikit-learn 创建人工数据,然后训练和评估高斯朴素贝叶斯算法。

建立数据集

为了创建数据集和测试多种机器学习算法,Scikit-learn 为我们提供了一个机器学习环境。

在此实例中,正在使用“make_classification”函数创建包含六个特征、三个类别和 800 个样本的数据集。

说明

此代码导入了 sklearn.datasets 模块中的 make_classification 函数。

  • 对于分类任务,make_classification 函数创建一个随机数据集。
  • 该函数接受以下参数:数据集的特征数量,也称为独立变量,称为 n_features。
  • 这种情况有六个方面。
  • n_classes:数据集中有多少个类(或目标变量)。
  • 在此实例中有三个类。
  • n_samples:数据集的总样本数(或观测值)。
  • 这种情况有 800 个样本。
  • 数据集的信息性特征计数,n_informative。
  • 这些特征对目标变量有实际影响。
  • 在此实例中有两个信息性特征。
  • random_state:随机数生成器的种子值。
  • 这确保了数据集的可重现性。
  • n_clusters_per_class:每个类别有多少个簇。
  • 这控制了课程之间的距离。
  • 在此实例中,每个类别只有一个簇。
  • 该函数返回两个数组 X:一个形状为 (n_samples, n_features) 的数组,其中包含数据集的特征。
  • y:一个形状为 (n_samples) 的数组,其中包含数据集的目标变量。

为了显示数据集,我们将使用 matplotlib.pyplot 中的散点图函数。

说明

在导入 matplotlib.pyplot 模块后,使用 scatter() 方法生成散点图。

  • 假定 X 和 Y 变量是已经建立的数组或数据帧。
  • scatter() 方法接受以下三个参数:X 数组的第一列和第二列分别由变量 X[:, 0] 和 X[:, 1] 表示,c=y 根据 y 数组中的相应值给每个点着色。
  • marker 参数(在此示例中为星号)确定用于每个点的标记类型。
  • X 的第一列中的值将绘制在 x 轴上,X 的第二列中的值将显示在 y 轴上,每个点将根据其在 y 中的相应值着色。

正如我们所看到的,有三种不同的目标标签类型,我们将开发一个多类分类模型。

划分训练集和测试集

在开始训练过程之前,我们必须将数据集分为训练集和测试集,以便进行模型评估。

说明

  • 此代码从 sklearn.model_selection 模块导入 train_test_split 函数。
  • 此函数用于划分数据集,创建训练集和测试集。
  • train_test_split 函数需要四个参数:X、y、test_size 和 random_state。
  • y 表示目标变量,X 表示输入特征。
  • test_size 是应分配给测试集的数据集百分比。
  • 在此实例中,它设置为 0.33,表示将使用 33% 的数据进行测试。
  • 通过使用 random_state 配置随机数生成器的种子,您可以确保每次程序执行时都会生成相同的随机划分。
  • X_train、X_test、Y_train 和 Y_test 变量是该函数返回的四个变量。
  • X_train 和 y_train 是训练集,而 X_test 和 y_test 是测试集。
  • 可以使用这些变量来测试和训练人工智能模型。

模型构建与训练

构建一个通用高斯朴素贝叶斯模型,然后使用训练数据对其进行训练。然后,将随机测试样本输入模型以获得预测值。

说明

此代码使用 scikit-learn 包创建高斯朴素贝叶斯分类器。

  • 代码首先从 sklearn.naive_bayes 模块导入 GaussianNB 类。
  • 之后,将 GaussianNB 类的新实例赋予变量“model”。
  • 之后,使用 fit() 方法训练模型,该方法需要训练数据 (X_train) 和关联的目标值 (y_train)。
  • 模型用于预测单个测试数据点(由 X_test 数组中的第七个元素表示)的结果,一旦它被训练。
  • “predicted”变量包含预测值。
  • 最后,y_test[6] 打印测试数据点的实际值,predicted[0] 打印预期值。

输出

Actual Value: 0
Predicted Value: 0

模型评估

我们不会在尚未看到的测试数据集上训练模型。首先,我们将对测试数据集的值进行预测,并利用这些预测来计算准确率和 F1 分数。

输出

Accuracy: 0.8484848484848485
F1 Score: 0.8491119695890328

说明

  • 此代码从 sklearn.metrics 包导入 accuracy_score、confusion_matrix、ConfusionMatrixDisplay 和 f1_score 方法。
  • 这些操作用于评估机器学习模型的运行情况。
  • 然后,代码使用模型。预测函数为测试数据 (X_test) 生成预测。
  • accuracy_score 和 f1_score 函数用于将这些预测与实际标签 (y_test) 进行比较。
  • 代码在计算模型预测的准确率(使用 accuracy_score 函数)和 F1 分数(精度和召回率的加权平均值,使用 f1_score 函数)后,打印出模型的准确率和 F1 分数。
  • 它显示了使用给定数据开发的模型的 F1 分数和准确率。
  • 准确率为 0.84848484848485,这表明在 84.8% 的情况下,模型准确地预测了结果。

F1 分数,通过考虑精确度和召回率来衡量模型的准确性,为 0.8491119695890328。更高的 F1 值表示模型性能更好。

计算混淆矩阵的真阳性和真阴性时,我们将使用“confusion_matrix”函数。显示带有标签的混淆矩阵时,我们将使用“ConfusionMatrixDisplay”函数。

说明

此代码中使用 ConfusionMatrixDisplay 生成混淆矩阵,使用 scikit-learn 模块。

  • 首先构建一个包含值 0、1 和 2 的标签列表。
  • 之后,调用 confusion_matrix 函数,将标签列表、测试标签 (y_test) 和预测标签 (y_pred) 作为输入。
  • 结果生成一个带有指定标签的混淆矩阵。
  • 之后,将混淆矩阵和标签列表作为输入,生成 ConfusionMatrixDisplay 对象。
  • 然后,在显示对象上使用 plot 方法以图形方式显示混淆矩阵。

我们可以通过缩放、预处理交叉验证和超参数调整来提高模型性能。我们的模型表现相当不错。

带有朴素贝叶斯分类器的贷款数据集

让我们使用实际数据集来训练朴素贝叶斯分类器。除了数据探索和准备,我们将重复大部分操作。

数据加载

在此示例中,我们将使用 pandas 的“read_csv”方法从 DataCamp Workspace 加载贷款数据。

说明

  • 此代码中使用“pd”别名导入 pandas 库。
  • 接下来,使用 pandas 的 read_csv() 函数读取名为“loan_data.csv”的 CSV 文件,并将生成的 DataFrame 分配给变量 df。
  • 最后,它使用 head() 函数显示 DataFrame 的前五行。
  • 此代码使用 Python 创建。

数据探索

'.info()' 将用于了解有关数据集的更多信息。

  • 数据集包含 9578 行和 14 列。
  • 除“purpose”外,列均为浮点数或整数。
  • “Not.fully.paid”是我们所追求的列。

说明

此 Python 程序在带有标识符 df 的 Pandas DataFrame 对象上调用 info() 函数。

为了快速了解 DataFrame 的结构和内容,info() 函数提供了 DataFrame 的摘要,包括行数和列数、每列的数据类型以及每列中的非空值数量。

说明

此代码片段显示了一个包含 9578 个条目和 14 列的数据集的摘要。

  • 第一行显示索引范围,即 0 到 9577。
  • 第二行显示每个列的非空值总数和数据类型。
  • 列标题显示在右侧,数字标识列。
  • Dtype 列显示每个列的数据类型,可以是 float64、int64 或 object。
  • 还显示了数据集的内存使用情况,即 1.0+ MB。
  • 此摘要描述了数据集及其结构,这可能有助于数据探索和分析。

在这种情况下,我们将创建一个模型来识别尚未全额偿还贷款的客户。让我们使用 Seaborn 的 countplot 来检查目的和目标列。

说明

此 Python 工具 seaborn 和 matplotlib 用于计算 df 数据框中的目的列,并使用 not.fully.paid 列按颜色分隔条形图。

  • 该图是使用 seaborn 的 sns.countplot() 函数制作的,数据参数设置为 df 以选择要使用的数据框。
  • hue 参数设置为“not.fully.paid”以根据该列中的值按颜色区分条形图,x 参数设置为“purpose”以定义要绘制的列。
  • x 轴标签旋转 45 度并向右对齐,以便于阅读,使用 matplotlib plt.xticks() 方法。

我们数据集中的不平衡将影响模型的性能。要获得处理不平衡数据集的实践经验,请参阅教程“重采样不平衡数据集”。

数据处理

现在我们将使用 pandas 的“get_dummies”方法将分类“purpose”列转换为整数。

说明

此代码使用 Python pandas 包为 DataFrame 'df' 的 'purpose' 列生成虚拟变量。

  • pd.get_dummies() 方法对给定列中的每个不同值创建一个新的 DataFrame,其中包含二进制列。
  • 在此实例中,它为“purpose”列中的每个不同值创建新列。
  • drop_first=True 选项从回归模型中删除第一列,以防止多重共线性。
  • 创建新 DataFrame,使用 .head() 函数显示其前几行,然后将其分配给变量 pre_df。

一旦我们指定了特征 (X) 和目标 (Y) 变量,数据集将被划分为训练集和测试集。

说明

此代码从 sklearn.model_selection 模块导入 train_test_split 函数。

  • 之后,代码构建变量 X 和 y。
  • Y 被赋予 pre_df 数据框中 not.fully.paid 列的值,而 X 被赋予 pre_df 数据框中除 not.fully.paid 列之外的所有其他列的值。
  • 之后调用 train_test_split 函数,参数为 X、y、test_size=0.33 和 random_state=125。
  • 此函数用于将数据划分为训练集和测试集。
  • random_state 参数定义了用于拆分过程的随机数生成器的种子,而 test_size 参数表示应用于测试的数据百分比。
  • X_train、X_test、Y_train 和 Y_test 是该函数返回的四个变量。
  • X 和 y 数据的训练集和测试集包含在这些变量中。
  • 训练集用于开发机器学习模型,而测试集用于评估模型的有效性。

模型构建与训练

构建和训练模型非常容易。在训练数据集上,我们将训练一个具有默认超参数的模型。

说明

此代码中使用 from sklearn.naive_bayes import GaussianNB 行从 Scikit-Learn 库导入高斯朴素贝叶斯算法。

  • 然后使用 model = GaussianNB() 表达式生成 GaussianNB 模型的新实例。
  • X_train 和 y_train(训练数据)作为参数传入,最后在模型对象上执行 fit() 函数。
  • 这使用提供的数据来训练模型。
  • 总的来说,此代码使用提供的训练数据创建并训练了一个高斯朴素贝叶斯模型。

模型评估

我们将使用准确率和 F1 分数来衡量模型性能,高斯朴素贝叶斯方法表现得相当不错。

说明

此代码从 sklearn.metrics 模块导入 accuracy_score、confusion_matrix、ConfusionMatrixDisplay、f1_score 和 classification_report 方法。

  • 这些操作用于评估机器学习模型的运行情况。
  • 然后,代码使用模型对象的 predict 函数为一组称为 X_test 的测试数据提供预测。y_pred 变量包含这些预测。
  • 接下来,代码分别使用 accuracy_score 和 f1_score 函数确定模型的预测准确率和 F1 分数。
  • accuracy_score 函数通过比较 y_test 中的真实标签和 y_pred 中的预测标签来计算准确预测的百分比。

然后,代码使用 print 函数将准确率和 F1 分数报告到控制台。f1_score 函数计算 F1 分数,它是精确度和召回率的加权平均值。

说明

此代码片段是某些代码运行的结果,而不是实际代码本身。

  • 它显示了使用给定数据开发的模型的 F1 分数和准确率。
  • 更高的准确率和 F1 分数表明模型在数据上运行良好;准确率衡量模型正确预测数据类别的频率,而 F1 分数衡量模型的精确度和召回率。

我们可以观察到,由于数据不平衡,混淆矩阵提供了不同的叙述。在少数目标“未全额支付”中发现了更多错误标记的数据。

说明

此代码片段可用于绘制二元分类问题的混淆矩阵。

  • 首先,使用术语“全额支付”和“未全额支付”建立标签列表。
  • 接下来,使用 confusion_matrix() 函数计算混淆矩阵,该函数接受真实标签 (y_test) 和预测标签 (y_pred) 作为输入。
  • 然后将混淆矩阵和标签列表输入到 ConfusionMatrixDisplay 对象的创建中。
  • 然后通过在 ConfusionMatrixDisplay 对象上使用 plot() 函数来显示混淆矩阵图。

如果您在训练或模型评估方面需要帮助,请查看带有 Scikit-learn Workspace 的朴素贝叶斯分类教程。它包括数据集、源代码和结果。

零概率问题

如果数据集中不存在危险贷款的元组,则后验概率将为 0,模型将无法预测任何内容。此问题被称为零概率,因为不存在该特定类别的实例。

拉普拉斯校正或拉普拉斯变换可用于解决此类问题。拉普拉斯调整是一种实现平滑的方法。在这里,您可以假设数据集足够大,如果您添加每种类型的一行,估计的概率将保持不变。这将解决概率值为零的问题。

例如,假设数据库包含 1000 个类别为贷款风险的训练元组。此数据库的收入字段中,低收入有 0 个元组,中等收入有 990 个,高收入有 10 个。如果没有拉普拉斯调整,这些事件的几率分别为 0、0.990(来自 990/1000)和 0.010(来自 10/1000)。

现在对给定的数据集应用拉普拉斯调整。对于每个收入-值对,让我们再添加一个元组。这些事件的可能性

优点

  • 使用这种策略进行预测不仅简单,而且快速准确。
  • 与连续变量相比,朴素贝叶斯在离散响应变量上表现更好,可用于涉及多类别数据的问题,并且计算成本非常低。
  • 它在文本分析问题中也表现良好。
  • 当独立性假设成立时,朴素贝叶斯分类器比逻辑回归等其他模型表现更好。

缺点

  • 假设存在不同的特征。实际上,模型获得一组 100% 独立的预测器是非常不可能的。
  • 当某个类别的训练元组不存在时,导致零后验概率。在这种情况下,模型无法预测。此问题被称为零概率/频率问题。

结论

您已完成本教程,恭喜!

在本课程中,您学习了朴素贝叶斯方法、其工作原理、假设问题、其实现以及其优缺点。您还学习了在 scikit-learn 中为二元和多项式类别开发和评估模型。

最基本和最有效的方法是朴素贝叶斯。即使机器学习在过去几年取得了巨大进步,它仍然证明了其有用性。它已成功应用于各种应用程序,包括文本分析和推荐引擎。


下一个主题Python 预测算法