Decision tree ID3

本文详细解析了ID3决策树算法过程,并提供了C++代码实现。包括算法逻辑、信息增益计算、属性选择等关键步骤。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

决策树的id3算法是之前学机器学习的一个作业,今天拿出来复习了一遍,想了想,贴到博客里共享吧

先把id3算法的过程贴出来

[html]  view plain copy
  1. ID3(Examples, Target_attributes, Attributes)  
  2. Examples are the training examples. Target_attribute is the attribute whose  
  3. value is to be predicted by the tree. Attributes is a list of other attributes that  
  4. may be tested by the learned decision tree. Returns a decision tree that correctly  
  5. classifies the given Examples.  
  6. Create a Root node for the tree  
  7. If all Examples are positive, Return the single‐node tree Root, with label = +  
  8. If all Examples are negative, Return the single‐node tree Root, with label = ‐  
  9. If Attributes is empty, Return the single‐node tree Root, with label = most  
  10. common value of Target_attribute in Examples  
  11. Otherwise Begin  
  12.    A ← the attribute from Attributes that best classifies Examples  
  13.     The decision attribute for Root ← A  
  14.    For each possible value, vi, of A                                                          
  15.        Add a new tree branch below Root, corresponding to the test A = vi  
  16.         Let Examplesvi be the subset of Examples that have value vi for A  
  17.         If Examplesvi is empty  
  18.          Then below this new branch add a leaf node with label = most commonvalue of Target_attribute in Examples  
  19.           Else below this new branch add the subtreeID3(Examplesvi, Target_attribute, Attributes ‐ {A})  
  20. End  
  21. Return   
  22. RootNote: The best attribute is the one with highest information gain//信息增益,怎么算,自己查书吧  

作业的元数据是这样的一张图:

下边是用C++写的源代码:

