贝叶斯的思想比较简单,网上阐述也很详细,这里就不赘述了。
这里只是简单的说一下编程的思路
首先明确我们要实验的内容,实现贝叶斯分类,那么要想编程实现,你必须对贝叶斯分类有足够的了解。而贝叶斯分类的过程并不难,总的来说就是,有了一些训练数据,当来了一条测试数据,首先根据训练数据计算先验概率,比如有17条训练数据,8条好瓜,9条坏瓜,那么P(好瓜) = 8 / 17,坏瓜以此类推。
紧接着计算后验概率,比如测试数据第一个属性是色泽,值为青绿,那么就计算训练数据中所有好瓜里面色泽为青绿的个数,比如有3个,那么得到P(青绿 | 好瓜) = 3 / 8,以此类推计算所有属性,那么比如测试数据有5个属性,而数据有两个类别,那么一共要计算10个概率。
最后将P(好瓜) * P(青绿 | 好瓜) * … * = P1
P(坏瓜) * P(青绿 | 坏瓜) * … * = P2
比较P1P1谁大,测试是数据就是哪个类别。

  • 伪代码
    Class BayesClassifier():
    1、 初始化,# 参数可以自己添加
    即让训练集为空
    2、 Fit
    其实就是输入训练集
    3、 计算先验概率
    4、 计算后验概率(难点)
    5、 预测
    输入一条测试数据,给出预测结果
    6、 评估
    输入一组测试数据(即测试集),返回测试精度

  • 思路
    我打算用sklearn的train_test_split来划分数据集。那么现在还要想明白的就是,将数据文件导入后,用什么数据类型便于计算呢?先验概率好求,后验概率怎么编程实现呢?在后续的编写中,我发现难点其实在于,你划分了数据集,X_train的样子大概是这样:

    而y_train的样子是这样:

那么问题来了,在计算后验概率的时候,你要如何将类别为好瓜的位置找出来呢?为什么要找?比如第一个属性,找出来才能计算好瓜中青绿的个数呀,找出来以后用什么存放呢?字典呀!我可以在计算先验概率时先算出好瓜的个数,坏瓜的个数,放到一个字典里面like:{‘好瓜’:4,’坏瓜’:8},接着因为y_train和X_train的索引是一一对应的,那么我就可以根据y_train得出好瓜的位置呀!like: {‘好瓜’:[3,5,7],’坏瓜’:[0,1,2,4,6]},再根据这个位置去找X_train统计青绿的个数。
统计完个数就可以计算后验概率了,like:{‘坏瓜’:[0.3,0.375,0.126,0.45],’好瓜’:[0.6,0.2,0.5,0.6]},这里我特地不加以区分的直接把所有概率放进一个列表里,为什么这么做呢?因为后面用到的时候只是把所有都乘起来即可,无需加以区分。

还需要注意的就是,对离散值和连续值的处理,离散值就是上面的方法,连续值就是需要先算出训练集该属性的均值和标准差接着用下面的公式:
计算即可,还有就是在计算之前判断一下是离散值还是连续值即可,一个if ,else就能解决的问题。
事实上如果编程实现了上面的步骤,拉普拉斯修正就是加几句代码的问题。
BayesClassifier.py

