朴素贝叶斯分类器
朴素贝叶斯分类器作为最简单的分类器,只要明白贝叶斯的两个概率公式即可:
贝叶斯公式:
全概率公式:p(X)=P(X|Y1)+P(X|Y2)+...+P(X|Yn)
朴素贝叶斯分类把所有的属性看成是相互独立得,因此使用计算向量概率得时候只需要相乘起来就可以了。
即使用乘法公式:
p(xyz)=p(x)*p(y)*p(z)
贝叶斯分类得思想是:对于给出得待分类项,从训练集中知道,在该项出现得条件下,哪个类别得概率最大,那么就把它分成哪一类。
贝叶斯公式得定义如下:
1.假设是一个待分类项,而每个a为x得一个特征属性。
2.有类别集合
3.计算
4.如果,则
现在所要做得就是计算第三步中得概率。
1.找到一个已知分类项得集合。
2.统计得到在各个类别下各个特征属性得条件概率估计。
3.根据贝叶斯定理有如下公式:
对于每个单独得训练样本,p(x)都是相同得,因此只须比较分子得大小即可。
由于各个属性相互独立,则有:
当属性为连续值得时候,通常假定其值服从高斯分布。
而
所以只需要计算出训练样本中各个类别中此特征划分得期望和标准差即可。
当p(a|y)=0的时候,为了解决这个问题,我们引入Laplace校准,它的思想非常简单,就是对没类别下所有划分的计数加1,这样如果训练样本集数量充分大时,并不会对结果产生影响,并且解决了上述频率为0的尴尬局面。
我们这次商务智能的作业是:
作业源代码:
1 // 2 // main.c 3 // classification 4 // 5 // Created by Wu Yongxing on 13-12-17. 6 // Copyright (c) 2013年 Wu Yongxing. All rights reserved. 7 // 8 #include <stdio.h> 9 #include <string.h> 10 #include <stdlib.h> 11 #include <string.h> 12 #include <math.h> 13 #define NUMBEROFROWS 3 14 #define PI 3.141592654 15 #define EI 2.718281828 16 double trainingData[100][3]; 17 double testData[100][3]; 18 int classCount[3];/*每个类有多少个*/ 19 int interCount[2][3];/* 离散变量 男 女 和类型的交集 */ 20 double expect[3];/*计算各个类型之中 各个属性之的期望*/ 21 double stdDev[3];/*计算各个类型之中 各个属性的标准差*/ 22 double gaosi(double x,double n,double d) 23 { 24 // printf("x: %lf n:%lf d:%lf\n",x,n,d); 25 double exp=-1*(x-n)*(x-n)/(2*d*d); 26 double fact=1/(sqrt(2*PI)*d); 27 double result=fact*pow(EI,exp); 28 // printf("result: %lf",result); 29 if(result-0.000001<0)result=1; 30 return result; 31 } 32 int main(int argc, const char * argv[]) 33 { 34 FILE *fp; 35 fp=fopen("./data.txt", "r"); 36 if(fp==NULL) 37 { 38 printf("Can not open file :("); 39 return 0; 40 } 41 char name[20]; 42 char gender[10]; 43 double height; 44 char kind[10]; 45 int numberOfLines=0; 46 while(fscanf(fp, "%s",name)!=EOF) 47 { 48 fscanf(fp,"%s",gender); 49 if(strcmp(gender, "M")==0) 50 { 51 trainingData[numberOfLines][0]=0; 52 } 53 else trainingData[numberOfLines][0]=1; 54 fscanf(fp, "%lf",&height); 55 trainingData[numberOfLines][1]=height; 56 fscanf(fp, "%s",kind); 57 if(strcmp(kind, "Short")==0) 58 { 59 trainingData[numberOfLines][2]=0; 60 } 61 else if(strcmp(kind, "Medium")==0) 62 { 63 trainingData[numberOfLines][2]=1; 64 } 65 else if(strcmp(kind, "Tall")==0) 66 { 67 trainingData[numberOfLines][2]=2; 68 } 69 numberOfLines++; 70 } 71 fclose(fp);fp=NULL; 72 int i,j; 73 // memset(classCount,0,sizeof(classCount)); 74 int classCount[3]; 75 classCount[0]=0;classCount[1]=0;classCount[2]=0; 76 for(i=0;i<numberOfLines;i++)/*统计各个类型的总个数*/ 77 { 78 classCount[(int)trainingData[i][2]]++; 79 } 80 for(i=0;i<numberOfLines;i++) 81 { 82 //printf("%lf\t%lf\n",trainingData[i][0],trainingData[i][2]); 83 interCount[(int)trainingData[i][0]][(int)trainingData[i][2]]++; 84 } 85 for(j=0/*short*/;j<=2;j++)//计算各个高度对应的类型得期望值 86 { 87 double heightsum=0.0; 88 int countInHeight=0; 89 for(i=0;i<numberOfLines;i++) 90 { 91 if(trainingData[i][2]==j/*height*/) 92 { 93 heightsum+=trainingData[i][1]; 94 countInHeight++; 95 } 96 } 97 expect[j]=heightsum/countInHeight; 98 } 99 for(j=0/*short*/;j<=2;j++)//计算各个高度对应的类型的方差值 100 { 101 double heightsum=0.0; 102 int countInHeight=0; 103 for(i=0;i<numberOfLines;i++) 104 { 105 if(trainingData[i][2]==j/*height*/) 106 { 107 heightsum+=(trainingData[i][1]-expect[j])*(trainingData[i][1]-expect[j]); 108 /*身高减去身高的期望值*/ 109 countInHeight++; 110 } 111 } 112 stdDev[j]= sqrt(heightsum/countInHeight); 113 } 114 fp=fopen("./testData.txt","r"); 115 if(fp==NULL) 116 { 117 printf("the file testData.txt can't be opened\n"); 118 return 0; 119 } 120 int testLines=0; 121 while(fscanf(fp,"%s",name)!=EOF) 122 { 123 fscanf(fp,"%s",gender); 124 if(strcmp(gender, "M")==0) 125 { 126 testData[testLines][0]=0; 127 } 128 else testData[testLines][0]=1; 129 fscanf(fp, "%lf",&height); 130 testData[testLines][1]=height; 131 testLines++; 132 } 133 fclose(fp);fp=NULL; 134 double maxv=-1; 135 int maxindex; 136 /* for(i=0;i<2;i++) 137 { 138 for(j=0;j<3;j++) 139 { 140 printf("interCount: %d %d %d\t",i,j,interCount[i][j]); 141 }printf("\n"); 142 }*/ 143 for(i=0;i<testLines;i++) 144 { 145 double testPossible[3]; 146 for(j=0;j<=2;j++) 147 { 148 // printf("gaosi: %lf\n",gaosi(testData[i][1],expect[j],stdDev[j])); 149 testPossible[j]=interCount[(int)testData[i][0]][j]/classCount[j]*gaosi(testData[i][1],expect[j],stdDev[j])*classCount[j]/numberOfLines; 150 // printf("testPossible: %lf\n",testPossible[j]); 151 if(testPossible[j]>maxv) 152 { 153 maxv=testPossible[j]; 154 maxindex=j; 155 } 156 } 157 switch(maxindex) 158 { 159 case 0:printf("the person of index %d is short\n",i);break; 160 case 1:printf("the person of index %d is medium\n",i);break; 161 case 2:printf("the person of index %d is tall\n",i);break; 162 } 163 } 164 }
改代码成功得对训练样本进行了分类。