前言:CART决策树生成的过程比较好理解,但是剪枝的过程看了好几遍才看明白,故写出下文,供同样困惑的朋友参考。下文不涉及复杂严密的数学推导,以辅助理解为主。
CART的损失函数用的是下式:
损失函数表征的是模型预测错误的程度,所以它越小越好。
上式中\(C_\alpha (T)\) 是关于 \(T\) 和 \(\alpha\) 的函数,\(T\) 表示一个决策树,\(C(T)\) 是对训练数据的预测误差(分类用基尼指数表示,回归用均方误差表示),\(|T|\) 表示树 \(T\) 的叶节点个数。$\alpha $ 是一个常数,用来平衡模型对数据的拟合程度(由\(C(T)\)项决定)和 模型的复杂度(\(\alpha|T|\)项决定,复杂度也就是树的分支多不多)。
如果 \(\alpha\) 非常小,那么损失函数 \(C_\alpha(T)\) 的值大小由 \(C(T)\) 决定,为了使损失函数的值小,\(C(T)\) 也就会趋于小,也就是多分枝,充分延展树(因为我们生成树时,选择属性的标准就是使基尼指数或者均方误差减小的最多,所以充分分枝意味着更小的 \(C(T)\));
反之,如果 \(\alpha\) 充分大,那么损失函数 \(C_\alpha(T)\) 的值大小由 \(\alpha |T|\) 决定,为了使损失函数的值小, \(|T|\) 也就会趋于小,而最小的树就是只有一个节点,所以此时剪枝成一个单节点树,\(|T|=1\) 。
总而言之,\(\alpha\) 越大,在损失函数的影响下,模型趋向于少分枝。\(\alpha\)越小,模型越趋向于多分枝。
假设通过CART生成一个完整的树\(T_0\),如下:
剪枝的整体思路是:
每次树所有的內结点(不是叶结点的结点,如上示树的N4,N2,N3,N7,N1),得出最适合剪枝的结点并对其剪枝,得到一个子树 \(T_i\) ,然后再分析 \(T_i\) 的所有內结点,找出 \(T_i\) 最适合剪枝的结点并对其剪枝,得到子树 \(T_{i+1}\);
\(\cdots\)
重复至最终得到的子树只剩下三个结点(一个根结点连着两个叶结点),如果这个过程中,我们得到了 k+1 个子树(注意,每次剪完枝得到的子树都要存储起来),不妨记作 {\(T_0,T_1,\cdots,T_k\)};
最后使用交叉验证,看看哪个树的性能最好,我们就选择哪个树。
核心步骤是第一步,以下给出具体解释和方法:
第一部分我们分析过:\(\alpha\) 越大,越趋向于多分枝;\(\alpha\) 越小,越趋向于少分枝。所以,必定存在一个\(\alpha\),使得分不分枝都可以(分枝与不分枝的损失函数值相同),我们记这个\(\alpha\) 为 \(\alpha_0\)。所以,我们只需要依次将树的內结点和它的子节点组成的子树拿出来(比如上示树中标示出来的以 \(N3\) 为根节点和以 \(N4\) 为根节点的子树),计算它的 \(\alpha_0\) 。对于全部的內结点,我们得到一组 \(\alpha_0\) 值,然后选择其中最小的 \(\alpha_0\) 对应內结点,并对其剪枝。
这句话需要稍微转个弯才能理解,为什么要选择 \(\alpha_0\) 最小的结点剪枝呢?假设我们选择了一个大于 \(min(\alpha_0)\) 的值 \(\alpha'\) 作为阈值,那么对于 剪枝阈值α0 小于 α′ 的结点,他们都处于 “趋向于不分枝“ 的状态,也就是需要剪枝,这样就会有多个结点需要剪枝,但是我们不能确保这些需要被剪枝的结点都是不相关的(剪掉一个后对另一个结点没有影响),所以我们需要控制每次只剪一个结点的枝,选择最小的\(\alpha_0\)对应的结点剪枝,就是为了控制每次只剪掉一个结点的枝,因为在损失函数是\(C_\alpha(T)=C(T)+\alpha_0 |T|\)的情况下,其他结点都处于 ”趋向于多分枝的状态“ 。
Breiman对此有严密的数学证明,感兴趣可以看看。
接下来就是确认每个內结点的\(\alpha_0\),注意,确认每个內结点的\(\alpha_0\)需要将该结点作为根节点的子树单独拿出来研究,以 \(N4\) 结点为例,首先我们把它作为根节点的子树拿出来:
不剪枝,它的损失函数是:
剪枝后,它只剩下 N4 一个结点,光杆司令,这时候损失函数是:
找“剪不剪枝都可以的\(\alpha\)” ,也就是找 \(C_\alpha(T_{N4})=C_\alpha(N4)\) 的 \(\alpha\) 。故有
可得,对于任意结点\(t\),记以 \(t\) 为根节点的子树为\(T_t\) ,只有 \(t\) 一个结点的树直接记为 \(t\) ,则得到计算结点 \(t\) “剪不剪枝都可以的\(\alpha\)” 的公式:
问题得解:我们对每个內结点都用式 (5) 找出它”剪不剪枝都可以“ 的临界\(\alpha_0\),然后筛选出最小的 \(\alpha_0\) 对应的內结点剪枝。
输入:CART算法生成的决策树\(T^0\)
输出:最优决策树 \(T_\alpha\)
设 \(k=0\)
设\(\alpha_t = +\infin\)
对树,\(T^k\)各个内部节点 \(t\) 计算\(C(T_t)\) ,\(T_t\) 以及
\(T_t\) 是以t结点为根节点的子树,\(t\)代表结点t,也表示只有 \(t\) 一个 结点的树,\(C(T_t)\) 是训练数据的预测误差(可以用基尼指数或者均方误差表征),\(|T_t|\) 是\(t\)为根节点的子树的叶结点数。
对\(\alpha(t)=\alpha\)的内部结点\(t\) 进行剪枝,对于剪枝后的结点\(t\) 采用多数表决法确认其类别,得到树 \(T^{k+1}\)
\(k=k+1\)
重复 3-5 ,直到\(T^k\)是一个三结点树(一个根节点两个叶结点)
对于得到的子树序列\({T_0,T_1,\cdots,T_n}\),采用交叉验证法选出最优子树\(T_\alpha\)
最近在学习CAN,记录一下,也供大家参考交流。推荐几个我觉得很好的CAN学习,本文也是在看了他们的好文之后做的笔记首先是瑞萨的CAN入门,真的通透;秀!靠这篇我竟然2天理解了CAN协议!实战STM32F4CAN!原文链接:https://blog.csdn.net/XiaoXiaoPengBo/article/details/116206252CAN详解(小白教程)原文链接:https://blog.csdn.net/xwwwj/article/details/105372234一篇易懂的CAN通讯协议指南1一篇易懂的CAN通讯协议指南1-知乎(zhihu.com)视频推荐CAN总线个人知识总
Transformers开始在视频识别领域的“猪突猛进”,各种改进和魔改层出不穷。由此作者将开启VideoTransformer系列的讲解,本篇主要介绍了FBAI团队的TimeSformer,这也是第一篇使用纯Transformer结构在视频识别上的文章。如果觉得有用,就请点赞、收藏、关注!paper:https://arxiv.org/abs/2102.05095code(offical):https://github.com/facebookresearch/TimeSformeraccept:ICML2021author:FacebookAI一、前言Transformers(VIT)在图
关闭。这个问题不符合StackOverflowguidelines.它目前不接受答案。我们不允许提问寻求书籍、工具、软件库等的推荐。您可以编辑问题,以便用事实和引用来回答。关闭3年前。Improvethisquestion我正处于学习Ruby的阶段,我想查看一些小型库的源代码以了解它们是如何构建的。我不知道什么是小型图书馆,但希望SO能推荐一些易于理解的图书馆来学习。因此,如果有人知道一两个非常小的库,这是新手Rubyists学习的好例子,请推荐!我想使用Manveru'sInnatelib,因为它试图保持在2000LOC以下,但我还不熟悉其中经常使用的Ruby速记。也许大约100-5
由于匿名block和散列block看起来大致相同。我正在玩它。我做了一些严肃的观察,如下所示:{}.class#=>Hash好的,这很酷。空block被视为Hash。print{}.class#=>NilClassputs{}.class#=>NilClass为什么上面的代码和NilClass一样,下面的代码又显示了Hash?puts({}.class)#Hash#=>nilprint({}.class)#Hash=>nil谁能帮我理解上面发生了什么?我完全不同意@Lindydancer的观点你如何解释下面几行:print{}.class#NilClassprint[].class#A
我很难理解Ruby中sender和receiver的实际含义。它们一般是什么意思?到目前为止,我只是将它们理解为方法调用和获取其返回值的调用。但是,我知道我的理解还远远不够。谁能给我一个Ruby中发送者和接收者的具体解释? 最佳答案 面向对象中的一个核心概念是消息传递和早期概念化,这在很大程度上借鉴了计算的Actor模型。艾伦·凯(AlanKay)创造了面向对象一词并发明了最早的OO语言之一SmallTalk,他拥有voicedregretatusingatermwhichputthefocusonobjectsinsteadofo
rails新手。只是想了解\assests目录中的这两个文件。例如,application.js文件有如下行://=requirejquery//=requirejquery_ujs//=require_tree.我理解require_tree。只是将所有JS文件添加到当前目录中。根据上下文,我可以看出requirejquery添加了jQuery库。但是它从哪里得到这些jQuery库呢?我没有在我的Assets文件夹中看到任何jquery.js文件——或者直接在我的整个应用程序中没有看到任何jquery.js文件?同样,我正在按照一些说明安装TwitterBootstrap(http:
我已经开始学习Ruby,我已经阅读了一些教程,甚至还买了一本书(“ProgrammingRuby1.9-ThePragmaticProgrammers'Guide”),我遇到了一些以前从未见过的新东西使用我知道的任何其他语言(我是一名PHP网络开发人员)。block和过程。我想我明白它们是什么,但我不明白的是为什么它们如此伟大,以及我应该在何时何地使用它们。我到处都看到他们说block和过程是Ruby中的一个很棒的特性,但我不理解它们。这里有人能给像我这样的Ruby新手一些解释吗? 最佳答案 block有很多好处。电梯演讲:bloc
rails中View的解析过程是怎样的?我对View中erb标记中原始html与ruby代码的解析顺序部分感兴趣。我认为这是View代码被解析并最终发送给请求者的顺序:Controller调用ViewView代码从上到下解析当Rails在解析过程中遇到erb标记时:rails解析它并将结果附加到解析的html(这包括erb标签引用助手)一旦整个View被解析,整体结果将发送给请求者这似乎并非如此。看来View代码会扫描任何erb片段并首先解析那些片段(包括对助手的引用)。之后,rails然后从上到下解析所有View代码并将结果发送给请求者。以这个View为例:#_form.html
我在某些代码中遇到了三元组,但我无法理解条件:str.split(/',\s*'/).mapdo|match|match[0]==?,?match:"somestring"end.join我确实理解我是在某些点上拆分字符串并将总结果转换为数组,然后依次处理数组的每个元素。除此之外,我不知道发生了什么。 最佳答案 一种(稍微)不那么令人困惑的写法是:str.split(/',\s*'/).mapdo|match|ifmatch[0]==?,matchelse"somestring"endend.join我认为多行三元语句很糟糕,尤其是
有没有人成功地将S3存储桶读取为子文件夹?文件夹1--子文件夹2----文件3----文件4--文件1--文件2文件夹2--子文件夹3--文件5--文件6我的任务是读取文件夹1。我希望看到子文件夹2、文件1和文件2,但看不到文件3或文件4。现在,因为我将存储桶键限制为prefix=>'folder1/',你仍然会得到file3和4,因为它们在技术上具有folder1前缀。似乎真正做到这一点的唯一方法是吸收folder1下的所有键,然后使用字符串搜索从结果数组中实际排除file3和file4。有没有人有过这方面的经验?我知道像Transmit和Cyberduck这样的FTP风格的S3