机器学习的实践方法(六)——朴素贝叶斯

谢谢

本文参考文献如下

拉普拉斯平滑(Laplacian smoothing)_潜心学习的渣渣的博客-CSDN博客_拉普拉斯平滑

极大似然估计详解_知行流浪-CSDN博客_极大似然估计

极大似然估计原理详细说明_majunfu-CSDN博客_极大似然估计的原理

(1条消息) 多项式分布的理解概率公式的理解_猪逻辑公园-CSDN博客_多项式分布

常用的概率分布:伯努利分布、二项式分布、多项式分布、先验概率,后验概率 – 志光 – 博客园 (cnblogs.com)

十分钟学习 统计学习方法 李航 第二版 之《4.1 朴素贝叶斯法:核心——贝叶斯定理》_哔哩哔哩_bilibili

【AI 版】十分钟学习 统计学习方法 李航 第二版 之《4.4 朴素贝叶斯法:极大似然法之原理篇》_哔哩哔哩_bilibili

6 朴素贝叶斯

6.1 概述

在这节课中,我们将学习朴素贝叶斯算法。它属于监督学习。

贝叶斯分类是分类算法的总称,都是基于贝叶斯定理的,所以统称为贝叶斯分类。

贝叶斯分类器的主要特点是:

  • 属性可以是离散的或稳定的。
  • 数学基础扎实,分类效率稳定。
  • 对丢失和嘈杂的数据不太敏感。
  • 如果属性不相关,则属性适用于分类,如果相关,则不低于决策树

让我们来直观对比一下KNN和朴素贝叶斯吧。在KNN中,我们通过模型来预测的结果一般可以通过和某类别的点距离远近给出该样本的所在分类;而对于朴素贝叶斯来说,其一般是算出该样本在各个类别中的概率,在哪个类别概率大就属于哪个类别。

image-20220307125019631

现在假设我们引发一个事件。

有一天我们坐在办公室里,看到有人快速的走过,我们没有看到这个人是谁。但是我们做一个猜测,Alex和Brenda坐在办公室的时间一样长,那么这两人都各有百分之五十的概率是那个快速走过的人。

image-20220307125234329

那现在我们又有一条新的推断信息,两个人都有一件红色的毛衣,而那个快速走过的人身上就穿了一件红色的毛衣。对于Alex来说她一个星期穿两次,而Brenda一个星期穿三次,所以这样的话快速走过的人是Alex的概率变成了百分之四十,是Brenda的概率变成了百分之六十。

image-20220307125409828

在这里,我们得到的 50% 是我们没有新信息时的先验概率。然后在我们获得新信息后,我们得到了 40% 和 60%。最后猜测的这两个概率称为后验概率。

现在还是刚才那个例子,加入我们还是看到一个人飞跑过去,跑的太快我们没注意,然后靠推断看看这个人是谁。我们最开始知道的消息是,Alex一个星期中有三天是待在办公室的,而Brenda一个星期只有一天是待在办公室的。所以Alex的先验概率是0.75,而Brenda是0.25,然后我们假设连续好几周都是这种情况,那么我们可以很简单的列一个表格。

image-20220307125535966

那么现在很先前一样,Alex每周有两次穿红色毛衣,而Brenda每周有三次穿红色毛衣。那么穿毛衣总数我们把他在表格中标红,两人穿红色毛衣的次数共九次。

因此,如果我们看到一个穿着红色毛衣的人快速经过,这个人是Alex的概率(后验概率)是三分之二,是Brenda的概率(后验概率)是三分之一。那么穿毛衣总数我们把他在表格中标红,两人穿红色毛衣的次数共九次。

image-20220307125629262

因此,如果我们看到一个穿着红色毛衣的人快速经过,这个人是Alex的概率(后验概率)是三分之二,是Brenda的概率(后验概率)是三分之一。

一般来说,先验概率是主观判断的概率。在一些新的信息改变了我们的主观判断之后,我们得出的最终结论称为后验概率。

让我们用以下数学来做一次:

