原文:

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

在之前介绍过决策树的ID3算法实现,今天主要来介绍决策树的另一种实现,即CART算法

Contents

   1. CART算法的认识

   2. CART算法的原理

   3. CART算法的实现

1. CART算法的认识

Classification And Regression Tree,即分类回归树算法,简称CART算法,它是决策树的一种实现,通

常决策树主要有三种实现,分别是ID3算法,CART算法和C4.5算法。

CART算法是一种二分递归分割技术,把当前样本划分为两个子样本,使得生成的每个非叶子结点都有两个分支,

因此CART算法生成的决策树是结构简洁的二叉树。由于CART算法构成的是一个二叉树,它在每一步的决策时只能

是“是”或者“否”,即使一个feature有多个取值,也是把数据分为两部分。在CART算法中主要分为两个步骤

(1)将样本递归划分进行建树过程

(2)用验证数据进行剪枝

2. CART算法的原理

上面说到了CART算法分为两个过程,其中第一个过程进行递归建立二叉树,那么它是如何进行划分的 ?

代表单个样本的个属性,表示所属类别。CART算法通过递归的方式将维的空间划分为不重

叠的矩形。划分步骤大致如下

(1)选一个自变量,再选取的一个值维空间划分为两部分,一部分的所有点都满足

另一部分的所有点都满足,对非连续变量来说属性值的取值只有两个,即等于该值或不等于该值。

(2)递归处理,将上面得到的两部分按步骤(1)重新选取一个属性继续划分,直到把整个维空间都划分完。

在划分时候有一个问题,它是按照什么标准来划分的 ? 对于一个变量属性来说,它的划分点是一对连续变量属

性值的中点。假设个样本的集合一个属性有个连续的值,那么则会有个分裂点,每个分裂点为相邻

两个连续值的均值。每个属性的划分按照能减少的杂质的量来进行排序,而杂质的减少量定义为划分前的杂质减

去划分后的每个节点的杂质量划分所占比率之和。而杂质度量方法常用Gini指标,假设一个样本共有类,那么

一个节点的Gini不纯度可定义为

其中表示属于类的概率,当Gini(A)=0时,所有样本属于同类,所有类在节点中以等概率出现时,Gini(A)

最大化,此时

有了上述理论基础,实际的递归划分过程是这样的:如果当前节点的所有样本都不属于同一类或者只剩下一个样

本,那么此节点为非叶子节点,所以会尝试样本的每个属性以及每个属性对应的分裂点,尝试找到杂质变量最大

的一个划分,该属性划分的子树即为最优分支。

下面举个简单的例子,如下图

在上述图中,属性有3个,分别是有房情况,婚姻状况和年收入,其中有房情况和婚姻状况是离散的取值,而年

收入是连续的取值。拖欠贷款者属于分类的结果。

假设现在来看有房情况这个属性,那么按照它划分后的Gini指数计算如下

而对于婚姻状况属性来说,它的取值有3种,按照每种属性值分裂后Gini指标计算如下

最后还有一个取值连续的属性,年收入,它的取值是连续的,那么连续的取值采用分裂点进行分裂。如下

根据这样的分裂规则CART算法就能完成建树过程。

建树完成后就进行第二步了,即根据验证数据进行剪枝。在CART树的建树过程中,可能存在Overfitting,许多

分支中反映的是数据中的异常,这样的决策树对分类的准确性不高,那么需要检测并减去这些不可靠的分支。决策

树常用的剪枝有事前剪枝和事后剪枝,CART算法采用事后剪枝,具体方法为代价复杂性剪枝法。可参考如下链接

剪枝参考:http://www.cnblogs.com/zhangchaoyang/articles/2709922.html

3. CART算法的实现

以下代码是网上找的CART算法的MATLAB实现。

