贝叶斯算法学习

贝叶斯算法

简单的来说,贝叶斯算法就是通过某件事情现在发生的概率,或者可能发生的概率来推算它发生的概率,或者再次发生的概率。

(以上属于个人理解)

下面我们上公式:

P ( A ∣ B ) = P ( B ∣ A ) P ( A ) P ( B ) P(A|B) = \frac{P(B|A)P(A)} {P(B)} P(AB)=P(B)P(BA)P(A)

P(A)是 A 的先验概率,之所以称为“先验”是因为它不考虑任何 B 方面的因素。

P(A|B)是已知 B 发生后 A 的条件概率,也由于得自 B 的取值而被称作 A 的后验概率。

P(B|A)是已知 A 发生后 B 的条件概率,也由于得自 A 的取值而被称作 B 的后验概率。

P(B)是 B 的先验概率,也作标淮化常量(normalizing constant)。

例:假设有两个各装了100个球的箱子,甲箱子中有70个红球,30个绿球,乙箱子中有30个红球,70个绿球。假设随机选择其中一个箱子,从中拿出一个球记下球色再放回原箱子,如此重复12次,记录得到8次红球,4次绿球。被选择的箱子是甲箱子的概率有多大?

首先选择两个箱子的概率相同,都为50%。即P(甲)=0.5,P(乙)=1-P(甲)。

这时在拿出一个球是红球的情况下,我们就应该根据这个信息来更新选择的是甲箱子的先验概率:

P(甲|红球1) = P(红球|甲) × P(甲) / (P(红球|甲) × P(甲) + (P(红球|乙) × P(乙)))

P(红球|甲):甲箱子中拿到红球的概率

P(红球|乙):乙箱子中拿到红球的概率

因此在出现一个红球的情况下,选择的是甲箱子的先验概率就可被修正为:

P(甲|红球1) = 0.7 × 0.5 / (0.7 × 0.5 + 0.3 × 0.5) = 0.7

即在出现一个红球之后,甲乙箱子被选中的先验概率就被修正为:

P(甲) = 0.7, P(乙) = 1 - P(甲) = 0.3;

下面我们用代码来实现:

# 定义一个自定义函数来选择甲箱的概率
def baysesFunc(pIsBox1,pBox1,pBox2):
    
# P(红|甲)P(甲)/P(红|甲)P(甲)+P(红|乙)P(乙)
    return (pIsBox1 * pBox1)/((pIsBox1 * pBox1)+(1-pIsBox1) * pBox2)
def redGreenBallProblem():
    pIsBox1 = 0.5      # 选择甲箱的概率
# 一共摸12个,8个红球,4个绿球
    for i in range(1,9):
        pIsBox1 = baysesFunc(pIsBox1,0.7,0.3)
        print("After red %d > in 甲 box: %f"%(i,pIsBox1))
    for i in range(1,5):
        pIsBox1 = baysesFunc(pIsBox1,0.3,0.7)
        print ("After green %d > in 甲 box: %f "% (i,pIsBox1))
redGreenBallProblem()

After red 1 > in 甲 box: 0.700000
After red 2 > in 甲 box: 0.844828
After red 3 > in 甲 box: 0.927027
After red 4 > in 甲 box: 0.967365
After red 5 > in 甲 box: 0.985748
After red 6 > in 甲 box: 0.993842
After red 7 > in 甲 box: 0.997351
After red 8 > in 甲 box: 0.998863
After green 1 > in 甲 box: 0.997351 
After green 2 > in 甲 box: 0.993842 
After green 3 > in 甲 box: 0.985748 
After green 4 > in 甲 box: 0.967365 

经历8次红球修正(概率增加),4此绿球修正(概率减少)之后,选择的是甲箱子的概率为:96.7%。

朴素贝叶斯分类算法

那么既然是朴素贝叶斯分类算法,它的核心算法又是什么呢?

是下面这个贝叶斯公式:

P ( A ∣ B ) = P ( B ∣ A ) P ( A ) P ( B ) P(A|B) = \frac{P(B|A)P(A)} {P(B)} P(AB)=P(B)P(BA)P(A)

换个表达形式就会明朗很多,如下:

P ( 类 别 ∣ 特 征 ) = P ( 特 征 ∣ 类 别 ) P ( 类 别 ) P ( 特 征 ) P(类别|特征) = \frac{P(特征|类别)P(类别)} {P(特征)} P()=P()P()P()

分类算法的内容是要求给定特征,让我们得出类别,这也是所有分类问题的关键。

具体例子戳:https://blog.csdn.net/amds123/article/details/70173402

朴素贝叶斯分类的优缺点

优点:
(1) 算法逻辑简单,易于实现。
(2)分类过程中时空开销小。(假设特征相互独立,只会涉及到二维存储)
缺点:
理论上,朴素贝叶斯模型与其他分类方法相比具有最小的误差率。但是实际上并非总是如此,这是因为朴素贝叶斯模型假设属性之间相互独立,这个假设在实际应用中往往是不成立的,在属性个数比较多或者属性之间相关性较大时,分类效果不好。

案例

