天天看點

貝葉斯分類器--文本分類的C語言實作

本文轉載自:http://blog.csdn.net/caiye917015406/article/details/7887221,謝謝原作者!

==============================================================================

第一個是用c語言做的關于文本的分類,主要是對待分類文本所有單詞在模闆中機率的後驗計算。算法比較簡單,從網上下的(沒記下位址,若不願意公開,請留言,自當處理),稍作了一點修改。。,等有時間可以實作垃圾郵件的分類,利用斯坦福機器學習公開課中方法,統計高頻詞,利用樸素貝葉斯。等有時間和大家分享。

[cpp]  view plain copy

  1. #include <stdio.h>  
  2. #include <string.h>  
  3. #include <direct.h> //_getcwd(), _chdir()  
  4. #include <stdlib.h> //_MAX_PATH, system()  
  5. #include <io.h> //_finddata_t, _findfirst(), _findnext(), _findclose()  
  6. #include<iostream>  
  7. using namespace std;  
  8. //#include<fstream>  
  9. char vocabulary[1000][20];  
  10. //@輸入參數:要分類的文本  
  11. //@輸出參數:該文本中總單詞數  
  12. int SplitToWord(char text[])  
  13. {  
  14. int i=0;  
  15. char seps[]=", .\n";    
  16. char *substring;   
  17. substring=strtok(text,seps);   
  18. while(substring!=NULL)   
  19. {     
  20.    strcpy(vocabulary[i],substring);//将單詞存儲到vocabulary數組中   
  21.    substring=strtok(NULL,seps);   
  22.    i++;  
  23. }  
  24. return i; //傳回一共多少個單詞  
  25. }  
  26. //@輸入參數:無  
  27. //@輸出參數:該目錄下.txt檔案數  
  28. int CountDirectory()  
  29. {  
  30. int count=0; //txt檔案計數器  
  31. long hFile;  
  32.     _finddata_t fileinfo;  
  33.     if ((hFile=_findfirst("*.txt",&fileinfo))!=-1L)  
  34.     {  
  35.         do  
  36.         {              
  37.     count++;  
  38.         } while (_findnext(hFile,&fileinfo) == 0);  
  39. }  
  40. return count;  
  41. }  
  42. //@輸入參數:分類文本中單詞數  
  43. //@輸出參數:該類别下∏P(ai|vj)  
  44. float CalculateWordProbability(int wordCount)  
  45. {  
  46. int countSame; //分類文本中的某單詞在所有訓練樣本中出現次數  
  47. int countAll=0; //訓練樣本中總單詞數  
  48. char token;  
  49. FILE *fp;  
  50. float wordProbability=1; //為後面聯乘做準備  
  51. int i,j;  
  52. long hFile;  
  53.     _finddata_t fileinfo;  
  54. for(j=0;j<wordCount;j++) //對于分類樣本中的每一個單詞  
  55. {  
  56.    countSame=0;  
  57.    countAll=0;  
  58.    if((hFile=_findfirst("*.txt",&fileinfo))!=-1L) //對于該類别下每一個.txt文本  
  59.    {  
  60.     do  
  61.     {  
  62.      if((fp=fopen(fileinfo.name,"r"))==NULL) //是否能打開該文本  
  63.      {  
  64.       printf("Sorry!Cannot open the file!\n");  
  65.       exit(0);  
  66.      }  
  67.      while((token = fgetc(fp)) != EOF)   
  68.      {  
  69.       char keyword[1024];   
  70.       i = 0;   
  71.       keyword[0] = token; // 将每個詞第一個字元賦給數組第一個元素  
  72.       while ((keyword[++i] = fgetc(fp)) != ' ' && keyword[i] != '\t' && keyword[i] != EOF && keyword[i] != '\n'); // 開始讀字元,直到遇到空白符,說明找到一個詞   
  73.       keyword[i] = '\0';// 加結束符  
  74.       countAll++;  
  75.       if (strcmp(keyword,vocabulary[j]) == 0) //比較兩個單詞是否相同  
  76.        countSame++;  
  77.      }  
  78.      fclose(fp);  
  79.     }while (_findnext(hFile,&fileinfo) == 0);   
  80.    }  
  81.    wordProbability*=(float)(countSame+1)/(float)(wordCount+countAll)*300; //計算∏P(wj|vi),為了擴大效果而*380  
  82. }  
  83. return wordProbability;  
  84. }  
  85. //@輸入參數:分類文本中單詞數  
  86. void CalculateProbability(int wordCount,int num)  
  87. {  
  88. FILE *fp;  
  89. char classList[10][20]; //類别清單  
  90.     char ch;    //臨時讀取字元使用  
  91.     int index=0; //classList的行标  
  92.     int className_c=0; //classList的列标  
  93. if((fp=fopen("ClassList.txt","r"))==NULL)  
  94.     {  
  95.         printf("Failed to open the file: ClassList.txt.\n");  
  96.     }  
  97.     ch = fgetc(fp);  
  98.     while(ch!=EOF)  
  99.     {  
  100.         if(ch!='\n')  
  101.         {  
  102.             classList[index][className_c]=ch;  
  103.             className_c++;  
  104.         }  
  105.         else  
  106.         {  
  107.             classList[index][className_c]='\0';  
  108.             index++;  
  109.             className_c=0;  
  110.         }  
  111.    ch = fgetc(fp);  
  112. }  
  113. int txtCount[10]; //每個類别下的訓練文本數  
  114. int countAll=0; //訓練集中總文本數  
  115. float wordProbability[10]; //每個類别的單詞機率,即∏P(ai|vj)  
  116. if(_chdir("D:\\openCV\\openCVProject\\openCVtext\\貝葉斯(文本分類)—c語言\\example\\1")) //更改目前絕對路徑  
  117.      printf("系統找不到指定路徑!\n");  
  118. else  
  119. {  
  120.    txtCount[0]=CountDirectory(); //擷取該類别下.txt檔案數  
  121.    countAll+=txtCount[0];  
  122.    wordProbability[0]=CalculateWordProbability(wordCount); //擷取該類别下∏P(wj|vi)  
  123. }  
  124. if(_chdir("D:\\openCV\\openCVProject\\openCVtext\\貝葉斯(文本分類)—c語言\\example\\2")) //更改目前絕對路徑  
  125.    printf("系統找不到指定路徑!\n");  
  126. else  
  127. {  
  128.    txtCount[1]=CountDirectory(); //擷取該類别下.txt檔案數  
  129.    countAll+=txtCount[1];  
  130.    wordProbability[1]=CalculateWordProbability(wordCount); //擷取該類别下∏P(wj|vi)  
  131. }  
  132. if(_chdir("D:\\openCV\\openCVProject\\openCVtext\\貝葉斯(文本分類)—c語言\\example\\3")) //更改目前絕對路徑  
  133.      printf("系統找不到指定路徑!\n");  
  134. else  
  135. {  
  136.    txtCount[2]=CountDirectory(); //擷取該類别下.txt檔案數  
  137.    countAll+=txtCount[2];  
  138.    wordProbability[2]=CalculateWordProbability(wordCount); //擷取該類别下∏P(wj|vi)  
  139. }  
  140. if(_chdir("D:\\openCV\\openCVProject\\openCVtext\\貝葉斯(文本分類)—c語言\\example\\4")) //更改目前絕對路徑  
  141.      printf("系統找不到指定路徑!\n");  
  142. else  
  143. {  
  144.    txtCount[3]=CountDirectory(); //擷取該類别下.txt檔案數  
  145.    countAll+=txtCount[3];  
  146.    wordProbability[3]=CalculateWordProbability(wordCount); //擷取該類别下∏P(wj|vi)  
  147. }  
  148. if(_chdir("D:\\openCV\\openCVProject\\openCVtext\\貝葉斯(文本分類)—c語言\\example\\5")) //更改目前絕對路徑  
  149.      printf("系統找不到指定路徑!\n");  
  150. else  
  151. {  
  152.    txtCount[4]=CountDirectory(); //擷取該類别下.txt檔案數  
  153.    countAll+=txtCount[4];  
  154.    wordProbability[4]=CalculateWordProbability(wordCount); //擷取該類别下∏P(wj|vi)  
  155. }  
  156. if(_chdir("D:\\openCV\\openCVProject\\openCVtext\\貝葉斯(文本分類)—c語言\\example\\6")) //更改目前絕對路徑  
  157.      printf("系統找不到指定路徑!\n");  
  158. else  
  159. {  
  160.    txtCount[5]=CountDirectory(); //擷取該類别下.txt檔案數  
  161.    countAll+=txtCount[5];  
  162.    wordProbability[5]=CalculateWordProbability(wordCount); //擷取該類别下∏P(wj|vi)  
  163. }  
  164. if(_chdir("D:\\openCV\\openCVProject\\openCVtext\\貝葉斯(文本分類)—c語言\\example\\7")) //更改目前絕對路徑  
  165.      printf("系統找不到指定路徑!\n");  
  166. else  
  167. {  
  168.    txtCount[6]=CountDirectory(); //擷取該類别下.txt檔案數  
  169.    countAll+=txtCount[6];  
  170.    wordProbability[6]=CalculateWordProbability(wordCount); //擷取該類别下∏P(wj|vi)  
  171. }  
  172. if(_chdir("D:\\openCV\\openCVProject\\openCVtext\\貝葉斯(文本分類)—c語言\\example\\8")) //更改目前絕對路徑  
  173.      printf("系統找不到指定路徑!\n");  
  174. else  
  175. {  
  176.    txtCount[7]=CountDirectory(); //擷取該類别下.txt檔案數  
  177.    countAll+=txtCount[7];  
  178.    wordProbability[7]=CalculateWordProbability(wordCount); //擷取該類别下∏P(wj|vi)  
  179. }  
  180. if(_chdir("D:\\openCV\\openCVProject\\openCVtext\\貝葉斯(文本分類)—c語言\\example\\9")) //更改目前絕對路徑  
  181.      printf("系統找不到指定路徑!\n");  
  182. else  
  183. {  
  184.    txtCount[8]=CountDirectory(); //擷取該類别下.txt檔案數  
  185.    countAll+=txtCount[8];  
  186.    wordProbability[8]=CalculateWordProbability(wordCount); //擷取該類别下∏P(wj|vi)  
  187. }  
  188. if(_chdir("D:\\openCV\\openCVProject\\openCVtext\\貝葉斯(文本分類)—c語言\\example\\10")) //更改目前絕對路徑  
  189.      printf("系統找不到指定路徑!\n");  
  190. else  
  191. {  
  192.    txtCount[9]=CountDirectory(); //擷取該類别下.txt檔案數  
  193.    countAll+=txtCount[9];  
  194.    wordProbability[9]=CalculateWordProbability(wordCount); //擷取該類别下∏P(wj|vi)  
  195. }  
  196. float max=0;  
  197. int classNo=0;  
  198. float priorProbability[10];  
  199. float finalProbability[10];  
  200. for(int i=0;i<num;i++)   
  201. {  
  202.    priorProbability[i]=(float)txtCount[i]/(float)countAll; //先驗機率  
  203.    finalProbability[i]=priorProbability[i]*wordProbability[i]; //最終機率  
  204.    if(finalProbability[i]>max) //找到最大機率并記錄  
  205.    {  
  206.     max=finalProbability[i];  
  207.     classNo=i;  
  208.    }  
  209.    printf("該文本為類别%s的機率為:%.5e\n",classList[i],finalProbability[i]); //輸出每個類别的最終機率  
  210. }  
  211. printf("\n經分析,該文本最有可能為%s類文本!\n",classList[classNo]); //輸出最後分類結果  
  212. }  
  213. //@輸入參數:分類文本  
  214. void NaiveBayesClassifier(char text[],int num)  
  215. {  
  216. int vocabularyCount;//分類樣本中單詞數  
  217. vocabularyCount=SplitToWord(text); //對要分類的文本進行單詞分割,結果存儲在vocabulary數組中,傳回分類樣本中單詞數  
  218. CalculateProbability(vocabularyCount,num); //計算最終機率  
  219. }  
  220. int main()  
  221. {  
  222.    FILE *fp;  
  223.    if((fp=fopen("text.txt","r"))==NULL)  
  224.    {  
  225.         printf("Failed to open the file: ClassList.txt.\n");  
  226.    }  
  227.    char ch = fgetc(fp);  
  228.    int i=0;  
  229.    while(ch!=EOF)  
  230.    {  
  231.        ch = fgetc(fp);  
  232.        i++;  
  233.    }  
  234.    char *text=new char(i+1);  
  235.    fseek(fp,0,SEEK_SET);//  
  236.    ch = fgetc(fp);  
  237.    int j=0;  
  238.    while(ch!=EOF)  
  239.    {  
  240.        ch = fgetc(fp);  
  241.        cout<<ch;  
  242.        text[j]=ch;  
  243.        j++;  
  244.    }  
  245.   // char text[]=new char(i);;  
  246.    int num = 2;  
  247.    NaiveBayesClassifier(text,num);   
  248. return 1;  
  249. }  

繼續閱讀