关闭

人工智能导论(1)——基本的决策树算法ID3

标签: 算法人工智能
72人阅读 评论(0) 收藏 举报
分类:

实验要求

有27个训练样本数据,每个样本的属性表为{Age sex region income married children car mortgage},并做了如下的预处理:
Age:30岁以下标记为“1”;30岁以上50岁以下标记为“2”;50岁以上标记为“3”。
Sex:FEMAL—-“1”;MALE—-“2”
Region:INNER CITY—-“1”; TOWN—-“2”; RURAL—-“3”; SUBURBAN—-“4”
Income:5000~2万—-“1”;2万~4万—-“2”;4万以上—-“3”
Married:已婚—1; 未婚—2
Children:有—-1; 无—2
Car:有—-1; 无—-2
Mortgage:有—1; 无—2;

分类Pep:以上八个条件,若为“是”标记为“1”,若为“否”标记为“2”。

用ID3算法设计实现决策树,实现分类。


代码实现

#include<iostream>
#include<vector> 
#include<set> 
#include<cmath>
#include<fstream>
using namespace std;

int object[27][9];
int test[37][8];

int obj_size;
int test_size; 
class Node{ //节点类 
    public:
        int flag;//叶节点标志 
        int final;//结果 
        int judge_attr_value;//属性判断值 
        int judge_attr_no; //属性编号 
        set<int> obj;//对象集 
        int attr[8];//属性可用集 
        vector<Node *> child;//子节点 
}root;
void input(){   
    ifstream in("sample.txt");
    in>>obj_size;
    for(int i=0;i<obj_size;i++)
        for(int j=0;j<9;j++)
            in>>object[i][j];
} 
void inputTest(){
    ifstream in("test.txt");
    in>>test_size;
    for(int i=0;i<test_size;i++)
        for(int j=0;j<8;j++)
            in>>test[i][j];
} 
void prepare(){//初始化 
    root.flag = 0;
    root.final = 0;
    for(int i=0;i<obj_size;i++) root.obj.insert(i);
    for(int i=0;i<8;i++) root.attr[i]=1; 
}
int Choose_Attribute(Node *node){ //选择属性 
    double min=99999;
    int min_attr;//最小属性 
    double size = (double) node->obj.size();//对象个数
    for(int i=0;i<8;i++){ //对于每一个属性 
        if(node->attr[i]){ //属性可选 
            double attr_classify[6][3]={0};//属性分类 
            for(set<int>::iterator it = node->obj.begin(); it != node->obj.end(); ++it){//本节点拥有的对象集合的属性分类 
                attr_classify[object[(*it)][i]][object[(*it)][8]]++;
                attr_classify[object[(*it)][i]][0]++;
            }
            double shang=0;
            for(int j=0;j<6;j++){//对于属性的每个值 
                double s=0;
                int num=0;
                double T,F;
                if(attr_classify[j][0]) { //属性存在,计算熵值
                    if(attr_classify[j][1]==0) T=0;//第一个结果不存在
                    if(attr_classify[j][2]==0) F=0;//第二个结果不存在
                    if(attr_classify[j][1]&&attr_classify[j][2]){//结果都存在
                        T = attr_classify[j][1]/attr_classify[j][0] * -( log(attr_classify[j][1]/attr_classify[j][0])/log(2));
                        F = attr_classify[j][2]/attr_classify[j][0] * -( log(attr_classify[j][2]/attr_classify[j][0])/log(2));
                    }
                    s = attr_classify[j][0]/size *( T + F );//熵 
                }
                shang += s; 
            }
            if(min>shang){
                min=shang;
                min_attr=i;//保存属性
            }   
        }
    }   
    return min_attr;//返回最优属性 
}
int node_for_each(Node *node){ //节点构造函数 
    int final_set[3]={0};//结果集 
    for(set<int>::iterator it = node->obj.begin(); it != node->obj.end(); ++it) final_set[object[*it][8]]++;
    if(final_set[1]==0||final_set[2]==0){//属性结果一致       
        node->flag = 1;
        if(final_set[1]) node->final = 1;
        if(final_set[2]) node->final = 2;
        return 0;
    }
    if(final_set[1]&&final_set[2]){//属性结果不一致,继续分类 
        int attribute_no;
        int attr[8];
        for(int i=0;i<8;i++) attr[i]=node->attr[i];//属性标志数组 
        attribute_no = Choose_Attribute(node); //选择属性
        attr[attribute_no] = 0;//属性已选 
        set<int> obj_for_attr[6];
        for(set<int>::iterator it = node->obj.begin(); it != node->obj.end(); ++it){
            for(int i=0;i<6;i++){
                obj_for_attr[object[(*it)][attribute_no]].insert((*it));//对于某属性的不同值的对象分类 
             }
         }
         for(int i=0;i<6;i++){//对于每一种分类,创建子节点
            if(obj_for_attr[i].size()!=0){ //有效分类 
                Node *childnode =new Node();
                childnode->judge_attr_value = i; //节点接受的属性值 
                //赋值 
                childnode->obj = obj_for_attr[i];
                childnode->judge_attr_no = attribute_no;
                for(int j=0;j<8;j++) childnode->attr[j] = attr[j];
                //添加到父节点  递归 
                node->child.push_back(childnode);
                node_for_each(childnode);   
             }      
         }   
    }    
} 
void printTree(Node *node){//打印树 
    cout<<"节点判断属性:"<<node->judge_attr_no<<"  属性值:"<<node->judge_attr_value<<"  属性个数:"<<node->child.size()<<endl;    
    for(int i=0;i<node->child.size();i++){
        Node *p = node->child[i];
        cout<<"-->"<<"子节点判断属性:"<<p->judge_attr_no<<"  属性值:"<<p->judge_attr_value<<"  结果:"<<p->child.size()<<endl;
    }
    cout<<"_____________________________________________________________________________\n";
    for(int i=0;i<node->child.size();i++){
        Node *p = node->child[i];
        printTree(p);
    }
}
int judge(Node *node,int size){//判断 
    Node *p = node;
    int result;
    int fz;
    for(int i=0;i<size;i++){//test集 
        p = node; 
        while(p->flag!=1){
            fz = p->child.size();
            for(int j=0;j<fz;j++){//对于每个分支 
                Node *childp = p->child[j];//选择子节点 
                if(childp->judge_attr_value == test[i][childp->judge_attr_no]){
                    p=childp;
                    break;
                } 
            }
        }
        result = p->final;
        cout<<result<<" ";
    }
}
int main(){
    input();
    prepare();
    node_for_each(&root);
    //printTree(&root);
    inputTest();
    judge(&root,test_size);
}