[plain] view plain copy print?

  1. CART
  2. function D = CART(train_features, train_targets, params, region)
  3. % Classify using classification and regression trees
  4. % Inputs:
  5. % features - Train features
  6. % targets     - Train targets
  7. % params - [Impurity type, Percentage of incorrectly assigned samples at a node]
  8. %                   Impurity can be: Entropy, Variance (or Gini), or Missclassification
  9. % region     - Decision region vector: [-x x -y y number_of_points]
  10. %
  11. % Outputs
  12. % D - Decision sufrace
  13. [Ni, M]    = size(train_features);
  14. %Get parameters
  15. [split_type, inc_node] = process_params(params);
  16. %For the decision region
  17. N           = region(5);
  18. mx          = ones(N,1) * linspace (region(1),region(2),N);
  19. my          = linspace (region(3),region(4),N)' * ones(1,N);
  20. flatxy      = [mx(:), my(:)]';
  21. %Preprocessing
  22. [f, t, UW, m]   = PCA(train_features, train_targets, Ni, region);
  23. train_features  = UW * (train_features - m*ones(1,M));;
  24. flatxy          = UW * (flatxy - m*ones(1,N^2));;
  25. %Build the tree recursively
  26. disp('Building tree')
  27. tree        = make_tree(train_features, train_targets, M, split_type, inc_node, region);
  28. %Make the decision region according to the tree
  29. disp('Building decision surface using the tree')
  30. targets = use_tree(flatxy, 1:N^2, tree);
  31. D = reshape(targets,N,N);
  32. %END
  33. function targets = use_tree(features, indices, tree)
  34. %Classify recursively using a tree
  35. if isnumeric(tree.Raction)
  36. %Reached an end node
  37. targets = zeros(1,size(features,2));
  38. targets(indices) = tree.Raction(1);
  39. else
  40. %Reached a branching, so:
  41. %Find who goes where
  42. in_right    = indices(find(eval(tree.Raction)));
  43. in_left     = indices(find(eval(tree.Laction)));
  44. Ltargets = use_tree(features, in_left, tree.left);
  45. Rtargets = use_tree(features, in_right, tree.right);
  46. targets = Ltargets + Rtargets;
  47. end
  48. %END use_tree
  49. function tree = make_tree(features, targets, Dlength, split_type, inc_node, region)
  50. %Build a tree recursively
  51. if (length(unique(targets)) == 1),
  52. %There is only one type of targets, and this generates a warning, so deal with it separately
  53. tree.right      = [];
  54. tree.left       = [];
  55. tree.Raction    = targets(1);
  56. tree.Laction    = targets(1);
  57. break
  58. end
  59. [Ni, M] = size(features);
  60. Nt      = unique(targets);
  61. N       = hist(targets, Nt);
  62. if ((sum(N < Dlength*inc_node) == length(Nt) - 1) | (M == 1)),
  63. %No further splitting is neccessary
  64. tree.right      = [];
  65. tree.left       = [];
  66. if (length(Nt) ~= 1),
  67. MLlabel   = find(N == max(N));
  68. else
  69. MLlabel   = 1;
  70. end
  71. tree.Raction    = Nt(MLlabel);
  72. tree.Laction    = Nt(MLlabel);
  73. else
  74. %Split the node according to the splitting criterion
  75. deltaI = zeros(1,Ni);
  76. split_point = zeros(1,Ni);
  77. op = optimset('Display', 'off');
  78. for i = 1:Ni,
  79. split_point(i) = fminbnd('CARTfunctions', region(i*2-1), region(i*2), op, features, targets, i, split_type);
  80. I(i) = feval('CARTfunctions', split_point(i), features, targets, i, split_type);
  81. end
  82. [m, dim] = min(I);
  83. loc = split_point(dim);
  84. %So, the split is to be on dimention 'dim' at location 'loc'
  85. indices = 1:M;
  86. tree.Raction= ['features(' num2str(dim) ',indices) >  ' num2str(loc)];
  87. tree.Laction= ['features(' num2str(dim) ',indices) <= ' num2str(loc)];
  88. in_right    = find(eval(tree.Raction));
  89. in_left     = find(eval(tree.Laction));
  90. if isempty(in_right) | isempty(in_left)
  91. %No possible split found
  92. tree.right      = [];
  93. tree.left       = [];
  94. if (length(Nt) ~= 1),
  95. MLlabel   = find(N == max(N));
  96. else
  97. MLlabel = 1;
  98. end
  99. tree.Raction    = Nt(MLlabel);
  100. tree.Laction    = Nt(MLlabel);
  101. else
  102. %...It's possible to build new nodes
  103. tree.right = make_tree(features(:,in_right), targets(in_right), Dlength, split_type, inc_node, region);
  104. tree.left  = make_tree(features(:,in_left), targets(in_left), Dlength, split_type, inc_node, region);
  105. end
  106. end
