原文:

http://blog.csdn.net/acdreamers/article/details/44661149

今天,我来讲解的是决策树。对于决策树来说,主要有两种算法:ID3算法C4.5算法。C4.5算法是

对ID3算法的改进。今天主要先讲ID3算法,之后会讲C4.5算法随机森林等。

Contents

     1. 决策树的基本认识

     2. ID3算法介绍

     3. 信息熵与信息增益

     4. ID3算法的C++实现

1. 决策树的基本认识

   决策树是一种依托决策而建立起来的一种树。在机器学习中,决策树是一种预测模型,代表的是一种对

象属性与对象值之间的一种映射关系,每一个节点代表某个对象,树中的每一个分叉路径代表某个可能

的属性值,而每一个叶子节点则对应从根节点到该叶子节点所经历的路径所表示的对象的值。决策树仅

有单一输出,如果有多个输出,可以分别建立独立的决策树以处理不同的输出。接下来讲解ID3算法。

2. ID3算法介绍

ID3算法是决策树的一种,它是基于奥卡姆剃刀原理的,即用尽量用较少的东西做更多的事。ID3算法

Iterative Dichotomiser 3迭代二叉树3代,是Ross Quinlan发明的一种决策树算法,这个

算法的基础就是上面提到的奥卡姆剃刀原理,越是小型的决策树越优于大的决策树,尽管如此,也不总

是生成最小的树型结构,而是一个启发式算法。

在信息论中,期望信息越小,那么信息增益就越大,从而纯度就越高。ID3算法的核心思想就是以信息

增益来度量属性的选择,选择分裂后信息增益最大的属性进行分裂。该算法采用自顶向下的贪婪搜索遍

历可能的决策空间。

3. 信息熵与信息增益

在信息增益中,重要性的衡量标准就是看特征能够为分类系统带来多少信息,带来的信息越多,该特征越

重要。在认识信息增益之前,先来看看信息熵的定义

这个概念最早起源于物理学,在物理学中是用来度量一个热力学系统的无序程度,而在信息学里面,熵

是对不确定性的度量。在1948年,香农引入了信息熵,将其定义为离散随机事件出现的概率,一个系统越

是有序,信息熵就越低,反之一个系统越是混乱,它的信息熵就越高。所以信息熵可以被认为是系统有序

化程度的一个度量。

假如一个随机变量的取值为,每一种取到的概率分别是,那么

的熵定义为

意思是一个变量的变化情况可能越多,那么它携带的信息量就越大。

对于分类系统来说,类别是变量,它的取值是,而每一个类别出现的概率分别是

而这里的就是类别的总数,此时分类系统的熵就可以表示为

以上就是信息熵的定义,接下来介绍信息增益

信息增益是针对一个一个特征而言的,就是看一个特征,系统有它和没有它时的信息量各是多少,两者

的差值就是这个特征给系统带来的信息量,即信息增益

接下来以天气预报的例子来说明。下面是描述天气数据表,学习目标是play或者not play

可以看出,一共14个样例,包括9个正例和5个负例。那么当前信息的熵计算如下

在决策树分类问题中,信息增益就是决策树在进行属性选择划分前和划分后信息的差值。假设利用

属性Outlook来分类,那么如下图

划分后,数据被分为三部分了,那么各个分支的信息熵计算如下

那么划分后的信息熵为

代表在特征属性的条件下样本的条件熵。那么最终得到特征属性带来的信息增益为

 信息增益的计算公式如下

其中为全部样本集合,是属性所有取值的集合,的其中一个属性值,中属性

值为的样例集合,中所含样例数。

在决策树的每一个非叶子结点划分之前,先计算每一个属性所带来的信息增益,选择最大信息增益的属性来划

分,因为信息增益越大,区分样本的能力就越强,越具有代表性,很显然这是一种自顶向下的贪心策略。以上

就是ID3算法的核心思想。

4. ID3算法的C++实现

接下来开始用C++实现ID3算法,包括以下文件

ID3.h

