朴素贝叶斯法是基于贝叶斯定理与特征条件独立假设的分类方法。对于搞机器学习的同学们来说,这是相对简单但效果较好的模型。

朴素贝叶斯方法的理论

设输入为n维特征向量X={x1,x2,...,xn},输出为类标记集合Y={c1,c2,...ck}。朴素贝叶斯法通过训练数据集学习联合概率分布P(X,Y),其中X是n维,Y是分类标记。有了模型P(X,Y),要预测一个特征向量的分类标记,则分别计算P(X,Y=c1),P(X,Y=c2),...P(X,Y=ck),选择取最大值的p(X,Y=cm),将cm作为X的分类标记。但对于模型P(X,Y)中的X是n维随机变量,若每一维特征取值最少有两个值,那么模型P(X,Y)参数量将是指数级的,这在特征维度较大的时候是不可行的。朴素贝叶斯法是引入条件独立性假设,由条件概率可得:

            P(X=x,Y=ck)

            =P(X(1)=x(1),X(2)=x(2),...X(n)=x(n)|Y=ck)*P(Y=ck)

 (应用条件独立性假设)=P(X(1)=x(1)|Y=ck)*P(X(2)=x(2)|Y=ck)*...*P(X(n)=x(n)|Y=ck)*P(Y=ck)

          即   =P(Y=ck)*∏i=1..nP(X(i)=x(i)|Y=ck)

条件独立性假设等于说用于分类的特征在类确定的情况下都是条件独立的。通过条件独立性假设,朴素贝叶斯法是模型变得简单,参数数量大大减少,但也牺牲一定的分类准确率。

朴素贝叶斯参数估计-极大似然估计

计算先验概率P(Y=ck)

P(Y=ck)=(∑i=1..nI(yi=ck))/N   , k=1,2,...,K

其中I(yi=ck)为指示函数,当yi=ck时函数值等于1,否则为0。

计算条件概率P(X(j)=ajl|Y=ck)

P(X(j)=ajl|Y=ck)=(∑i=1..nI(xi(j)=ajl,yi=ck))/∑i=1..nI(yi=ck)   ,j=1,2,,,n; l=1,2,S;k=1,2,K

其中Sj是第j维特征的取值数。

由于计算条件概率可能会造成某个特征的计数为零,这样在预测分类的时候就会对有该特征的类计算值为0.为了避免这种情况,可采用拉普拉斯平滑处理。

预测分类

对给定的实例x=(x(1),x(2),...x(n))T,计算

P(Y=ck)*∏i=1..nP(X(i)=x(i)|Y=ck), k=1,2,...,K

然后根据上述K个结果,确定x的分类

y=argmax P(Y=ck)*∏i=1..n P(X(i)=x(i)|Y=ck)

例:

训练数据

  1 2 3 4 5 6 7 8 9 10 11 12 13 14 15
x(1) 1 1 1 1 1 2 2 2 2 2 3 3 3 3 3
x(2) S M M S S S M M L L L M M L L
Y -1 -1 1 1 -1 -1 -1 1 1 1 1 1 1 1 -1

数据存储在文件中,每一行存储格式为<x(1) x(2) Y>,即特征1,特征2,分类属性以空格分隔。如下

1 S -1
1 M -1
1 M  1
1 S  1
1 S -1
2 S -1
2 M -1
2 M  1
2 L  1
2 L  1
3 L  1
3 M 1
3 M 1
3 L  1
3 L -1

代码如下:

