学习C++STL已经有一段时间了,除了将书上的小程序跑跑之外,好像也不知道该怎么学习这门强大的工具(或者是信仰),在网上看到一位大神使用C++实现了决策树,于是也就有了这篇文章,
关于朴素贝叶斯不需要再多说什么,如果大家想看相关的内容的话,建议大家看看结构之法,算法之道的博客或者是刘未鹏师兄的博客,在这里不再多说什么,比起那些大牛,我们还有许多需要去学习,那下面直接上代码好了,
#include <iostream>
#include <vector>
#include <string>
#include <map>
#include <set>
#include <algorithm>
#include <utility>
const int Maxlen=6;//列数
using namespace std;
vector<string> item(Maxlen);
vector<vector<string>>sample;//训练数据
vector<string> Type;//训练数据的分类
vector<string> attribute_row;//属性列
map<string,set<string>> map_attribute_values;//每种属性对应的所有可能的取值(不包括重复的值)
string istreamend("end");//训练数据输入结束标志
map<string,double> map_priority;//贝叶斯公式中的先验概率
map<string,int> map_freuency;//为了计算上面的先验概率而需要存储的频数
map<string,int> map_freuency1;//上述的副本
map<pair<string,string>,int>map_attribute_frequency;//属性/属性值形成的pair以及对应的次数int
typedef map<pair<string,string>,int>* map_ptr;
const int para=1;//平滑因子
pair<string,string> pair_string;
typedef map<pair<string,string>,double>* map_ptr1;
//自定义比较函数,用于对训练数据的排序,我是按照类别进行排序的
bool sortfunc(const vector<string>& str1,const vector<string>&str2)
{
if(str1[Maxlen-1]<=str2[Maxlen-1])
return true;
else
return false;
}
//自定义比较函数,用于对类别的排序
bool sortfunc1(const string& str1,const string& str2)
{
if(str1<=str2)
return true;
else return false;
}
//初始化训练样本集
void Initilizesample()
{
string s;
int i;
while(cin>>s,s.compare(istreamend)!=0)
{
item[0]=s;
for(i=1;i<Maxlen;i++)
{
cin.get();
cin>>item[i];
if(i==Maxlen-1)
Type.push_back(item[i]);
}
sample.push_back(item);
}
for(i=1;i<Maxlen-1;i++)
arrribute_row.push_back(sample[0][i]);
sort(sample.begin(),sample.end(),sortfunc);
sort(Type.begin(),Type.end(),sortfunc1);
vector<string>::iterator pos=uniue(Type.begin(),Type.end());
Type.erase(pos,Type.end());
}
//初始化属性/属性值,非重复
void InitilizeMap_attribute_values()
{
int sample_size=sample.size()-1;
int i,j;
for(i=0;i<Maxlen-2;i++)
{
for(j=1;j<=sample_size;j++)
{
map_attribute_values[attribute_row[i]].insert(sample[j][i+1]);
}
}
}
//计算先验概率
void CalPrioriprobablity()
{
int sample_size=sample.size()-1;
int Type_size=Type.size();
int i,j;
for(i=1;i<=sample_size;i++)
for(j=0;j<Type_size;j++)
{
if(!sample[i][Maxlen-1]==Type[j]))
{
map_frequency[Type[j]]++;
map_frequency1[Type[j]]++;
break;
}
}
double sample_size1=double(sample_size+para*Type_size);
for(j=0;j<Type_size;j++)
map_priority[Type[j]]=(map_frequency[Type[j]]+para)/sample_size1;
}
//计算后验频率
void Calpor(map_ptr& por)
{
int Type_size=Type.size();
int k;
int j;
for(j=1;j<Type_size;j++)
map_frequency[Type[j]]=map_frequency[Type[j-1]]+map_frequency1[Type[j]];
por=new map<pair<string,string>,int>[Type_size];
for(int i=1;i<sample.size();i++)
{
for(k=0;k<Type_size;k++)
if(i<=map_frequency[Type[k]])
break;
for(int j=0;j<Maxlen-2;j++)
{
pair_string=make_pair(attribute_row[j],sample[i][j+1]);
por[k][pair_string]++;
}
}
//计算后验概率
void Calproba(map_ptr1& ptr1,const map_ptr& ptr)
{
int Type_size=Type.size();
int k;
map<pair<string,string>,int>::itreator pos;
ptr1=new map<pair<string,string>,double>[Type_size];
for(int i=0;i<Type_size;i++)
{
for(pos=ptr[i].begin();pos!=ptr[i].end();pos++)
{
pair_string=pos->first;
k=map_attribute_values[pair_string.first].size();
ptr1[i][pair_string]=(double(ptr[i][pair_string])+para)/(map_freuency1[Type[i]+k*para);
}
}
}
void Initilze()
{
Initilizesample();
InitilizeMap_attribute_values();
}
//朴素贝叶斯估计
void NBCcompare(map_ptr1& ptr,vector<string>& com)
{
int Type_size=Type.size();
map<pair<string,string>,double>::iterator pos;
map<string,double> count_values;
map<string,double>::iterator pos1;
string s;
double max_value=-1.0;
double current_value=1.0;
for(int i=0;i<Type_size;i++)
{
for(int j=1;j<Maxlen-1;j++)
{
pair_string=make_pair(attribute_row[j-1],com[j]);
for(pos=ptr[i].begin();pos!=ptr[i].end();pos++)
if(pos->first==pair_string)
{
current_value*=pos->second;
break;
}
}
count_values[Type[i]]=current_value;
current_value=1.0;
}
for(pos1=count_values.begin();pos1!=count_values.end();pos1++)
if(pos1->second>=max_value)
{
max_value=pos1->second;
s=pos1->first;
}
cout<<"The classificion is "<<s<<endl;
}
int main(void)
{
Initilize();
map_ptr ptr;
Calpor(ptr);
map_ptr1 ptr1;
Calproba(ptr1,ptr);
cout<<"Please input a sample\n"<<endl;
vector<string> com;
string s;
for(int i=0;i<Maxlen-1;i++)
{
cin>>s;
com.push_back(s);
}
NBCcompare(ptr1,com);
cin.get();
return 0;
}
欢迎大神们指正