[cpp] view plaincopy print?
  1. #ifndef _ID3_H_
  2. #define _ID3_H_
  3. #include <utility>
  4. #include <list>
  5. #include <map>
  6. #define Type int   //样本数据类型
  7. #define   Map1        std::map< int, Type >    //定义一维map
  8. #define   Map2        std::map< int, Map1 >    //定义二维map
  9. #define   Map3        std::map< int, Map2 >    //定义三维map
  10. #define   Pair        std::pair<int, Type>
  11. #define   List        std::list< Pair >        //一维list
  12. #define   SampleSpace std::list< List >        //二维list 用于存放样本数据
  13. #define   Child       std::map< int, Node* >   //定义后继节点集合
  14. #define   CI          const_iterator
  15. /*
  16. *   在ID3算法中,用二维链表存放样本,结构为list< list< pair<int, int> > >,简记为SampleSpace,取名样本空间
  17. *   样本数据从根节点开始往下遍历。每一个节点的定义如下结构体
  18. */
  19. struct Node
  20. {
  21. int index;                    //当前节点样本最大增益对应第index个属性,根据这个进行分类的
  22. int type;                     //当前节点的类型
  23. Child next;                   //当前节点的后继节点集合
  24. SampleSpace sample;           //未分类的样本集合
  25. };
  26. class ID3{
  27. public:
  28. ID3(int );
  29. ~ID3();
  30. void PushData(const Type*, const Type);   //将样本数据Push给二维链表
  31. void Build();                             //构建决策树
  32. int  Match(const Type*);                  //根据新的样本预测结果
  33. void Print();                             //打印决策树的节点的值
  34. private:
  35. void   _clear(Node*);
  36. void   _build(Node*, int);
  37. int    _match(const int*, Node*);
  38. void   _work(Node*);
  39. double _entropy(const Map1&, double);
  40. int    _get_max_gain(const SampleSpace&);
  41. void   _split(Node*, int);
  42. void   _get_data(const SampleSpace&, Map1&, Map2&, Map3&);
  43. double _info_gain(Map1&, Map2&, double, double);
  44. int    _same_class(const SampleSpace&);
  45. void   _print(Node*);
  46. private:
  47. int dimension;
  48. Node *root;
  49. };
  50. #endif // _ID3_H_
#ifndef _ID3_H_
#define _ID3_H_#include <utility>
#include <list>
#include <map>#define Type int   //样本数据类型#define   Map1        std::map< int, Type >    //定义一维map
#define   Map2        std::map< int, Map1 >    //定义二维map
#define   Map3        std::map< int, Map2 >    //定义三维map
#define   Pair        std::pair<int, Type>
#define   List        std::list< Pair >        //一维list
#define   SampleSpace std::list< List >        //二维list 用于存放样本数据
#define   Child       std::map< int, Node* >   //定义后继节点集合
#define   CI          const_iterator/**   在ID3算法中,用二维链表存放样本,结构为list< list< pair<int, int> > >,简记为SampleSpace,取名样本空间*   样本数据从根节点开始往下遍历。每一个节点的定义如下结构体*/struct Node
{int index;                    //当前节点样本最大增益对应第index个属性,根据这个进行分类的int type;                     //当前节点的类型Child next;                   //当前节点的后继节点集合SampleSpace sample;           //未分类的样本集合
};class ID3{public:ID3(int );    ~ID3();void PushData(const Type*, const Type);   //将样本数据Push给二维链表void Build();                             //构建决策树int  Match(const Type*);                  //根据新的样本预测结果void Print();                             //打印决策树的节点的值private:void   _clear(Node*);void   _build(Node*, int);int    _match(const int*, Node*);void   _work(Node*);double _entropy(const Map1&, double);int    _get_max_gain(const SampleSpace&);void   _split(Node*, int);void   _get_data(const SampleSpace&, Map1&, Map2&, Map3&);double _info_gain(Map1&, Map2&, double, double);int    _same_class(const SampleSpace&);void   _print(Node*);private:int dimension;Node *root;
};#endif // _ID3_H_