/********************************************************************/
/*
朴素贝叶斯法
*/
/************************************************************************/
#include<iostream>
#include<string>
#include<fstream>
#include<sstream>
#include<vector>
#include<map>
#include<set>
using namespace std;
class naiveBayes{
public:
     //载入数据并统计分量计数  
void loadData(){
ifstream fin(dataFile.c_str());
if(!fin){
cout<<"数据文件打开失败"<<endl;
exit(0);
}
while(fin){
string line;
getline(fin,line);
if(line.size()>1){
stringstream sin(line);
string s[2];
int c;
sin>>s[0]>>s[1]>>c;
//cout<<s1<<" "<<s2<<" "<<c<<endl;
dataSize++;
if(ym.count(c)>0){
ym[c]++;
}else{
ym[c]=1;
}
for(int i=0;i<2;i++){
if(feam.count(s[i])>0){
if(feam[s[i]].count(c)>0){
feam[s[i]][c]++;
}else{
feam[s[i]][c]=1;
}
}else{
map<int,int> mt;
mt[c]=1;
feam[s[i]]=mt;
}
}
} } }
     //显示map模型
void dispModel(){
cout<<"训练数据总数"<<endl;
cout<<dataSize<<endl;
cout<<"分类统计计数"<<endl;
for(map<int,int>::iterator mi=ym.begin();mi!=ym.end();mi++){
cout<<mi->first<<" "<<mi->second<<endl;
}
cout<<"特征统计计数:"<<endl;
for(map<string, map<int,int> >::iterator mi=feam.begin();mi!=feam.end();mi++){
cout<<mi->first<<": ";
for(map<int,int>::iterator ii=mi->second.begin();ii!=mi->second.end();ii++){
cout<<"<"<<ii->first<<" "<<ii->second<<"> ";
}
cout<<endl;
}
}
     //预测分类
void predictive(){
string x1,x2;
cout<<"请输入测试数据(包括两维特征,第一维取值<1,2,3>;第二维取值<S,M,L>)"<<endl;
string a1[]={"1","2","3"};
string a2[]={"M","S","L"};
set<string> a1set(a1,a1+3);
set<string> a2set(a2,a2+3);
while(cin>>x1>>x2){
if(a1set.count(x1)>0&&a2set.count(x2)>0){
double py1=(double(ym[-1])/dataSize)*(double(feam[x1][-1])/ym[-1])*(double(feam[x2][-1])/ym[-1]);
double py2=(double(ym[1])/dataSize)*(double(feam[x1][1])/ym[1])*(double(feam[x2][1])/ym[1]);
cout<<"y=-1的得分为"<<py1<<endl;
cout<<"y=1的得分为"<<py2<<endl;
cout<<"<"<<x1<<","<<x2<<">"<<"所属分类为:";
if(py1>py2){
cout<<"-1";
}else{
cout<<"1";
}
cout<<endl;
cout<<endl;
cout<<"继续测试(ctrl+Z结束)"<<endl;
}else{
cout<<"输入特征为:第一维取值<1,2,3>;第二维取值<S,M,L>,空格分隔。输入有误,请重新输入"<<endl;
}
}
}
naiveBayes(string df="data.txt"):dataFile(df),dataSize(0){
}
private:
string dataFile;
int dataSize;
//分类->计数
map<int,int> ym;
//分类->( 特征->计数 )
map<string, map<int,int> >feam;
};
int main(){
naiveBayes nb;
nb.loadData();
nb.dispModel();
nb.predictive();
system("pause");
return 0;
}

程序运行结果:

本例中,参数估计采用的是贝叶斯估计,有时间再把拉普拉斯平滑加上。

