决策树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实现
决策树的分类过程和人的决策过程比较相似,就是先挑“权重”最大的那个考虑,然后再往下细分.比如你去看医生,症状是流鼻涕,咳嗽等,那么医生就会根据你的流鼻涕这个权重最大的症状先认为你是感冒,接着再根据你咳 ...
随机推荐
- Cocos2d 学习资料推荐
总算找到了一本介绍cocos2d的好书,注意,不是cocos2d-x!这本书叫 <cocos2d 权威指南> 定价99元,淘宝60多元,详细介绍了cocos2d的各个方面!不过你需要有oc ...
- Java for LeetCode 174 Dungeon Game
The demons had captured the princess (P) and imprisoned her in the bottom-right corner of a dungeon. ...
- ORACLE查询当前资产状态,和另一个数据库联查,(查询重复数据中第一条),子查询作为字段查询
背景:ORACLE查询当前资产状态,包含资产信息(表1),资产维修状态(表2),资产报废状态(表3) 如下: 资产信息:
- Codeforces 417 C
Football Time Limit: 1000MS Memory Limit: 262144KB 64bit IO Format: %I64d & %I64u Submit Sta ...
- ubuntu修改文件访问权限
遇到“bash .....权限不够”的问题时, 从控制台进入到那个文件夹 chmod 777 * -R 全部子目录及文件权限改为 777
- Java中比较不同的MD5计算方式
在项目中经常需要使用计算文件的md5,用作一些用途,md5计算算法,通常在网络上查询时,一般给的算法是读取整个文件的字节流,然后计算文件的md5,这种方式当文件较大,且有很大并发量时,则可能导致内存打 ...
- .NET 下各种Resource的读取方式
1) Embedded Resource (Build Action 设置为 Embedded Resource) 在运行时使用GetManifestResourceStream读取 Image.Fr ...
- Ps 之路 更改前景色
用快速选中工具 选中要改变的图片,选中你喜欢的颜色,按Alt+Del
- poj 2392 多重背包
题意:有几个砖,给出高度,能放的最大高度和数目,求这些砖能垒成的最大高度 依据lim排个序,按一层一层进行背包 #include<cstdio> #include<iostream& ...
- 动态链接库(dll)简介(转)
DLL 是 Dynamic Link Library 的缩写,译为“动态链接库”.DLL也是一个被编译过的二进制程序,可以被其他程序调用,但与 exe 不同,DLL不能独立运行,必须由其他程序调用载入 ...