机器学习-朴素贝叶斯(基础讲解+代码实现+图像展示)

本文介绍了朴素贝叶斯分类器在预测天气情况中的应用,通过实例展示了如何利用贝叶斯定理计算下雨概率。接着,通过实际数据集展示了贝叶斯分类器的使用,包括贝努力朴素贝叶斯、高斯朴素贝叶斯和多项式朴素贝叶斯。实验结果显示,高斯朴素贝叶斯在复杂分类任务中表现出较高的准确性,而多项式朴素贝叶斯在不适合的数据集上表现不佳。
摘要由CSDN通过智能技术生成

朴素贝叶斯

定理:

某晚,C准备收拾东西接女朋友,那么小C要不要带伞呢。

已知:天气预报说今日降水概率为50%–P(A)

晚高峰堵车的概率为80%–P(B)

如果下雨,晚高峰堵车的概率是95%–P(B|A)

小C向窗外看去,看到了堵车,则根据贝叶斯定理:

​ P(A|B)=(P(B|A)*P(A))/P(B)

求得下雨的概率为0.5*0.95/0.8=0.59375,较大概率下雨,拿伞

应用:

过去七天中,3天有雨,4天没雨,用数组表示就是:y=[0,1,1,0,1,0,0]。

其它信息包括刮风、闷热、多云等信息。

刮北风闷热多云天气预报有雨
第一天
第二天
第三天
第四天
第五天
第六天
第七天

用0表示否,赢1表示是,得到一个数组:

X=[0,1,0,1],[1,1,1,0],[0,1,1,0],[0,0,0,1],[0,1,1,0],[0,1,0,1],[1,0,0,1]

代码实现:

导入numpy
import numpy as np
X = np.array([[0,1,0,1],
              [1,1,1,0],
              [0,1,1,0],
              [0,0,0,1],
              [0,1,1,0],
              [0,1,0,1],
              [1,0,0,1]])
y = np.array([0,1,1,0,1,0,0])
counts = {}
# 对不同分了i计算每个特征值为1的数量
for label in np.unique(y):
    counts[label] = X[y == label].sum(axis=0)
    print(counts)
运行结果:{0: array([1, 2, 0, 4]), 1: array([1, 3, 3, 0])}

这个结果的意思是,当y=0时,即没有下雨的4天当中,有一天刮了被封,有两天比较闷热,而没有出现多云的情况,但这四天中天气预报全部播报为有雨。同时,在y=1时,也就是下雨的三天当中有1天刮了北风,3天全都比较闷热,且三天全部出现了多云的现象,而这三天天气预报都是没有雨。

那么对于朴素贝叶斯,它会根据上述计算来进行推理。它会认为,如果某一天天气预报没有播报有雨,但出现了多云的情况,它会倾向于把这一天放到‘下雨’这一分类中。

# 导入贝努力贝叶斯
from sklearn.naive_bayes import BernoulliNB
clf = BernoulliNB()
clf.fit(X,y)
# 要进行预测的这一天没有刮风也不闷热
#但是多云,天气预报说没有雨
Next_Day=[[0,0,1,0]]
pre = clf.predict(Next_Day)
if pre == [1]:
    print('要下雨啦,收衣服了!')
else:
    print('放心,今天是个艳阳天')

运行结果: 要下雨啦,收衣服了!

可以看出,朴素贝叶斯分类器把这一天放到了会下雨的分类中。

那么朴素贝叶斯的准确率怎么样,用predict_proba方法测试

print(clf.predict_proba(Next_day))

[[0.13848881 0.86151119]]

意思是,不下雨的概率为13.8%,下雨的概率为86.2%,预测结果还不错。

但是如果在scikit-learn官网上查看文档,会发现一段很搞笑的描述–虽然朴素贝叶斯是相当好的分类器,但对于预测具体的数值并不是很擅长,因此predict_proda给出的预测概率,大家不要太当真。

其它方法:

  • 贝努力朴素贝叶斯

    这种方法比较适合符合贝努力分布的数据集,贝努力分布也称为“二项分布或者”0-1“分布,比如抛硬币游戏,硬币落下来只有两种结果:正面或反面,这种情况下我们就称抛硬币的结果是贝叶斯分布。如果用复杂的数据集交给贝努力贝叶斯,结果就会遍得不同。

  #  导入是数据集生成工具
  from sklearn.datasets import make_blobs
  
  #导入数据集拆分工具
  from sklearn.model_selection import train_test_split
  #生成样本数量为500,分类为5的数据集
  X, y = make_blobs(n_samples=500, centers=5, random_state=8)
  
  #将数据集拆分成训练集和测试集
  X_train, X_test, y_train, y_test = train_test_split(X, y,random_state=8)
  
  # 使用贝努力贝叶斯拟合数据
  nb = BernoulliNB()
  nb.fit(X_train, y_train)
  
  print(f'模型得分{nb.score(X_test,y_test)}')

运行结果: 模型得分0.544

可以看出对于手工生成的数据,贝努力贝叶斯得分很差。

通过通过图像来了解以贝努力朴素贝叶斯的工作过程。

