python编程实现贝叶斯分类

article/2025/10/15 15:27:27

贝叶斯的思想比较简单,网上阐述也很详细,这里就不赘述了。
这里只是简单的说一下编程的思路
首先明确我们要实验的内容,实现贝叶斯分类,那么要想编程实现,你必须对贝叶斯分类有足够的了解。而贝叶斯分类的过程并不难,总的来说就是,有了一些训练数据,当来了一条测试数据,首先根据训练数据计算先验概率,比如有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


http://chatgpt.dhexx.cn/article/fqKYLVU5.shtml

相关文章

机器学习-贝叶斯分类实验

机器学习-贝叶斯分类 1. 中文文本分类介绍2. 文本分类的一般步骤&#xff1a;3. 具体操作4. 实验步骤5. 实验完整代码python 1. 中文文本分类介绍 文本挖掘是指从大量的文本数据中抽取事先未知的、可理解的、最终可用的知识的过程&#xff0c;同时运用这些知识更好的组织信息以…

贝叶斯分类——贝叶斯网络

在“贝叶斯分类——朴素贝叶斯算法”中&#xff0c;我介绍了朴素贝叶斯分类的相关知识。其中的核心思想是利用变量之间的“朴素”性质&#xff0c;计算出联合概率密度。这依赖于朴素贝叶斯分类的一个限制条件&#xff0c;就是特征属性必须有条件独立或基本独立。但现实中各个特…

模式识别:最小错误率贝叶斯决策分类

一、引言 1.用贝叶斯决策理论分类要事先知道两个条件及要求&#xff1a; ①.各类的先验概率&#xff1a; 及特征向量的条件概率密度&#xff1a; 或后验概率&#xff1a; ②.决策分类的类别一定 2.解决的问题&#xff1a; 已知一定数目的样本&#xff0c;设计分类器&…

机器学习——朴素贝叶斯分类

一贝叶斯原理 1.1贝叶斯原理产生背景&#xff1a; 贝叶斯原理是英国数学家托马斯贝叶斯提出的&#xff0c;他写的一篇关于归纳推理的论文直接影响了接下来两个多世纪的统计学&#xff0c;是科学史上著名的论文之一。 贝叶斯原理是贝叶斯为了解决一个叫“逆向概率”问题写了一…

贝叶斯分类器做文本分类案例

贝叶斯分类器做文本分类 文本分类是现代机器学习应用中的一大模块&#xff0c;更是自然语言处理的基础之一。我们可以通过将文字数据处理成数字数据&#xff0c;然后使用贝叶斯来帮助我们判断一段话&#xff0c;或者一篇文章中的主题分类&#xff0c;感情倾向&#xff0c;甚至…

贝叶斯分类——朴素贝叶斯算法

在机器学习分类算法中&#xff0c;大多数的分类算法&#xff0c;比如决策树&#xff0c;KNN&#xff0c;SVM等&#xff0c;他们都是判别方法&#xff0c;也就是直接学习出特征输出Y和特征X之间的关系&#xff0c;要么是决策函数 Yf(x) ,要么是条件分布 P(Y|X)。 但是朴素贝叶斯…

朴素贝叶斯分类:原理

贝叶斯原理是英国数学家托马斯贝叶斯提出的。贝叶斯是个很神奇的人&#xff0c;他的经历类似梵高。生前没有得到重视&#xff0c;死后&#xff0c;他写的一篇关于归纳推理的论文被朋友翻了出来&#xff0c;并发表了。这一发表不要紧&#xff0c;结果这篇论文的思想直接影响了接…

贝叶斯多分类原理与python代码

贝叶斯处理多分类问题时&#xff0c;对于不同的数据特征要采用不同的贝叶斯变体。这里主要说下处理“连续型”变量的高斯贝叶斯分类和处理”离散型“变量的多项式贝叶斯分类。 回顾&#xff1a;贝叶斯公式 p(x)&#xff1a;对于输入的每个x值是随机的&#xff0c;它们应该有相…

朴素贝叶斯分类的概念(一)

朴素贝叶斯模型是一组非常简单快速的分类算法,通常适用于维度非常高的数据集.速度快,可调参数少.非常适合为分类问题提供快速粗糙的基本方案. 作为一个数学小白,乍一听到朴素贝叶斯这个名词时一般都是晕的,根据多年的初等数学学习经验,贝叶斯应该是一个人,但是"朴素"…

Python3 实现朴素贝叶斯分类

