【Python数据科学手册】专题:朴素贝叶斯分类

简介: 朴素贝叶斯模型是一组非常简单快速的分类算法,通常适用于维度非常高的数据集。因为运行速度快,而且可调参数少,因此非常适合为分类问题提供快速粗糙的基本方案。

朴素贝叶斯模型是一组非常简单快速的分类算法,通常适用于维度非常高的数据集。因为运行速度快,而且可调参数少,因此非常适合为分类问题提供快速粗糙的基本方案。

1、贝叶斯分类

朴素贝叶斯分类器建立在贝叶斯分类方法的基础上,其数学基础是贝叶斯定理(Bayes’s theorem)——一个描述统计量条件概率关系的公式。在贝叶斯分类中,我们希望确定一个具有某些特征的样本属于某类标签的概率,通常记为P(L|特征)

image.png

假如需要确定两种标签,定义为L1 和L2,一种方法就是计算这两个标签的后验概率的比值:

image.png

现在需要一种模型,帮我们计算每个标签的P ( 特征 | Li)。这种模型被称为生成模型,因为它可以训练出生成输入数据的假设随机过程(或称为概率分布)。为每种标签设置生成模型是贝叶斯分类器训练过程的主要部分。

之所以称为“朴素”或“朴素贝叶斯”,是因为如果对每种标签的生成模型进行非常简单的假设,就能找到每种类型生成模型的近似解,然后就可以使用贝叶斯分类。

首先导入需要用的程序库:

%matplotlib inline
import numpy as np
import matplotlib.pyplot as plt
import seaborn as sns; sns.set()

2、高斯朴素贝叶斯

最容易理解的朴素贝叶斯分类器可能就是高斯朴素贝叶斯(Gaussian naive Bayes)

假设每个标签的数据都服从简单的高斯分布。假如你有下面的数据

from sklearn.datasets import make_blobs
X, y = make_blobs(100, 2, centers=2, random_state=2, cluster_std=1.5)
plt.scatter(X[:, 0], X[:, 1], c=y, s=50, cmap='RdBu');

image.png

一种快速创建简易模型的方法就是假设数据服从高斯分布,且变量无协方差(no covariance,指线性无关)。只要找出每个标签的所有样本点均值和标准差,再定义一个高斯分布,就可以拟合模型了。

image.png

图中的椭圆曲线表示每个标签的高斯生成模型,越靠近椭圆中心的可能性越大。通过每种类型的生成模型,可以计算出任意数据点的似然估计(likelihood)P(特征|L1),然后根据贝叶斯定理计算出后验概率比值,从而确定每个数据点可能性最大的标签。

from sklearn.naive_bayes import GaussianNB
model = GaussianNB()
model.fit(X, y);

生成一些新数据来预测标签:

rng = np.random.RandomState(0)
Xnew = [-6, -14] + [14, 18] * rng.rand(2000, 2)
ynew = model.predict(Xnew)

将这些新数据画出来,看看决策边界的位置

plt.scatter(X[:, 0], X[:, 1], c=y, s=50, cmap='RdBu')
lim = plt.axis()
plt.scatter(Xnew[:, 0], Xnew[:, 1], c=ynew, s=20, cmap='RdBu', alpha=0.1)
plt.axis(lim);

image.png

在分类结果中看到一条稍显弯曲的边界——通常,高斯朴素贝叶斯的边界是二次方曲线。 贝叶斯主义(Bayesian formalism)的一个优质特性是它天生支持概率分类,我们可以用predict_proba 方法计算样本属于某个标签的概率。

yprob = model.predict_proba(Xnew)
yprob[-8:].round(2)

image.png

这个数组分别给出了前两个标签的后验概率。如果你需要评估分类器的不确定性,那么这类贝叶斯方法非常有用。

当然,由于分类的最终效果只能依赖于一开始的模型假设,因此高斯朴素贝叶斯经常得不到非常好的结果。

3、多项式朴素贝叶斯