import matplotlib.pyplot as plt
import numpy as np
# 限定横轴与纵轴的最大值
x_min, x_max = X[:,0].min() - 0.5, X[:,0].max()+0.5
y_min, y_max = X[:,1].min()- 0.5, X[:,0].max()+0.5
# 用不同颜色的背景色表示不同的分类
xx, yy = np.meshgrid(np.arange(x_min, x_max,.02),
                    np.arange(y_min,y_max,.02))
z = nb.predict(np.c_[(xx.ravel(), yy.ravel())]).reshape(xx.shape)
plt.pcolormesh(xx,yy,z,cmap=plt.cm.Pastel1)
# 将训练集和测试集用散点图表示

plt.scatter(X_train[:,0],X_train[:,1],c=y_train,cmap=plt.cm.cool,edgecolors='k')
plt.scatter(X_test[:,0],X_test[:,1],c=y_test,cmap=plt.cm.cool,marker='*',edgecolor='k')

plt.xlim(xx.min(),xx.max())
plt.ylim(yy.min(),yy.max())

# 定义图题
plt.title('Classifier:BernoulliNB')

# 图片
plt.show()

在这里插入图片描述

此时朴素贝叶斯分类比较简单,所以在多特征多分类时,贝努力贝叶斯就不能再使用,应该考虑高斯贝叶斯。

  • 高斯朴素贝叶斯

    顾名思义就是假设样本的特征符合高斯分布,或者符合正态分布时所用的算法。接下来用高斯分布对数据集进行拟合。

  # 导入高斯贝叶斯
  from sklearn.naive_bayes import GaussianNB
  # 使用高斯贝叶斯拟合数据
  gnb = GaussianNB()
  gnb.fit(X_train,y_train)
  print(f'模型得分为:{gnb.score(X_test,y_test)}')

运行结果:模型得分:0.968

准确率达到了96.8%。再用图像进行演示。

  z = nb.predict(np.c_[(xx.ravel(), yy.ravel())]).reshape(xx.shape)
  plt.pcolormesh(xx,yy,z,cmap=plt.cm.Pastel1)
  # 将训练集和测试集用散点图表示
  
  plt.scatter(X_train[:,0],X_train[:,1],c=y_train,cmap=plt.cm.cool,edgecolors='k')
  plt.scatter(X_test[:,0],X_test[:,1],c=y_test,cmap=plt.cm.cool,marker='*',edgecolor='k')
  
  plt.xlim(xx.min(),xx.max())
  plt.ylim(yy.min(),yy.max())
  
  # 定义图题
  plt.title('Classifier:GaussianNB')
  
  # 图片
  plt.show()

在这里插入图片描述

结果分析:高斯朴素贝叶斯的分类边界比贝努力贝叶斯的分类边界要复杂的多,也基本上把数据点都放进了正确的分类当中了。

事实上,高斯朴素贝叶斯也确实能够胜任大部分的分类任务,这是因为在自然科学和社会科学领域,有大量的现象都是呈现出正态分布的状态。

  • 多项式朴素贝叶斯

    主要用于拟合多项式分布的数据集。需要注意的是多项式朴素贝叶斯要求输入的X值必须是正直,所以需要对输入的值进行归一化处理。MinMaxScaler的作用默认将数据转化到0~1。

  # 导入多项式朴素贝叶斯
  from sklearn.naive_bayes import MultinomialNB
  
  # 导入数据预处理工具
  from sklearn.preprocessing import MinMaxScaler
  # 使用数据预处理工具使数据全部为非负值
  scaler = MinMaxScaler()
  scaler.fit(X_train)
  
  X_train_scaled = scaler.transform(X_train)
  X_test_scaled = scaler.transform(X_test)
  #使用多项式朴素贝叶斯拟合经过预处理之后的数据
  mnb = MultinomialNB()
  mnb.fit(X_train_scaled,y_train)
  print(f'模型得分:{mnb.score(X_test_scaled,y_test)}')

运行结果:模型得分:0.32

准确率比贝努力朴素贝叶斯还低。

画图看一下

z = mnb.predict(np.c_[(xx.ravel(), yy.ravel())]).reshape(xx.shape)
plt.pcolormesh(xx,yy,z,cmap=plt.cm.Pastel1)
# 将训练集和测试集用散点图表示

plt.scatter(X_train[:,0],X_train[:,1],c=y_train,cmap=plt.cm.cool,edgecolors='k')
plt.scatter(X_test[:,0],X_test[:,1],c=y_test,cmap=plt.cm.cool,marker='*',edgecolor='k')

plt.xlim(xx.min(),xx.max())
plt.ylim(yy.min(),yy.max())

# 定义图题
plt.title('Classifier:MultinomialNB')

# 图片
plt.show()

在这里插入图片描述

可以看出多项式朴素贝叶斯分类能i非常差,大部分数据点放到了错误的位置上。

这是因为,多项式朴素贝叶斯只适合对非负离散数值特征进行分类,典型的例子就是对转化为向量后的文本数据进行分类。

可以看出多项式朴素贝叶斯分类能i非常差,大部分数据点放到了错误的位置上。

这是因为,多项式朴素贝叶斯只适合对非负离散数值特征进行分类,典型的例子就是对转化为向量后的文本数据进行分类。

注:本文为参考《深入浅出python机器学习》做的个人笔记,经过个人理解与简单修改。

  • 2
    点赞
  • 39
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值