朴素贝页斯分类法 c++实现的更多相关文章

  1. 亚马逊CEO贝索斯致股东信:阐述公司未来计划

    亚马逊CEO 杰夫·贝索斯(Jeff Bezos)今天发布年度股东信, 详细描述了亚马逊的产品.服务和未来计划,当然,信中并没有任何的硬数据,比如说亚马逊Kindle的销量等等.但这封信也包括一些颇令 ...

  2. ios项目里扒出来的json文件

    p.p1 { margin: 0.0px 0.0px 0.0px 0.0px; font: 13.0px Menlo; color: #000000 } p.p2 { margin: 0.0px 0. ...

  3. Github上关于iOS的各种开源项目集合(强烈建议大家收藏,查看,总有一款你需要)

    下拉刷新 EGOTableViewPullRefresh - 最早的下拉刷新控件. SVPullToRefresh - 下拉刷新控件. MJRefresh - 仅需一行代码就可以为UITableVie ...

  4. iOS及Mac开源项目和学习资料【超级全面】

    UI 下拉刷新 EGOTableViewPullRefresh – 最早的下拉刷新控件. SVPullToRefresh – 下拉刷新控件. MJRefresh – 仅需一行代码就可以为UITable ...

  5. iOS:iOS开发非常全的三方库、插件等等

    iOS开发非常全的三方库.插件等等 github排名:https://github.com/trending, github搜索:https://github.com/search. 此文章转自git ...

  6. iOS开发--iOS及Mac开源项目和学习资料

    文/零距离仰望星空(简书作者)原文链接:http://www.jianshu.com/p/f6cdbc8192ba著作权归作者所有,转载请联系作者获得授权,并标注“简书作者”. 原文出处:codecl ...

  7. iOS、mac开源项目及库汇总

    原文地址:http://blog.csdn.net/qq_26359763/article/details/51076499    iOS每日一记------------之 中级完美大整理 iOS.m ...

  8. iOS、mac开源项目及库(感谢原作者的分享)

    目录 模糊效果 富文本 表相关 HUD与Toast 其他UI 其他动画 网络测试 网络聊天 Model 数据库 PDF 摄像照相视频音频处理 消息相关 消息推送服务器端 版本新API的Demo 测试及 ...

  9. iOS超全开源框架、项目和学习资料汇总--数据库、缓存处理、图像浏览、摄像照相视频音频篇

    iOS超全开源框架.项目和学习资料汇总--数据库.缓存处理.图像浏览.摄像照相视频音频篇 感谢:Ming_en_long 的分享 大神超赞的集合,http://www.jianshu.com/p/f3 ...

随机推荐

  1. poj 1328 Radar Installation (简单的贪心)

    Radar Installation Time Limit: 1000MS   Memory Limit: 10000K Total Submissions: 42925   Accepted: 94 ...

  2. android账号与同步之发起同步

    上一篇博文我介绍了账号与同步的同步实现过程,当中提供了一个工系统进程调用的服务,那么这个服务究竟是怎么被启动和使用的呢?这篇博文我就大体梳理一下启动过程. 事实上作为一个一般开发者,我们仅仅要知道要想 ...

  3. ROOT android 原理。 基于(zergRush)

    出自: http://bbs.gfan.com/android-2996211-1-1.html 须要ROOT的同学请去上面的地址下载. a.控制手机创建个暂时目录,然后把zergRush脚本写入此目 ...

  4. veridata实验举例(2)验证表BONUS与表SALGRADE两节点同步情况

    veridata实验举例(2)验证表BONUS与表SALGRADE两节点同步情况 续接前几篇文章: 1.GoldenGate配置(一)之单向复制配置 地址:点击打开链接 2.GoldenGate配置( ...

  5. Asp.net MVC + EF + Spring.Net 项目实践(四)

    这篇写一写如何使用Spring.net来解耦各个项目 1. 在接口层添加IStudentBLL文件,里面有GetStudent和GetAllStudents两个方法:然后在StudentBLL类里实现 ...

  6. jquery.validate 验证(支持前台js验证通过,然后ajax后台数据校验)二

      jquery.validate  为啥 源码 里面 规定 dataType: "json" 呢 因为 他配套的 是  messages  下面 的 remote  属性 验证失 ...

  7. 项目管理实践 -- 健身小管家(Fitness housekeeper)的管理(4)

    提前几天把检查更新的功能完成了.

  8. asp.net mvc3 数据验证(四)—Remote验证的一个注意事项

    原文:asp.net mvc3 数据验证(四)-Remote验证的一个注意事项         前几篇把asp.net mvc3 中基于Model的主要数据验证的方法都已经讲完了,本节纯粹只是讲一个我 ...

  9. Java笔试题集锦

    Java笔试题集锦 1.MVC的各个部分都有那些技术来实现?怎样实现? 答:MVC是Model-View-Controller的简写."Model" 代表的是应用的业务逻辑(通过J ...

  10. itext之pdf导出添加水印Java工具类

    import java.io.IOException; import com.itextpdf.text.Document; import com.itextpdf.text.DocumentExce ...