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

这篇具有很好参考价值的文章主要介绍了机器学习原理到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    float64
 1   SepalWidth   120 non-null    float64
 2   PetalLength  120 non-null    float64
 3   PetalWidth   120 non-null    float64
 4   Species      120 non-null    int64  
dtypes: float64(4), int64(1)
memory usage: 4.8 KB
SepalLength SepalWidth PetalLength PetalWidth Species
0 6.4 2.8 5.6 2.2 2
1 5.0 2.3 3.3 1.0 1
2 4.9 2.5 4.5 1.7 2
3 4.9 3.1 1.5 0.1 0
4 5.7 3.8 1.7 0.3 0

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

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-1
                axes[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])


机器学习原理到Python代码实现之NaiveBayes【朴素贝叶斯】,基于python的算法设计,机器学习,机器学习,python,人工智能
机器学习原理到Python代码实现之NaiveBayes【朴素贝叶斯】,基于python的算法设计,机器学习,机器学习,python,人工智能

[ 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 = None
        self.class_cond_prob = None
        self.discretization = None
        self.n_classes = None

    # 该函数将输入某一个维度的连续特征,将返回服从高斯分布的特征参数
    def gaussian_process(self, feature):
        # feature是pd.DataFrame
        mean = feature.mean()
        std = feature.std()
        return mean, std
    
    # 该函数将输入某一个维度的连续特征,将返回划分区域的area个区域,同时需要考虑到在feature分布外的数据[-inf, inf]
    def zoning_process(self, feature, area=5):
        # feature是pd.DataFrame
        min_value = feature.min() - 0.01
        max_value = feature.max() + 0.01
        step = (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.Series
        self.discretization = discretization
        # 计算class_prob
        self.class_prob = Y.value_counts(normalize=True).to_dict()
        self.n_classes = len(self.class_prob.keys())

        # 计算class_mean
        self.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] = 0
                        index = (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.DataFrame
        prediction = []
        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]:
                        continue
                    if 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_prob
                    elif 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. 对连续型特征的处理能力有限: 对于连续型特征,朴素贝叶斯算法通常采用离散化或分段的方式进行处理,这可能影响分类的准确性。

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

到了这里,关于机器学习原理到Python代码实现之NaiveBayes【朴素贝叶斯】的文章就介绍完了。如果您还想了解更多内容,请在右上角搜索TOY模板网以前的文章或继续浏览下面的相关文章,希望大家以后多多支持TOY模板网!

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处: 如若内容造成侵权/违法违规/事实不符,请点击违法举报进行投诉反馈,一经查实,立即删除!

领支付宝红包 赞助服务器费用

相关文章

  • 【Chatgpt4 教学】 NLP(自然语言处理)第九课 朴素贝叶斯分类器的工作原理 机器学习算法

    我在起,点更新NLP自然语言处理==》《 王老师带我成为救世主 》 为啥为它单独开章,因为它值得,它成功的让我断了一更,让我实践了自上而下找能够理解的知识点,然后自下而上的学习给自己的知识升级,将自己提升到能够解决当前遇到的问题的水平。 (1)--------------

    2023年04月15日
    浏览(49)
  • 机器学习——基于朴素贝叶斯分类算法实现垃圾邮件分类

    贝叶斯定理: 贝叶斯理论指的是,根据一个已发生事件的概率,计算另一个事件的发生概率。贝叶斯理论从数学上的表示可以写成这样:  ,在这里A和B都是事件, P(B)P(B)不为0。 在贝叶斯定理中: 1. P(A) 称为”先验概率”,即在B事件发生之前,我们对A事件概率的一个判断。如

    2024年02月04日
    浏览(51)
  • 机器学习图像特征提取—SIFT特征提取原理及代码实现

    目录 1 SIFT简介 2 SIFT原理及特点 2.1 SIFT算法特点 2.2 SIFT特征检测 3 SIFT代码实现        SIFT,即尺度不变特征变换(Scale-invariant feature transform,SIFT),是用于图像处理领域的一种描述。这种描述具有尺度不变性,可在图像中检测出关键点,是一种局部特征描述子。       SIF

    2024年02月06日
    浏览(39)
  • 机器学习——XGboost原理及python实现

    XGBoost 算法是boost 集成算法中的一种,Boosting 算法的思想是将许多弱分类器集成在一起形成一个强分类器。XGBoost 是一种提升树模型,是将许多树模型集成在一起,形成强分类器。XGBoost 中使用的弱分类器为CART (classification and regression tree)回归树。 xgboost并没有提出一种新的

    2024年02月05日
    浏览(35)
  • 基于机器学习算法:朴素贝叶斯和SVM 分类-垃圾邮件识别分类系统(含Python工程全源码)

    本项目采用朴素贝叶斯和支持向量机(SVM)分类模型作为基础,通过对垃圾邮件和正常邮件的数据进行训练,旨在实现垃圾邮件的自动识别功能。 通过训练这两个分类模型,我们的目标是建立一个高效准确的垃圾邮件识别系统。当接收到新的邮件时,系统将对邮件文本进行预

    2024年02月09日
    浏览(49)
  • 机器学习 C4.5算法原理 + 决策树分裂详解(离散属性+连续属性) 附python代码

    一.C4.5算法的简介: C4.5并不是单单一个算法而是 一套算法 ,主要用于对机器学习和数据挖掘中的分类问题。它是一种有监督的学习,也就是说对于该算法我们需要 先给它们提供一个数据集 ,这个数据集包含多个实例,每个实例都包含多个属性,该实例用这些属性描述, 根

    2024年02月08日
    浏览(54)
  • python机器学习——分类模型评估 & 分类算法(k近邻,朴素贝叶斯,决策树,随机森林,逻辑回归,svm)

    交叉验证:为了让被评估的模型更加准确可信 交叉验证:将拿到的数据,分为训练和验证集。以下图为例:将数据分成5份,其中一份作为验证集。然后经过5次(组)的测试,每次都更换不同的验证集。即得到5组模型的结果,取平均值作为最终结果。又称5折交叉验证。 通常情

    2024年02月03日
    浏览(65)
  • A.图机器学习(GML)&图神经网络(GNN)原理和代码实现(前置学习系列二)

    图学习图神经网络算法专栏简介:主要实现图游走模型(DeepWalk、node2vec);图神经网络算法(GCN、GAT、GraphSage),部分进阶 GNN 模型(UniMP标签传播、ERNIESage)模型算法等,完成项目实战 专栏链接 :图学习图神经网络算法专栏简介:含图算法(图游走模型、图神经网络算法等)原

    2024年02月01日
    浏览(39)
  • 决策树的原理、方法以及python实现——机器学习笔记

    * * * * * *  The Machine Learning Noting Series  * * * * * * 决 策树(Decision Tree)是机器学习的核心算法之一,在较小训练样本或有限计算资源下仍有较好表现,它包括分类树和回归树,是目前应用最广泛的分类预测和回归预测方法。 0 引言 1 决策树的概念     分类树     回归树 2  

    2024年02月04日
    浏览(50)
  • [机器学习]K-means算法详解:原理、优缺点、代码实现、变体及实际应用

    文章首发于若绾 [机器学习]K-means算法详解:原理、优缺点、代码实现、变体及实际应用,转载请注明出处。 K-means算法是一种非常流行的无监督学习方法,主要应用于聚类问题。本篇博客将详细介绍K-means算法的原理、优缺点及实际应用场景。 K-means算法的核心思想是将数据划分

    2024年02月08日
    浏览(39)

觉得文章有用就打赏一下文章作者

支付宝扫一扫打赏

博客赞助

微信扫一扫打赏

请作者喝杯咖啡吧~博客赞助

支付宝扫一扫领取红包,优惠每天领

二维码1

领取红包

二维码2

领红包