朴素贝页斯分类法 c++实现
朴素贝叶斯法是基于贝叶斯定理与特征条件独立假设的分类方法。对于搞机器学习的同学们来说,这是相对简单但效果较好的模型。
朴素贝叶斯方法的理论
设输入为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,Sj ;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++实现的更多相关文章
- 亚马逊CEO贝索斯致股东信:阐述公司未来计划
亚马逊CEO 杰夫·贝索斯(Jeff Bezos)今天发布年度股东信, 详细描述了亚马逊的产品.服务和未来计划,当然,信中并没有任何的硬数据,比如说亚马逊Kindle的销量等等.但这封信也包括一些颇令 ...
- 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. ...
- Github上关于iOS的各种开源项目集合(强烈建议大家收藏,查看,总有一款你需要)
下拉刷新 EGOTableViewPullRefresh - 最早的下拉刷新控件. SVPullToRefresh - 下拉刷新控件. MJRefresh - 仅需一行代码就可以为UITableVie ...
- iOS及Mac开源项目和学习资料【超级全面】
UI 下拉刷新 EGOTableViewPullRefresh – 最早的下拉刷新控件. SVPullToRefresh – 下拉刷新控件. MJRefresh – 仅需一行代码就可以为UITable ...
- iOS:iOS开发非常全的三方库、插件等等
iOS开发非常全的三方库.插件等等 github排名:https://github.com/trending, github搜索:https://github.com/search. 此文章转自git ...
- iOS开发--iOS及Mac开源项目和学习资料
文/零距离仰望星空(简书作者)原文链接:http://www.jianshu.com/p/f6cdbc8192ba著作权归作者所有,转载请联系作者获得授权,并标注“简书作者”. 原文出处:codecl ...
- iOS、mac开源项目及库汇总
原文地址:http://blog.csdn.net/qq_26359763/article/details/51076499 iOS每日一记------------之 中级完美大整理 iOS.m ...
- iOS、mac开源项目及库(感谢原作者的分享)
目录 模糊效果 富文本 表相关 HUD与Toast 其他UI 其他动画 网络测试 网络聊天 Model 数据库 PDF 摄像照相视频音频处理 消息相关 消息推送服务器端 版本新API的Demo 测试及 ...
- iOS超全开源框架、项目和学习资料汇总--数据库、缓存处理、图像浏览、摄像照相视频音频篇
iOS超全开源框架.项目和学习资料汇总--数据库.缓存处理.图像浏览.摄像照相视频音频篇 感谢:Ming_en_long 的分享 大神超赞的集合,http://www.jianshu.com/p/f3 ...
随机推荐
- 【C语言的日常实践(八)】弦
串数据类型是一个重要的,但C有没有明确的语言字符串数据类型.头文件string.h它包括大多数字符串处理函数. 故,有操作的串.通常包括string.h头文件. 1.字符串的长度:对字符串进行的操作中 ...
- Android经常使用的布局类整理(一)
Android经常使用的布局类整理 近期又回头做了一下android的项目,发觉越来越不从心,非常多东西都忘了,简单的页面布局也非常多写不出来,首先还是先整理一下一些会混淆的概念先 layout_wi ...
- 数学思想方法-sasMEMO(17)
SAS日期及时间格式 data _null_;input mydate YYMMDD10.;put mydate YYMMDDB10.;put mydate YYMMDDC10.;put mydat ...
- 我展示了视频采集前端vfe和camera,decode等交互驱动的体系结构
到现在都与处理器接触较多.更深入的驱动主要是前端视频采集.控制TI的DM64xx,DM3730.纪氏A31等待.他们发现,它们的使用的基本框架的是不一样的. 当然,典型camera例如ov系列,dec ...
- MSMQ-发送消息到远程专用队列 实例
目录 一:MSMQ的一些理论上的知识 二:队列类型(Queue Type) 三:安装消息队列 四:在C#中Messagequeue class 五:MSMQ-发送消息到远程专用队列 六:例子 一. ...
- 【SICP练习】150 练习4.6
练习4-6 原版的 Exercise 4.6. Let expressions are derived expressions, because (let (( ) - ( )) ) is equiv ...
- CSS定位:几种类型的position定位的元素
当人们刚接触布局的时候都比较倾向于使用定位的方式.因为定位的概念看起来好像比较容易掌握.表面上你确切地指定了一个块元素所处的位置那么它就会坐落于那里.可是定位比你刚看到的时候要稍微复杂一点.对于定位来 ...
- SharePoint 2013 搜索SharePoint 特定列和特定文档(自己定义搜索)
SharePoint 2013 搜索SharePoint 特定列和特定文档 1,操作步骤和图例,因语言和版本号的不同 我尽量使用抓图方式. 2. In Central Administration, ...
- 优秀的前端project如何制定一个老师--html学习路径
一个好的前端project教师发展,不是一蹴而就,它需要大量的学习和积累. 至于谁刚开始学习的人,如何入门.学习如何选择我的路线,做了各种工具? 1. 学习之前 1.不要着急看一些复杂网页效果的代码 ...
- ORA-00932: inconsistent datatypes: expected - got CLOB
从最近的数据库10.2.0.3升级到10.2.0.5之后,一些对象可以不被编译.查看这些对象的主列表不严格写入之前现在SQL这些语法结果package无法成功编译,诸如select查询列中不能使用混淆 ...