sample.txt:

27

1     2    1       1       2       1      1     2      2 
1     2    1       1       2       2      2     2      1 
2     1    4       1       2       1      2     2      1  
2     1    1       1       1       2      2     2      2 
1     2    1       1       1       2      2     2      2     
1     2    1       1       2       1      2     1      1      
2     1    2       1       1       2      1     1      2      
2     1    1       1       2       1      1     2      1      
2     1    3       1       2       2      1     2      1      
2     1    2       2       2       1      2     2      2      
2     2    1       2       2       2      2     1      1      
2     1    2       2       1       1      2     1      1      
2     2    1       2       1       2      2     1      2      
1     1    1       2       1       2      2     2      1      
3     2    1       2       1       1      1     2      2  
1     1    1       2       1       1      1     2      1  
1     1    3       2       2       2      1     2      1  
3     1    2       2       1       2      2     2      1  
3     2    3       3       1       1      1     2      1  
3     2    2       3       1       2      1     1      2
3     1    3       3       1       1      2     2      1  
3     2    1       3       1       2      1     2      2  
3     2    1       3       1       1      1     1      1  
3     1    1       3       1       2      1     1      2  
3     1    3       3       1       2      2     2      2  
3     2    4       3       1       2      2     1      1  
3     1    3       3       2       2      1     1      2

test.txt:

37
1     2    1       1       2       1      1     2       
1     2    1       1       2       2      2     2       
2     1    4       1       2       1      2     2        
2     1    1       1       1       2      2     2       
1     2    1       1       1       2      2     2           
1     2    1       1       2       1      2     1            
2     1    2       1       1       2      1     1            
2     1    1       1       2       1      1     2            
2     1    3       1       2       2      1     2            
2     1    2       2       2       1      2     2            
2     2    1       2       2       2      2     1            
2     1    2       2       1       1      2     1            
2     2    1       2       1       2      2     1            
1     1    1       2       1       2      2     2            
3     2    1       2       1       1      1     2       
1     1    1       2       1       1      1     2        
1     1    3       2       2       2      1     2        
3     1    2       2       1       2      2     2        
3     2    3       3       1       1      1     2        
3     2    2       3       1       2      1     1      
3     1    3       3       1       1      2     2        
3     2    1       3       1       2      1     2        
3     2    1       3       1       1      1     1       
3     1    1       3       1       2      1     1        
3     1    3       3       1       2      2     2        
3     2    4       3       1       2      2     1        
3     1    3       3       2       2      1     1      

