数据挖掘之朴素贝叶斯算法

/*
朴素贝叶斯算法思想: 举个例子,假如某天是否要出去打网球,有两种选择:是和否,即最后分成两个类别。但是受3个因素的影响,分别是天气、温度和是否有风。天气有3个值:晴、多云和有雨。温度有3个值:高,正常和低。是否有风有两个值:是和否。假如样本A是{天气晴,温度正常,无风,打网球},样本B是{天气有雨,温度低,有风,不打网球},还有其他的样本,可以得到样本的某些先验概率,即已经知道了是否打网球的结果某因素出现的概率。然后利用到贝叶斯公式的一些转换(数学的知识不在这里推),计算后验概率,即知道因素的情况,估计打网球与不打网球各自的概率。
*/
#include<iostream> #include<fstream> #include<string> #include<vector> #include<map> using namespace std; vector<string> split(const string& src,const string& delimiter); /**分离字符串**/ void rejudge(); /**重新判断原输入数据的类别**/ vector<vector<string> > vect; /**二维容器**/ map<string,int> category; /**存放类别**/ map<string,double> pro_map; /**各种概率的map容器**/ int main(){ string strLine; pro_map.clear(); ifstream readfile("weather.txt"); /**打开文件**/ if(!readfile){ cout<<"Fail to open file weather!"<<endl; cout<<getchar(); return 0; } else{ cout<<"读取原始数据如下:"<<endl; vector<vector<string> >::size_type st_x; /**二维容器x坐标**/ vector<string> temp_vect; vector<string>::size_type st_y; /**二维容器y坐标**/ while(getline(readfile,strLine)){ /**读入数据**/ //cout<<strLine<<endl; temp_vect=split(strLine,","); /**分离字符串**/ vect.push_back(temp_vect); /**存放到容器中**/ temp_vect.clear(); } string temp_string; vector<string>::size_type temp_size1=vect.size()-1; /**总行数**/ vector<string>::size_type temp_size2=vect[0].size();/**总列数**/ for(int i=0;i<temp_size1+1;i++) { for(int j=0;j<temp_size2;j++) cout<<vect[i][j]<<' '; cout<<endl; } for(st_x=1;st_x<temp_size1+1;st_x++){ /**遍历二维容器,统计各种类别、属性|类别的个数,以便后面的 概率的计算(跳过第一行的属性标题) **/ for(st_y=0;st_y<temp_size2;st_y++){ if(st_y!=temp_size2-1){ /**统计每一行前面的属性,统计属性|类别的个数**/ temp_string=vect[0][st_y]+"="+vect[st_x][st_y]+"|" +vect[0][temp_size2-1]+"="+vect[st_x][temp_size2-1]; pro_map[temp_string]+=1; /**map记录**/ } else{ temp_string=vect[0][temp_size2-1]+"="+vect[st_x][temp_size2-1]; /**类别**/ pro_map[temp_string]+=1; category[vect[st_x][temp_size2-1]]=1; } temp_string.erase(); } } string::size_type st; cout<<"统计过程如下:"<<endl; for(map<string,double>::iterator it=pro_map.begin();it!=pro_map.end();it++){ cout<<it->first<<":"<<it->second<<endl; if((st=it->first.find("|"))!=string::npos){ /**计算概率**/ it->second=it->second/pro_map[it->first.substr(st+1)]; } } cout<<"计算概率过程如下:"<<endl; for(map<string,double>::iterator it2=pro_map.begin();it2!=pro_map.end();it2++){ if((st=it2->first.find("|"))==string::npos){ pro_map[it2->first]=pro_map[it2->first]/(double)temp_size1; /**每个类别占比**/ } cout<<it2->first<<":"<<it2->second<<endl; } rejudge(); } cout<<getchar(); return 0; } vector<string> split(const string& src,const string& delimiter){ string::size_type st; if(src.empty()) throw "Empty string!"; if(delimiter.empty()) throw "Empty delimiter"; /**字符串为空或者分隔符为空**/ vector<string> vect; string::size_type last_st=0; while((st=src.find_first_of(delimiter,last_st))!=string::npos){ /**找到第一个为分隔符的位置**/ if(st!=last_st) vect.push_back(src.substr(last_st,st-last_st)); /**分离出字符串,可能第一个为分隔符,跳过**/ last_st=st+1; } if(last_st!=src.size()){ /**最后可能还有一个字符串**/ vect.push_back(src.substr(last_st,string::npos)); } return vect; } void rejudge(){ string temp_string; double temp_pro; map<string,double> temp_map; /**存放后验概率的临时容器**/ cout<<"经过简单贝叶斯算法重新分类的结果如下:"<<endl; for(vector<vector<string> >::size_type st_x=1;st_x<vect.size();st_x++){ for(map<string,int>::iterator it=category.begin();it!=category.end();it++){ temp_pro=1.0; temp_string=vect[0][vect[0].size()-1]+"="+it->first; temp_pro*=pro_map[temp_string];/**计算每种类别的概率**/ temp_string.erase(); for(vector<string>::size_type st_y=0;st_y<vect[st_x].size();st_y++){ if(it==category.begin()&&st_y!=vect[st_x].size()-1) cout<<vect[st_x][st_y]<<" "; if(st_y!=vect[st_x].size()-1){ temp_string=vect[0][st_y]+"="+vect[st_x][st_y]+ "|"+vect[0][vect[0].size()-1]+"="+it->first; temp_pro*=pro_map[temp_string]; temp_string.erase(); } } temp_map[it->first]=temp_pro; } string temp_string2; temp_pro=0; cout<<"后验概率:"; for(map<string,double>::iterator it2=temp_map.begin();it2!=temp_map.end();it2++){ cout<<it2->first<<":"<<it2->second<<" "; if(it2->second>temp_pro){ /**找最大的后验概率**/ temp_string2.erase(); temp_string2=it2->first; temp_pro=it2->second; } } cout<<"归类:"<<vect[0][vect[0].size()-1]<<"="<<temp_string2<<endl; } }

 

posted @ 2017-03-29 22:12  wust_ouyangli  阅读(990)  评论(0编辑  收藏  举报