朴素贝叶斯分类器Naive Bayesian ClassifierC语言实现信息电气工程学院计算本1102班20112212465马振磊1.贝叶斯公式通过贝叶斯公式,我们可以的知在属性F1-Fn成立的情况下,该样本属于分类C的概率。
而概率越大,说明样本属于分类C的可能性越大。
若某样本可以分为2种分类A,B。
要比较P(A | F1,F2......) 与P(B | F1,F2......)的大小只需比较,P(A)P(F1,F2......| A) ,与P(B)P(F1,F2......| B) 。
因为两式分母一致。
而P(A)P(F1,F2......| A)可以采用缩放为P(A)P(F1|A)P(F2|A).......(Fn|A)因此,在分类时,只需比较每个属性在分类下的概率累乘,再乘该分类的概率即可。
分类属性outlook 属性temperature 属性humidity 属性wind no sunny hot high weakno sunny hot high strongyes overcast hot high weakyes rain mild high weakyes rain cool normal weakno rain cool normal strongyes overcast cool normal strongno sunny mild high weakyes sunny cool normal weakyes rain mild normal weakyes sunny mild normal strongyes overcast mild high strongyes overcast hot normal weakno rain mild high strong以上是根据天气的4种属性,某人外出活动的记录。
若要根据以上信息判断(Outlook = sunny,Temprature = cool,Humidity = high,Wind = strong)所属分类。
P(yes| sunny ,cool ,high ,strong )=P(yes)P(sunny|yes)P(cool |yes)P(high|yes)P(strong|yes)/KP(no| sunny ,cool ,high ,strong )=P(no)P(sunny|no)P(cool |no)P(high|no)P(strong|no)/KK为缩放因子,我们只需要知道两个概率哪个大,所以可以忽略K。
P(yes)=9/14 P(no)=5/14P(sunny|yes)=2/9 P(cool|yes)=1/3 P(high|yes)=1/3 P(strong|yes)=1/3P(sunny|no)=3/5 P(cool|no)=1/5 P(high|no)=4/5 P(strong|no)=3/5P(yes| sunny ,cool ,high ,strong)=9/14*2/9*1/3*1/3*1/3=0.00529P(no| sunny ,cool ,high ,strong )=5/14*3/5*1/5*4/5*3/5=0.20571No的概率大,所以该样本实例属于no分类。
2.数据结构及代码实现1.属性及分类我们限定分类器的属性不大于9个,每个属性拥有不大于9个值。
于是,我们考虑采用一个9 X 9的表格存储属性及其值。
属性1 值1 值2 值3 值4 值5 值6 值7 值8 值9属性2 值1 值2 值3 值4 值5 值6 值7 值8 值9属性3 值1 值2 值3 值4 值5 值6 值7 值8 值9属性4 值1 值2 值3 值4 值5 值6 值7 值8 值9属性5 值1 值2 值3 值4 值5 值6 值7 值8 值9属性6 值1 值2 值3 值4 值5 值6 值7 值8 值9属性7 值1 值2 值3 值4 值5 值6 值7 值8 值9属性8 值1 值2 值3 值4 值5 值6 值7 值8 值9属性9 值1 值2 值3 值4 值5 值6 值7 值8 值9为了调用数据方便,我们把数据从第一行开始储存。
为了充分利用存储空间,我们把第零行储存分类数据。
分类1 分类2 分类3 分类4 分类5 分类6 分类7 分类8 分类9属性1 值1 值2 值3 值4 值5 值6 值7 值8 值9属性2 值1 值2 值3 值4 值5 值6 值7 值8 值9属性3 值1 值2 值3 值4 值5 值6 值7 值8 值9属性4 值1 值2 值3 值4 值5 值6 值7 值8 值9属性5 值1 值2 值3 值4 值5 值6 值7 值8 值9属性6 值1 值2 值3 值4 值5 值6 值7 值8 值9属性7 值1 值2 值3 值4 值5 值6 值7 值8 值9属性8 值1 值2 值3 值4 值5 值6 值7 值8 值9属性9 值1 值2 值3 值4 值5 值6 值7 值8 值9现在,我们可以采用一个10 X 10 的表格来储存数据了。
而每个单元格的内容需要占用一定的储存空间,我们可以用一个三维数组char feature[10][10][10]来表示这种结构的数据。
用来容纳9个属性的9个值。
第0行,我们用来储存分类数据。
而第一行的第一列没有被使用,而其中含有10个char类型的数据我们可以用它来储存属性值的多少。
如图:分类的个数属性1值的个数属性2值的个数........... 属性9值的个数前一段的数据:分类:yes no属性outlook :sunny overcast rain属性temperature:hot mild cool属性humidity:high normal属性wind:strong weak如下图yes nooutlook sunny overcast rainTempera hot mild coolhumidity high normalwind strong weak第0行,第0列2 3 3 2 2代码如下:int x=1,y;printf("请输入属性名称(小于9个字符):");gets(feature[x][0]);printf("该属性有几种值(不多于9个值):");scanf("%c",&feature[0][0][x]); //把属性值储存入feature[0][0][x];feature[0][0][x]-=48; //feature[0][0][x]是由字符格式输入的-48变为数字getchar();system("cls");for(y=1;y<=feature[0][0][x];y++) //根据feature[0][0][x]循环输入,将属性的值存入数组{printf("请输入第%d个值:",y);gets(feature[x][y]);}x++;通过这段代码的循环,输入属性及其值进入feature数组。
通过以下代码将分类数据存入数组第0行。
printf("该事物可以被分为几种类别:");scanf("%c",&feature[0][0][0]); //分类数目存入feature[0][0][0]feature[0][0][0]-=48;getchar();system("cls");for(y=1;y<=feature[0][0][0];y++) //通过循环将分类存入第0行{printf("请输入第%d种类别的名称:",y);gets(feature[0][y]);}2.训练样本每个训练样本的属性最多有9个值,再加上分类一个值,所以,我们采用一个10列的表格储存训练样本数据。
no sunny hot high weakno sunny hot high strongyes overcast hot high weakyes rain mild high weakyes rain cool normal weakno rain cool normal strongyes overcast cool normal strongno sunny mild high weakyes sunny cool normal weakyes rain mild normal weakyes sunny mild normal strongyes overcast mild high strongyes overcast hot normal weakno rain mild high strong同样,每个单元格里限制最多有9个字符,加上一个’\0’终止符,共十个。
而样本数量,也就是行数,可以适当的多一点,暂设为30。
因此我们采用三维数组char sample[30][10][10]来容纳样本数据。
X的初始值为1for(y=1;y<=FeatureNum;y++){printf("特征%s的取值:",feature[y][0]);gets(sample[x-1][y]);}printf("该样本归于哪一种分类:");gets(sample[x-1][0]);x++;SampleNum++; //统计样本的数量3.计算概率class probability{public:int id; //给每个概率值一个定位ID,方便查找double p;probability(){p=0;}};probability prob[729];采用一729个类来存放每个属性值在不同分类下的概率。
至多有9种属性,每个属性至多拥有9个值,而要计算这9个属性的9种值在9种不同分类下的概率,所以我们用了729个类。
并且在构造函数里面初始化概率p 为0.接下来,统计各种分类出现的个数。
9种分类出现的数目,分别储存在SampleClassNum[9]的不同单元格里。
int SampleClassNum[9]={0,0,0,0,0,0,0,0,0};for(c=1;c<=feature[0][0][0];c++)for(x=0;x<SampleNum;x++)if(strcmp(feature[0][c],sample[x][0])==0)SampleClassNum[c-1]++;然后,我们可以开始计算概率了。
for(c=1;c<=feature[0][0][0];c++)for(x=1;x<=FeatureNum;x++)for(y=1;y<=feature[0][0][x];y++){prob[counter].id=c*100+x*10+y;for(i=0;i<SampleNum;i++){if(strcmp(feature[x][y],sample[i][x])==0 &&strcmp(feature[0][c],sample[i][0])==0)prob[counter].p++; //统计某一值在某一分类下的出现个数}prob[counter].p=prob[counter].p/SampleClassNum[c-1]; //出现个数除以分类出//现总数,计算出概率counter++;}每个概率的ID为3位整数,百位记录了分类信息,个位十位分别是,其属性值在表格中的X,Y坐标。