[html]  view plain copy
  1. #include <iostream>  
  2. #include <fstream>  
  3. #include <math.h>  
  4. #include <string>  
  5. using namespace std;  
  6.   
  7. #define ROW 14  
  8. #define COL 5  
  9. #define log2 0.69314718055  
  10.   
  11. typedef struct TNode  
  12. {  
  13.     char data[15];  
  14.     char weight[15];   
  15.     TNode * firstchild,*nextsibling;  
  16. }*tree;  
  17.   
  18. typedef struct LNode  
  19. {  
  20.     char  OutLook[15];  
  21.     char  Temperature[15];  
  22.     char  Humidity[15];  
  23.     char  Wind[15];  
  24.     char  PlayTennis[5];  
  25.   
  26.     LNode *next;  
  27. }*link;  
  28. typedef struct AttrNode  
  29. {  
  30.     char   attributes[15];//属性  
  31.     int    attr_Num;//属性的个数  
  32.   
  33.     AttrNode *next;  
  34. }*Attributes;  
  35.   
  36. char * Examples[ROW][COL] = {//"OverCast","Cool","High","Strong","No",  
  37.                     //  "Rain","Hot","Normal","Strong","Yes",  
  38.                         "Sunny","Hot","High","Weak","No",  
  39.                           "Sunny","Hot","High","Strong","No",  
  40.                           "OverCast","Hot","High","Weak","Yes",  
  41.                           "Rain","Mild","High","Weak","Yes",  
  42.                         "Rain","Cool","Normal","Weak","Yes",  
  43.                         "Rain","Cool","Normal","Strong","No",  
  44.                         "OverCast","Cool","Normal","Strong","Yes",  
  45.                         "Sunny","Mild","High","Weak","No",  
  46.                         "Sunny","Cool","Normal","Weak","Yes",  
  47.                         "Rain","Mild","Normal","Weak","Yes",  
  48.                         "Sunny","Mild","Normal","Strong","Yes",  
  49.                         "OverCast","Mild","Normal","Strong","Yes",  
  50.                         "OverCast","Hot","Normal","Weak","Yes",  
  51.                         "Rain","Mild","High","Strong","No"  
  52.                         };  
  53. char * Attributes_kind[4] = {"OutLook","Temperature","Humidity","Wind"};  
  54. int    Attr_kind[4] = {3,3,2,2};  
  55.   
  56. char * OutLook_kind[3] = {"Sunny","OverCast","Rain"};  
  57. char * Temperature_kind[3] = {"Hot","Mild","Cool"};  
  58. char * Humidity_kind[2] = {"High","Normal"};  
  59. char * Wind_kind[2] = {"Weak","Strong"};  
  60.   
  61. /*int i_Exampple[14][5] = {0,0,0,0,1,  
  62.                         0,0,0,1,1,  
  63.                         1,0,0,1,0,  
  64.                         2,1,0,0,0,  
  65.                         2,2,1,0,0,  
  66.                         2,2,1,1,1,  
  67.                         1,2,1,1,0,  
  68.                         0,1,0,0,1,  
  69.                         0,2,1,0,0,  
  70.                         2,1,1,0,0,  
  71.                         0,1,1,1,0,  
  72.                         1,1,1,1,0,  
  73.                         1,1,1,0,0,  
  74.                         2,1,0,0,1  
  75.                         };*/  
  76. void treelists(tree T);  
  77. void InitAttr(Attributes &attr_link,char * Attributes_kind[],int Attr_kind[]);  
  78. void InitLink(link &L,char * Examples[][COL]);  
  79. void ID3(tree &T,link L,link Target_Attr,Attributes attr);  
  80. void PN_Num(link L,int &positve,int &negative);  
  81. double Gain(int positive,int negative,char * atrribute,link L,Attributes attr_L);  
  82.   
  83. void main()  
  84. {  
  85.     link LL,p;  
  86.     Attributes attr_L,q;  
  87.   
  88.     tree T;  
  89.     T = new TNode;  
  90.     T->firstchild = T->nextsibling = NULL;  
  91.     strcpy(T->weight,"");  
  92.     strcpy(T->data,"");  
  93.   
  94.     attr_L = new AttrNode;  
  95.     attr_L->next = NULL;  
  96.   
  97.     LL = new LNode;  
  98.     LL->next = NULL;  
  99.   
  100.     //成功建立两个链表  
  101.     InitLink(LL,Examples);  
  102.     InitAttr(attr_L,Attributes_kind,Attr_kind);  
  103.   
  104.     ID3(T,LL,NULL,attr_L);  
  105.   
  106.     cout<<"决策树以广义表形式输出如下:"<<endl;  
  107.     treelists(T);//以广义表的形式输出树  
  108. //  cout<<Gain(9,5,"OutLook",LL,attr_L)<<endl;  
  109.   
  110.     cout<<endl;  
  111. }  
  112.   
  113. //以广义表的形式输出树  
  114. void treelists(tree T)  
  115. {  
  116.     tree p;  
  117.   
  118.     if(!T)  
  119.         return;  
  120.     cout<<"{"<<T->weight<<"}";  
  121.     cout<<T->data;  
  122.   
  123.     p = T->firstchild;  
  124.     if (p)  
  125.     {  
  126.         cout<<"(";  
  127.         while (p)  
  128.         {  
  129.             treelists(p);  
  130.             p = p->nextsibling;  
  131.             if (p)cout<<',';  
  132.         }  
  133.         cout<<")";  
  134.     }  
  135. }  
  136. void InitAttr(Attributes &attr_link,char * Attributes_kind[],int Attr_kind[])  
  137. {  
  138.     Attributes p;  
  139.   
  140.     for (int i =0;i < 4;i++)  
  141.     {  
  142.         p = new AttrNode;  
  143.         p->next = NULL;  
  144.           
  145.         strcpy(p->attributes,Attributes_kind[i]);  
  146.         p->attr_Num = Attr_kind[i];  
  147.   
  148.         p->next = attr_link->next;  
  149.         attr_link->next = p;  
  150.     }  
  151. }  
  152. void InitLink(link &LL,char * Examples[][COL])  
  153. {  
  154.     link p;   
  155.   
  156.     for (int i = 0;i < ROW;i++)  
  157.     {  
  158.         p = new LNode;  
  159.         p->next = NULL;  
  160.   
  161.         strcpy(p->OutLook,Examples[i][0]);  
  162.         strcpy(p->Temperature,Examples[i][1]);  
  163.         strcpy(p->Humidity,Examples[i][2]);  
  164.         strcpy(p->Wind,Examples[i][3]);  
  165.         strcpy(p->PlayTennis,Examples[i][4]);  
  166.   
  167.         p->next = LL->next;  
  168.         LL->next = p;      
  169.     }  
  170. }  
  171. void PN_Num(link L,int &positve,int &negative)  
  172. {  
  173.     positve = 0;  
  174.     negative = 0;  
  175.     link p;  
  176.       
  177.     p = L->next;  
  178.     while (p)  
  179.     {  
  180.         if (strcmp(p->PlayTennis,"No") == 0)  
  181.             negative++;  
  182.         else if(strcmp(p->PlayTennis,"Yes") == 0)  
  183.             positve++;  
  184.   
  185.         p = p->next;  
  186.     }         
  187. }  
  188.   
  189. //计算信息增益  
  190. //link L: 样本集合S  
  191. //attr_L:属性集合  
  192. double Gain(int positive,int negative,char * atrribute,link L,Attributes attr_L)  
  193. {  
  194.     int atrr_kinds;//每个属性中的值的个数  
  195.   
  196.     Attributes p = attr_L->next;  
  197.     link q = L->next;  
  198.   
  199.     int attr_th = 0;//第几个属性  
  200.     while (p)  
  201.     {  
  202.         if (strcmp(p->attributes,atrribute) == 0)  
  203.         {  
  204.             atrr_kinds = p->attr_Num;          
  205.             break;  
  206.         }  
  207.         p = p->next;  
  208.         attr_th++;  
  209.     }  
  210.   
  211.     double entropy,gain=0;  
  212.   
  213.     double p1 = 1.0*positive/(positive + negative);  
  214.     double p2 = 1.0*negative/(positive + negative);  
  215.   
  216.     entropy = -p1*log(p1)/log2 - p2*log(p2)/log2;//集合熵  
  217.     gain = entropy;  
  218.   
  219.     //获取每个属性值在训练样本中出现的个数  
  220.     //获取每个属性值所对应的正例和反例的个数  
  221.       
  222.     //声明一个3*atrr_kinds的数组  
  223.     int ** kindsnew int * [3];  
  224.     for (int j =0;j < 3;j++)  
  225.     {  
  226.         kinds[j] = new int[atrr_kinds];//保存每个属性值在训练样本中出现的个数  
  227.     }  
  228.   
  229.     //初始化  
  230.     for (j = 0;j< 3;j++)  
  231.     {  
  232.         for (int i =0;i < atrr_kinds;i++)  
  233.         {  
  234.             kinds[j][i] = 0;  
  235.         }  
  236.     }  
  237.     while (q)  
  238.     {  
  239.         if (strcmp("OutLook",atrribute) == 0)  
  240.         {  
  241.             for (int i = 0;i < atrr_kinds;i++)  
  242.             {  
  243.                 if(strcmp(q->OutLook,OutLook_kind[i]) == 0)  
  244.                 {  
  245.                     kinds[0][i]++;  
  246.   
  247.                     if(strcmp(q->PlayTennis,"Yes") == 0)  
  248.                         kinds[1][i]++;  
  249.                     else  
  250.                         kinds[2][i]++;  
  251.                 }  
  252.             }  
  253.         }  
  254.         else if (strcmp("Temperature",atrribute) == 0)  
  255.         {  
  256.             for (int i = 0;i < atrr_kinds;i++)  
  257.             {  
  258.                 if(strcmp(q->Temperature,Temperature_kind[i]) == 0)  
  259.                 {  
  260.                     kinds[0][i]++;  
  261.   
  262.                     if(strcmp(q->PlayTennis,"Yes") == 0)  
  263.                         kinds[1][i]++;  
  264.                     else  
  265.                         kinds[2][i]++;  
  266.                 }  
  267.             }  
  268.         }  
  269.         else if (strcmp("Humidity",atrribute) == 0)  
  270.         {  
  271.             for (int i = 0;i < atrr_kinds;i++)  
  272.             {  
  273.                 if(strcmp(q->Humidity,Humidity_kind[i]) == 0)  
  274.                 {  
  275.                     kinds[0][i]++;  
  276.   
  277.                     if(strcmp(q->PlayTennis,"Yes") == 0)  
  278.                         kinds[1][i]++;//   
  279.                     else  
  280.                         kinds[2][i]++;  
  281.                 }  
  282.             }  
  283.         }  
  284.         else if (strcmp("Wind",atrribute) == 0)  
  285.         {  
  286.             for (int i = 0;i < atrr_kinds;i++)  
  287.             {  
  288.                 if(strcmp(q->Wind,Wind_kind[i]) == 0)  
  289.                 {  
  290.                     kinds[0][i]++;  
  291.   
  292.                     if(strcmp(q->PlayTennis,"Yes") == 0)  
  293.                         kinds[1][i]++;  
  294.                     else  
  295.                         kinds[2][i]++;  
  296.                 }  
  297.             }  
  298.         }  
  299.         q = q->next;  
  300.     }  
  301.   
  302.     //计算信息增益  
  303.     double * gain_kind = new double[atrr_kinds];  
  304.     int positive_kind = 0,negative_kind = 0;  
  305.   
  306.     for (j = 0;j < atrr_kinds;j++)  
  307.     {  
  308.         if (kinds[0][j] != 0 && kinds[1][j] != 0 && kinds[2][j] != 0)  
  309.         {  
  310.             p1 = 1.0*kinds[1][j]/kinds[0][j];  
  311.             p2 = 1.0*kinds[2][j]/kinds[0][j];  
  312.               
  313.             gain_kind[j] = -p1*log(p1)/log2-p2*log(p2)/log2;  
  314.               
  315.             gain = gain - (1.0*kinds[0][j]/(positive + negative))*gain_kind[j];  
  316.         }  
  317.         else  
  318.             gain_kind[j] = 0;  
  319.     }  
  320.     return gain;  
  321. }  
  322.   
  323. //在ID3算法中的训练样本子集合与属性子集合的链表需要进行清空  
  324. void FreeLink(link &Link)  
  325. {  
  326.     link p,q;  
  327.       
  328.     p = Link->next;  
  329.       
  330.     Link->next = NULL;  
  331.     while (p)  
  332.     {  
  333.         q = p;  
  334.         p = p->next;  
  335.         free(q);  
  336.     }  
  337. }  
  338. void ID3(tree &T,link L,link Target_Attr,Attributes attr)  
  339. {  
  340.     Attributes p,max,attr_child,p1;  
  341.     link q,link_child,q1;  
  342.     tree r,tree_p;  
  343.       
  344.     int positive =0,negative =0;  
  345.   
  346.     PN_Num(L,positive,negative);  
  347.   
  348.     //初始化两个子集合  
  349.     attr_child = new AttrNode;  
  350.     attr_child->next = NULL;  
  351.   
  352.     link_child = new LNode;  
  353.     link_child->next = NULL;  
  354.   
  355.     if (positive == 0)//全是反例  
  356.     {  
  357.         strcpy(T->data,"No");  
  358.         return;  
  359.     }  
  360.     else if( negative == 0)//全是正例  
  361.     {  
  362.         strcpy(T->data,"Yes");  
  363.         return;  
  364.     }  
  365.       
  366.     p = attr->next; //属性链表  
  367.   
  368.     double gain,g = 0;  
  369.   
  370.     /************************************************************************/  
  371.     /* 建立属性子集合与训练样本子集合有两个方案:  
  372.         一:在原来链表的基础上进行删除;  
  373.         二:另外申请空间进行存储子集合;  
  374.         采用第二种方法虽然浪费了空间,但也省了很多事情,避免了变量之间的应用混乱  
  375.     */  
  376.     /************************************************************************/  
  377.   
  378.     if(p)  
  379.     {  
  380.         while (p)  
  381.         {  
  382.             gain = Gain(positive,negative,p->attributes,L,attr);  
  383.             cout<<p->attributes<<"  "<<gain<<endl;  
  384.             if(gain > g)  
  385.             {  
  386.                 g = gain;  
  387.                 max = p;//寻找信息增益最大的属性  
  388.             }  
  389.             p = p->next;  
  390.         }  
  391.         strcpy(T->data,max->attributes);//增加决策树的节点  
  392.           
  393.         cout<<"信息增益最大的属性:max->attributes = "<<max->attributes<<endl<<endl;  
  394.         //下面开始建立决策树  
  395.   
  396.         //创建属性子集合  
  397.         p = attr->next;  
  398.         while (p)  
  399.         {  
  400.             if (strcmp(p->attributes,max->attributes) != 0)  
  401.             {  
  402.                 p1 = new AttrNode;  
  403.                 strcpy(p1->attributes,p->attributes);  
  404.                 p1->attr_Num = p->attr_Num;  
  405.                 p1->next = NULL;  
  406.   
  407.                 p1->next = attr_child->next;  
  408.                 attr_child->next = p1;         
  409.             }  
  410.             p = p->next;  
  411.         }  
  412.           
  413.         //需要区分出是哪一种属性  
  414.         //建立每一层的第一个节点  
  415.         if (strcmp("OutLook",max->attributes) == 0)  
  416.         {  
  417.             r = new TNode;  
  418.             r->firstchild = r->nextsibling = NULL;  
  419.             strcpy(r->weight,OutLook_kind[0]);  
  420.             T->firstchild = r;  
  421.             //获取与属性值相关的训练样例Example(vi),建立一个新的训练样本链表link_child  
  422.             q = L->next;  
  423.             while (q)  
  424.             {  
  425.                 if (strcmp(q->OutLook,OutLook_kind[0]) == 0)  
  426.                 {  
  427.                     q1 = new LNode;  
  428.                     strcpy(q1->OutLook,q->OutLook);  
  429.                     strcpy(q1->Humidity,q->Humidity);  
  430.                     strcpy(q1->Temperature,q->Temperature);  
  431.                     strcpy(q1->Wind,q->Wind);  
  432.                     strcpy(q1->PlayTennis,q->PlayTennis);  
  433.                     q1->next = NULL;  
  434.                       
  435.                     q1->next = link_child->next;  
  436.                     link_child->next = q1;  
  437.                 }  
  438.                 q = q->next;  
  439.             }  
  440.         }  
  441.         else if (strcmp("Temperature",max->attributes) == 0)  
  442.         {  
  443.             r = new TNode;  
  444.             r->firstchild = r->nextsibling = NULL;  
  445.             strcpy(r->weight,Temperature_kind[0]);  
  446.             T->firstchild = r;  
  447.             //获取与属性值相关的训练样例Example(vi),建立一个新的训练样本链表link_child  
  448.             q = L->next;  
  449.             while (q)  
  450.             {  
  451.                 if (strcmp(q->Temperature,Temperature_kind[0]) == 0)  
  452.                 {  
  453.                     q1 = new LNode;  
  454.                     strcpy(q1->OutLook,q->OutLook);  
  455.                     strcpy(q1->Humidity,q->Humidity);  
  456.                     strcpy(q1->Temperature,q->Temperature);  
  457.                     strcpy(q1->Wind,q->Wind);  
  458.                     strcpy(q1->PlayTennis,q->PlayTennis);  
  459.                     q1->next = NULL;  
  460.                       
  461.                     q1->next = link_child->next;  
  462.                     link_child->next = q1;  
  463.                 }  
  464.                 q = q->next;  
  465.             }  
  466.         }  
  467.         else if (strcmp("Humidity",max->attributes) == 0)  
  468.         {  
  469.             r = new TNode;  
  470.             r->firstchild = r->nextsibling = NULL;  
  471.             strcpy(r->weight,Humidity_kind[0]);  
  472.             T->firstchild = r;  
  473.             //获取与属性值相关的训练样例Example(vi),建立一个新的训练样本链表link_child  
  474.             q = L->next;  
  475.             while (q)  
  476.             {  
  477.                 if (strcmp(q->Humidity,Humidity_kind[0]) == 0)  
  478.                 {  
  479.                     q1 = new LNode;  
  480.                     strcpy(q1->OutLook,q->OutLook);  
  481.                     strcpy(q1->Humidity,q->Humidity);  
  482.                     strcpy(q1->Temperature,q->Temperature);  
  483.                     strcpy(q1->Wind,q->Wind);  
  484.                     strcpy(q1->PlayTennis,q->PlayTennis);  
  485.                     q1->next = NULL;  
  486.                       
  487.                     q1->next = link_child->next;  
  488.                     link_child->next = q1;  
  489.                 }  
  490.                 q = q->next;  
  491.             }  
  492.         }  
  493.         else if (strcmp("Wind",max->attributes) == 0)  
  494.         {  
  495.             r = new TNode;  
  496.             r->firstchild = r->nextsibling = NULL;  
  497.             strcpy(r->weight,Wind_kind[0]);  
  498.   
  499.             T->firstchild = r;  
  500.             //获取与属性值相关的训练样例Example(vi),建立一个新的训练样本链表link_child  
  501.             q = L->next;  
  502.             while (q)  
  503.             {  
  504.                 if (strcmp(q->Wind,Wind_kind[0]) == 0)  
  505.                 {  
  506.                     q1 = new LNode;  
  507.                     strcpy(q1->OutLook,q->OutLook);  
  508.                     strcpy(q1->Humidity,q->Humidity);  
  509.                     strcpy(q1->Temperature,q->Temperature);  
  510.                     strcpy(q1->Wind,q->Wind);  
  511.                     strcpy(q1->PlayTennis,q->PlayTennis);  
  512.                     q1->next = NULL;  
  513.                       
  514.                     q1->next = link_child->next;  
  515.                     link_child->next = q1;  
  516.                 }  
  517.                 q = q->next;  
  518.             }  
  519.         }  
  520.   
  521.         int p = 0,n = 0;  
  522.         PN_Num(link_child,p,n);  
  523.         if (p != 0 && n != 0)  
  524.         {  
  525.             ID3(T->firstchild,link_child,Target_Attr,attr_child);  
  526.             FreeLink(link_child);  
  527.         }  
  528.         else if(p == 0)  
  529.         {  
  530.             strcpy(T->firstchild->data,"No");  
  531.             FreeLink(link_child);  
  532.             //  strcpy(T->firstchild->data,q1->PlayTennis);//----此处应该需要修改----:)  
  533.         }  
  534.         else if(n == 0)  
  535.         {  
  536.             strcpy(T->firstchild->data,"Yes");  
  537.             FreeLink(link_child);  
  538.         }  
  539.   
  540.         //建立每一层上的其他节点  
  541.         tree_p = T->firstchild;  
  542.         for (int i = 1;i < max->attr_Num;i++)  
  543.         {  
  544.             //需要区分出是哪一种属性  
  545.             if (strcmp("OutLook",max->attributes) == 0)  
  546.             {  
  547.                 r = new TNode;  
  548.                 r->firstchild = r->nextsibling = NULL;  
  549.                 strcpy(r->weight,OutLook_kind[i]);  
  550.                 tree_p->nextsibling = r;  
  551.                 //获取与属性值相关的训练样例Example(vi),建立一个新的训练样本链表link_child  
  552.                 q = L->next;  
  553.                 while (q)  
  554.                 {  
  555.                     if (strcmp(q->OutLook,OutLook_kind[i]) == 0)  
  556.                     {  
  557.                         q1 = new LNode;  
  558.                         strcpy(q1->OutLook,q->OutLook);  
  559.                         strcpy(q1->Humidity,q->Humidity);  
  560.                         strcpy(q1->Temperature,q->Temperature);  
  561.                         strcpy(q1->Wind,q->Wind);  
  562.                         strcpy(q1->PlayTennis,q->PlayTennis);  
  563.                         q1->next = NULL;  
  564.   
  565.                         q1->next = link_child->next;  
  566.                         link_child->next = q1;  
  567.                     }  
  568.                     q = q->next;  
  569.                 }  
  570.             }  
  571.             else if (strcmp("Temperature",max->attributes) == 0)  
  572.             {  
  573.                 r = new TNode;  
  574.                 r->firstchild = r->nextsibling = NULL;  
  575.                 strcpy(r->weight,Temperature_kind[i]);  
  576.                 tree_p->nextsibling = r;  
  577.                 //获取与属性值相关的训练样例Example(vi),建立一个新的训练样本链表link_child  
  578.                 q = L->next;  
  579.                 while (q)  
  580.                 {  
  581.                     if (strcmp(q->Temperature,Temperature_kind[i]) == 0)  
  582.                     {  
  583.                         q1 = new LNode;  
  584.                         strcpy(q1->OutLook,q->OutLook);  
  585.                         strcpy(q1->Humidity,q->Humidity);  
  586.                         strcpy(q1->Temperature,q->Temperature);  
  587.                         strcpy(q1->Wind,q->Wind);  
  588.                         strcpy(q1->PlayTennis,q->PlayTennis);  
  589.                         q1->next = NULL;  
  590.                           
  591.                         q1->next = link_child->next;  
  592.                         link_child->next = q1;  
  593.                     }  
  594.                     q = q->next;  
  595.                 }  
  596.                   
  597.             }  
  598.             else if (strcmp("Humidity",max->attributes) == 0)  
  599.             {  
  600.                 r = new TNode;  
  601.                 r->firstchild = r->nextsibling = NULL;  
  602.                 strcpy(r->weight,Humidity_kind[i]);  
  603.                 tree_p->nextsibling = r;  
  604.                 //获取与属性值相关的训练样例Example(vi),建立一个新的训练样本链表link_child  
  605.                 q = L->next;  
  606.                 while (q)  
  607.                 {  
  608.                     if (strcmp(q->Humidity,Humidity_kind[i]) == 0)  
  609.                     {  
  610.                         q1 = new LNode;  
  611.                         strcpy(q1->OutLook,q->OutLook);  
  612.                         strcpy(q1->Humidity,q->Humidity);  
  613.                         strcpy(q1->Temperature,q->Temperature);  
  614.                         strcpy(q1->Wind,q->Wind);  
  615.                         strcpy(q1->PlayTennis,q->PlayTennis);  
  616.                         q1->next = NULL;  
  617.                           
  618.                         q1->next = link_child->next;  
  619.                         link_child->next = q1;  
  620.                     }  
  621.                     q = q->next;  
  622.                 }  
  623.             }  
  624.             else if (strcmp("Wind",max->attributes) == 0)  
  625.             {  
  626.                 r = new TNode;  
  627.                 r->firstchild = r->nextsibling = NULL;  
  628.                 strcpy(r->weight,Wind_kind[i]);  
  629.                 tree_p->nextsibling = r;  
  630.                 //获取与属性值相关的训练样例Example(vi),建立一个新的训练样本链表link_child  
  631.                 q = L->next;  
  632.                 while (q)  
  633.                 {  
  634.                     if (strcmp(q->Wind,Wind_kind[i]) == 0)  
  635.                     {  
  636.                         q1 = new LNode;  
  637.                         strcpy(q1->OutLook,q->OutLook);  
  638.                         strcpy(q1->Humidity,q->Humidity);  
  639.                         strcpy(q1->Temperature,q->Temperature);  
  640.                         strcpy(q1->Wind,q->Wind);  
  641.                         strcpy(q1->PlayTennis,q->PlayTennis);  
  642.                         q1->next = NULL;  
  643.                           
  644.                         q1->next = link_child->next;  
  645.                         link_child->next = q1;  
  646.                     }  
  647.                     q = q->next;  
  648.                 }  
  649.             }  
  650.             int p = 0,n = 0;  
  651.             PN_Num(link_child,p,n);  
  652.             if (p != 0 && n != 0)  
  653.             {  
  654.                 ID3(tree_p->nextsibling,link_child,Target_Attr,attr_child);  
  655.                 FreeLink(link_child);  
  656.             }  
  657.             else if(p == 0)  
  658.             {  
  659.                 strcpy(tree_p->nextsibling->data,"No");  
  660.                 FreeLink(link_child);  
  661.             }  
  662.             else if(n == 0)  
  663.             {  
  664.                 strcpy(tree_p->nextsibling->data,"Yes");  
  665.                 FreeLink(link_child);  
  666.             }  
  667.   
  668.             tree_p = tree_p->nextsibling;//建立所有的孩子结点  
  669.         }//建立决策树结束  
  670.     }  
  671.     else  
  672.     {  
  673.         q = L->next;  
  674.         strcpy(T->data,q->PlayTennis);  
  675.         return;//这个地方要赋以训练样本Example中最普遍的Target_attributes的值  
  676.     }  
  677. }  
来自:http://blog.youkuaiyun.com/cxf7394373/article/details/6665968
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值