1     2    1       3       1       2      2     2      
1     2    1       3       2       1      1     1       
1     1    2       3       1       1      2     1       
2     1    4       1       1       2      1     1       
1     1    3       2       1       2      2     2           
1     2    1       1       2       1      1     1           
2     2    2       2       1       2      1     1           
1     1    1       1       1       1      1     1            
2     1    3       3       2       2      1     2           
1     1    2       2       2       1      2     2        

此为记录实验用

0
0
查看评论
发表评论
* 以上用户言论只代表其个人观点,不代表CSDN网站的观点或立场

决策树——ID3算法的java实现

所谓决策树就是用树来帮助我们做决策,从树的根节点开始一级一级的访问节点,直到叶子节点,也就完成了决策的过程。 决策树算法是描述用已知的样本来构建决策树的过程,这边用比较经典的“气候—玩”的例子来说明...
  • cq1982
  • cq1982
  • 2015-03-25 16:24
  • 4604

《机器学习实战》基于信息论的三种决策树算法(ID3,C4.5,CART)

决策树是通过一系列规则对数据进行分类的过程,他提供一种在什么条件下会得到什么值的类似规则方法,决策树分为分类树和回归树,分类树对离散变量最决策树,回归树对连续变量做决策树如果不考虑效率等,那么样本所有...
  • Gamer_gyt
  • Gamer_gyt
  • 2016-04-26 11:50
  • 7281

机器学习算法之决策树算法

该节主要是把《机器学习实战》书上第三章关于决策树的相关代码照样子实现了一遍。对其中一些内容作了些补充,对比ID3与C45区别,同时下载了一个大样本集实验决策树的准确率。首先,对于决策树的原理,很多很好...
  • on2way
  • on2way
  • 2015-07-31 20:47
  • 2853

0/1背包算法与决策树ID3算法实现

  • 2014-08-04 17:02
  • 420KB
  • 下载

人工智能实验 ID3决策树(java实现)

  • 2017-11-12 11:28
  • 242KB
  • 下载

决策树1 -- ID3_C4.5算法

声明:          1,本篇为个人对《2012.李航.统计学习方法.pdf》的学习总结,不得用作商用,欢迎转载,但请注明出处(即:本帖地址)。       ...
  • xueyingxue001
  • xueyingxue001
  • 2016-02-19 16:03
  • 1013

论文笔记1《基于ID3决策树改进算法的客户流失预测分析》

《计算机科学》 2010年 部分摘要:指出了该算法的取指偏向性以及运算效率不高等缺点,在此基础上提出了改进的ID3算法,该算法通过引入先验知识度参数,有效克服ID3算法中的取值偏向性和运算效率不高等问...
  • Txiaomiao
  • Txiaomiao
  • 2015-12-08 15:45
  • 699

机器学习实战之决策树(1)---ID3算法与信息熵,基尼不纯度

(1)关于ID3算法百度文库有一篇十分详细的文章,介绍看一个例子,给出了具体的计算过程。 文章链接:http://wenku.baidu.com/view/7933c2f6f61fb7360b4...
  • promise_LOVE
  • promise_LOVE
  • 2015-06-17 10:39
  • 1376

机器学习实战之决策树(1)---ID3算法与信息熵,基尼不纯度

关于ID3算法百度文库有一篇十分详细的文章,介绍看一个例子,给出了具体的计算过程。 文章链接:http://wenku.baidu.com/view/7933c2f6f61fb7360b4c65fd....
  • chchlh
  • chchlh
  • 2014-12-02 11:26
  • 2539

机器学习实战之决策树(1)---ID3算法与信息熵,基尼不纯度

机器学习实战之决策树(1)---ID3算法与信息熵,基尼不纯度 2014-12-2阅读552 评论0 (1)关于ID3算法百度文库有一篇十分详细的文章,介绍看一个例子,给出...
  • xinsuixiaofeiyu
  • xinsuixiaofeiyu
  • 2015-07-07 16:10
  • 1773
    个人资料
    • 访问:1934次
    • 积分:117
    • 等级:
    • 排名:千里之外
    • 原创:10篇
    • 转载:1篇
    • 译文:0篇
    • 评论:0条
    文章分类