决策树ID3算法示例
决策树代码如下:
#include "MyID3.h"
using namespace std;
void ReadData() //读入数据
{
ifstream fin("F:\\data.txt");
for(int i=;i<NUM;i++)
{
for(int j=;j<;j++)
{
fin>>DataTable[i][j];
cout<<DataTable[i][j]<<"\t";
}
cout<<endl;
}
fin.close();
} double ComputLog(double &p) //计算以2为底的log
{
if(p==||p==)
return ;
else
{
double result=log(p)/log();
return result;
}
} double ComputInfo(double &p) //计算信息熵
{
//cout<<"The value of p is: "<<p<<endl;
double q=-p;
double m=/p;
double n=/q;
return (p*ComputLog(m)+q*ComputLog(n));
} void CountInfoNP(int begin,int end,int &CountP,int &CountN) //搜索的起始位置、终止位置、计数变量
{
CountP=;
CountN=;
for(int i=begin;i<=end;i++)
if(DataTable[i][]=="Yes")
CountP++;
else
CountN++;
} bool CompareData(string &data,int &count,string &result) //判断该属性值是否出现过
{
for(int k=;k<count;k++)
if(data==DataValueWeight[k].AttriValueName) //如果该值出现过,则将其出现次数加一
{
DataValueWeight[k].ValueWeight+=;
if(result=="Yes")
DataValueWeight[k].ValuePWeight+=;
else
DataValueWeight[k].ValueNWeight+=;
//cout<<"Exist Here"<<endl;
return false;
}
return true; //如果该值没有出现过,则返回真值
} int SearchData(const int &begin,const int &end,const int &k) //对于第k列进行检索
{
//cout<<"Enter SearchData() "<<begin<<" "<<end<<" "<<k<<endl;
int count=;
for(int i=;i<VALUENUM;i++)
{
DataValueWeight[i].ValueWeight=;
DataValueWeight[i].ValueNWeight=;
DataValueWeight[i].ValuePWeight=;
} for(int i=begin;i<=end;i++)
if(i==begin)
{
DataValueWeight[count].AttriValueName=DataTable[i][k];
DataValueWeight[count].ValueWeight+=;
if(DataTable[i][]=="Yes")
DataValueWeight[count].ValuePWeight+=;
else
DataValueWeight[count].ValueNWeight+=; count++;
}
else
{
string data=DataTable[i][k];
string result=DataTable[i][];
if(CompareData(data,count,result)) //如果该值没有出现过
{
DataValueWeight[count].AttriValueName=data;
DataValueWeight[count].ValueWeight+=; if(DataTable[i][]=="Yes")
DataValueWeight[count].ValuePWeight+=;
else
DataValueWeight[count].ValueNWeight+=;
count++;
}
} //for(int s=0;s<count;s++)
// cout<<"Hello: "<<DataValueWeight[s].AttriValueName<<"\t"<<DataValueWeight[s].ValueWeight<<
// "\t"<<DataValueWeight[s].ValuePWeight<<" \t"<<DataValueWeight[s].ValueNWeight<<endl; for(int i=;i<count;i++)
{
if(DataValueWeight[i].ValueNWeight!=)
DataValueWeight[i].ValueNWeight=DataValueWeight[i].ValueWeight/DataValueWeight[i].ValueNWeight;
else
DataValueWeight[i].ValueNWeight=; if(DataValueWeight[i].ValuePWeight!=)
DataValueWeight[i].ValuePWeight=DataValueWeight[i].ValueWeight/DataValueWeight[i].ValuePWeight;
else
DataValueWeight[i].ValuePWeight=;
//cout<<"N: "<<DataValueWeight[i].ValueNWeight<<" P: "<<DataValueWeight[i].ValuePWeight<<endl;
}
return count;
} int PickAttri()
{
double max=;
int pos; for(int i=;i<;i++)
if(InfoResult[i].AttriI>max)
{
pos=i;
max=InfoResult[i].AttriI;
}
return pos;
}
int SortByAttriValue(int &begin,int &end,int &temp,int *position)
{ for(int i=begin;i<=end;i++) //将相应的数据拷贝到另一个阵列
for(int j=;j<=;j++)
{
int posy=i-begin;
CopyDataTable[posy][j]=DataTable[i][j];
}
//cout<<"have a look"<<endl; /*cout<<"************* Show Result First ****************"<<endl;
cout<<InfoResult[temp].AttriName<<endl;
for(int i=begin;i<=end;i++)
{
for(int j=0;j<=5;j++)
cout<<DataTable[i][j]<<"\t";
cout<<endl;
}*/ int low=,high=end-begin;
int count=;
int countpos=;
position[]=begin;
for(int i=;i<InfoResult[temp].AttriKind;i++)
{
for(int j=low;j<=high;j++)
if(CopyDataTable[j][temp]==DataValueWeight[i].AttriValueName)
{
int pos=count+begin; for(int k=;k<;k++)
DataTable[pos][k]=CopyDataTable[j][k];
count++;
}
position[countpos]=count+begin;
countpos++;
} /*cout<<"************* Show Result Second ****************"<<endl;
cout<<InfoResult[temp].AttriName<<endl;
for(int i=begin;i<=end;i++)
{
for(int j=0;j<=5;j++)
cout<<DataTable[i][j]<<"\t";
cout<<endl;
}
cout<<"\n\n\n";*/
return countpos;
} void BuildTree(int begin,int end,Node *parent)
{
int CountP=,CountN=;
CountInfoNP(begin,end,CountP,CountN); cout<<"************************ The data be sorted **************************"<<endl;
for(int i=begin;i<=end;i++)
{
for(int j=;j<=;j++)
cout<<DataTable[i][j]<<"\t";
cout<<endl;
}
cout<<"\n\n\n"; cout<<parent->AttriName<<" have a look: "<<CountP<<endl;
if(CountP==||CountN==) //该子集当中只包含Yes或者No时为叶子节点,返回调用处;
{
cout<<"creat leaf node"<<endl;
Node* t=new Node(); //建立叶子节点
if(CountP==)
t->AttriName="No";
else
t->AttriName="Yes";
parent->Children.push_back(t); //插入孩子节点
return;
}
else
{
double p=(double)CountP/(CountP+CountN);
double InfoH=ComputInfo(p); //获得信息熵 for(int k=;k<;k++) //循环计算各个属性的条件信息熵,并计算出互信息
{
int KindOfValue=SearchData(begin,end,k);
int sum=+end-begin;
for(int j=;j<KindOfValue;j++) //计算出属性的每种取值的权重的倒数
DataValueWeight[j].ValueWeight=DataValueWeight[j].ValueWeight/sum; double InfoGain=;
if(DataValueWeight[].ValueNWeight!=&&DataValueWeight[].ValuePWeight!=)
InfoGain=DataValueWeight[].ValueWeight*(ComputLog(DataValueWeight[].ValueNWeight)/DataValueWeight[].ValueNWeight+ComputLog(DataValueWeight[].ValuePWeight)/DataValueWeight[].ValuePWeight); for(int j=;j<KindOfValue;j++) //计算条件信息
if(DataValueWeight[j].ValueNWeight!=&&DataValueWeight[j].ValuePWeight!=)
InfoGain+=DataValueWeight[j].ValueWeight*(ComputLog(DataValueWeight[j].ValueNWeight)/DataValueWeight[j].ValueNWeight+ComputLog(DataValueWeight[j].ValuePWeight)/DataValueWeight[j].ValuePWeight); InfoResult[k].AttriI=InfoH-InfoGain; //计算互信息
InfoResult[k].AttriKind=KindOfValue;
}
int temp=PickAttri(); //选出互信息最大的属性作为节点建树
Node* t=new Node();
t->AttriName=InfoResult[temp].AttriName;
SearchData(begin,end,temp);
for(int k=;k<InfoResult[temp].AttriKind;k++)
{
string name=DataValueWeight[k].AttriValueName;
t->AttriValue.push_back(name);
}
t->parent=parent;
parent->Children.push_back(t); //孩子节点压入vector当中
int position[NUMOFPOS]; cout<<"before SortByAttriValue Begin: "<<begin<<",END: "<<end<<endl; SortByAttriValue(begin,end,temp,position); //将数据按照选定属性的取值不同进行划分
int times=InfoResult[temp].AttriKind;
for(int l=;l<=times;l++)
cout<<position[l]<<" ";
cout<<endl;
for(int k=;k<times;k++)
{
int head,rear;
head=position[k];
int hire=k+;
rear=position[hire]-;
for(int l=;l<=times;l++)
cout<<position[l]<<" ";
cout<<endl;
cout<<"Head: "<<head<<" ,Rear: "<<rear<<endl;
BuildTree(head,rear,t);
}
}
} void ShowTree(Node *root)
{ if(root->AttriName=="Yes"||root->AttriName=="No")
{
cout<<root->AttriName<<endl;
return;
}
else
{
cout<<root->AttriName<<endl;
for(vector<string>::iterator itvalue=root->AttriValue.begin();itvalue!=root->AttriValue.end();itvalue++)
{
string value=*itvalue;
cout<<value<<" ";
}
cout<<endl;
for(vector<Node*>::iterator itnode=root->Children.begin();itnode!=root->Children.end();itnode++)
{
Node *t=*itnode;
ShowTree(t);
}
}
}
int main()
{
InfoResult[].AttriName="天气";
InfoResult[].AttriName="气温";
InfoResult[].AttriName="湿度";
InfoResult[].AttriName="风";
ReadData();
Node *Root=new Node;
BuildTree(,NUM-,Root); //vector<Node>::iterator it=Root.Children.begin();
ShowTree(Root);
/*Node t=*it;
cout<<t.AttriName<<endl;
for(vector<string>::iterator itvalue=t.AttriValue.begin();itvalue!=t.AttriValue.end();itvalue++)
cout<<*itvalue<<endl;
it=t.Children.begin(); t=*it;
cout<<t.AttriName<<endl;*/
//ShowTree(t);
//cout<<"Root: "<<t.AttriName<<" ,Value: "<<*(t.AttriValue.begin())<<endl;
return ;
}
决策树ID3算法示例的更多相关文章
- 数据挖掘之决策树ID3算法(C#实现)
决策树是一种非常经典的分类器,它的作用原理有点类似于我们玩的猜谜游戏.比如猜一个动物: 问:这个动物是陆生动物吗? 答:是的. 问:这个动物有鳃吗? 答:没有. 这样的两个问题顺序就有些颠倒,因为一般 ...
- 决策树ID3算法[分类算法]
ID3分类算法的编码实现 <?php /* *决策树ID3算法(分类算法的实现) */ /* *求信息增益Grain(S1,S2) */ //-------------------------- ...
- 决策树---ID3算法(介绍及Python实现)
决策树---ID3算法 决策树: 以天气数据库的训练数据为例. Outlook Temperature Humidity Windy PlayGolf? sunny 85 85 FALSE no ...
- 02-21 决策树ID3算法
目录 决策树ID3算法 一.决策树ID3算法学习目标 二.决策树引入 三.决策树ID3算法详解 3.1 if-else和决策树 3.2 信息增益 四.决策树ID3算法流程 4.1 输入 4.2 输出 ...
- 机器学习之决策树(ID3)算法与Python实现
机器学习之决策树(ID3)算法与Python实现 机器学习中,决策树是一个预测模型:他代表的是对象属性与对象值之间的一种映射关系.树中每个节点表示某个对象,而每个分叉路径则代表的某个可能的属性值,而每 ...
- 决策树 -- ID3算法小结
ID3算法(Iterative Dichotomiser 3 迭代二叉树3代),是一个由Ross Quinlan发明的用于决策树的算法:简单理论是越是小型的决策树越优于大的决策树. 算法归 ...
- 决策树ID3算法的java实现(基本试用所有的ID3)
已知:流感训练数据集,预定义两个类别: 求:用ID3算法建立流感的属性描述决策树 流感训练数据集 No. 头痛 肌肉痛 体温 患流感 1 是(1) 是(1) 正常(0) 否(0) 2 是(1) 是(1 ...
- 【Machine Learning in Action --3】决策树ID3算法
1.简单概念描述 决策树的类型有很多,有CART.ID3和C4.5等,其中CART是基于基尼不纯度(Gini)的,这里不做详解,而ID3和C4.5都是基于信息熵的,它们两个得到的结果都是一样的,本次定 ...
- 决策树ID3算法的java实现
决策树的分类过程和人的决策过程比较相似,就是先挑“权重”最大的那个考虑,然后再往下细分.比如你去看医生,症状是流鼻涕,咳嗽等,那么医生就会根据你的流鼻涕这个权重最大的症状先认为你是感冒,接着再根据你咳 ...
随机推荐
- iOS 端的第三方语音识别库
最近在看语音识别方面的库,主要看了2个收费的项目,一个是 At&t 的,一个是Nuance的.这2个项目虽然是收费的,但是仅仅测试的话,是免费的,连接如下 https://developer. ...
- putty mtputty 设置utf8编码
2013年10月30日 10:02:36 先load你指定的ip 然后选择左侧目录中的windows->translation 再在右侧选择utf-8编码 选中后,点击左侧目录中的session ...
- mysql源码:关于innodb中两次写的探索
两次写可以说是在Innodb中很独特的一个功能点,而关于它的说明或者解释非常少,至于它存在的原因更没有多少文章来说,所以我打算专门对它做一次说明. 首先说明一下为什么会有两次写这个东西:因为innod ...
- 利用WinHEX,重构狂牛加密视频1.0.0.1【只适合RIFF(AVI)】
幸亏是视频部分没有进行加密 1.用 WinHEX 打开狂牛加密视频, 查找 [RIFF] 字符串 2.光标放在 RIFF的 [R]上面, 按 CTRL+SHIFT+END 3.把选择的块写入新文件 H ...
- 桐桐的贸易--WA
问题 A: 桐桐的贸易 时间限制: 1 Sec 内存限制: 64 MB提交: 15 解决: 2[提交][状态][讨论版] 题目描述 桐桐家在Allianceance城,好友ROBIN家在Horde ...
- 一个程序中关于多个osgGA::GUIEventHandler同时存在的问题
平时使用GUIEventHandler不太注意handle()函数的返回值,觉得返回true或者false都无所谓,其实不然. 我遇到的问题是程序中一个节点添加了GUIEventHandler对象pi ...
- Android中如何让手机屏幕不待机
在Android中,申请WakeLock可以让你的进程持续执行即使手机进入睡眠模式,比较实用的是比如后台有网络功能,可以保证操作持续进行. 方法: 在操作之前加入 PowerManager pm = ...
- android 中如何分析内存泄漏
转载:http://blog.csdn.net/fulinwsuafcie/article/details/8363218 前提条件: 1,电脑安装了java 运行环境 2,手机端开启了 USB 调试 ...
- 高效开发 Android App 的 10 个建议(转)
文章写的非常好,值得大家好好研究研究,仔细分析一下. 引文地址: http://www.cnblogs.com/xiaochao1234/p/3644989.html 假如要Google Play上做 ...
- kvm虚似机监控
[root@ok Desktop]# yum install virt-top [root@ok Desktop]# virt-top virt-top 22:53:44 - x86_64 4/4CP ...