ID3.cpp

[cpp] view plaincopy print?
  1. #include <iostream>
  2. #include <cassert>
  3. #include <cmath>
  4. #include "ID3.h"
  5. using namespace std;
  6. //初始化ID3的数据成员
  7. ID3::ID3(int dimension)
  8. {
  9. this->dimension = dimension;
  10. root = new Node();
  11. root->index = -1;
  12. root->type = -1;
  13. root->next.clear();
  14. root->sample.clear();
  15. }
  16. //清空整个决策树
  17. ID3::~ID3()
  18. {
  19. this->dimension = 0;
  20. _clear(root);
  21. }
  22. //x为dimension维的属性向量,y为向量x对应的值
  23. void ID3::PushData(const Type *x, const Type y)
  24. {
  25. List single;
  26. single.clear();
  27. for(int i = 0; i < dimension; i++)
  28. single.push_back(make_pair(i + 1, x[i]));
  29. single.push_back(make_pair(0, y));
  30. root->sample.push_back(single);
  31. }
  32. void ID3::_clear(Node *node)
  33. {
  34. Child &next = node->next;
  35. Child::iterator it;
  36. for(it = next.begin(); it != next.end(); it++)
  37. _clear(it->second);
  38. next.clear();
  39. delete node;
  40. }
  41. void ID3::Build()
  42. {
  43. _build(root, dimension);
  44. }
  45. void ID3::_build(Node *node, int dimension)
  46. {
  47. //获取当前节点未分类的样本数据
  48. SampleSpace &sample = node->sample;
  49. //判断当前所有样本是否是同一类,如果不是则返回-1
  50. int y = _same_class(sample);
  51. //如果所有样本是属于同一类
  52. if(y >= 0)
  53. {
  54. node->index = -1;
  55. node->type = y;
  56. return;
  57. }
  58. //在_max_gain()函数中计算出当前节点的最大增益对应的属性,并根据这个属性对数据进行划分
  59. _work(node);
  60. //Split完成后清空当前节点的所有数据,以免占用太多内存
  61. sample.clear();
  62. Child &next = node->next;
  63. for(Child::iterator it = next.begin(); it != next.end(); it++)
  64. _build(it->second, dimension - 1);
  65. }
  66. //判断当前所有样本是否是同一类,如果不是则返回-1
  67. int ID3::_same_class(const SampleSpace &ss)
  68. {
  69. //取出当前样本数据的一个Sample
  70. const List &f = ss.front();
  71. //如果没有x属性,而只有y,直接返回y
  72. if(f.size() == 1)
  73. return f.front().second;
  74. Type y = 0;
  75. //取出第一个样本数据y的结果值
  76. for(List::CI it = f.begin(); it != f.end(); it++)
  77. {
  78. if(!it->first)
  79. {
  80. y = it->second;
  81. break;
  82. }
  83. }
  84. //接下来进行判断,因为list是有序的,所以从前往后遍历,发现有一对不一样,则所有样本不是同一类
  85. for(SampleSpace::CI it = ss.begin(); it != ss.end(); it++)
  86. {
  87. const List &single = *it;
  88. for(List::CI i = single.begin(); i != single.end(); i++)
  89. {
  90. if(!i->first)
  91. {
  92. if(y != i->second)
  93. return -1;         //发现不是同一类则返回-1
  94. else
  95. break;
  96. }
  97. }
  98. }
  99. return y;     //比较完所有样本的输出值y后,发现是同一类,返回y值。
  100. }
  101. void ID3::_work(Node *node)
  102. {
  103. int mai = _get_max_gain(node->sample);
  104. assert(mai >= 0);
  105. node->index = mai;
  106. _split(node, mai);
  107. }
  108. //获取最大的信息增益对应的属性
  109. int ID3::_get_max_gain(const SampleSpace &ss)
  110. {
  111. Map1 y;
  112. Map2 x;
  113. Map3 xy;
  114. _get_data(ss, y, x, xy);
  115. double s = ss.size();
  116. double entropy = _entropy(y, s);   //计算熵值
  117. int mai = -1;
  118. double mag = -1;
  119. for(Map2::iterator it = x.begin(); it != x.end(); it++)
  120. {
  121. double g = _info_gain(it->second, xy[it->first], s, entropy);    //计算信息增益值
  122. if(g > mag)
  123. {
  124. mag = g;
  125. mai = it->first;
  126. }
  127. }
  128. if(!x.size() && !xy.size() && y.size())   //如果只有y数据
  129. return 0;
  130. return mai;
  131. }
  132. //获取数据,提取出所有样本的y值,x[]属性值,以及属性值和结果值xy。
  133. void ID3::_get_data(const SampleSpace &ss, Map1 &y, Map2 &x, Map3 &xy)
  134. {
  135. for(SampleSpace::CI it = ss.begin(); it != ss.end(); it++)
  136. {
  137. int c = 0;
  138. const List &v = *it;
  139. for(List::CI p = v.begin(); p != v.end(); p++)
  140. {
  141. if(!p->first)
  142. {
  143. c = p->second;
  144. break;
  145. }
  146. }
  147. ++y[c];
  148. for(List::CI p = v.begin(); p != v.end(); p++)
  149. {
  150. if(p->first)
  151. {
  152. ++x[p->first][p->second];
  153. ++xy[p->first][p->second][c];
  154. }
  155. }
  156. }
  157. }
  158. //计算熵值
  159. double ID3::_entropy(const Map1 &x, double s)
  160. {
  161. double ans = 0;
  162. for(Map1::CI it = x.begin(); it != x.end(); it++)
  163. {
  164. double t = it->second / s;
  165. ans += t * log2(t);
  166. }
  167. return -ans;
  168. }
  169. //计算信息增益
  170. double ID3::_info_gain(Map1 &att_val, Map2 &val_cls, double s, double entropy)
  171. {
  172. double gain = entropy;
  173. for(Map1::CI it = att_val.begin(); it != att_val.end(); it++)
  174. {
  175. double r = it->second / s;
  176. double e = _entropy(val_cls[it->first], it->second);
  177. gain -= r * e;
  178. }
  179. return gain;
  180. }
  181. //对当前节点的sample进行划分
  182. void ID3::_split(Node *node, int idx)
  183. {
  184. Child &next = node->next;
  185. SampleSpace &sample = node->sample;
  186. for(SampleSpace::iterator it = sample.begin(); it != sample.end(); it++)
  187. {
  188. List &v = *it;
  189. for(List::iterator p = v.begin(); p != v.end(); p++)
  190. {
  191. if(p->first == idx)
  192. {
  193. Node *tmp = next[p->second];
  194. if(!tmp)
  195. {
  196. tmp = new Node();
  197. tmp->index = -1;
  198. tmp->type = -1;
  199. next[p->second] = tmp;
  200. }
  201. v.erase(p);
  202. tmp->sample.push_back(v);
  203. break;
  204. }
  205. }
  206. }
  207. }
  208. int ID3::Match(const Type *x)
  209. {
  210. return _match(x, root);
  211. }
  212. int ID3::_match(const Type *v, Node *node)
  213. {
  214. if(node->index < 0)
  215. return node->type;
  216. Child &next = node->next;
  217. Child::iterator p = next.find(v[node->index - 1]);
  218. if(p == next.end())
  219. return -1;
  220. return _match(v, p->second);
  221. }
  222. void ID3::Print()
  223. {
  224. _print(root);
  225. }
  226. void ID3::_print(Node *node)
  227. {
  228. cout << "Index    = " << node->index << endl;
  229. cout << "Type     = " << node->type << endl;
  230. cout << "NextSize = " << node->next.size() << endl;
  231. cout << endl;
  232. Child &next = node->next;
  233. Child::iterator p;
  234. for(p = next.begin(); p != next.end(); ++p)
  235. _print(p->second);
  236. }
