朴素贝叶斯分类器

 朴素贝叶斯分类器作为最简单的分类器,只要明白贝叶斯的两个概率公式即可:

贝叶斯公式:

全概率公式: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 }

改代码成功得对训练样本进行了分类。

posted @ 2013-12-30 17:02  湖心北斗  阅读(401)  评论(0编辑  收藏  举报