前言
贝叶斯决策是模式识别中最基础的理论,是解决模式分类的一种基本统计途径,是后续学习的基础
- 本文为笔者学习过程的原创笔记,转载请附本文链接及作者信息。
- 后附连续型数据的贝叶斯分类器python实现
- 有问题欢迎在交流区探讨学习,QQ:761322725
- 码字不易,好心人随手点个赞👍
总括:
贝叶斯决策论是解决模式分类问题的一种基本统计途径 。
出发点是利用概率决策与相应代价之间的折中 。
(概率学派与频率学派)
它做了如下假设 - 决策问题可以用概率形式来描述
- 所有有关的概率结构均已知
原理讲解
所用教材为机械工业出版社所译《模式识别》,使用了鱼分拣的例子,即二分类问题
问题的抽象描述如下
通用的系统框架如下图所示,实现从现实世界到符号世界的转换,完成最后的分类任务。
分类系统构成 规范化定义 后验概率是后续的关键,理解为当下数据为的条件下,标签为的概率。
最小错误率决策
最小错误率解释
对贝叶斯公式再进行分析如下
- 从最小错误率的要求出发,利用贝叶斯公式就能得出使错误率最小的分类决策 称之为 。
- 可知使 错误率最小的决策就是
- 具体决策规则可以表示如下:
决策边界
至于多类情况,同样可以推广利用
image.png
最小风险决策
- 很多场合 不同的错误决策所造成的损失不同(癌症误判 、 鱼分拣)
- 需要引入更一般的损失函数来替代错误率
- 计算各种不同误判的风险 采取总风险最小的决策 。
-
最小风险贝叶斯决策,允许更多行动 ( 而不仅仅是类别判定,当决策风险大于不决策时 可以拒绝做决策 (引申:三支决策)
image.png 相应决策过程如下:
分类器、判别函数与决策面
将分类模型表示进一步形式化,利用判别函数进行表示定义如下:
贝叶斯分类器的判别函数如下正态分布下的贝叶斯决策
我们讨论一个很常见的情况,在数据呈现正态分布下的贝叶斯决策如何计算。正态分布的相关知识点回顾如下:
则最小错误率贝叶斯判别函数如下:
上式是实际计算的关键,当取特殊值时,上式有不同的简化形式,在此不予讨论
小结
以上即为贝叶斯决策的基本原理,原理简单易懂,掌握住两种不同思路的决策方法即可
代码实现
数据说明
使用莺尾花标准数据(常用来坐分类实验demo),Iris_data网上都能下载到,数据规格:
- 多分类问题 150*5大小
- 各属性值属于连续型数据
- 数据分布为正态分布
具体算法实现流程
image.png完整代码
使用python编程实现,面向对象编程的编写方式,可以训练和预测;
模型参数存储功能当时比较急没有实现。
"""
Author:Arthur_Pang
Time: 2019/09/28
Description: [贝叶斯分类算法实现]
"""
import pandas as pd
import numpy as np
import logging
import math
import json
from sklearn.model_selection import train_test_split
logging.basicConfig(format='%(asctime)s - %(levelname)s: %(message)s',
level=logging.DEBUG)
"""
class:贝叶斯分类器
功能:- 读取加载数据
- 数据划分
- 模型训练
- 模型预测
- 模型参数保存
"""
class Bayes_classfier:
def __init__(self,path):
# 模型数据集路径
self.data_path=path
#模型参数记录
self.params=dict()
'''
func:数据集读取与训练测试集划分
return:None
'''
def data_processing(self):
self.df=pd.read_csv(self.data_path,header=None)
logging.info('loading datasets,volume:{}'.format(self.df.shape))
#数据列名称指定
self.df.columns = ['sepal_length', 'sepal_width', 'petal_length', 'petal_width', 'species']
#特征与标签提取
#features=self.df[[x for x in self.df.columns if x not in ['species']]]
features=self.df
label=self.df['species']
# 训练集与测试集切分
self.X_train, self.X_valid, self.y_train, self.y_valid=train_test_split(features, label, test_size=0.25, random_state=300,stratify=label)
logging.info('split datasets,train_datasets:{},test_datasets:{}'.format(self.X_train.shape, self.X_valid.shape))
pass
'''
func: 模型训练过程,即计算贝叶斯各个参数
return :None
'''
def fit(self):
# 计算先验概率:
priori_prob=(self.y_train.value_counts()+1)/(self.y_train.shape[0]+3)
logging.info('计算训练集先验概率...')
#print(priori_prob)
# 记录各模型参数的值用于预测
self.params['priori_prob']=priori_prob
# 计算各类均值mu,协方差矩阵的逆,协方差矩阵的行列式
mu_=dict()
sigma_inv=dict()
det_=dict()
logging.info('计算mu,sigma等矩阵运算...')
for _label,groups in self.X_train.groupby(['species']):
groups=groups[[x for x in self.df.columns if x not in ['species']]]
#print(_label,groups.mean(axis=0))
mu_[_label]=groups.mean(axis=0)
sigma_=np.cov(groups.T, bias=True)
sigma_inv[_label]=np.linalg.inv(sigma_)
det_[_label]=np.linalg.det(sigma_)
self.params['class_mu']=mu_
self.params['class_sigma_inv']=sigma_inv
self.params['class_det']=det_
'''
func: 分类判别函数,即利用代码实现上述判别函数
return: 判别值
注: @ 为numpy矩阵乘法运算
'''
def g(self,x, mu, sigma_inv, det, priori_prob):
#print(mu,sigma_inv)
return -0.5 * (x - mu).T @ sigma_inv @ (x - mu) - 0.5 * math.log(det) + math.log(priori_prob)
'''
func: 构建判别函数用于预测,对测试集中各类别进行测试
return None
'''
def predict(self):
# 对各类进行测试
for _label,test_group in self.X_valid.groupby(['species']):
logging.info('test the {},volume:{}'.format(_label,test_group.shape[0]))
test_feature=test_group[[x for x in self.df.columns if x not in ['species']]]
##
print(_label)
# 记录测试结果是否正确
test_res=[]
for _,row in test_feature.iterrows():
#print(self.params['priori_prob'][_label])
score=dict()
# 计算各类别的得分情况
for _l in self.df['species'].unique():
score[_l]=self.g(np.array(row.values),
self.params['class_mu'][_l].values,
self.params['class_sigma_inv'][_l],
self.params['class_det'][_l],
self.params['priori_prob'][_l])
#print(score)
predict_res=max(score, key=score.get)
print('[测试]当前预测类别:{},实际类别:{},{}'.format(predict_res,_label,predict_res==_label))
test_res.append(predict_res==_label)
print('{}类别测试准确率:{}'.format(_label,test_res.count(True)/len(test_res)))
classfier=Bayes_classfier('./data/iris.data')
classfier.data_processing()
classfier.fit()
classfier.predict()
代码输出结果如下:
2019-09-28 16:04:26,719 - INFO: loading datasets,volume:(150, 5)
2019-09-28 16:04:26,731 - INFO: split datasets,train_datasets:(112, 5),test_datasets:(38, 5)
2019-09-28 16:04:26,734 - INFO: 计算训练集先验概率...
2019-09-28 16:04:26,736 - INFO: 计算mu,sigma等矩阵运算...
2019-09-28 16:04:26,748 - INFO: test the Iris-setosa,volume:12
2019-09-28 16:04:26,766 - INFO: test the Iris-versicolor,volume:13
2019-09-28 16:04:26,784 - INFO: test the Iris-virginica,volume:13
Iris-setosa
[测试]当前预测类别:Iris-setosa,实际类别:Iris-setosa,True
[测试]当前预测类别:Iris-setosa,实际类别:Iris-setosa,True
[测试]当前预测类别:Iris-setosa,实际类别:Iris-setosa,True
[测试]当前预测类别:Iris-setosa,实际类别:Iris-setosa,True
[测试]当前预测类别:Iris-setosa,实际类别:Iris-setosa,True
[测试]当前预测类别:Iris-setosa,实际类别:Iris-setosa,True
[测试]当前预测类别:Iris-setosa,实际类别:Iris-setosa,True
[测试]当前预测类别:Iris-setosa,实际类别:Iris-setosa,True
[测试]当前预测类别:Iris-setosa,实际类别:Iris-setosa,True
[测试]当前预测类别:Iris-setosa,实际类别:Iris-setosa,True
[测试]当前预测类别:Iris-setosa,实际类别:Iris-setosa,True
[测试]当前预测类别:Iris-setosa,实际类别:Iris-setosa,True
Iris-setosa类别测试准确率:1.0
Iris-versicolor
[测试]当前预测类别:Iris-versicolor,实际类别:Iris-versicolor,True
[测试]当前预测类别:Iris-versicolor,实际类别:Iris-versicolor,True
[测试]当前预测类别:Iris-versicolor,实际类别:Iris-versicolor,True
[测试]当前预测类别:Iris-versicolor,实际类别:Iris-versicolor,True
[测试]当前预测类别:Iris-virginica,实际类别:Iris-versicolor,False
[测试]当前预测类别:Iris-versicolor,实际类别:Iris-versicolor,True
[测试]当前预测类别:Iris-versicolor,实际类别:Iris-versicolor,True
[测试]当前预测类别:Iris-versicolor,实际类别:Iris-versicolor,True
[测试]当前预测类别:Iris-versicolor,实际类别:Iris-versicolor,True
[测试]当前预测类别:Iris-versicolor,实际类别:Iris-versicolor,True
[测试]当前预测类别:Iris-versicolor,实际类别:Iris-versicolor,True
[测试]当前预测类别:Iris-versicolor,实际类别:Iris-versicolor,True
[测试]当前预测类别:Iris-versicolor,实际类别:Iris-versicolor,True
Iris-versicolor类别测试准确率:0.9230769230769231
Iris-virginica
[测试]当前预测类别:Iris-virginica,实际类别:Iris-virginica,True
[测试]当前预测类别:Iris-virginica,实际类别:Iris-virginica,True
[测试]当前预测类别:Iris-virginica,实际类别:Iris-virginica,True
[测试]当前预测类别:Iris-virginica,实际类别:Iris-virginica,True
[测试]当前预测类别:Iris-virginica,实际类别:Iris-virginica,True
[测试]当前预测类别:Iris-virginica,实际类别:Iris-virginica,True
[测试]当前预测类别:Iris-virginica,实际类别:Iris-virginica,True
[测试]当前预测类别:Iris-virginica,实际类别:Iris-virginica,True
[测试]当前预测类别:Iris-virginica,实际类别:Iris-virginica,True
[测试]当前预测类别:Iris-virginica,实际类别:Iris-virginica,True
[测试]当前预测类别:Iris-virginica,实际类别:Iris-virginica,True
[测试]当前预测类别:Iris-virginica,实际类别:Iris-virginica,True
[测试]当前预测类别:Iris-virginica,实际类别:Iris-virginica,True
Iris-virginica类别测试准确率:1.0
- 本文为笔者学习过程的原创笔记,转载请附本文链接及作者信息。
- 有问题欢迎在交流区探讨学习,QQ:761322725
- 码字不易,好心人随手点个赞👍
网友评论