#include <iostream>
#include <cassert>
#include <cmath>#include "ID3.h"using namespace std;//初始化ID3的数据成员
ID3::ID3(int dimension)
{this->dimension = dimension;root = new Node();root->index = -1;root->type = -1;root->next.clear();root->sample.clear();
}//清空整个决策树
ID3::~ID3()
{this->dimension = 0;_clear(root);
}//x为dimension维的属性向量,y为向量x对应的值
void ID3::PushData(const Type *x, const Type y)
{List single;single.clear();for(int i = 0; i < dimension; i++)single.push_back(make_pair(i + 1, x[i]));single.push_back(make_pair(0, y));root->sample.push_back(single);
}void ID3::_clear(Node *node)
{Child &next = node->next;Child::iterator it;for(it = next.begin(); it != next.end(); it++)_clear(it->second);next.clear();delete node;
}void ID3::Build()
{_build(root, dimension);
}void ID3::_build(Node *node, int dimension)
{//获取当前节点未分类的样本数据SampleSpace &sample = node->sample;//判断当前所有样本是否是同一类,如果不是则返回-1int y = _same_class(sample);//如果所有样本是属于同一类if(y >= 0){node->index = -1;node->type = y;return;}//在_max_gain()函数中计算出当前节点的最大增益对应的属性,并根据这个属性对数据进行划分_work(node);//Split完成后清空当前节点的所有数据,以免占用太多内存sample.clear();Child &next = node->next;for(Child::iterator it = next.begin(); it != next.end(); it++)_build(it->second, dimension - 1);
}//判断当前所有样本是否是同一类,如果不是则返回-1
int ID3::_same_class(const SampleSpace &ss)
{//取出当前样本数据的一个Sampleconst List &f = ss.front();//如果没有x属性,而只有y,直接返回yif(f.size() == 1)return f.front().second;Type y = 0;//取出第一个样本数据y的结果值for(List::CI it = f.begin(); it != f.end(); it++){if(!it->first){y = it->second;break;}}//接下来进行判断,因为list是有序的,所以从前往后遍历,发现有一对不一样,则所有样本不是同一类for(SampleSpace::CI it = ss.begin(); it != ss.end(); it++){const List &single = *it;for(List::CI i = single.begin(); i != single.end(); i++){if(!i->first){if(y != i->second)return -1;         //发现不是同一类则返回-1elsebreak;}}}return y;     //比较完所有样本的输出值y后,发现是同一类,返回y值。
}void ID3::_work(Node *node)
{int mai = _get_max_gain(node->sample);assert(mai >= 0);node->index = mai;_split(node, mai);
}//获取最大的信息增益对应的属性
int ID3::_get_max_gain(const SampleSpace &ss)
{Map1 y;Map2 x;Map3 xy;_get_data(ss, y, x, xy);double s = ss.size();double entropy = _entropy(y, s);   //计算熵值int mai = -1;double mag = -1;for(Map2::iterator it = x.begin(); it != x.end(); it++){double g = _info_gain(it->second, xy[it->first], s, entropy);    //计算信息增益值if(g > mag){mag = g;mai = it->first;}}if(!x.size() && !xy.size() && y.size())   //如果只有y数据return 0;return mai;
}//获取数据,提取出所有样本的y值,x[]属性值,以及属性值和结果值xy。
void ID3::_get_data(const SampleSpace &ss, Map1 &y, Map2 &x, Map3 &xy)
{for(SampleSpace::CI it = ss.begin(); it != ss.end(); it++){int c = 0;const List &v = *it;for(List::CI p = v.begin(); p != v.end(); p++){if(!p->first){c = p->second;break;}}++y[c];for(List::CI p = v.begin(); p != v.end(); p++){if(p->first){++x[p->first][p->second];++xy[p->first][p->second][c];}}}
}//计算熵值
double ID3::_entropy(const Map1 &x, double s)
{double ans = 0;for(Map1::CI it = x.begin(); it != x.end(); it++){double t = it->second / s;ans += t * log2(t);}return -ans;
}//计算信息增益
double ID3::_info_gain(Map1 &att_val, Map2 &val_cls, double s, double entropy)
{double gain = entropy;for(Map1::CI it = att_val.begin(); it != att_val.end(); it++){double r = it->second / s;double e = _entropy(val_cls[it->first], it->second);gain -= r * e;}return gain;
}//对当前节点的sample进行划分
void ID3::_split(Node *node, int idx)
{Child &next = node->next;SampleSpace &sample = node->sample;for(SampleSpace::iterator it = sample.begin(); it != sample.end(); it++){List &v = *it;for(List::iterator p = v.begin(); p != v.end(); p++){if(p->first == idx){Node *tmp = next[p->second];if(!tmp){tmp = new Node();tmp->index = -1;tmp->type = -1;next[p->second] = tmp;}v.erase(p);tmp->sample.push_back(v);break;}}}
}int ID3::Match(const Type *x)
{return _match(x, root);
}  int ID3::_match(const Type *v, Node *node)
{if(node->index < 0)return node->type;Child &next = node->next;Child::iterator p = next.find(v[node->index - 1]);if(p == next.end())return -1;return _match(v, p->second);
}void ID3::Print()
{_print(root);
}void ID3::_print(Node *node)
{cout << "Index    = " << node->index << endl;cout << "Type     = " << node->type << endl;cout << "NextSize = " << node->next.size() << endl;cout << endl;Child &next = node->next;Child::iterator p;for(p = next.begin(); p != next.end(); ++p)_print(p->second);
}

