Bayes Classifier 分类
C++实现简单贝叶斯分类
outlook | temperature | humidity | windy | play |
sunny | hot | high | FALSE | no |
sunny | hot | high | TRUE | no |
overcast | hot | high | FALSE | yes |
rainy | mild | high | FALSE | yes |
rainy | cool | normal | FALSE | yes |
rainy | cool | normal | TRUE | no |
overcast | cool | normal | TRUE | yes |
sunny | mild | high | FALSE | no |
sunny | cool | normal | FALSE | yes |
rainy | mild | normal | FALSE | yes |
sunny | mild | normal | TRUE | yes |
overcast | mild | high | TRUE | yes |
overcast | hot | normal | FALSE | yes |
rainy | mild | high | TRUE | no |
/* 实现简单贝叶斯算法 Changfengmingzhi */ #include<iostream> #include<fstream> #include<string> #include<vector> #include<map> usingnamespace std; vector<string> split(conststring& src,conststring& delimiter);//根据定界符分离字符串 void rejudge();//重新判断原输入数据的类别 vector<vector<string>> vect;//二维容器 map<string,int> category;//存放类别 map<string,double> pro_map;//存放各种概率的map容器 int main() { string strLine; ifstream readfile(".\weather.csv"); if(!readfile)//打开文件失败! { cout<<"Fail to open file weather!"<<endl; return0; } else { cout<<"读取原始数据如下:"<<endl; vector<vector<string>>::size_type st_x;//二维容器x坐标 vector<string>::size_type st_y;//二维容器y坐标 vector<string> temp_vect; 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();//总行数 vector<string>::size_type temp_size2=vect[0].size();//总列数 for(st_x=1;st_x<temp_size1;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 } 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(); } return0; } vector<string> split(conststring& src,conststring& 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)//2个标记间的字符串为一个子字符串 { 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++)//遍历类别,取出p(x|c1)和p(x|c2)等的概率值 { temp_pro=1.0; temp_string=vect[0][vect[0].size()-1]+"="+it->first; temp_pro*=pro_map[temp_string];//乘上p(ci) 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)//乘上p(xi|cj),跳过最后一列,因为是类别而非属性 { 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];//乘上p(xi|cj) temp_string.erase(); } } temp_map[it->first]=temp_pro;//存下概率 } //////////根据概率最大判断哪个该条记录应属于哪个类别 string temp_string2; temp_pro=0;//初始化概率为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;//输出该条记录所属的类别 } }
http://blog.sina.com.cn/s/blog_4fb4d8d40100nrcx.html
http://blog.csdn.net/xlm289348/article/details/8876862
Bayes Classifier 分类
C++实现简单贝叶斯分类
outlook | temperature | humidity | windy | play |
sunny | hot | high | FALSE | no |
sunny | hot | high | TRUE | no |
overcast | hot | high | FALSE | yes |
rainy | mild | high | FALSE | yes |
rainy | cool | normal | FALSE | yes |
rainy | cool | normal | TRUE | no |
overcast | cool | normal | TRUE | yes |
sunny | mild | high | FALSE | no |
sunny | cool | normal | FALSE | yes |
rainy | mild | normal | FALSE | yes |
sunny | mild | normal | TRUE | yes |
overcast | mild | high | TRUE | yes |
overcast | hot | normal | FALSE | yes |
rainy | mild | high | TRUE | no |
/* 实现简单贝叶斯算法 Changfengmingzhi */ #include<iostream> #include<fstream> #include<string> #include<vector> #include<map> usingnamespace std; vector<string> split(conststring& src,conststring& delimiter);//根据定界符分离字符串 void rejudge();//重新判断原输入数据的类别 vector<vector<string>> vect;//二维容器 map<string,int> category;//存放类别 map<string,double> pro_map;//存放各种概率的map容器 int main() { string strLine; ifstream readfile(".\weather.csv"); if(!readfile)//打开文件失败! { cout<<"Fail to open file weather!"<<endl; return0; } else { cout<<"读取原始数据如下:"<<endl; vector<vector<string>>::size_type st_x;//二维容器x坐标 vector<string>::size_type st_y;//二维容器y坐标 vector<string> temp_vect; 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();//总行数 vector<string>::size_type temp_size2=vect[0].size();//总列数 for(st_x=1;st_x<temp_size1;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 } 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(); } return0; } vector<string> split(conststring& src,conststring& 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)//2个标记间的字符串为一个子字符串 { 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++)//遍历类别,取出p(x|c1)和p(x|c2)等的概率值 { temp_pro=1.0; temp_string=vect[0][vect[0].size()-1]+"="+it->first; temp_pro*=pro_map[temp_string];//乘上p(ci) 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)//乘上p(xi|cj),跳过最后一列,因为是类别而非属性 { 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];//乘上p(xi|cj) temp_string.erase(); } } temp_map[it->first]=temp_pro;//存下概率 } //////////根据概率最大判断哪个该条记录应属于哪个类别 string temp_string2; temp_pro=0;//初始化概率为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;//输出该条记录所属的类别 } }