CARTfunction D = CART(train_features, train_targets, params, region)% Classify using classification and regression trees
% Inputs:
% features - Train features
% targets     - Train targets
% params - [Impurity type, Percentage of incorrectly assigned samples at a node]
%                   Impurity can be: Entropy, Variance (or Gini), or Missclassification
% region     - Decision region vector: [-x x -y y number_of_points]
%
% Outputs
% D - Decision sufrace[Ni, M]    = size(train_features);%Get parameters
[split_type, inc_node] = process_params(params);%For the decision region
N           = region(5);
mx          = ones(N,1) * linspace (region(1),region(2),N);
my          = linspace (region(3),region(4),N)' * ones(1,N);
flatxy      = [mx(:), my(:)]';%Preprocessing
[f, t, UW, m]   = PCA(train_features, train_targets, Ni, region);
train_features  = UW * (train_features - m*ones(1,M));;
flatxy          = UW * (flatxy - m*ones(1,N^2));;%Build the tree recursively
disp('Building tree')
tree        = make_tree(train_features, train_targets, M, split_type, inc_node, region);%Make the decision region according to the tree
disp('Building decision surface using the tree')
targets = use_tree(flatxy, 1:N^2, tree);D = reshape(targets,N,N);
%ENDfunction targets = use_tree(features, indices, tree)
%Classify recursively using a treeif isnumeric(tree.Raction)%Reached an end nodetargets = zeros(1,size(features,2));targets(indices) = tree.Raction(1);
else%Reached a branching, so:%Find who goes wherein_right    = indices(find(eval(tree.Raction)));in_left     = indices(find(eval(tree.Laction)));Ltargets = use_tree(features, in_left, tree.left);Rtargets = use_tree(features, in_right, tree.right);targets = Ltargets + Rtargets;
end
%END use_treefunction tree = make_tree(features, targets, Dlength, split_type, inc_node, region)
%Build a tree recursivelyif (length(unique(targets)) == 1),%There is only one type of targets, and this generates a warning, so deal with it separatelytree.right      = [];tree.left       = [];tree.Raction    = targets(1);tree.Laction    = targets(1);break
end[Ni, M] = size(features);
Nt      = unique(targets);
N       = hist(targets, Nt);if ((sum(N < Dlength*inc_node) == length(Nt) - 1) | (M == 1)),%No further splitting is neccessarytree.right      = [];tree.left       = [];if (length(Nt) ~= 1),MLlabel   = find(N == max(N));elseMLlabel   = 1;endtree.Raction    = Nt(MLlabel);tree.Laction    = Nt(MLlabel);else%Split the node according to the splitting criteriondeltaI = zeros(1,Ni);split_point = zeros(1,Ni);op = optimset('Display', 'off'); for i = 1:Ni,split_point(i) = fminbnd('CARTfunctions', region(i*2-1), region(i*2), op, features, targets, i, split_type);I(i) = feval('CARTfunctions', split_point(i), features, targets, i, split_type);end[m, dim] = min(I);loc = split_point(dim);%So, the split is to be on dimention 'dim' at location 'loc'indices = 1:M;tree.Raction= ['features(' num2str(dim) ',indices) >  ' num2str(loc)];tree.Laction= ['features(' num2str(dim) ',indices) <= ' num2str(loc)];in_right    = find(eval(tree.Raction));in_left     = find(eval(tree.Laction));if isempty(in_right) | isempty(in_left)%No possible split foundtree.right      = [];tree.left       = [];if (length(Nt) ~= 1),MLlabel   = find(N == max(N));elseMLlabel = 1;endtree.Raction    = Nt(MLlabel);tree.Laction    = Nt(MLlabel);else%...It's possible to build new nodestree.right = make_tree(features(:,in_right), targets(in_right), Dlength, split_type, inc_node, region);tree.left  = make_tree(features(:,in_left), targets(in_left), Dlength, split_type, inc_node, region);    endend

在Julia中的决策树包:https://github.com/bensadeghi/DecisionTree.jl/blob/master/README.md