main.cpp

[cpp] view plaincopy print?
  1. #include <iostream>
  2. #include "ID3.h"
  3. using namespace std;
  4. enum outlook {SUNNY, OVERCAST, RAIN };
  5. enum temp    {HOT,   MILD,     COOL };
  6. enum hum     {HIGH,  NORMAL         };
  7. enum windy   {WEAK,  STRONG         };
  8. int samples[14][4] =
  9. {
  10. {SUNNY   ,       HOT ,      HIGH  ,       WEAK  },
  11. {SUNNY   ,       HOT ,      HIGH  ,       STRONG},
  12. {OVERCAST,       HOT ,      HIGH  ,       WEAK  },
  13. {RAIN    ,       MILD,      HIGH  ,       WEAK  },
  14. {RAIN    ,       COOL,      NORMAL,       WEAK  },
  15. {RAIN    ,       COOL,      NORMAL,       STRONG},
  16. {OVERCAST,       COOL,      NORMAL,       STRONG},
  17. {SUNNY   ,       MILD,      HIGH  ,       WEAK  },
  18. {SUNNY   ,       COOL,      NORMAL,       WEAK  },
  19. {RAIN    ,       MILD,      NORMAL,       WEAK  },
  20. {SUNNY   ,       MILD,      NORMAL,       STRONG},
  21. {OVERCAST,       MILD,      HIGH  ,       STRONG},
  22. {OVERCAST,       HOT ,      NORMAL,       WEAK  },
  23. {RAIN    ,       MILD,      HIGH  ,       STRONG}
  24. };
  25. int main()
  26. {
  27. ID3 Tree(4);
  28. Tree.PushData((int *)&samples[0], 0);
  29. Tree.PushData((int *)&samples[1], 0);
  30. Tree.PushData((int *)&samples[2], 1);
  31. Tree.PushData((int *)&samples[3], 1);
  32. Tree.PushData((int *)&samples[4], 1);
  33. Tree.PushData((int *)&samples[5], 0);
  34. Tree.PushData((int *)&samples[6], 1);
  35. Tree.PushData((int *)&samples[7], 0);
  36. Tree.PushData((int *)&samples[8], 1);
  37. Tree.PushData((int *)&samples[9], 1);
  38. Tree.PushData((int *)&samples[10], 1);
  39. Tree.PushData((int *)&samples[11], 1);
  40. Tree.PushData((int *)&samples[12], 1);
  41. Tree.PushData((int *)&samples[13], 0);
  42. Tree.Build();
  43. Tree.Print();
  44. cout << endl;
  45. for(int i = 0; i < 14; ++i)
  46. cout << "predict value :    " <<Tree.Match( (int *)&samples[i] ) << endl;
  47. return 0;
  48. }
