【模式识别】贝叶斯分类器的C++实现
来源:互联网 发布:java线程yield 编辑:程序博客网 时间:2024/05/29 16:28
分类问题
在介绍贝叶斯分类器之前我们首先需要知道分类问题是什么。
给你一个训练数据集,数据集中有一些样本,每个样本有一个或若干特征
x (这里x 的是向量),每个样本都属于一个类别wi ,现在让你通过这个训练集得到一个分类器,这个分类器具有这样的功能:给定一个新的样本(也就是给定一个特征
x ),你的分类器能判断它属于哪个类别其实我们可以把分类器看成是一个函数
f(x) ,函数的返回值就是对应特征所属的类别,所有的分类器的目的都是去寻找一个比较好的函数能更好的描述特征与类别之间的关系。
贝叶斯定理:
P(wi|x)=P(x|wi)P(wi)∑kj=1P(x|wj)P(wj)
P(wi) 是,表示在不知道样本特征的情况下,某个样本属于wi 类的概率。P(x|wi) 是类条件概率密度,可以看成是在某一类别的情况下特征的分布(概率密度函数)P(wi|x) 是后验概率,就是在知道样本的特征的情况下该样本属于某一个特征的概率。
贝叶斯分类器的设计思路
一句话概括贝叶斯分类器:
在知道先验概率和类条件概率密度的情况下算后验概率,后验概率最大的类别作为最终类别
我们的问题是”给定特征判断这个特征所对应的类别”,一个容易想到的思路是算出这个特征属于每个类别的概率,然后取最大的那个类别作为最终的分类。其中”属于某个类别的概率”可以表示成条件概率的形式
P(wi|x) ,也就是贝叶斯定理中的后验概率,接下来就是去求得P(x|wi) 和P(wi) 就行了.例子
将人的身高(height)和体重(weight)作为分类特征,分为两组类别,男性(male)和女性(female),现在给你一组男性的身高和体重的数据和女性的身高体重数据作为训练数据集训练出一个贝叶斯分类器。
男性的数据保存在MALE.TXT,包含若干行数据,每行两个数x1 x2分别表示身高和体重
女性的数据类似
假设二者相关,在正态分布假设下估计概率密度函数
由于假设了两个特征满足正态分布,所以我们可以通过
μ1、μ2、θ1、θ2、ρ 五个参数确定某个类别的样本分布,也就是类条件概率密度P(x|wi) 代码实现
#include<iostream>#include<fstream>#include<cmath>#include<cstdio>using namespace std;const int MAXN=1000;const double pi=3.1415926;ifstream cin1("FEMALE.TXT");ifstream cin2("MALE.TXT");ifstream cin3("test2.txt");ofstream cout1("result.txt");struct HUMAN{ double height; double weight;};HUMAN female[MAXN];HUMAN male[MAXN];int female_num;int male_num;double P_female;double P_male;struct NORMAL{ double mu1; double mu2; double delta1; double delta2; double rho;};NORMAL female_normal;NORMAL male_normal;/*读入文件数据*/void In(){ male_num=0; female_num=0; while(cin1>>female[female_num+1].height>>female[female_num+1].weight) { female_num++; } while(cin2>>male[male_num+1].height>>male[male_num+1].weight) { male_num++; }}void Init(){ P_female=0.5; P_male=0.5;}/*读入样本数量个样本,并求出该样本的二维正态分布*/void Normalization(struct HUMAN *human,int human_num,struct NORMAL &human_normal){ double mu1,mu2,delta1,delta2,rho; mu1=0;mu2=0;delta1=0;delta2=0,rho=0; for(int i=1;i<=human_num;i++) { mu1+=human[i].height; mu2+=human[i].weight; } mu1/=human_num; mu2/=human_num; for(int i=1;i<=human_num;i++) { delta1+=(human[i].height-mu1)*(human[i].height-mu1); delta2+=(human[i].weight-mu2)*(human[i].weight-mu2); } delta1/=human_num; delta2/=human_num; delta1=sqrt(delta1); delta2=sqrt(delta2); for(int i=1;i<=human_num;i++) { rho+=human[i].height*human[i].weight; } rho/=human_num; rho-=mu1*mu2; rho/=(delta1*delta2); human_normal.mu1=mu1; human_normal.mu2=mu2; human_normal.delta1=delta1; human_normal.delta2=delta2; human_normal.rho=rho; cout<<mu1<<" "<<delta1<<" "<<mu2<<" "<<delta2<<" "<<rho<<endl;}/*在分布为normal的条件下特征为(x1,x2)的条件概率*/double P(struct NORMAL &normal,double x1,double x2){ double ans; double mu1=normal.mu1; double mu2=normal.mu2; double delta1=normal.delta1; double delta2=normal.delta2; double rho=normal.rho; rho=0; ans=(1/(2*pi*delta1*delta2* sqrt(1-rho*rho) ))*exp(-1/(2*sqrt(1-rho*rho) )*( ((x1-mu1)*(x1-mu1))/(delta1*delta1) + ((x2-mu2)*(x2-mu2))/(delta2*delta2) - (2*rho*(x1-mu1)*(x2-mu2))/(delta1*delta2) ) ); return ans;}/*归为normal的后验概率t为0表示female,1表示male*/double Posterior_probability1(double x1,double x2,bool t){ double Pw; struct NORMAL normal; if(t==0)return (P(female_normal,x1,x2)*P_female)/(P(female_normal,x1,x2)*P_female+P(male_normal,x1,x2)*P_male); else return (P(male_normal,x1,x2)*P_male)/(P(female_normal,x1,x2)*P_female+P(male_normal,x1,x2)*P_male);}/*判断是哪个类别,返回0表示female,1表示male*/bool Classify(double x1,double x2){ //cout<<Posterior_probability1(x1,x2,0)<<" "<<Posterior_probability1(x1,x2,1)<<endl; if(Posterior_probability1(x1,x2,0)>=Posterior_probability1(x1,x2,1))return 0; else return 1;}/*得到错误率并将错误率输出到result.txt中*/void Find_error_rate(){ double height,weight; char c; int right_num=0; int wrong_num=0; while(cin3>>height>>weight>>c) { if( (c=='f' || c=='F') && Classify(height,weight)==0)//分类为女性并且正确 right_num++; else if( (c=='m' || c=='M') && Classify(height,weight)==1)//分类为男性并且正确 right_num++; else wrong_num++; cout1<<height<<" "<<weight<<" "<<Classify(height,weight)<<endl; } cout<<"error rate is "<<(double)wrong_num/(double)(wrong_num+right_num)<<endl;}int main(){ In(); Init(); Normalization(female,female_num,female_normal); Normalization(male,male_num,male_normal); //female_normal.rho=0; //male_normal.rho=0; Find_error_rate(); return 0;}
- 【模式识别】贝叶斯分类器的C++实现
- 模式识别三--MATLAB实现贝叶斯分类器
- 模式识别中Fisher分类器的Matlab实现及测试
- 模式识别(七):MATLAB 实现朴素贝叶斯分类器
- 模式识别读书笔记1 基于贝叶斯决策理论的分类器
- OpenCV的分类器(模式识别)
- 模式识别:分类器的性能评价
- 模式识别二--分类器的性能评价
- 模式识别: 线性分类器
- 分类器(模式识别)
- 模式识别: 线性分类器
- 模式识别之分类器
- 模式识别: 线性分类器
- 贝叶斯分类器--文本分类的C语言实现
- 感知器算法(C语言)模式识别几何分类发(线性可分时)感知器算法(3维C语言实现)
- 模式识别:感知器的实现
- 模式识别:感知器的实现
- 模式识别:感知器的实现
- 异常总结
- Android Studio 过滤不需要的Log
- jsp Session
- 程序猿学习第九天,浮动和盒子模型标签属性
- 二叉排序树基本用法
- 【模式识别】贝叶斯分类器的C++实现
- 监听器
- ffmpeg 解码 png apng 图片
- jiebaR中文分词,从入门到喜欢
- 爬虫设置代理
- centos7 五大查找常用命令
- 更改Eclipse下Tomcat的部署目录
- sqlserver 还原出错
- 集体婚礼