选修课老师布置了一道非常简单的作业,作为一学期没上课的学渣,靠百度搜索写完了作业,现把代码贴出,关于贝叶斯分类器的知识,网上一大堆,我就不费时间重复了。
听说MATLAB可以实现,但我MATLAB学的太烂,不会用,只好自己动手,丰衣足食了。
废话不多说,直接上代码
题目
题目:基于几何形态的鸢尾花分类
说明:
1935年,美国植物学家Edgar Anderson在加拿大Gaspe Peninsula岛上采集了三种不同的鸢尾属花卉(具体种类分别为setosa,versicolor和virginica)的几何形态数据。其原始目的是为了调查不同地理区域的植物异变现象。次年,英国统计学家Ronald Fisher在他的经典论文《The use of multiple measurements in taxonomic problems》中引入了Anderson采集的数据,将其整理为著名的Fisher’s Iris数据集(简称Iris)用于分类学研究。Iris数据集一般被认为是模式识别领域早期最具代表性和影响力的数据集之一,它包含了从150株鸢尾属花卉上测量到的四种不同特征,包括花萼宽度、花萼长度、花瓣宽度、花瓣长度,并由Anderson给出了对应花卉种类。
附件(文件:iris-dataset.xlsx)给出了Iris数据集,其中90个样本作为训练样本,60个样本作为测试样本。利用iris数据库进行以下计算:
1) 请选择1种特征,利用训练数据集,使用最大似然估计方法为三种鸢尾花建立概率密度函数模型,并给出模型参数估计值。
2) 根据题1中给出的概率模型估计结果,采用贝叶斯分类器对测试样本进行分类,统计一下分错了几个?
3) 如果允许选择2种特征作为分类依据,重复上述过程,观察错误分类的样本数量是否减少?
4) 你还能想出其他分类方法吗?请给出新方法描述和分类结果,判断是否比贝叶斯分类器的结果更好?
附件内容格式如下:
例程
题目一
#include<stdio.h>
#include<math.h>
#define PI 3.1415926
#ifndef e
#define e 2.71828
#endif // e
double FGaussian(double , double , double );
double P_ai(double);
double posterior(int, double);
typedef struct
{
double u;
double a;
}class_t;
//class1,class2,class3为第一问得到的正态分布参数值,第一问采用的excel计算,并未写进代码。
class_t class1 = {0.2467, 0.0098}, class2 = {1.3533, 0.0432}, class3 = {2.0067, 0.0644};
double testingSample[60]= {0.2 , 0.4 , 0.1 , 0.2 , 0.2 , 0.2 , 0.2 , 0.1 , 0.2 , 0.2 ,
0.3 , 0.3 , 0.2 , 0.6 , 0.4 , 0.3 , 0.2 , 0.2 , 0.2 , 0.2 ,
1.1 , 1 , 1.2 , 1.6 , 1.5 , 1.6 , 1.5 , 1.3 , 1.3 , 1.3 ,
1.2 , 1.4 , 1.2 , 1 , 1.3 , 1.2 , 1.3 , 1.3 , 1.1 , 1.3 ,
1.9 , 2 , 2.2 , 1.5 , 1.4 , 2.3 , 2.4 , 1.8 , 1.8 , 2.1 ,
2.4 , 2.3 , 1.9 , 2.3 , 2.5 , 2.3 , 1.9 , 2 , 2.3 , 1.8};
int main()
{
double posterior1 = 0, posterior2 = 0, posterior3 = 0;
int i = 0;
for(i = 0; i <60; i++)
{
posterior1 = posterior(1, testingSample[i] );
posterior2 = posterior(2, testingSample[i] );
posterior3 = posterior(3, testingSample[i] );
if(posterior1 > posterior2 && posterior1 > posterior3)
{
printf("样本%d属于setosa\r\n",i+1);
}
else if(posterior2 > posterior1 && posterior2 > posterior3)
{
printf("样本%d属于versicolor\r\n", i+1);
}
else if(posterior3 > posterior1 && posterior3 > posterior2)
{
printf("样本%d属于virginica\r\n", i+1);
}
else
{
printf("样本%d error posterior1 %lf posterior2 %lf posterior3 %lf\r\n", i, posterior1 , posterior2 , posterior3);
}
}
return 0;
}
// 求待分类项x在正态分布里的概率
double FGaussian(double x, double u, double a)
{
double P_ak_yi = 0;
P_ak_yi = (1/(a*sqrt(2*PI))) * pow(e, -(pow(x-u,2)/(2*pow(a,2))));
return P_ak_yi;
}
//求待测样本x出现的概率
double P_ai(double x )
{
double result = 0;
result = (1/3.f)*(FGaussian(x,class1.u, class1.a) + FGaussian(x,class2.u, class2.a) + FGaussian(x,class3.u, class3.a));
return result;
}
//计算待测样本x的后验概率
double posterior(int classifer, double x)
{
double result = 0;
switch (classifer)
{
case 1:
result = ((1/3.f) * FGaussian(x,class1.u,class1.a ))/P_ai(x);
break;
case 2:
result = ((1/3.f) * FGaussian(x,class2.u,class2.a ))/P_ai(x);
break;
case 3:
result = ((1/3.f) * FGaussian(x,class3.u,class3.a ))/P_ai(x);
break;
}
return result;
}
题目三
#include<stdio.h>
#include<math.h>
#define PI 3.1415926
#ifndef e
#define e 2.71828
#endif // e
double FGaussian(double , double , double );
double P_ai(double, double);
double posterior(int, double, double);
typedef struct
{
double u;
double a;
}class_t;
class_t class1 = {0.2467, 0.0098}, class2 = {1.3533, 0.0432}, class3 = {2.0067, 0.0644};
class_t classlength1 = {1.4733, 0.0333}, classlength2 = {4.3333, 0.2042}, classlength3 = {5.6033, 0.3797};
double testingSample[2][60]= {{0.2 , 0.4 , 0.1 , 0.2 , 0.2 , 0.2 , 0.2 , 0.1 , 0.2 , 0.2 ,
0.3 , 0.3 , 0.2 , 0.6 , 0.4 , 0.3 , 0.2 , 0.2 , 0.2 , 0.2 ,
1.1 , 1 , 1.2 , 1.6 , 1.5 , 1.6 , 1.5 , 1.3 , 1.3 , 1.3 ,
1.2 , 1.4 , 1.2 , 1 , 1.3 , 1.2 , 1.3 , 1.3 , 1.1 , 1.3 ,
1.9 , 2 , 2.2 , 1.5 , 1.4 , 2.3 , 2.4 , 1.8 , 1.8 , 2.1 ,
2.4 , 2.3 , 1.9 , 2.3 , 2.5 , 2.3 , 1.9 , 2 , 2.3 , 1.8},
{1.6 , 1.5 , 1.5 , 1.4 , 1.5 , 1.2 , 1.3 , 1.4 , 1.3 , 1.5 ,
1.3 , 1.3 , 1.3 , 1.6 , 1.9 , 1.4 , 1.6 , 1.4 , 1.5 , 1.4 ,
3.8 , 3.7 , 3.9 , 5.1 , 4.5 , 4.5 , 4.7 , 4.4 , 4.1 , 4 ,
4.4 , 4.6 , 4 , 3.3 , 4.2 , 4.2 , 4.2 , 4.3 , 3 , 4.1 ,
6.1 , 6.4 , 5.6 , 5.1 , 5.6 , 6.1 , 5.6 , 5.5 , 4.8 , 5.4 ,
5.6 , 5.1 , 5.1 , 5.9 , 5.7 , 5.2 , 5 , 5.2 , 5.4 , 5.1}};
int main()
{
double posterior1 = 0, posterior2 = 0, posterior3 = 0;
int i = 0;
for(i = 0; i <60; i++)
{
posterior1 = posterior(1, testingSample[0][i], testingSample[1][i] );
posterior2 = posterior(2, testingSample[0][i], testingSample[1][i] );
posterior3 = posterior(3, testingSample[0][i], testingSample[1][i] );
if(posterior1 > posterior2 && posterior1 > posterior3)
{
printf("样本%d属于setosa\r\n",i+1);
}
else if(posterior2 > posterior1 && posterior2 > posterior3)
{
printf("样本%d属于versicolor\r\n", i+1);
}
else if(posterior3 > posterior1 && posterior3 > posterior2)
{
printf("样本%d属于virginica\r\n",i+1);
}
else
{
printf("样本%d error posterior1 %lf posterior2 %lf posterior3 %lf\r\n", i+1, posterior1 , posterior2 , posterior3);
}
}
return 0;
}
// 求待分类项x在正态分布里的概率
double FGaussian(double x, double u, double a)
{
double P_ak_yi = 0;
P_ak_yi = (1/(a*sqrt(2*PI))) * pow(e, -(pow(x-u,2)/(2*pow(a,2))));
return P_ak_yi;
}
//求待测样本x出现的概率
double P_ai(double a1, double a2 )
{
double result = 0;
result = (1/3.f)*(FGaussian(a1,class1.u, class1.a) * FGaussian(a2,classlength1.u,classlength1.a)\
+ FGaussian(a1,class2.u, class2.a) * FGaussian(a2,classlength2.u,classlength2.a)\
+ FGaussian(a1,class3.u, class3.a) * FGaussian(a2,classlength3.u,classlength3.a));
return result;
}
//计算待测样本x的后验概率 a1,a2为样本的两个特征,1为宽度,2为长度
double posterior(int classifer, double a1, double a2)
{
double result = 0;
switch (classifer)
{
case 1:
result = ((1/3.f) * FGaussian(a1,class1.u,class1.a) * FGaussian(a2,classlength1.u,classlength1.a))/P_ai(a1, a2);
break;
case 2:
result = ((1/3.f) * FGaussian(a1,class2.u,class2.a) * FGaussian(a2,classlength2.u,classlength2.a))/P_ai(a1, a2);
break;
case 3:
result = ((1/3.f) * FGaussian(a1,class3.u,class3.a) * FGaussian(a2,classlength3.u,classlength3.a))/P_ai(a1, a2);
break;
}
return result;
}
这已经完整的代码了,如果需要完整的作业文件,应该也用不到吧?
需要的话请点击以下链接。
链接:https://pan.baidu.com/s/1UeEnp1KfSYfD87pbvoNl_g
提取码:ztch