朴素贝叶斯分类

一. 朴素贝叶斯

朴素贝叶斯中的朴素一词的来源就是假设各特征之间相互独立。这一假设使得朴素贝叶斯算法变得简单,但有时会牺牲一定的分类准确率。

首先给出贝叶斯公式:
在这里插入图片描述
换成分类任务的表达式:
在这里插入图片描述

我们最终求的p(类别|特征)即可!就相当于完成了我们的任务。
则,朴素贝特斯公式为:
在这里插入图片描述

二. 实例解析

首先,给出数据如下:
在这里插入图片描述
现在给我们的问题是,如果一对男女朋友,男生想女生求婚,男生的四个特点分别是不帅,性格不好,身高矮,不上进,请你判断一下女生是嫁还是不嫁?

这是典型的二分类问题,按照朴素贝叶斯的求解,转换为P(嫁|不帅、性格不好、矮、不上进)和P(不嫁|不帅、性格不好、矮、不上进)的概率,最终选择嫁与不嫁的答案。

这里我们根据贝特斯公式:
在这里插入图片描述
由此,我们将(嫁|不帅、性格不好、矮、不上进)转换成三个可求的P(嫁)、P(不帅、性格不好、矮、不上进|嫁)、P(不帅、性格不好、矮、不上进)。进一步分解可以得:

P(不帅、性格不好、矮、不上进)=P(嫁)P(不帅|嫁)P(性格不好|嫁)P(矮|嫁)P(不上进|嫁)+P(不嫁)P(不帅|不嫁)P(性格不好|不嫁)P(矮|不嫁)P(不上进|不嫁)。

P(不帅、性格不好、矮、不上进|嫁)=P(不帅|嫁)P(性格不好|嫁)P(矮|嫁)P(不上进|嫁)

将上面的公式整理一下可得:
在这里插入图片描述
P(嫁)=1/2、P(不帅|嫁)=1/2、P(性格不好|嫁)=1/6、P(矮|嫁)=1/6、P(不上进|嫁)=1/6。
P(不嫁)=1/2、P(不帅|不嫁)=1/3、P(性格不好|不嫁)=1/2、P(矮|不嫁)=1、P(不上进|不嫁)=2/3
但是由贝叶斯公式可得:对于目标求解为不同的类别,贝叶斯公式的分母总是相同的。所以,只求解分子即可:
在这里插入图片描述
于是,对于类别“嫁”的贝叶斯分子为:P(嫁)P(不帅|嫁)P(性格不好|嫁)P(矮|嫁)P(不上进|嫁)=1/2 * 1/2 * 1/6 * 1/6 * 1/6=1/864
对于类别“不嫁”的贝叶斯分子为:P(不嫁)P(不帅|不嫁)P(性格不好|不嫁)P(矮|不嫁)P(不上进|不嫁)=1/2 * 1/3 * 1/2 * 1* 2/3=1/18。
经代入贝叶斯公式可得:P(嫁|不帅、性格不好、矮、不上进)=(1/864) / (1/864+1/18)=1/49=2.04%
P(不嫁|不帅、性格不好、矮、不上进)=(1/18) / (1/864+1/18)=48/49=97.96%
则P(不嫁|不帅、性格不好、矮、不上进) > P(嫁|不帅、性格不好、矮、不上进),则该女子选择不嫁!

三. 朴素贝叶斯的优缺点

优点:
(1) 算法逻辑简单,易于实现(算法思路很简单,只要使用贝叶斯公式转化即可!)
(2)分类过程中时空开销小(假设特征相互独立,只会涉及到二维存储)
缺点:
朴素贝叶斯假设属性之间相互独立,这种假设在实际过程中往往是不成立的。在属性之间相关性越大,分类误差也就越大。

对P(xj∣Ck)的计算需要事先假设样本特征xj 的数据分布情况。对特征分布的假设,我们称之为事件模型,通常会采用以下三种假设。