我们开始的时候,Alex一个星期在办公室三次,Brenda一个星期在办公室一次,那么就是四分之三和四分之一的概率,而后,两人穿红毛衣的概率和不穿红毛衣概率分别是0.4和0.6,0.6和0.4。然后分别计算他们的条件概率,如下图所示。

image-20220307125713650

但是,我们只想找到那个人,而找不到的因素与我们无关,所以我们将其他因素四舍五入,使主要因素的总和成为一。

image-20220307125754581

从上图中,我们可以概括出步骤,那么可以得到贝叶斯公式如下。

image-20220307125817997

现在让我们用一个更好的例子来理解贝叶斯公式。

假如你身体不舒服,要去医院看医生,医生告诉你,你可能的了某种严重的疾病,而且诊断这种疾病的准确率是百分之99。(先验概率)然后你在等待检测的过程中,上网搜索了一下资料,然后发现平均有万分之一的人患这种病。结果你在检测完的第二天医生就打电话来告诉你,你的检查结果为阳性,这时候你感到开始恐慌了,那请问我们患病的概率是多少?

image-20220307125851927

我们用数学的方法好好来计算一下,假设现在有一百万人,那么就有999900人健康,100人患病,健康的人中,可能有9999的人会被误诊,有989901个人检测正确,而患病的人里面有99个成功检测并得到治疗,有一个人是诊断不出来而乖乖送死。

image-20220307125929121

那么按我们刚才的计算,我们应该计算出来的患病概率为:0.0098

image-20220307125950407

6.2 概率论

6.2.1 大数定律

让我们将上述知识归档。假设现在我们有一枚硬币,我们定义一个概率事件:抛硬币并以正面结束的概率是多少。

如果在这个硬币质地均匀的情况下,我们会不加思索地回答:百分之50。实际上,这个浅显易懂的道理是根据大数定律推断出来的。大数定律的内容是:如果统计数据足够大,那么事件出现的概率就能无限接近它的期望值。

6.2.2 基本概念

  • 事件:每个结果
  • 样本空间(结果空间):所有基本事件的集合Ω,例如投掷一次硬币的样本空间是:{正,反};投掷一次骰子的样本空间是:{1,2,3,4,5,6}
  • 样本点:样本空间元素(基本事件w)
  • 联合概率:联合概率也是我们说的and事件,即A = a和B = b同时发生的概率是多少。
  • 条件概率:设AB两个事件,且P(B)>0,则称%5Cfrac%20%7BP%28AB%29%7D%7BP%28B%29%7D为事件B已发生的条件下事件A发生的条件概率记为P(A|B)。
  • 独立性:我们常说的独立性说成大白话就是互不影响,比如连续抛出两次骰子,第二次抛出不会受第一次影响;还有投篮啊,打靶啊都是独立的;也就是说,设有A、B是两个任意事件,如果P(AB) = P(A)P(B),则称事件A和B相互独立,简称A和B独立。
  • 乘法定理:P(A|B) =%5Cfrac%20%7BP%28AB%29%7D%7BP%28B%29%7D
  • 贝叶斯定理:贝叶斯定理也叫逆概公式。由于P(AB)可以以乘法定理为桥梁,拓展出P%28AB%29%20%3D%20P%28B%7CA%29P%28A%29%20%E6%88%96%E8%80%85P%28AB%29%20%3D%20P%28A%7CB%29P%28B%29, 所以当以P(AB)为桥梁时,贝叶斯定理就产生了P%28A%7CB%29%20%3D%20%5Cfrac%20%7BP%28B%7CA%29P%28A%29%7D%7BP%28B%29%7D

6.2.3 极大似然估计

为了让后面的学习更顺畅,有必要讲一下概率论中的最大似然估计(maximumlikelihoodestimate)。

最大似然估计原理的思想可以用一个例子来说明。假设由两个外形完全相同的箱子,甲箱有99只白球,1只黑球;乙箱有99只黑球,一只白球。假设现在有个人摸到一颗球拿到你的面前,你大概率认为它是从乙箱拿出来的。