#include <iostream>
#include "ID3.h"using namespace std;enum outlook {SUNNY, OVERCAST, RAIN };
enum temp    {HOT,   MILD,     COOL };
enum hum     {HIGH,  NORMAL         };
enum windy   {WEAK,  STRONG         };int samples[14][4] =
{{SUNNY   ,       HOT ,      HIGH  ,       WEAK  },{SUNNY   ,       HOT ,      HIGH  ,       STRONG},{OVERCAST,       HOT ,      HIGH  ,       WEAK  },{RAIN    ,       MILD,      HIGH  ,       WEAK  },{RAIN    ,       COOL,      NORMAL,       WEAK  },{RAIN    ,       COOL,      NORMAL,       STRONG},{OVERCAST,       COOL,      NORMAL,       STRONG},{SUNNY   ,       MILD,      HIGH  ,       WEAK  },{SUNNY   ,       COOL,      NORMAL,       WEAK  },{RAIN    ,       MILD,      NORMAL,       WEAK  },{SUNNY   ,       MILD,      NORMAL,       STRONG},{OVERCAST,       MILD,      HIGH  ,       STRONG},{OVERCAST,       HOT ,      NORMAL,       WEAK  },{RAIN    ,       MILD,      HIGH  ,       STRONG}
};int main()
{ID3 Tree(4);Tree.PushData((int *)&samples[0], 0);Tree.PushData((int *)&samples[1], 0);Tree.PushData((int *)&samples[2], 1);Tree.PushData((int *)&samples[3], 1);Tree.PushData((int *)&samples[4], 1);Tree.PushData((int *)&samples[5], 0);Tree.PushData((int *)&samples[6], 1);Tree.PushData((int *)&samples[7], 0);Tree.PushData((int *)&samples[8], 1);Tree.PushData((int *)&samples[9], 1);Tree.PushData((int *)&samples[10], 1);Tree.PushData((int *)&samples[11], 1);Tree.PushData((int *)&samples[12], 1);Tree.PushData((int *)&samples[13], 0);Tree.Build();Tree.Print();cout << endl;for(int i = 0; i < 14; ++i)cout << "predict value :    " <<Tree.Match( (int *)&samples[i] ) << endl;return 0;
}

