决策树代码如下:

#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算法示例的更多相关文章

  1. 数据挖掘之决策树ID3算法(C#实现)

    决策树是一种非常经典的分类器,它的作用原理有点类似于我们玩的猜谜游戏.比如猜一个动物: 问:这个动物是陆生动物吗? 答:是的. 问:这个动物有鳃吗? 答:没有. 这样的两个问题顺序就有些颠倒,因为一般 ...

  2. 决策树ID3算法[分类算法]

    ID3分类算法的编码实现 <?php /* *决策树ID3算法(分类算法的实现) */ /* *求信息增益Grain(S1,S2) */ //-------------------------- ...

  3. 决策树---ID3算法(介绍及Python实现)

    决策树---ID3算法   决策树: 以天气数据库的训练数据为例. Outlook Temperature Humidity Windy PlayGolf? sunny 85 85 FALSE no ...

  4. 02-21 决策树ID3算法

    目录 决策树ID3算法 一.决策树ID3算法学习目标 二.决策树引入 三.决策树ID3算法详解 3.1 if-else和决策树 3.2 信息增益 四.决策树ID3算法流程 4.1 输入 4.2 输出 ...

  5. 机器学习之决策树(ID3)算法与Python实现

    机器学习之决策树(ID3)算法与Python实现 机器学习中,决策树是一个预测模型:他代表的是对象属性与对象值之间的一种映射关系.树中每个节点表示某个对象,而每个分叉路径则代表的某个可能的属性值,而每 ...

  6. 决策树 -- ID3算法小结

          ID3算法(Iterative Dichotomiser 3 迭代二叉树3代),是一个由Ross Quinlan发明的用于决策树的算法:简单理论是越是小型的决策树越优于大的决策树. 算法归 ...

  7. 决策树ID3算法的java实现(基本试用所有的ID3)

    已知:流感训练数据集,预定义两个类别: 求:用ID3算法建立流感的属性描述决策树 流感训练数据集 No. 头痛 肌肉痛 体温 患流感 1 是(1) 是(1) 正常(0) 否(0) 2 是(1) 是(1 ...

  8. 【Machine Learning in Action --3】决策树ID3算法

    1.简单概念描述 决策树的类型有很多,有CART.ID3和C4.5等,其中CART是基于基尼不纯度(Gini)的,这里不做详解,而ID3和C4.5都是基于信息熵的,它们两个得到的结果都是一样的,本次定 ...

  9. 决策树ID3算法的java实现

    决策树的分类过程和人的决策过程比较相似,就是先挑“权重”最大的那个考虑,然后再往下细分.比如你去看医生,症状是流鼻涕,咳嗽等,那么医生就会根据你的流鼻涕这个权重最大的症状先认为你是感冒,接着再根据你咳 ...

随机推荐

  1. jquery validate自定义checkbox验证规则和样式

    参考:http://blog.csdn.net/xh16319/article/details/9987847 自定义checkbox验证,“检查checkbox是否选中” jQuery.valida ...

  2. MYSQL集群的搭建

    按照此配置完全可以配置成功!! 一.介绍========测试环境:Server1:ndbd 192.168.1.225Server2:ndbd 192.168.1.226Server3:mysqld ...

  3. Java用Scanner类获取用户输入

    用Java编写程序时,有些数据需要用户输入,这个时候需要调用java提供的Scanner类,这个类在包java.util下,比如求一个矩形的面积,简单的看一下用法: import java.util. ...

  4. Python——内置类型

    Python定义了丰富的数据类型,包括: 数值型:int, float, complex 序列:(iterable) str, unicode, tuple, list, bytearray, buf ...

  5. jsp之间传参中文乱码问题

    jsp页面之间传参,传中文会出现乱码问题. 如下: $('.yzjjfa_row').eq(0).append('<a class="yzjjfa_contItem jjfa_acti ...

  6. Eclipse中android工程C++文件中出现的莫名其妙的错误

    大多数是std库相关的问题,例如 vector<int> v; v.push_back(23);//这句语法是没有错误的,但是每次执行Run As的时候就会报错 尝试1:在工程名右键-Cl ...

  7. [Linux] AWK命令详解(大全)

    转载自:http://caoyanbao.iteye.com/blog/570868 什么是awk? 你可能对UNIX比较熟悉,但你可能对awk很陌生,这一点也不奇怪,的确,与其优秀的功能相比,awk ...

  8. Repairing Company(poj 3216)

    题目大意: 有Q个地点,告诉你Q个地点之间的相互距离(从i地点赶到j地点需要的时间).有M项任务, 给你M项任务所在的地点block.开始时间start和任务完成需要时间time.一个工人只有在 他准 ...

  9. LeetCode之Min Stack 实现最小栈

    LeetCode相关的网上资源比较多,看到题目一定要自己做一遍,然后去学习参考其他的解法. 链接: https://oj.leetcode.com/problems/min-stack/ 题目描述: ...

  10. ***php解析JSON二维数组字符串(json_decode函数第二个参数True和False的区别)

    客户端的请求体中的数据:[{"msg_id": 1, "msg_status": "HAS_READ" }, { "msg_id& ...