朴素贝叶斯分类器 C++ STL 实现

学习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;
}

欢迎大神们指正

  • 2
    点赞
  • 8
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值