Makefile

[cpp] view plaincopy print?
  1. Test: main.cpp ID3.h ID3.cpp
  2. g++ -o Test ID3.cpp main.cpp
  3. clean:
  4. rm Test
Test: main.cpp ID3.h ID3.cppg++ -o Test ID3.cpp main.cppclean:rm Test

决策树(一)--ID3相关推荐

  1. 【Machine Learning】决策树之ID3算法 (2)

    决策树之ID3算法 Content 1.ID3概念 2.信息熵 3.信息增益 Information Gain 4. ID3 bias 5. Python算法实现(待定) 一.ID3概念 ID3算法最 ...

  2. 机器学习爬大树之决策树(ID3,C4.5)

    自己自学机器学习的相关知识,过了一遍西瓜书后准备再刷一遍,后来在看别人打比赛的代码时多次用到XGBoost,lightGBM,遂痛下决心认真学习机器学习关于树的知识,自己学习的初步流程图为: 决策树( ...

  3. 利用计算机语言实现ID3算法,机器学习之决策树学习-id3算法-原理分析及c语言代码实现.pdf...

    机器学习之决策树学习-id3算法-原理分析及c语言代码实现.pdf 还剩 23页未读, 继续阅读 下载文档到电脑,马上远离加班熬夜! 亲,很抱歉,此页已超出免费预览范围啦! 如果喜欢就下载吧,价低环保 ...

  4. 决策树之ID3、C4.5、C5.0等五大算法及python实现

    每每以为攀得众山小,可.每每又切实来到起点,大牛们,缓缓脚步来俺笔记葩分享一下吧,please~ --------------------------- C5.0决策树之ID3.C4.5.C5.0算法 ...

  5. R语言决策树(ID3、CART、C4.5、C5.0)算法使用举例

    1.环境及数据准备 #环境变量 rm(list = ls());#清空变量空间#载入所需R Rackages library(rattle) library(rpart) library(rpart. ...

  6. 第四章 决策树和ID3 python3.5.1代码理解

    一.部分概念: 决策树:为了对新事例进行分类. 决策树学习的目的:为了获得泛化能力强的决策树. 决策树包括根结点,内部结点,叶结点: 1)根结点:包涵样本全集. 2)内部结点:对应于一个测试属性. 3 ...

  7. 决策树(1)——ID3算法与C4.5算法的理论基础与python实现

    1.前言   决策树是一种常用的机器学习算法,既可以做分类任务也可以做回归任务,本文主要讨论用于分类任务的决策树.决策树与数据结构中的树相同,也是由一个根结点.若干个内部结点和若干个叶结点构成.这里我 ...

  8. 决策树之ID3算法以及决策树挑西瓜代码实现

    决策树之ID3算法以及决策树挑西瓜代码实现 一.决策树 1. 决策树的基本认识 2. 决策树的构造过程 (1)特征选择 (2)决策树的生成 (3)决策树的裁剪 决策树的优缺点 二.决策树之ID3算法 ...

  9. 【机器学习基础】数学推导+纯Python实现机器学习算法4:决策树之ID3算法

    Python机器学习算法实现 Author:louwill 作为机器学习中的一大类模型,树模型一直以来都颇受学界和业界的重视.目前无论是各大比赛各种大杀器的XGBoost.lightgbm还是像随机森 ...

  10. 机器学习:决策树及ID3,C4.5,CART算法描述

    文章目录 概念理解 熵: 条件熵: 信息增益,互信息: 信息增益比 基尼指数 ID3算法描述 C4.5算法描述 CART (Classification and Regression Tree)算法描 ...