4.三种计算贝叶斯分类方法

1.多项式分布
如果特征xj 是离散值,可以假设它符合 多项式分布。可以统计xj 的某个特征在样本中的频率来估算其概率。

假设 特征xj 有 Sj 个可能的取值(比如天气有阴、晴、雨三种状态,则 Sj=3 ),并且在n个样本中,类别为 Ck 特征 xj 取值为 s 的样本有mkjs个。则
在这里插入图片描述
有时候样本中某个特征的特定取值的样本数 mkjs}= 0,这将导致整个 P ( C k ) ∏ n j = 1 P ( x j ∣ C k ) = 0 P(Ck)∏nj=1P(xj∣Ck)=0 P(Ck)nj=1P(xjCk)=0,严重扭曲了该特征的概率分布。因此,通常可以采用拉普拉斯平滑来避免这种情况发生。即
在这里插入图片描述
通常取 λ=1

2.伯努利分布

如果特征xj是稀疏二项离散值,可以假设它符合 伯努利分布。打网球的案例中,湿度取值是 {high,normal},风力取值是 {strong,weak},这两个特征都是二项离散值。
伯努利分布只有两种可能的取值,我们将其编码为 {0,1},则
在这里插入图片描述
另外注意到伯努利分布其实是多项式分布的特例,所以我们可以用上面公式计算,也可以用之前多项式分布公式计算。

垃圾邮件分类等涉及文本的任务中可以采用伯努利分布,比如构造一个5000个不同单词的向量作为输入特征x,对于一段文本,其中有出现的单词,在x中对应单词的位置设为1,其它位置为0,这样x中的每个特征(单词)的取值为1或0,符合伯努利分布。

3.高斯分布

如果特征xj是连续变量,可以假设它符合 高斯分布(正态分布)。准确点说,是假设每个类别 Ck下的 xkj符合高斯分布。这样,我们可以通过高斯分布的概率密度函数来计算样本中 xj某个特定值的条件概率 P(xjs∣Ck) 高斯分布的概率密度函数为:
在这里插入图片描述
其中 μ是均值,σ2是方差。
假设在类别 Ck中,特征 xj 的均值为 μkj,方差为 σ2kj (这两项可以通过样本数据统计出来)。则在这里插入图片描述
处理连续数值问题的另一种常用的技术是通过离散化连续数值的方法。通常,当训练样本数量较少或者是精确的分布已知时,通过概率分布的方法是一种更好的选择。
而在大量样本的情形下离散化的方法表现更优,因为大量的样本可以学习到数据的实际分布,而不用“朴素”的假设其分布。典型情况下很多任务都会提供大量的样本,所以这时选择离散化方法会比概率分布估计的方法更好。

代码

import numpy as np
import math
#对003-AI-KNN-datasets-Iris.txt数据进行处理
raw_data_X=np.loadtxt('/content/drive/My Drive/Colab Notebooks/数据/003-AI-KNN-datasets-Iris.txt',dtype=float,delimiter=',',usecols=(0,1,2,3))
raw_data_y=np.loadtxt('/content/drive/My Drive/Colab Notebooks/数据/003-AI-KNN-datasets-Iris.txt',dtype=str,delimiter=',',usecols=(4))
#把整个数据集以1:4的比例随机分为测试集和训练集
arr = np.random.choice(int(len(raw_data_X)),size=30,replace=False)
X_train=np.delete(raw_data_X,arr,axis=0)
y_train=np.delete(raw_data_y,arr)
x_test=[]
y_test=[]
for i in arr:
    x_test.append(raw_data_X[i])
    y_test.append(raw_data_y[i])
X_test=np.array(x_test)
a=0
b=0
c=0
setosa=[]
color=[]
virginica=[]
for i in range(len(y_train)):
  if y_train[i]=='Iris-setosa':
    a+=1
    setosa.append(X_train[i])
  if y_train[i]=='Iris-versicolor':
    b+=1
    color.append(X_train[i])
  if y_train[i]=='Iris-virginica':
    c+=1
    virginica.append(X_train[i])