Python3 实现朴素贝叶斯分类 贝叶斯定理朴素贝叶斯源代码样例测试 贝叶斯定理 贝叶斯定理是由已知事件概率和条件概率计算未知条件概率的概率推理算法&#xff0c;其公式如下&#xff1a; 其中&#xff0c;P(Bi|A)是要计算的目标条件概率&#xff0c;表示事件 A 发生的条件下…

浅谈贝叶斯分类

贝叶斯分类 贝叶斯分类是一类分类算法的总称&#xff0c;以贝叶斯定理为基础。其中我们较为熟悉的朴素朴素贝叶斯分类是贝叶斯分类中最简单&#xff0c;也是常见的一种分类方法。 贝叶斯网络 贝叶斯网络是一种概念图模型。概率图模型就是用图论和概率论的知识&#xff0c;利…

基于Python实现的图片贝叶斯分类器分类

使用流程及应用展示&#xff1a; 1. 选择图片&#xff1a; 控制台版本从命令行输入 当直接回车时将读取默认路径图片&#xff08;./assets/生活照-武.jpg&#xff09;,相对路径是从打开程序的文件夹开始的&#xff0c;若输入路径无效或不可读将继续询问输入 GUI 从文件浏览器…

【贝叶斯分类4】贝叶斯网

文章目录 1. 半朴素贝叶斯分类器知识回顾2. 贝叶斯网学习笔记2.1 引言2.2 知识卡片2.3 概率图模型(PGM)2.3.1 引言2.3.2 为什么引入概率图?2.3.3 概率图的三个基本问题&#xff08;表示&#xff0c;学习&#xff0c;推断&#xff09; 2.4 贝叶斯网2.4.1 贝叶斯网的表达2.4.2 结…

机器学习算法-朴素贝叶斯分类

机器学习算法--朴素贝叶斯分类 引入贝叶斯决策论条件概率和全概率公式贝叶斯推断和朴素贝叶斯推断拉普拉斯平滑 代码实例1、言论过滤器2、垃圾邮件过滤器 代做 引入 贝叶斯决策论(Bayesian decision theory)是概率论框架下实施决策的基本方法。对分类任务来说&#xff0c;在所有…

【ML】贝叶斯分类和朴素贝叶斯分类

一、介绍 贝叶斯定理是英国数学家托马斯贝叶斯提出的&#xff0c;为了解决一个“逆概率”问题。 贝叶斯分类是一类分类算法的总称&#xff0c;这类算法均以贝叶斯定理为基础&#xff0c;故统称为贝叶斯分类。而朴素贝叶斯分类是贝叶斯分类中最简单&#xff0c;也是常见的一种…

机器学习之朴素贝叶斯分类

朴素贝叶斯分类 贝叶斯定理和基础概率论朴素贝叶斯高斯朴素贝叶斯&#xff0c;多项式朴素贝叶斯&#xff0c;伯努利朴素贝叶斯的区别几种朴素贝叶斯实战总结 贝叶斯定理和基础概率论 概率&#xff0c;其实在我们生活中十分常见&#xff0c;它是对未来事件发生可能性的表述&…

机器学习--朴素贝叶斯分类函数

一、前言 朴素贝叶斯算法是有监督的学习算法&#xff0c;解决的是分类问题&#xff0c;如客户是否流失、是否值得投资、信用等级评定等多分类问题。该算法的优点在于简单易懂、学习效率高、在某些领域的分类问题中能够与决策树、神经网络相媲美。但由于该算法以自变量之间的独…

机器学习之贝叶斯算法图像分类

数据集&#xff1a;数据集采用Sort_1000pics数据集。数据集包含1000张图片&#xff0c;总共分为10类。分别是人(0)&#xff0c;沙滩&#xff08;1&#xff09;&#xff0c;建筑&#xff08;2&#xff09;&#xff0c;大卡车&#xff08;3&#xff09;&#xff0c;恐龙&#xff…

使用 Python 进行朴素贝叶斯分类

定义 在机器学习中&#xff0c;贝叶斯分类器是一种简单的概率分类器&#xff0c;它基于应用贝叶斯定理。朴素贝叶斯分类器使用的特征模型做出了很强的独立性假设。这意味着一个类的特定特征的存在与其他所有特征的存在是独立的或无关的。 独立事件的定义&#xff1a; 两个事件…

数据分类《二》贝叶斯分类

本博客是参考《数据仓库与数据挖掘技术》以及诸多道友的blog。仅作为自己学习的一个总结。 贝叶斯分类是一种基于统计学的分类方法&#xff0c;可以预测一个类成员关系的可能性。数据挖掘主要使用两种分类&#xff0c;朴素贝叶斯和贝叶斯网络方法。前者使用贝叶斯进行预测&…