最新文章

  1. Kubernetes vs Docker:了解2021年的容器
  2. 未来科学家数学与计算机奖,未来科学大奖“对话未来科学家”
  3. JavaScript label语句
  4. silverlight turntable
  5. 多元化时代敏捷软件开发的崛起与传统软件工程的延续
  6. Envi和ArcGIS软件打开和处理.NC4数据
  7. php 区块链算法_PoW/BFT等5种主流区块链共识算法的开源代码实现
  8. Hive - Create TableDrop Table ALTER Table(中)
  9. Cacti auth.php,Liunx运维监控_shark巨菜_cacti篇
  10. 【终终极版】linux(Ubuntu)下wineQQ的安装办法
  11. java 验证是否为省份证号 详细验证 验证月份 日期等 要素
  12. c语言 键盘扫描码 c-free,FreeBarcode条形码制作工具
  13. java获取本机物理ip地址吗_Java获取本机所有ip地址
  14. Exposure X8 ps人像图片调色滤镜插件
  15. Qcom平台添加一款新的sensor (msm8953)
  16. JAVA proxy dns回源_常见问题 - CDN 回源配置相关问题
  17. 批量修改WORD文档密码
  18. less和css的区别是什么
  19. jquery ajax 参数放到 request playload 中
  20. 微信公众号 隐藏菜单

热门文章

  1. 多速率多传感器数据融合估计(二)
  2. VALSE学习(六):机器学习中的标记分布与标记增强
  3. aspen二元体系共沸组分_应用Aspen Plus分离共沸物
  4. Android Studio实现记事本项目
  5. Tcl Tutorial 笔记3 ·math
  6. linux系统安装klocwork,linux下klocwork的使用
  7. java+io体系结构图_Java IO 体系结构
  8. python寻路_【PYTHON】a-start寻路算法
  9. 做工作流时候 Mybatis 在 insert 之后想获取自增的主键 id,但却总是返回1
  10. frpc客户端 linux安装,centos配置frp服务端,与客户端