我们这里所说的“大概率”称为最大似然原理。

如果我们看前面的描述,用标准的描述来表达上面的知识点,最大似然估计就是在做一件事:利用已知的样本结果,反推最有可能导致这个结果的参数值.在概率论中,最大似然估计提供了一种在给定观测数据的情况下评估模型参数的方法,即给定模型并定位参数。通过多次实验,观察结果,并利用实验结果得到某个参数值,可以使样本出现的概率最大化,称为最大似然估计。

6.2.4 多项式分布

多项式分布二项式分布的推广。在此之前,让我们了解一些其他概念。

6.2.4.1 伯努利分布

伯努利分布又叫0-1分布,指一次随机试验,结果只有两种。这种分布典型的是投一次硬币,预测结果是正是反。

6.2.4.2 二项分布

二项分布为n次伯努利实验的结果。如果我们扔n次硬币,p为硬币朝上的概率,那么扔第k次硬币朝上的概率如下所示:
P%28X%20%3D%20k%29%20%3D%20C%5Ek_np%5Ek%281-p%29%5E%7Bn-k%7D%2Ck%20%3D%200%2C1%2C2%2C3%2C4%2C...n

6.2.5 朴素贝叶斯

让我们看一下朴素贝叶斯最流行的应用之一——垃圾邮件过滤器。我们的手机或多或少都收到过垃圾邮件,每封垃圾邮件上写着什么:赢钱之类的字很容易,而普通邮件上写着什么:你好,你好吗?之类的话。而我们需要做的是收到一封电子邮件,像获胜这样的词是垃圾邮件的概率是多少。如下所示:

image-20220307131722456

这里我们从上面可以看出,垃圾邮件中包含easy这个词的概率是三分之一,而包含money这个词的概率是三分之二。我们现在根据贝叶斯公式计算,带有“easy”这个词的垃圾邮件的概率是1/2,带有“money”这个词的垃圾邮件的概率是2/3。

而朴素贝叶斯的“朴素”就会在这个时候体现在这里。

我们假设“easy”和“money”是两个相互独立的词,那么我们可以利用事件的独立性将这两个概率相乘。那么我们得到的概率是:如果它同时包含“easy”和“money”这两个词,那么这封邮件是垃圾邮件的概率是1/3。

image-20220307131852763

当然,这种想法在数学上肯定是不合逻辑的,但这样的假设通常会帮助我们得到想要的结果,毕竟他还是有一定道理的。尽管这个假设是一个幼稚的错误假设,但它在实践中运行良好,使算法更有效。

总结一句话就是:朴素贝叶斯其实等于朴素+贝叶斯,其中朴素是指特征相互独立,贝叶斯指的是贝叶斯公式。朴素贝叶斯常用于文本分类。

6.3 朴素贝叶斯文本分类

6.3.1 一个例子

我们将上面的贝叶斯公式应用到文本分类中,公式可以改成:
P%28C%7CF_1%2CF_2%2C...%29%20%3D%20%5Cfrac%7BP%28F_1%2CF_2%2C...%7CC%29P%28C%29%7D%7BP%28F_1%2CF_2%2C...%29%7D
公式可以分为三部分:

  • P%28C%29:每个文档类别的概率(某文档的类别数/总文档数量)
  • P%28W%7CC%29:给定类别下的特征(出现在预测文档中的单词)的概率。
  • 计算方法:P%28F_1%29%20%3D%20N_i/N%28%E8%AE%AD%E7%BB%83%E6%96%87%E6%A1%A3%E4%B8%AD%E5%8E%BB%E8%AE%A1%E7%AE%97%29,其中Ni为该F_1词在C类别所有文档中出现的次数,N为所属类别C下的文档所有词出现的次数和。
  • P%28F_1%2CF_2%EF%BC%8C...%29:预测文档中每个单词的概率

你可能对上面的公式感到眼花缭乱,我们通过一个例子来看看。