多项式朴素贝叶斯(multinomial naive Bayes),它假设特征是由一个简单多项式分布生成的。多项分布可以描述各种类型样本出现次数的概率,因此多项式朴素贝叶斯非常适合用于描述出现次数或者出现次数比例的特征。

  1. 案例:文本分类

多项式朴素贝叶斯通常用于文本分类,其特征都是指待分类文本的单词出现次数或者频次。

这里用20 个网络新闻组语料库(20 Newsgroups corpus,约20000 篇新闻)的单词出现次数作为特征,演示如何用多项式朴素贝叶斯对这些新闻组进行分类。

from sklearn.datasets import fetch_20newsgroups

data = fetch_20newsgroups()
data.target_names

image.png

image.png

简化演示过程,只选择四类新闻,下载训练集和测试集:

categories = ['talk.religion.misc', 'soc.religion.christian',
              'sci.space', 'comp.graphics']
train = fetch_20newsgroups(subset='train', categories=categories)
test = fetch_20newsgroups(subset='test', categories=categories)

选其中一篇新闻看看:

print(train.data[5])

image.png

为了让这些数据能用于机器学习,需要将每个字符串的内容转换成数值向量。可以创建一个管道,将TF–IDF 向量化方法与多项式朴素贝叶斯分类器组合在一起:

from sklearn.feature_extraction.text import TfidfVectorizer
from sklearn.naive_bayes import MultinomialNB
from sklearn.pipeline import make_pipeline

model = make_pipeline(TfidfVectorizer(), MultinomialNB())
通过这个管道,就可以将模型应用到训练数据上,预测出每个测试数据的标签

model.fit(train.data, train.target)
labels = model.predict(test.data)

这样就得到每个测试数据的预测标签,可以进一步评估评估器的性能了。例如,用混淆矩阵统计测试数据的真实标签与预测标签的结果。

from sklearn.metrics import confusion_matrix
mat = confusion_matrix(test.target, labels)
sns.heatmap(mat.T, square=True, annot=True, fmt='d', cbar=False,
            xticklabels=train.target_names, yticklabels=train.target_names)
plt.xlabel('true label')
plt.ylabel('predicted label');

image.png

从图中可以明显看出,虽然用如此简单的分类器可以很好地区分关于宇宙的新闻和关于计算机的新闻,但是宗教新闻和基督教新闻的区分效果却不太好。

但现在我们有一个可以对任何字符串进行分类的工具了,只要用管道的predict() 方法就可以预测。下面的函数可以快速返回字符串的预测结果:

def predict_category(s, train=train, model=model):
    pred = model.predict([s])
    return train.target_names[pred[0]]

下面试试模型预测效果:

predict_category('sending a payload to the ISS')

predict_category('discussing islam vs atheism')

predict_category('determining the screen resolution')

虽然这个分类器不会比直接用字符串内单词(加权的)频次构建的简易概率模型更复杂,但是它的分类效果却非常好。由此可见,即使是一个非常简单的算法,只要能合理利用并进行大量高维数据训练,就可以获得意想不到的效果。

4、朴素贝叶斯的应用场景

由于朴素贝叶斯分类器对数据有严格的假设,因此它的训练效果通常比复杂模型的差。其优点主要体现在以下四个方面。

  • 训练和预测的速度非常快。
  • 直接使用概率预测。
  • 通常很容易解释。
  • 可调参数(如果有的话)非常少

朴素贝叶斯分类器非常适合用于以下应用场景。

  • 假设分布函数与数据匹配(实际中很少见)。
  • 各种类型的区分度很高,模型复杂度不重要。
  • 非常高维度的数据,模型复杂度不重要。

后面两条看似不同,其实彼此相关:随着数据集维度的增加,任何两点都不太可能逐渐靠近(毕竟它们得在每一个维度上都足够接近才行)。也就是说,在新维度会增加样本数据信息量的假设条件下,高维数据的簇中心点比低维数据的簇中心点更分散。因此,随着数据维度不断增加,像朴素贝叶斯这样的简单分类器的分类效果会和复杂分类器一样,甚至更好——只要你有足够的数据,简单的模型也可以非常强大。