A=np.sum(setosa,axis=0)/a#Iris-setosa类各特征均值集合
B=np.sum(color,axis=0)/b#Iris-versicolor类各特征均值集合
C=np.sum(virginica,axis=0)/c#Iris-virginica类各特征均值集合
A1=np.sum((setosa-A)**2,axis=0)#Iris-setosa类各特征方差集合
B1=np.sum((color-B)**2,axis=0)#Iris-versicolor类各特征方差集合
C1=np.sum((virginica-C)**2,axis=0)#Iris-virginica类各特征方差集合
a1=a/len(raw_data_y)#p(Iris-setosa)
b1=b/len(raw_data_y)#p(Iris-versicolor)
c1=c/len(raw_data_y)#p(Iris-virginica)
R=0
r=1
for i in range(len(X_test)):
  P=1#p(特征)
  a4=1
  b4=1
  c4=1
  for j in range(len(X_test[i])):
    a3=(1/math.sqrt(2*math.pi*A1[j]))*math.exp(-(X_test[i][j]-A[j])**2/2*A1t[j])#p(特征|类别)
    b3=(1/math.sqrt(2*math.pi*B1[j]))*math.exp(-(X_test[i][j]-B[j])**2/2*B1[j])
    c3=(1/math.sqrt(2*math.pi*C1[j]))*math.exp(-(X_test[i][j]-C[j])**2/2*C1[j])
    a4=a3*a4
    b4=b3*b4
    c4=c3*c4
  a5=a4*a1#p(类别)*p(特征|类别)or p(类别|特征)
  b5=b4*b1
  c5=c4*c1
  if a5==max(a5,b5,c5):
    result='Iris-setosa'
  if b5==max(a5,b5,c5):
    result='Iris-versicolor'
  if c5==max(a5,b5,c5):
    result='Iris-virginica'
  if result==y_test[i]:
    R+=1
  print("预测:{},实际:{}".format(result,y_test[i]))
print("准确率:",R/len(y_test))

结果

预测:Iris-versicolor,实际:Iris-versicolor
预测:Iris-versicolor,实际:Iris-versicolor
预测:Iris-virginica,实际:Iris-virginica
预测:Iris-setosa,实际:Iris-setosa
预测:Iris-virginica,实际:Iris-versicolor
预测:Iris-setosa,实际:Iris-setosa
预测:Iris-virginica,实际:Iris-virginica
预测:Iris-virginica,实际:Iris-virginica
预测:Iris-setosa,实际:Iris-setosa
预测:Iris-setosa,实际:Iris-setosa
预测:Iris-virginica,实际:Iris-virginica
预测:Iris-setosa,实际:Iris-setosa
预测:Iris-setosa,实际:Iris-setosa
预测:Iris-virginica,实际:Iris-virginica
预测:Iris-versicolor,实际:Iris-virginica
预测:Iris-setosa,实际:Iris-setosa
预测:Iris-setosa,实际:Iris-setosa
预测:Iris-setosa,实际:Iris-setosa
预测:Iris-setosa,实际:Iris-setosa
预测:Iris-versicolor,实际:Iris-versicolor
预测:Iris-virginica,实际:Iris-virginica
预测:Iris-virginica,实际:Iris-virginica
预测:Iris-setosa,实际:Iris-setosa
预测:Iris-virginica,实际:Iris-virginica
预测:Iris-setosa,实际:Iris-setosa
预测:Iris-virginica,实际:Iris-virginica
预测:Iris-versicolor,实际:Iris-versicolor
预测:Iris-virginica,实际:Iris-versicolor
预测:Iris-setosa,实际:Iris-setosa
预测:Iris-virginica,实际:Iris-virginica
准确率: 0.9
数据集

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值