在下面的例子中我们要做的是这么一件事,在某些特别的分类文档如China类中,它们时常会出现训练集中的词,如Chinese Beijing、Chinese等。但是出现这类词不一定就是China类。而我们要做的,就是在测试集中给出一篇新文章,根据文章中的词来判断该文章属不属于China类。

image-20220308141621554

让我们用贝叶斯公式来计算一下,我们实际上是要计算测试集中该文档的$P = (C|Chinese,Chinese,Chinese,Tokyo,Japan) 和 P(非C|Chinese,Chinese,Chinese,Tokyo,Japan) $,然后比对其大小即可判断该文档是否属于该类别。我们看一下下面的计算过程,如果不是没有笔的情况,我建议你也算一下。

image-20220308143716495

可以看出,最后算出来P%28F%7CC%29的概率为0,也就意味着带入贝叶斯公式,P%28C%7CF%29的概率也为0,这怎么可能!从测试集中文档含有三个Chinese来看,这篇文档再怎么不济也不可能属于Chinese的概率是0。而之所以概率为0,究其原因是因为样本量太少,没有出现Tokyo和Japan。为了防止这种概率为0的情况发生,我们引入下面的知识点。

6.3.2 拉普拉斯平滑系数

拉普拉斯平滑系数是法国数学家拉普拉斯首先提出来的,是为了解决零概率问题的发生。其基本思想是假定训练样本很大,每个分量x的计数加1造成的估计概率变化可以忽略不计,但是这种操作却可以有效地避免零概率问题。

对于上述6.3.1的文本分类问题,我们可以把拉普拉斯平滑系数改写为如下形式:
P%28F1%7CC%29%20%3D%20%5Cfrac%20%7BN_i%2Ba%7D%7BN%2Bam%7D%20%5C%5C%E5%85%B6%E4%B8%ADa%E4%B8%BA%E6%8C%87%E5%AE%9A%E7%9A%84%E7%B3%BB%E6%95%B0%EF%BC%8C%E4%B8%80%E8%88%AC%E4%B8%BA1%20%5C%5Cm%E4%B8%BA%E8%AE%AD%E7%BB%83%E6%96%87%E6%A1%A3%E4%B8%AD%E7%BB%9F%E8%AE%A1%E5%87%BA%E7%9A%84%E7%89%B9%E5%BE%81%E8%AF%8D%E4%B8%AA%E6%95%B0
得到的拉普拉斯平滑系数是一把利剑,我们再计算一下上面的P%28F%7CC%29

image-20220308151235031

6.3.3 算法实现

我们将举一个例子来加强我们之前的学习,我们将使用多项式贝叶斯分类器对新闻组数据集进行分类。分类步骤如下:

  • 检索数据
  • 划分数据集
  • 特征工程
  • 朴素贝叶斯估计过程
  • 模型评估

在sklearn中朴素贝叶斯的API为:

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

  • 其中alpha为拉普拉斯平滑系数,浮点数类型

新闻数据集的来源是:

20个新闻组数据集是大约20000个新闻组文档的集合,平均分布在20个不同的新闻组中。它最初是由Ken lang手机的。

数据被组织成20个不同的新闻组,每个新闻组对应不同的主题。

# 导入模块
from sklearn.datasets import fetch_20newsgroups
from sklearn.naive_bayes import MultinomialNB
from sklearn.model_selection import train_test_split
from sklearn.feature_extraction.text import TfidfVectorizer


def nb_news():
    """导入数据并且处理"""
    # 获取数据
    news = fetch_20newsgroups(subset="all")

    # 2 划分数据集
    x_train, x_test, y_train, y_test = train_test_split(news.data, news.target, random_state=6)

    # 3 文本特征抽取
    transfer = TfidfVectorizer()
    x_train = transfer.fit_transform(x_train)
    x_test = transfer.transform(x_test)

    # 4 朴素贝叶斯算法预估器流程
    estimator = MultinomialNB()
    estimator.fit(x_train, y_train)

    # 5 模型评估
    y_predict = estimator.predict(x_test)
    print("y_predict:\n", y_predict)
    print("直接比对预测值和真实值:\n", y_test == y_predict)

    # 计算准确率
    score = estimator.score(x_test, y_test)
    print("准确率为:\n", score)

    return None