目录
相关文章
|
1月前
|
数据采集 数据可视化 大数据
Python在数据科学中的实际应用:从数据清洗到可视化的全流程解析
Python在数据科学中的实际应用:从数据清洗到可视化的全流程解析
34 1
|
1月前
|
数据可视化 程序员 数据处理
Python代码对身高进行分类
Python代码对身高进行分类
34 0
|
2月前
|
机器学习/深度学习 算法 PyTorch
python手把手搭建图像多分类神经网络-代码教程(手动搭建残差网络、mobileNET)
python手把手搭建图像多分类神经网络-代码教程(手动搭建残差网络、mobileNET)
43 0
|
19天前
|
机器学习/深度学习 算法 Python
朴素贝叶斯代码实现python
朴素贝叶斯代码实现python
25 3
|
30天前
|
存储 数据挖掘 数据处理
探索数据科学中的Python神器——Pandas库的强大功能
在数据科学领域中,Python语言的Pandas库被广泛应用于数据处理和分析。本文将深入探讨Pandas库的核心功能及其在数据科学中的重要性,帮助读者更好地理解和利用这一强大工具。
|
1月前
|
机器学习/深度学习 数据可视化 算法
python数据分析——在面对各种问题时,因如何做分析的分类汇总
Python数据分析是指使用Python编程语言对数据进行收集、处理、分析和可视化的过程。Python是一种非常流行的编程语言,具有简单易学、代码可读性高、生态系统强大的特点,因此在数据科学领域得到广泛应用。
79 0
|
1月前
|
数据采集 机器学习/深度学习 数据可视化
Python在数据科学中的应用:从入门到精通
【2月更文挑战第12天】 本文旨在探讨Python语言在数据科学领域的广泛应用,从基础语法到高级数据分析和机器学习模型的实现。我们将通过实际案例,展示如何使用Python进行数据处理、分析与可视化,以及如何利用Python的强大库和框架(如Pandas、NumPy、Matplotlib、Scikit-learn等)解决复杂的数据科学问题。此外,文章还将介绍一些最佳实践和技巧,帮助读者更有效地使用Python进行数据科学项目。无论你是数据科学的新手还是希望提升现有技能的专业人士,本文都将为你提供宝贵的资源和启发。
28 3
|
1月前
|
数据采集 数据可视化 数据挖掘
Python在数据科学中的应用
【2月更文挑战第11天】随着数据科学的迅速发展,Python已成为该领域不可或缺的工具之一。本文将从Python在数据科学中的角色出发,探讨其在数据处理、分析及可视化方面的应用。我们将通过实际案例,展示Python如何帮助数据科学家高效地解决问题,从而揭示Python在数据科学中的重要性和其未来的发展潜力。与传统摘要不同,本文旨在通过具体实例,为读者提供一个直观且实用的视角,让读者能够深刻理解Python在数据科学中的应用价值。
20 2
|
2月前
|
机器学习/深度学习 数据可视化 数据挖掘
探索Python在数据科学中的应用:从数据处理到深度学习
本文全面探讨了Python语言在数据科学领域的关键应用,突破了传统摘要的界限,采用故事化手法引入主题。我们从一个数据科学项目的起点出发,描述了一个数据科学家如何使用Python进行数据收集、清洗、分析、可视化,以及如何应用机器学习和深度学习模型来提取洞见和做出预测。文章不仅阐述了Python在各个环节的具体应用,还介绍了相关的库和工具,旨在为读者提供一个关于Python在数据科学中应用的全景视图。
|
3月前
|
算法 Python Java
Python每日一练(20230426) 删除重复字符、颜色分类、计算圆周率
Python每日一练(20230426) 删除重复字符、颜色分类、计算圆周率
39 0
Python每日一练(20230426) 删除重复字符、颜色分类、计算圆周率

热门文章

最新文章