机器学习决策树 ID3算法的源代码
合集下载
相关主题
- 1、下载文档前请自行甄别文档内容的完整性,平台不提供额外的编辑、内容补充、找答案等附加服务。
- 2、"仅部分预览"的文档,不可在线预览部分如存在完整性等问题,可反馈申请退款(可完整预览的文档不适用该条件!)。
- 3、如文档侵犯您的权益,请联系客服反馈,我们会尽快为您处理(人工客服工作时间:9:00-18:30)。
break; case 5:test[count_test][5]=temp;
break; case 6:test[count_test][6]=temp;
break;
} } testfile.close(); for(i=1;i<=count_test;i++)
test[0]=0; //以确保评估分类准确率 cout<<"count_test="<<count_test<<'\n'; cout<<"count_train="<<count_train<<'\n'; //用测试集来评估分类准确率 for(i=1;i<=count_test;i++){
cout<<"无法使用训练集,请重试!"<<'\n'; exit(1); } count_test=0; j=-1;
//读取测试集数据 while(testfile>>temp){
j=j+1; k=j%(M+2); if(k==0) count_test+=1; switch(k){ case 0:test[count_test][7]=temp;
l=1; if(test[7]==path_a[j][0]) true_class+=1; break; } if(test[7]==most && l==0) true_class+=1; }
cout<<"测试集与训练集的比例为:"<<float(count_train)/count_test<<'\n'; cout<<"分类准确率为:"<<float(true_class)/count_test<<'\n'; }
} } for(i=0,k=-1;i<l;i++){
k++; for(ll=0;ll<M+2;ll++)
s[k][ll]=a[i][ll]; } count=count-bn; } else { if(sn==0){//候选属性集为空时,标记为训练集中最普通的类 //记录路径与前一路径相同的部分
cout<<setw(4)<<s[j]; } //most 记录训练集中哪类样本数比较多,以用于确定递归终止时不确定的类别 for(i=0,j=0,k=0;i<=count;i++){
if(s[0]==0) j+=1; else k+=1; } if(j>k) most=0; else most=1; //count_train 记录训练集的样本数 count_train=count+1; //训练的属性 for(i=0;i<M;i++) attribute_test_list1=i+1;
break; case 6:s[count][6]=temp;
break; case 7:s[count][7]=temp;
break; } } trainfile.close(); //输出训练集 for(i=0;i<=count;i++){ if(i%2==0) cout<<'\n'; for(j=0;j<M+2;j++)
cout<<"无法使用训练集,请重试!"<<'\n'; exit(1); } //读取训练集 while(trainfile>>temp){ j=j+1; k=j%(M+2); if(k==0||j==0) count+=1; //count 为训练集的第几个,k 代表室第几个属性 switch(k){ case 0:s[count][0]=temp;
void Generate_decision_tree(int b[][M+2],int bn,int attribute_test_list[],int sn,int ai,int aj) {
//定义数组 a 记录目前待分的训练样本集,定义数组 b 记录目前要分结点中所含的训练样本集 //same_class 用来记数,判别 samples 是否都属于同一个类 Trip+=1;//用 Trip 记录每一个叶子递归次数 path_a[leaves][Trip]=ai;//用 path_a[N][M+1],path_b[N][M+1]记录每一片叶子的路径 path_b[leaves][Trip]=aj; int same_class,i,j,k,l,ll,lll;
break; case 1:test[count_test][1]=temp;
break; case 2:test[count_test][2]=temp;
break; case 3:test[count_test][3]=temp;
break; case 4:test[count_test][4]=temp;
//首次调用递归函数,即是生成根结点的分支 Generate_decision_tree(s,count+1,attribute_test_list1,count_list,0,0);
cout<<'\n'<<"叶子结点的个数为:"<<leaves<<'\n'; cout<<"请输入测试集文件名:"; cin>>testname; ifstream testfile; testfile.open(testname,ios::in|ios::nocreate); if(!testfile){
} cout<<'\n'<<"IF "; for(i=1;i<=Trip;i++)
if(i==1) cout<<"a["<<path_b[leaves][i]<<"]="<<path_a[leaves][i];
else cout<<"^a["<<path_b[leaves][i]<<"]="<<path_ຫໍສະໝຸດ Baidu[leaves][i];
l=0; for(j=1;j<=leaves;j++)
if(test[path_b[j][1]]==path_a[j][1]&&test[path_b[j][2]]==path_a[j][2]&&test[path_b[j][3]] ==path_a[j][3]&&test[path_b[j][4]]==path_a[j][4]&&test[path_b[j][5]]==path_a[j][5]&&test[path_ b[j][6]]==path_a[j][6]){
if(bn==0) {//待分结点的样本集为空时,加上一个树叶,标记为训练集中最普通的类
//记录路径与前一路径相同的部分 for(i=1;i<Trip;i++)
if(path_a[leaves][i]==0){ path_a[leaves][i]=path_a[leaves-1][i]; path_b[leaves][i]=path_b[leaves-1][i];
} cout<<'\n'<<"IF "; for(i=1;i<=Trip;i++)
if(i==1) cout<<"a["<<path_b[leaves][i]<<"]="<<path_a[leaves][i]; else cout<<"^a["<<path_b[leaves][i]<<"]="<<path_a[leaves][i]; cout<<" THEN class="<<most; path_a[leaves][0]=most; //修改树的深度 if(path_a[leaves][Trip]==av[path_b[leaves][Trip]-1]) for(i=Trip;i>1;i--)
same_class+=1; if(same_class==bn){//待分样本集属于同一类时以该类标记
//记录路径与前一路径相同的部分 for(i=1;i<Trip;i++)
if(path_a[leaves][i]==0){ path_a[leaves][i]=path_a[leaves-1][i]; path_b[leaves][i]=path_b[leaves-1][i];
机器学习决策树 ID3 算法的源代码(VC6.0)
#include<iostream.h> #include<fstream.h> #include<string.h> #include<stdlib.h> #include<math.h> #include<iomanip.h> #define N 500 //N 定义为给定训练数据的估计个数 #define M 6 //M 定义为候选属性的个数 #define c 2 //定义 c=2 个不同类 #define s_max 5 //定义 s_max 为每个候选属性所划分的含有最大的子集数
int most;
void main(void) {
int i,j=-1,k,temp,l,count_test,true_class=0,count_train; char trainname[256],testname[256]; int test[N][8]; cout<<"请输入训练集文件名:"; cin>>trainname; ifstream trainfile; trainfile.open(trainname,ios::in|ios::nocreate); if(!trainfile){
if(path_a[leaves][i]==av[path_b[leaves][i]-1]) Trip-=1; else
break; Trip-=1; leaves+=1; } else { same_class=1; for(i=0;i<bn-1;i++) if(b[i][0]==b[i+1][0])
cout<<" THEN class="<<b[0][0]; path_a[leaves][0]=b[0][0];
//修改树的深度 if(path_a[leaves][Trip]==av[path_b[leaves][Trip]-1])
for(i=Trip;i>1;i--) if(path_a[leaves][i]==av[path_b[leaves][i]-1]) Trip-=1; else break;
int av[M]={3,3,2,3,4,2}; int s[N][M+2],a[N][M+2]; //数组 s[j]用来记录第 i 个训练样本的第 j 个属性值 int path_a[N][M+1],path_b[N][M+1]; //用 path_a[N][M+1],path_b[N][M+1]记录每一片叶子的路径 int count_list=M; //count_list 用于记录候选属性个数 int count=-1; //用 count+1 记录训练样本数 int attribute_test_list1[M]; int leaves=1; //用数组 ss[k][j]表示第 k 个候选属性划分的子集 Sj 中类 Ci 的样本数,数组的具体大小可根据给定训练数据调整 int ss[M][c][s_max]; //第 k 个候选属性划分的子集 Sj 中样本属于类 Ci 的概率 double p[M][c][s_max]; //count_s[j]用来记录第 i 个候选属性的第 j 个子集中样本个数 int count_s[M][s_max]; //分别定义 E[M],Gain[M]表示熵和熵的期望压缩 double E[M]; double Gain[M]; //变量 max_Gain 用来存储最大的信息增益 double max_Gain; int Trip=-1; //用 Trip 记录每一个叶子递归次数
Trip-=1;
leaves+=1; //未分类的样本集减少 for(i=0,l=-1;i<=count;i++){
for(j=0,lll=0;j<bn;j++) if(s[i][M+1]==b[j][M+1]) lll++;
if(lll==0){ l+=1; for(ll=0;ll<M+2;ll++) a[l][ll]=s[i][ll];
break; case 1:s[count][1]=temp;
break; case 2:s[count][2]=temp;
break; case 3:s[count][3]=temp;
break; case 4:s[count][4]=temp;
break; case 5:s[count][5]=temp;
break; case 6:test[count_test][6]=temp;
break;
} } testfile.close(); for(i=1;i<=count_test;i++)
test[0]=0; //以确保评估分类准确率 cout<<"count_test="<<count_test<<'\n'; cout<<"count_train="<<count_train<<'\n'; //用测试集来评估分类准确率 for(i=1;i<=count_test;i++){
cout<<"无法使用训练集,请重试!"<<'\n'; exit(1); } count_test=0; j=-1;
//读取测试集数据 while(testfile>>temp){
j=j+1; k=j%(M+2); if(k==0) count_test+=1; switch(k){ case 0:test[count_test][7]=temp;
l=1; if(test[7]==path_a[j][0]) true_class+=1; break; } if(test[7]==most && l==0) true_class+=1; }
cout<<"测试集与训练集的比例为:"<<float(count_train)/count_test<<'\n'; cout<<"分类准确率为:"<<float(true_class)/count_test<<'\n'; }
} } for(i=0,k=-1;i<l;i++){
k++; for(ll=0;ll<M+2;ll++)
s[k][ll]=a[i][ll]; } count=count-bn; } else { if(sn==0){//候选属性集为空时,标记为训练集中最普通的类 //记录路径与前一路径相同的部分
cout<<setw(4)<<s[j]; } //most 记录训练集中哪类样本数比较多,以用于确定递归终止时不确定的类别 for(i=0,j=0,k=0;i<=count;i++){
if(s[0]==0) j+=1; else k+=1; } if(j>k) most=0; else most=1; //count_train 记录训练集的样本数 count_train=count+1; //训练的属性 for(i=0;i<M;i++) attribute_test_list1=i+1;
break; case 6:s[count][6]=temp;
break; case 7:s[count][7]=temp;
break; } } trainfile.close(); //输出训练集 for(i=0;i<=count;i++){ if(i%2==0) cout<<'\n'; for(j=0;j<M+2;j++)
cout<<"无法使用训练集,请重试!"<<'\n'; exit(1); } //读取训练集 while(trainfile>>temp){ j=j+1; k=j%(M+2); if(k==0||j==0) count+=1; //count 为训练集的第几个,k 代表室第几个属性 switch(k){ case 0:s[count][0]=temp;
void Generate_decision_tree(int b[][M+2],int bn,int attribute_test_list[],int sn,int ai,int aj) {
//定义数组 a 记录目前待分的训练样本集,定义数组 b 记录目前要分结点中所含的训练样本集 //same_class 用来记数,判别 samples 是否都属于同一个类 Trip+=1;//用 Trip 记录每一个叶子递归次数 path_a[leaves][Trip]=ai;//用 path_a[N][M+1],path_b[N][M+1]记录每一片叶子的路径 path_b[leaves][Trip]=aj; int same_class,i,j,k,l,ll,lll;
break; case 1:test[count_test][1]=temp;
break; case 2:test[count_test][2]=temp;
break; case 3:test[count_test][3]=temp;
break; case 4:test[count_test][4]=temp;
//首次调用递归函数,即是生成根结点的分支 Generate_decision_tree(s,count+1,attribute_test_list1,count_list,0,0);
cout<<'\n'<<"叶子结点的个数为:"<<leaves<<'\n'; cout<<"请输入测试集文件名:"; cin>>testname; ifstream testfile; testfile.open(testname,ios::in|ios::nocreate); if(!testfile){
} cout<<'\n'<<"IF "; for(i=1;i<=Trip;i++)
if(i==1) cout<<"a["<<path_b[leaves][i]<<"]="<<path_a[leaves][i];
else cout<<"^a["<<path_b[leaves][i]<<"]="<<path_ຫໍສະໝຸດ Baidu[leaves][i];
l=0; for(j=1;j<=leaves;j++)
if(test[path_b[j][1]]==path_a[j][1]&&test[path_b[j][2]]==path_a[j][2]&&test[path_b[j][3]] ==path_a[j][3]&&test[path_b[j][4]]==path_a[j][4]&&test[path_b[j][5]]==path_a[j][5]&&test[path_ b[j][6]]==path_a[j][6]){
if(bn==0) {//待分结点的样本集为空时,加上一个树叶,标记为训练集中最普通的类
//记录路径与前一路径相同的部分 for(i=1;i<Trip;i++)
if(path_a[leaves][i]==0){ path_a[leaves][i]=path_a[leaves-1][i]; path_b[leaves][i]=path_b[leaves-1][i];
} cout<<'\n'<<"IF "; for(i=1;i<=Trip;i++)
if(i==1) cout<<"a["<<path_b[leaves][i]<<"]="<<path_a[leaves][i]; else cout<<"^a["<<path_b[leaves][i]<<"]="<<path_a[leaves][i]; cout<<" THEN class="<<most; path_a[leaves][0]=most; //修改树的深度 if(path_a[leaves][Trip]==av[path_b[leaves][Trip]-1]) for(i=Trip;i>1;i--)
same_class+=1; if(same_class==bn){//待分样本集属于同一类时以该类标记
//记录路径与前一路径相同的部分 for(i=1;i<Trip;i++)
if(path_a[leaves][i]==0){ path_a[leaves][i]=path_a[leaves-1][i]; path_b[leaves][i]=path_b[leaves-1][i];
机器学习决策树 ID3 算法的源代码(VC6.0)
#include<iostream.h> #include<fstream.h> #include<string.h> #include<stdlib.h> #include<math.h> #include<iomanip.h> #define N 500 //N 定义为给定训练数据的估计个数 #define M 6 //M 定义为候选属性的个数 #define c 2 //定义 c=2 个不同类 #define s_max 5 //定义 s_max 为每个候选属性所划分的含有最大的子集数
int most;
void main(void) {
int i,j=-1,k,temp,l,count_test,true_class=0,count_train; char trainname[256],testname[256]; int test[N][8]; cout<<"请输入训练集文件名:"; cin>>trainname; ifstream trainfile; trainfile.open(trainname,ios::in|ios::nocreate); if(!trainfile){
if(path_a[leaves][i]==av[path_b[leaves][i]-1]) Trip-=1; else
break; Trip-=1; leaves+=1; } else { same_class=1; for(i=0;i<bn-1;i++) if(b[i][0]==b[i+1][0])
cout<<" THEN class="<<b[0][0]; path_a[leaves][0]=b[0][0];
//修改树的深度 if(path_a[leaves][Trip]==av[path_b[leaves][Trip]-1])
for(i=Trip;i>1;i--) if(path_a[leaves][i]==av[path_b[leaves][i]-1]) Trip-=1; else break;
int av[M]={3,3,2,3,4,2}; int s[N][M+2],a[N][M+2]; //数组 s[j]用来记录第 i 个训练样本的第 j 个属性值 int path_a[N][M+1],path_b[N][M+1]; //用 path_a[N][M+1],path_b[N][M+1]记录每一片叶子的路径 int count_list=M; //count_list 用于记录候选属性个数 int count=-1; //用 count+1 记录训练样本数 int attribute_test_list1[M]; int leaves=1; //用数组 ss[k][j]表示第 k 个候选属性划分的子集 Sj 中类 Ci 的样本数,数组的具体大小可根据给定训练数据调整 int ss[M][c][s_max]; //第 k 个候选属性划分的子集 Sj 中样本属于类 Ci 的概率 double p[M][c][s_max]; //count_s[j]用来记录第 i 个候选属性的第 j 个子集中样本个数 int count_s[M][s_max]; //分别定义 E[M],Gain[M]表示熵和熵的期望压缩 double E[M]; double Gain[M]; //变量 max_Gain 用来存储最大的信息增益 double max_Gain; int Trip=-1; //用 Trip 记录每一个叶子递归次数
Trip-=1;
leaves+=1; //未分类的样本集减少 for(i=0,l=-1;i<=count;i++){
for(j=0,lll=0;j<bn;j++) if(s[i][M+1]==b[j][M+1]) lll++;
if(lll==0){ l+=1; for(ll=0;ll<M+2;ll++) a[l][ll]=s[i][ll];
break; case 1:s[count][1]=temp;
break; case 2:s[count][2]=temp;
break; case 3:s[count][3]=temp;
break; case 4:s[count][4]=temp;
break; case 5:s[count][5]=temp;