nb_news()

6.4 贝叶斯分类器

虽然掌握贝叶斯分类器已经够难了,但请允许我让你更难。下面,我们描述剩下的贝叶斯分类器。我们将使用手写数据集作为分类示例。

6.4.1 多项式贝叶斯分类器

其实我们前面使用的贝叶斯分类器是多项式贝叶斯分类器,我们来仔细看看。

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

  • 其中alpha为拉普拉斯平滑系数,浮点数类型
  • 多项贝叶斯分类器实际上假设特征的条件概率遵循多项分布

6.4.2 高斯贝叶斯分类器

sklearn.naive_bayes.GaussianNB

  • 这个分类器没有参数
  • 该分类器假设特征的条件概率分布满足高斯分布

6.4.3 伯努利贝叶斯分类器

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

  • alpha:拉普拉斯平滑系数
  • binarize:一个浮点数或者None,如果是None则假定原始数据已经二元化,如果是浮点数则以该数为界,特征取值大于它的作为1,特征取值小于它的作为0
  • fit_prior:布尔值。如果为True,则不去学习P(y%20%3D%20c_k),替代以均匀分布;如果为false,择取学习P(y%20%3D%20c_k)
  • class_prior:一个数组。它指定了每个分类的先验概率。如果指定了该参数,则每个分类的先验概率不再从数据集中学得

6.4.4 代码实现

# 导入模块
from sklearn import datasets, naive_bayes
from sklearn.model_selection import train_test_split
import matplotlib.pyplot as plt


def show_digits():
    """查看手写数据集内容"""
    digits = datasets.load_digits()
    # 构建画布
    fig = plt.figure()
    # 输出
    print("vector from image 0:", digits.data[0])
    for i in range(25):
        ax = fig.add_subplot(5, 5, i + 1)
        ax.imshow(digits.images[i], cmap=plt.cm.gray_r, interpolation='nearest')
        plt.show()


def load_data():
    """加载数据集"""
    digits = datasets.load_digits()
    return train_test_split(digits.data, digits.target, test_size=0.25, random_state=0)


def test_MutinomialNB():
    """调用多项式贝叶斯分类器"""
    digits = datasets.load_digits()
    x_train, x_test, y_train, y_test = load_data()
    # 设置转换器
    estimator = naive_bayes.MultinomialNB()
    estimator.fit(x_train, y_train)
    # 模型评估
    print("MutinomialNB Train Score:\n", estimator.score(x_train, y_train))
    print("MutinomialNB Test Score:\n", estimator.score(x_test, y_test))


def test_GaussianNB():
    """调用高斯贝叶斯分类器"""
    x_train, x_test, y_train, y_test = load_data()
    # 设置转换器
    estimator = naive_bayes.GaussianNB
    estimator.fit(x_train, y_train)
    # 模型评估
    print("GaussianNB Train Score:\n", estimator.score(x_train, y_train))
    print("GaussianNB Test Score:\n", estimator.score(x_test, y_test))


def test_BernoulliNB():
    """调用伯努利贝叶斯分类器"""
    x_train, x_test, y_train, y_test = load_data()
    # 设置转换器
    estimator = naive_bayes.BernoulliNB
    estimator.fit(x_train, y_train)
    # 模型评估
    print("BernoulliNB Train Score:\n", estimator.score(x_train, y_train))
    print("BernoulliNB Test Score:\n", estimator.score(x_test, y_test))


# 调用函数
# test_MutinomialNB()
# test_GaussianNB()
test_BernoulliNB()

版权声明:本文为博主弄鹊原创文章,版权归属原作者,如果侵权,请联系我们删除!

原文链接:https://blog.csdn.net/chengyuhaomei520/article/details/123370921

共计人评分,平均

到目前为止还没有投票!成为第一位评论此文章。

(0)
社会演员多的头像社会演员多普通用户
上一篇 2022年3月11日 下午12:41
下一篇 2022年3月11日 下午1:13

相关推荐