人脸检测(四)--CART原理及实现相关推荐

  1. 门禁系统中人脸检测技术的原理剖析和使用教程

    引言 人脸检测 API 是一种基于深度学习技术的图像处理API,可以快速地检测出一张图片中的人脸,并返回人脸的位置和关键点坐标,在人脸识别系统.人脸情绪识别等多种场景下都有极大的应用. 本文将从人脸检 ...

  2. 算丰边缘计算开发板人脸检测识别-实现原理与代码介绍

    一.概述 本文章会尝试用简单的语言,来给大家介绍一下,如何搭建一个最基本的人脸检测以及识别的场景.当然,这篇文章不只是讲解关于人脸检测相关的部分,而是围绕这个核心,包含概括了整个前端的uvc,甚至so ...

  3. 一文带你了解人脸检测算法的类型及其工作原理

    在过去的几年里,人脸识别受到了广泛的关注,被认为是图像分析领域最有前途的应用之一.人脸检测可以考虑人脸识别操作的很大一部分.根据其强度将计算资源集中在持有人脸的图像部分.图片中的人脸检测方法很复杂,因 ...

  4. 一文综述人脸检测算法(附资源)

    文章来源:SIGAI 本文共9400字,建议阅读10+分钟. 本文将和大家一起回顾人脸检测算法的整个发展历史. [导读] 人脸检测是目前所有目标检测子方向中被研究的最充分的问题之一,它在安防监控,人证 ...

  5. 第九节、人脸检测之Haar分类器

    人脸检测属于计算机视觉的范畴,早期人们的主要研究方向是人脸识别,即根据人脸来识别人物的身份,后来在复杂背景下的人脸检测需求越来越大,人脸检测也逐渐作为一个单独的研究方向发展起来. 目前人脸检测的方法主 ...

  6. 人脸检测MTCNN和人脸识别Facenet(附源码)

    原文链接:人脸检测MTCNN和人脸识别Facenet(附源码) 在说到人脸检测我们首先会想到利用Harr特征提取和Adaboost分类器进行人脸检测(有兴趣的可以去一看这篇博客第九节.人脸检测之Haa ...

  7. 人脸检测:人脸检测算法综述

    https://blog.csdn.net/SIGAI_CSDN/article/details/80751476 问题描述 人脸检测的目标是找出图像中所有的人脸对应的位置,算法的输出是人脸外接矩形在 ...

  8. (转)第三十七节、人脸检测MTCNN和人脸识别Facenet(附源码)

    http://www.cnblogs.com/zyly/p/9703614.html 在说到人脸检测我们首先会想到利用Harr特征提取和Adaboost分类器进行人脸检测(有兴趣的可以去一看这篇博客第 ...

  9. Adaboost算法详解(haar人脸检测)

    转自:https://wizardforcel.gitbooks.io/dm-algo-top10/content/adaboost.html(脸书动不动上不去故转载)(主要看adaboost的例子. ...

  10. 人脸检测:传统到深度学习方法汇总

    虽然人脸的结构是确定的,由眉毛.眼睛.鼻子和嘴等部位组成,近似是一个刚体,但由于姿态和表情的变化,不同人的外观差异,光照,遮挡的影响,准确的检测处于各种条件下的人脸是一件相对困难的事情. 人脸检测算法 ...

最新文章

  1. Elasticsearch之Mapping Meta-Fields
  2. 两个获取http页面的c#函数
  3. APP里如何添加本地文本
  4. (stack栈)rails
  5. 2017.9.2 最大半联通子图 思考记录
  6. 后台拿webshell的方法总结
  7. script标签中的crossorigin属性
  8. 2019年web前端全集_2019年最佳30+ Web工具
  9. spss进行偏相关分析
  10. 红外遥控接收头 的引脚参数
  11. java libtorrent_基于libtorrent最简单的BT下载程序 | 学步园
  12. 计算机网络安全知识讲座新闻稿,我院开展网络安全与信息化建设讲座
  13. implicit declaration of function 警告解决方法 (函数的隐式说明)
  14. arm架构 CF-WU810N网卡驱动安装经验
  15. 计算机中丢失d3dx941,d3dx9_41.dll(支持64位)
  16. python QRcode
  17. pe管厂家_mpp管与PE管的区别
  18. Winlogon事件通知包
  19. VLC,FFMPEG, RTP,28181 学习 网址做了个汇总
  20. 使用远程机与本地文件交互不能复制粘贴的办法

热门文章

  1. Android LowMemoryKiller ADJ原理
  2. Typora MarkDown语法笔记(一)
  3. web多线程之webworkers
  4. python之pyc
  5. Pycharm连接Mysql问题: Server returns invalid timezone. Go to 'Advanced' tab and set 'serverTimezon
  6. 阿里python400集_自学成才的阿里大牛整理的400集自用Python视频资料,万物皆可爬...
  7. 安装pkgconfig_一个R包怎么也安装不上,憋着急!
  8. qoq是什么意思的缩写_买鞋多年分不清PE、SE、TD什么意思?建议收藏,这些缩写一定要知道...
  9. 如何用C++从文件读取学生成绩再求出平均成绩送回文件中
  10. mysql innodbdatahomedir_mysql gtid复制