# -*- coding: utf-8 -*-"""
Created on Tue Apr 21 10:53:41 2020@author: Hja
@Company:北京师范大学珠海分校
@version: V1.0
@contact: 583082258@qq.com 2018--2020
@software: Spyder
@file: BayesClassifier.py
@time: 2020/4/22 9:02
@Desc:贝叶斯分类器
@PS : 将贝叶斯分类器封装起来
"""import numpy as np
import pandas as pd
from sklearn.model_selection import train_test_split
import warnings
warnings.filterwarnings("ignore")#消除警告class Bayes_Classifier(object):'''贝叶斯分类器'''def __init__(self):'''定义训练集'''self.X_train = Noneself.y_train = Nonedef fit(self,X_train,y_train):#   给训练集赋值'''X_train is array ,shape like [n_samples,shapes]X_train is array ,shape like [n_samples,1]'''self.X_train = X_trainself.y_train = y_traindef cal_base_rates(self):'''计算先验概率data为训练集'''#存放先验概率,如{'好瓜':0.471}cal_base_rates = {}#首先查看数据一共有几个决策属性labels = self.Get_Decision_attribute()#计算先验概率for label in labels:#如 :  '是'在y_train_data中出现的次数 / 在y_train_data的长度priori_prob = sum(self.y_train == label) / len(self.y_train)#放入字典中cal_base_rates[label] = priori_probreturn cal_base_ratesdef Get_Decision_attribute(self):'''获得数据集的决策属性'''labels = set(self.y_train)return labelsdef Conditional_Probability(self,X_test):'''为每个属性估计条件概率,data为待预测数据return {'好瓜':{'青绿': 0.375}}X_train_data,y_train_data为训练集X_test like:['青绿', '蜷缩', '浊响', '清晰', '凹陷', '硬滑', 0.697, 0.46]'''labels = self.Get_Decision_attribute()#统计不同类别的个数,如{'好' : 3,'坏':8}labels_count = {}#存放好瓜,坏瓜的编号,like :{’好': [[2],[4],[10]],'坏' : [...]}labels_place = {}#  存放后验概率cal_base_rates = {}for label in labels:labels_count[label] = sum(self.y_train == label)#记录好瓜,坏瓜的编号labels_place[label] = np.argwhere(self.y_train == label)cal_base_rates[label] = []#  初始化flag = 0#计算每个属性的条件概率for value in X_test:#对连续值的处理if type(value) != str:for label,places in labels_place.items():#int_value = []#如:存放好瓜的密度for place in places:int_value.append(self.X_train[place,flag])#将取值放入,方便等会计算均值,标准差#  计算均值,标准差value_mean = np.mean(int_value)value_std = np.std(int_value)#高斯模型race = (np.exp(((value - value_mean) ** 2) / (-2 * (value_std ** 2)))) / (np.sqrt(2 * np.pi) * value_std)cal_base_rates[label].append(race)#   对离散值的处理else:for label,places in labels_place.items():#value_count = 0#  用来统计某个元素的个数: 如'青绿' 3 次,那么value_count = 3for place in places:if value == self.X_train[place,flag]:value_count += 1#计算概率race = value_count / len(places) #places的个数即好瓜的个数 or 坏瓜#  这里不加标记是那个取值的概率,是因为后面都是直接乘积cal_base_rates[label].append(race)#  like: {'好' :[0.357,0.625,...]}flag = flag + 1return cal_base_ratesdef Predict(self,X_test):'''给出一条数据的预测结果,X_test like:['青绿', '蜷缩', '浊响', '清晰', '凹陷', '硬滑', 0.697, 0.46] '''from functools import reduce#   得出先验概率和后验概率result_behind = self.Conditional_Probability(X_test)result_before = self.cal_base_rates()#  计算概率max_race = 0flag = Nonefor label,value in result_behind.items():race = reduce(lambda x,y:x * y,value) * result_before[label]   #  计算概率if max_race < race:  max_race = raceflag = labelreturn flag   #   返回类别def Score_model(self,X_test,y_test):'''返回测试集精度给出一组数据的精度结果,X_test like:['青绿', '稍蜷', '浊响', '稍糊', '凹陷', '硬滑', 0.639, 0.161],['青绿', '蜷缩', '浊响', '清晰', '凹陷', '硬滑', 0.6970000000000001, 0.46],['青绿', '蜷缩', '沉闷', '清晰', '凹陷', '硬滑', 0.608, 0.318]......'''y_pred = []for item in X_test:result = self.Predict(item)y_pred.append(result)return np.mean(y_pred == y_test)#  考虑到该模型精度波动大,我们做十次去均值
def Mean_of_model(data,cv = 10):'''data为数据集'''score = []for i in range(cv):X_train,X_test,y_train,y_test = train_test_split(data[:,:-1],data[:,-1],test_size = 0.3)score.append(Score_model(X_train,y_train,X_test,y_test))return np.mean(score)if __name__ == '__main__':#设置数据文件路径path = r'F:\大三下\李艳老师数据挖掘实践\实验五\西瓜数据.csv'#读取文件data = pd.read_csv(path)data.drop(columns = '编号',inplace = True)#转换为array类型,便于计算data_np = np.array(data)#插看前五行#print(data_np[:5,:])#色泽,根蒂,敲声,纹理,脐部,触感,密度,含糖率,好瓜#划分数据,data_np[:,-1]为决策属性列X_train,X_test,y_train,y_test = train_test_split(data_np[:,:-1],data_np[:,-1],\test_size = 0.3)#test = np.array(['青绿','蜷缩','浊响','清晰','凹陷','硬滑',0.697,0.460])test = ['青绿','蜷缩','浊响','清晰','凹陷','硬滑',0.697,0.460]#  建立模型bayes = Bayes_Classifier()#  训练模型bayes.fit(X_train,y_train)#  给出对test的预测结果y_pred = bayes.Predict(test)print("{} 的分类结果 {} 好瓜".format(test,y_pred))#print(y_pred)#  查看后验概率#print(bayes.Conditional_Probability(test))#   打印测试集精度print("Test set score: {:.2f}".format(bayes.Score_model(X_test,y_test)))#  用全部数据作为训练集,看得出的结果与PPT的是否相同,证明是相同的bayes.fit(data_np[:,:-1],data_np[:,-1])y_pred = bayes.Predict(test)#  从结果可以看出,p(青绿|好瓜) = 0.375,p(青绿|坏瓜) = 0.333...print("后验概率:",bayes.Conditional_Probability(test))print("先验概率:",bayes.cal_base_rates())#print("{} 的分类结果 {} 好瓜".format(test,y_pred))#  用十次留出法的均值来评估模型cv = 50scores = []for i in range(cv):X_train,X_test,y_train,y_test = train_test_split(data_np[:,:-1],data_np[:,-1],\test_size = 0.3)bayes = Bayes_Classifier()bayes.fit(X_train,y_train)#    print("Test set score: {:.2f}".format(bayes.Score_model(X_test,y_test)))scores.append(bayes.Score_model(X_test,y_test))#print("用{}次留出法的均值来评估模型 :{:.2f}".format(cv,np.mean(scores)))#   画图import matplotlib.pyplot as plt#    不同的划分对模型的影响plt.figure(figsize = (4,4),dpi = 144)plt.grid()plt.plot(range(cv),scores,'g-')plt.xlabel('Differernt  Divide')plt.ylabel('Score')plt.title('Influence of different Divide on accuracy')plt.show()
  • 结果分析
    我首先使用一条数据去测试,即
test = ['青绿','蜷缩','浊响','清晰','凹陷','硬滑',0.697,0.460]
#  建立模型
bayes = Bayes_Classifier()
#  训练模型
bayes.fit(X_train,y_train)
y_pred = bayes.Predict(test)
print("{} 的分类结果 {} 好瓜".format(test,y_pred))

Out:

如果你仔细看过代码,可以发现,bayes.Predict是针对一条数据进行预测的,而bayes.Score_model的输入是测试集,即遍历每一条数据,将每一条数据代入bayes.Predict进行计算。

为了验证程序的正确性,我将所有数据作为训练集,单独测试下面的数据,看下计算出来的概率和PPT中的是否相同。
test = [‘青绿’,‘蜷缩’,‘浊响’,‘清晰’,‘凹陷’,‘硬滑’,0.697,0.460]

#  用全部数据作为训练集,看得出的结果与PPT的是否相同,证明是相同的
bayes.fit(data_np[:,:-1],data_np[:,-1])
y_pred = bayes.Predict(test)
#  从结果可以看出,p(青绿|好瓜) = 0.375,p(青绿|坏瓜) = 0.333...
print("后验概率:",bayes.Conditional_Probability(test))
print("先验概率:",bayes.cal_base_rates())

Out:

该结果中,如“否”:[0.3333333333333333, 0.3333333333333333, 0.4444444444444444, 0.2222222222222222, 0.2222222222222222, 0.6666666666666666, 1.194154974103892, 0.042477456013491184],那么第一个值0.333即为P(青绿|坏瓜) = 0.33,第三个0.44即
P(浊响|坏瓜) = 0.44,显然与PPT计算的一致。

考虑到用该数据集训练的模型波动比较大,我想找出该模型测试集的均值大概是多少,于是我使用100次划分的数据去训练模型,将得到的精度取均值。
并将结果可视化

#  用cv次留出法的均值来评估模型
cv = 100
scores = []
for i in range(cv):
X_train,X_test,y_train,y_test = train_test_split(data_np[:,:-1],data_np[:,-1],\test_size = 0.3)
bayes = Bayes_Classifier()
bayes.fit(X_train,y_train)
#    print("Test set score: {:.2f}".format(bayes.Score_model(X_test,y_test)))
scores.append(bayes.Score_model(X_test,y_test))print("用{}次留出法的均值来评估模型 :{:.2f}".format(cv,np.mean(scores)))#   画图
import matplotlib.pyplot as plt
#    不同的划分对模型的影响
plt.figure(figsize = (4,4),dpi = 144)
plt.grid()
plt.plot(range(cv),scores,'g-')
plt.xlabel('Differernt  Divide')
plt.ylabel('Score')
plt.title('Influence of different Divide on accuracy')
plt.show()

Out:

从结果可以看出,对于该数据训练出来的模型,泛化能力并不是特别好,对于测试集的精度只在0.5左右。

  • 后续
    最后:至于拉普拉斯修正嘛,很简单在源程序计算先验概率中修改红字部分

    该步对应以下步骤


    该步实现以下的步骤

    修改以后看看精度有无提升:

    可以看到拉普拉斯修正对模型的确实有一定的改正能力。

程序用到的数据集已上传百度云,需要的朋友自行下载
链接:https://pan.baidu.com/s/1ujtT2YsAbHNOm2mbCRNUiA
提取码:q911

python编程实现贝叶斯分类相关推荐

  1. 基于jupyter notebook的python编程-----MNIST数据集的的定义及相关处理学习

    基于jupyter notebook的python编程-----MNIST数据集的相关处理 一.MNIST定义 1.什么是MNIST数据集 2.python如何导入MNIST数据集并操作 3.接下来, ...

  2. 马斯克如何颠覆航天? 1/5385成本,c++和python编程!

    马斯克如何颠覆航天? 1/5385成本,c++和python编程! 5月31日,经历了重重困难,马斯克的SpaceX载人飞船成功发射,这是美国自2011年以来首次发射载人航天飞船,也是美国进入由商业主 ...

  3. CSS、JavaScript、PHP和Python编程合二为一

    CSS, JavaScript,PHP And Python Programming All in One Course 在一门课程中学习Javascript.PHP和Python编程语言的CSS 你 ...

  4. python编程代码示例_python编程线性回归代码示例

    用python进行线性回归分析非常方便,有现成的库可以使用比如:numpy.linalog.lstsq例子.scipy.stats.linregress例子.pandas.ols例子等. 不过本文使用 ...

  5. 《树莓派Python编程指南》——2.2 一个Python游戏:猫和老鼠

    本节书摘来自华章计算机<树莓派Python编程指南>一书中的第2章,第2.2节,作者:(美) Alex Bradbury Ben Everard更多章节内容可以访问云栖社区"华章 ...

  6. 《树莓派Python编程指南》—— 1.3 树莓派快速指南

    本节书摘来自华章计算机<树莓派Python编程指南>一书中的第1章,第1.3节,作者:(美) Alex Bradbury Ben Everard更多章节内容可以访问云栖社区"华章 ...

  7. Python编程规范及性能优化

    为什么80%的码农都做不了架构师?>>>    Ptyhon编程规范 编码 所有的 Python 脚本文件都应在文件头标上 # -*- coding:utf-8 -*- .设置编辑器 ...

  8. 学习Python编程开发可以从事的岗位有哪些?

    Python编程技术在人工智能领域的发展有目共睹,很多人都想学习Python技术,而且从事Python开发,所从事的工作机会和工作岗位及工作内容可选择的余地很多,未来发展空间也很大.下面我们就来详细的 ...

  9. Python编程比较好的机构怎么选择

    想要进入到IT行业,很多人的首要选择都是学习Python编程语言,因为Python编程语言入门是相对比较简单的,但是想要学好Python技术,找一个好的Python培训机构是非常重要的,那么Pytho ...

最新文章

  1. 轨道阱 matlab,赛默飞四极杆-轨道阱液质联用仪核心参数详解
  2. TopShell管理服务
  3. [POJ 3345] Bribing FIPA
  4. jquery文件的引入
  5. Mysql 主从复制+MHA搭建
  6. SAP Spartacus B2B Org Unit树状结构的加载机制
  7. JDK7的日期时间类
  8. 前端学习(2733):重读vue电商网站43之使用 lodash 中 cloneDeep(obj) 来实现深拷贝
  9. creportctrl 排序_witclient 智能客户端
  10. shell字符串是否以a-zA-Z字母开头
  11. HDU 4548 美素数
  12. python打印100以内质数_python输出100以内的质数与合数实例代码
  13. 手把手教你配置阿里云服务器搭建网站(图文教程)
  14. HTML5 终于定稿,八年后我们再一次谈谈怎么改变世界
  15. Android系统java/native crash和anr异常处理流程以及DroboxManagerService日志记录
  16. 高通 Hexagon V65 HVX 编程参考手册(1)
  17. C++实现七参数转换法(布尔莎模型)
  18. 区块链学习笔记(2)难度整定,区块形成,区块体,Merkle树,Merkle Proof默克尔证明
  19. 一个mybatis动态 SQL查询的完整小案例。包含多表联合查询。
  20. 【svn】如何批量忽略文件和文件夹

热门文章

  1. 瞄准大鱼号这八种收益,让你轻松月入过万
  2. 知乎引流推广运营全攻略
  3. SpringCloud Alibaba 2021微服务实战十三 gateway 全局过滤器打印日志及如何忽略全局过滤器
  4. 文本效果-white-space、overflow、text-overflow
  5. 在IntelliJ IDEA中使用Spring Initializr创建项目以及Maven集成与配置
  6. 医院信息系统集成服务平台建设方案
  7. 推荐几款免费视频格式转换软件,比格式工厂更好用
  8. 司创电梯发卡软件_防复制电梯IC卡系统上位机管理软件设计
  9. html网页制作教程课件,第2章 HTML入门(网页制作案例教程课件).ppt
  10. 算法 64式 7、搜索算法整理_第4部分_46到60题