本部分主要介绍了朴素贝叶斯分类在python语言中的实现过程。本次实验采用了经典的Mushroom数据集, 目的通过数据集中给出的蘑菇的物理特性,结合朴素贝叶斯分类算法,来判断蘑菇属于有毒的还是可食用的类别。

案例主要涉及以下六个小部分:

∙ \bullet 数据集介绍

∙ \bullet 导入数据

∙ \bullet 数据探索与预处理

∙ \bullet 朴素贝叶斯建模

∙ \bullet 模型评估

数据集介绍

数据集名称为Mushroom Data Set,数据集中包含从奥杜邦的野外指南中得到的描述蘑菇的物理特性。本数据集记录了有关伞菌属和环柄菇属蘑菇的对应假想样本的23种描述,每一个物种都被认为是可以食用的,绝对有毒的,或者是未知的可食性,不推荐食用。而且该指南明确指出,没有简单的规则来确定蘑菇的可食性。

变量名变量解释
class蘑菇类别:edible=e, poisonous=p
cap.shape菌盖形状:bell=b, conical=c…
cap.surface菌盖表面: fibrous=f, grooves=g…
cap-color菌盖颜色: brown=n, buff=b…
odor气味:almond=a, anise=l…
stalk.shape茎的形状:enlarging=e, tapering=t
stalk.surface.above.ring菌环上方茎表面:fibrous=f scaly=y…
ring.number菌环数量:none=n, one=o, two=t

数据有23列,8124行,由于变量数量太多,就选择部分特征变量进行解释。

# 导入所需模块
import pandas as pd
from sklearn.model_selection import train_test_split
from sklearn.naive_bayes import MultinomialNB
import matplotlib.pyplot as plt
from sklearn.metrics import roc_curve, auc    #计算roc和auc

# 导入数据
mushrooms = pd.read_csv("F:/data/mushrooms.csv")
# 查看数据的基本特征,对数据进行简单处理,其中veil-type一列所有特征皆为p不具有分类意义
describe = mushrooms.describe()
mushrooms.drop('veil-type',axis = 1,inplace = True)      # 删除列 “veil-type”
mushrooms = pd.get_dummies(mushrooms)                   # 对数据进行哑变量处理
mushrooms.drop('class_p',axis = 1,inplace = True)       # 删除列

∙ \bullet 通过查看数据的基本特征,可以看出veil-type一列只有一个特征,对这次分类没有意义,所以将这列数据删除。
∙ \bullet 由于特征变量都为字符串,所以我们需要进行哑变量处理。
∙ \bullet 哑变量处理后,class_e,class_p两列内容相同,选择删掉一列。

# 对数据进行分层抽样,测试集占30%
x,y = mushrooms.ix[:,1:],mushrooms.ix[:,0]
x_train,x_test,y_train,y_test = train_test_split(x,y,test_size=0.3,random_state=0)
# 导入贝叶斯模型
from sklearn.naive_bayes import MultinomialNB
clf = MultinomialNB()
clf = clf.fit(x_train, y_train)    # 标准化
y_pred=clf.predict(x_test)         # 预测

模型评估,是用来衡量一个模型好坏的操作,下面我们使用了三种不同的评估方法

# 模型评估
#准确度评估 评估正确/总数
#方法1
accuracy = clf.score(x_test, y_test)

#方法2
from sklearn.metrics import accuracy_score
accuracy2 = accuracy_score(y_pred,y_test)

print(accuracy,accuracy2)
0.96349466776 0.96349466776

ROC曲线是根据一系列不同的二分类方式(分界值或决定阈),以真阳性率TPR(灵敏度)为纵坐标,假阳性率FPR(1-特异度)为横坐标绘制的曲线。

ROC曲线的作用:

1.较容易地查出任意界限值时的对类别的识别能力

2.选择最佳的诊断界限值。ROC曲线越靠近左上角,试验的准确性就越高。最靠近左上角的ROC曲线的点是错误最少的最好阈值,其假阳性和假阴性的总数最少。

3.两种或两种以上不同诊断试验对算法性能的比较。在对同一种算法的两种或两种以上诊断方法进行比较时,可将各试验的ROC曲线绘制到同一坐标中,以直观地鉴别优劣,靠近左上角的ROC曲线所代表的受试者工作最准确。亦可通过分别计算各个试验的ROC曲线下的面积(AUC)进行比较,哪一种试验的AUC最大,则哪一种试验的诊断价值最佳。

# 方法3
# 绘制ROC曲线
fpr,tpr,threshold = roc_curve(y_test, y_pred) #计算真正率和假正率
roc_auc = auc(fpr,tpr)                        #计算auc的值
plt.figure()
plt.figure(figsize=(8,8))
plt.plot(fpr, tpr, color='darkorange',
         label='ROC curve (area = %0.2f)' % roc_auc)   #假正率为横坐标,真正率为纵坐标做曲线
plt.plot([0, 1], [0, 1], color='navy', linestyle='--')
plt.xlabel('False Positive Rate')
plt.ylabel('True Positive Rate')
plt.legend(loc="lower right")
plt.show()
<matplotlib.figure.Figure at 0x190325af550>

在这里插入图片描述

模型的AUC值为0.96,分类效果较优。

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值