面向产品领导者的决策分析 A/B 测试
将直觉编入数学中,进行强有力的决策对话
图片来源:延斯·勒列
TL;DR 现有的 A/B 测试方法采用频率主义方法进行统计假设测试。这些将产品负责人的直觉排除在流程之外,甚至将其视为非法。贝叶斯基础上的决策分析方法翻转过来,给产品领导一个直观的定量语言。由此产生的 A/B 测试方法比以前有更多的批判性思维和假设透明度的空间。我为此开发的一个开源工具( Excel , HTML )帮助产品领导者建立数学直觉。
A/B 测试已经成为产品团队对小的变更进行迭代测试的一个规程,测试对象是一个小的但是有代表性的用户群。有很好的课程教你 A/B 测试的细微差别。然而,这些课程中的大部分是面向数据科学方向的人的。作为产品负责人,您正在寻找推动决策对话的方法。你已经对你的用户和你管理的产品有了大量的直觉,但是支持你的数据科学团队是“数据驱动的”,不会为你的直觉留出空间。反过来,你会发现自己变得不耐烦。这不是一个学术博士练习。您有时想知道您的数据科学团队是否理解您需要快速做出决策。当你获得数据并开始下结论时,你的数据科学团队会不断提醒你,你做得有些过头了。如果这些挫折听起来很熟悉,并且你一直在为缺乏统计知识而自责,那么我可能有一些好消息要告诉你。
如果让你失望的不是统计知识,而是统计本身的当前味道,那会怎样?如果有一种更好的味道,实际上更容易理解,旨在支持决策,并为您的直觉提供明确的空间,会怎么样?如果这种更好的风格已经被您的数据科学团队理解和欣赏,或者需要一点点高度可实现的提升,会怎么样?事实证明,传统的 A/B 测试是在“频率统计”的帮助下完成的统计学的这一分支在与决策的兼容性方面非常有限,并且与将你的直觉带入数学的概念完全不相容。通过在正式实验中取缔产品领导者的直觉,这个统计学分支实际上是问题的一部分。
如果让你失望的不是统计知识,而是统计本身的当前味道,那会怎样?
有更好的方法,贝叶斯 A/B 测试的变革之风已经吹向那个方向(见这里、这里、这里和这里)。在本文中,我将更进一步,讨论在贝叶斯基础上进行 A/B 测试的决策分析方法。原因很简单。产品领导者必须最终做出决策,而不是获得数据科学的博士学位。我将利用我的产品定位来设计对话,让您的直觉直接参与进来。如果你像我一样是一名工程师,只有当你能修补一些东西时,直觉才会产生。所以,我会让你接触一个我为此设计的教学工具:将你的产品直觉带入 A/B 测试的数学中,并推动高质量的决策对话。
在我们开始之前,让我们花一点时间在 frequentist A/B 测试的核心问题上。
频率主义者 A/B 测试的问题 没有决策的区分,频率主义者的统计就被迫创造出各种不必要的区分(比如统计力)。借助决策分析透镜,我们可以使用直接工具来测试我们决策的稳健性。这一点都不新鲜。事实上,贝叶斯决策分析透镜实验在 1970 年就已经解决了。今年是那篇论文发表 50 周年(2020!),这也是我写这篇文章和附带工具的动机之一。
对于那些从来没有听说过贝叶斯统计学派的产品领导,你可能想知道这有什么大惊小怪的。在本文中我不会深入探讨这个问题(因为我在这篇文章中已经这样做了),但是让我们快速浏览一下。虽然关于这一点可以说很多,但我将把重点放在最有力的论点上。统计学实验的目的是从一个我们可以接触到的很小的、有希望有代表性的子集里了解一些关于人口的情况。
换句话说,假设我们的数据是真实的,我们想知道我们的人口模型是否真实。frequentist A/B 测试的数学回答了完全相反的问题:假设人口模型是真实的,那么数据也是真实的吗?我们必须从假设总体呈正态分布开始,并在假设正态分布成立的情况下,尝试对偶然看到效果的可能性做出陈述(有一天,有人会向我解释偶然看到某个东西的可能性意味着什么)。这是一个正在解决的错误问题,我甚至不会谈论它是如何被草率解决的。我将引用美国统计协会 2016 年的历史性声明中的第 5 条,该声明敦促统计学家走向后 p 值世界:
一个 p 值,或统计显著性,并不能衡量一个效果的大小或一个结果的重要性。
然后,还有那些聪明的统计学家的所有复出之母,他们已经学会了频率主义和贝叶斯方法,“哦,如果有足够的数据,你采取哪种方法真的无关紧要。”这是一个危险的论点,因为尽管从技术上来说是正确的,但它让我们绕过了深入思考我们正在学习什么以及我们如何学习的问题。我们将在本文稍后正式进行这种批判。现在,我将注意到批判性思维是产品领导者的重要职责,我们必须努力找到将数据科学和产品管理的最佳天赋结合在一起的方法。
凭直觉学习我将为一篇关于贝叶斯统计的文章做些奇怪的事情。我不会向你扔任何数学方程式。相反,我将使用我认为容易理解的简单区别,并让您使用这个为此目的而构建的开源教学工具( Excel , HTML )来发展自己的直觉。顺便说一下,HTML 工具使用 FISH 架构,这意味着它是一个单独的 HTML 文件,你可以安全地下载到你的计算机中,它不会向任何地方传输任何数据。使用这个工具,你可以理解我的观点,这很容易理解。
设置
对于我们的 A/B 测试,让我们从一些设置开始。我们想知道在主页上增加行动号召按钮的大小是否会增加点击量。让我们假设我们的实验转移单元是“用户”,这意味着一个用户将只在实验组或控制组中,而不是两者都在。我们将我们的实验建模为独立的硬币投掷,其中每次硬币投掷代表特定用户的页面视图。页面视图是一个页面,有一个按钮,我们希望用户点击。如果用户点击按钮,这与我们的模型所说的掷硬币“正面落地”相对应
该模型假设抛硬币是相互“独立”的。在您的实验中,您需要确保您没有对同一用户的同一页面的多次浏览量进行计数。关于设计好的 A/B 测试,一般都有很好的建议,你会想去留意的,我就不多说了。我们感兴趣的关键指标是头部的长期比例,我们可以将其解释为按钮点击的长期比例。
请注意,这是经过仔细定义的,因此不是是一个概率。这很重要,因为很快,我们将会表达我们对这种区别的不确定性。你只能对没有内在不确定性的事物表达不确定性。为了理解这一点,考虑一下下雨的的概率。如果对“雨”的含义有任何不确定性,那么在一个不清楚的区别上再增加一个可能性是没有意义的。为了使下雨的可能性有意义,你和我必须就下雨的精确定义达成一致,这个定义不能有任何不确定性。
你只能对定义中没有内在不确定性的事物表达不确定性。
决策分析有一个很好的概念,可以帮助我们围绕这个问题进行思考。这被称为透明度测试。如果一个千里眼能够告诉我们这种区别在未来将如何解决,那么这种区别就通过了清晰度测试。透视者被定义为只能陈述关于未来的事实,但不能做出任何判断的人(虚构的)。例如,一个透视者不能告诉你你的模型是否正确,因为模型存在于你的头脑中,而不是存在于事实的世界中。只有当一个区别通过了清晰测试,我们才能给它一个概率。我们不能把概率放在正面概率上。但是我们可以对人头的长期比例设定一个概率,因为千里眼可以精确地告诉我们在长期中有多少人头出现(当然,我们必须同意多久是长期),因此,给我们长期比例。我将留给读者一个练习,让他们弄清楚像“假设正确的概率”这样的陈述是否通过了清晰性测试。我们在这里不需要这样的声明。
千里眼无法告诉你你的模型是否正确,因为模型存在于你的头脑中,而不是存在于事实的世界中。
工具中 A/B 测试的设置
您将从上面的截图中注意到,这里也有决策分析元素。具体来说,我们正在评估每次点击的价值。产品负责人往往会有这种感觉,所以我在这里就不深究了。对于我们的例子,我们将假设它是 1 美元。我们还在评估最终的发布受众规模(这里设定为 100 万),前提是我们决定推出该功能,以及这样一次发布的成本(设定为 2 万美元)。我们稍后将使用这些信息来指导我们的决策分析。
为实验和控制建立先验
好吧,那么这个词“优先”是什么意思?贝叶斯区分的好处在于,它们与该术语的英文含义一致。先验是指你在实验前的知识状态。我们人类基于我们所知道的来学习。如果我们什么都不知道,我们从数据中学到很多。如果我们对某件事了解得非常透彻,在我们改变主意之前,我们需要看到大量不确定的证据。这些明智的逻辑学习方法与统计假设检验不相容。相反,它们是贝叶斯方法的起点。我们必须利用我们所知道的兴趣的区别。
参与我们所知道的不仅仅是一个反思的练习。我们还在这里做一个建模决策,并以一种特定的形式表达我们的不确定性,这种形式代表了我们对的感受*。还记得关于能够在数学中捕捉你的直觉的承诺吗?这就是我们在这里讨论的问题。如果现在你的闹钟响了,这是有原因的。我们都被灌输了为了科学而客观的饮食,但是再深入一点,最伟大的认识论者会告诉你一个坏消息,“科学是主观的。”问题不在于主观性,而在于我们对待主观性的方式缺乏严谨性和透明度。我更希望我们使用停止假装客观的语言,并乐于暴露我们的假设。这样,我们可以建立一种学习文化,而不是被我们不知道的假设所阻碍。*
前科有三种选择。在工具中,单击要使用的工具。
当您在工具中展开“构建先验”部分时,您将看到三个选项。第一个是不知情的先验,它对应着这样一种信念:“我对兴趣的区别一无所知。”乍一看,有些人会声称这是正确的科学立场。乍一看,当你知道 好的按钮点击率很少达到 10%时,这是没有意义的。如果超过 20%,产品领导就不会想,“太棒了!”相反,他们在想,“实验出了问题,让我们找出原因。”现在,我们先不讨论这个论点,如果你有大量的数据,先验知识就不重要了。
第二个选项是对称先验,对应于:“我有一种感觉,用户点击率将达到平均 50%,并且它同样可能以对称的方式高于或低于该值。”这是一个非常具体和强烈的信念,看起来非常奇怪,鉴于我们对上述统一先验的批判。
最后,剩下不对称先验的第三种选择。你可能已经注意到了,我正在鼓励你用这个选项来表达自己。如果科学是关于以最严格的方式找到你的真理,如果这个分布允许你严格地表达那个真理,那么我将声称这是最好的科学选择。只要宣布出来,其他人就可以挑战你,如果他们愿意的话,用他们自己的前科。从数学上讲,所有这些选择都映射到 Beta 分布的特定形状参数上。Beta 版是一个灵活的发行版,它还有一个重要的特性。当我们通过增加形状参数将它与伯努利试验(掷硬币试验)结合起来时,很容易更新。在本文的其余部分,我们将不再深入研究贝塔分布的数学。
当你向下滚动你的选择,你会看到一些形状选项,像这样:
请注意,当我们增加缩放倍率时,方差如何下降。需要注意的关键是,概率是概率分布函数(PDF)曲线下面积的度量。总面积总是正好等于 1。
上面的例子可以让你表达你的信念,平均来说,你认为你会达到令人印象深刻的 10%的点击率。分布的粗细代表了你对此的确信程度。虽然设置这一点的技术方法是使用方差,但我引入了一个称为“先验标度能力”的区别,以使这一点更加直观。先验标度功效是一个乘以分布形状参数的数字,影响方差,但T5 而非 平均值。您可以看到,当您向右拖动缩放比例时,方差是如何下降的,而平均值保持不变。
让我们直观地想到这一点。你的先验是一种将你的直觉等同于数据的方式。如果你像我们这里一样以 1/10 的概率开始,你是说你的直觉相当于看到 1/10 的投掷。然后,如果你把标度力量设置为 10,你现在说你的直觉相当于 100 次投掷中的 10 个头。虽然这将平均值保持在 0.1,但方差减少了,因为投掷次数增加了,你应该理所当然地减少一点不确定性。随着你越来越确定,通过增加先前的能力,你正在减少你的不确定区域。实际上,看看显示分布百分位数的表格是如何变化的(这是我们的贝叶斯 80%置信区间)。当缩放比例为 1 时,它们开始于(0.012-0.074-0.226),当缩放比例为 100 时,它们结束于(0.088-0.1-0.112)。基本上,随着方差的下降,范围越来越窄。
假设我们可以接受先验均值为 0.1,标度为 2,这相当于 20 次投掷中有 2 次。这让我们在表达知识的同时,也为不确定性留下了足够的空间。我们现在可以继续为控件构建我们的先验。以类似的方式,让我们说,我们相信它产生按钮点击的可能性是一半,我们可以选择 0.05 作为先前的平均值,标度幂为 2。这个先验相当于 20 次投掷中有 1 次。我们现在准备进入下一阶段,从我们的实验中学习。
从实验中学习
建立先验知识后,您将希望充分利用现有的所有知识来设计好的实验,这些知识可以来自您所学的课程,也可以来自您的数据科学团队的指导。你在实验和控制中收集了你的数据。你现在可以开始学习了。打开工具中的“从实验中学习”部分,输入实验和控制中的投掷次数(页面浏览量)和点击次数。在我们假设的例子中,假设实验组的 10,000 次页面浏览中有 400 次点击,而对照组的 10,000 次页面浏览中有 300 次点击。最初,这使得后验分布看起来相当窄。
向实验组和对照组学习
我将在这里介绍另一个区别,“后验标度能力”,它类似于“前验标度能力”。我们将数据(投掷次数和头数)除以这个幂。这个操作可以让我们表达自己希望被数据影响到什么程度。如果我们将此值设为 1,那么我们将按面值获取全部数据。如果我们增加它,我们开始降低我们看到的数据的能力。直观地说,后验标度 100 意味着 100 次点击(和 100 次浏览量)会被计为 1。您正在设置从数据中学习的尺度。有了这个区别,你就能提高真正确定的标准。这就是我们如何应对这样的批评,即如果我们有“足够”的数据,先验并不重要。有了足够高的后验标度能力,这就很重要了。
虽然有一个很强的诱惑去问,“我们应该在哪里为后验规模力量设置障碍”,但是一个更好的问题是:我们的决策将如何基于后验规模力量而改变?注意上图中桌子下面的线条。他们报告有助于我们做出决策的价值指标。这个模型有一个简单的价值模型——我们将长期点击分数的平均值(也是下一个人点击的概率)乘以将获得已推出功能的用户数量和每次点击的价值。即使如此简单,我们也可以看到,最初,当数据被充分利用时,我们不应该启动,因为成本超过了收益。然而,如果我们缩小一点数据,保留更多的不确定性(通过增加后验标度能力),这种不确定性允许更高的点击率,因此,价值上升。在后验标度为 251 的情况下,我们的决策有一个交叉,如下面的灵敏度图所示(在工具的灵敏度部分)。
对后验标度能力的敏感性
这种敏感性分析告诉我们的是,我们推出的决定对我们对数据的怀疑是非常坚定的,但如果我们从表面上看数据,就会改变。为什么会这样呢?这与我们先前的信念有关。记住,我们一开始就相信实验会比控制组好一倍。为了在行动中看到这种信念,让我们一起将实验归零(在“从实验中学习”一节中为所有四个输入输入 0)。这将立即揭示,如果你根本不做实验,你应该只是发射。
也可以做相反的灵敏度分析。让我们对这些数据持怀疑态度,选择一个 400 的后验幂标度。这意味着你将每 400 次点击(和浏览量)视为 1 次点击(和浏览量)。让我们找出需要在控件中看到多少个头才能改变我们的想法。下面的分析清楚地表明,如果我们看到 414 次点击或更多,我们应该改变主意,重新考虑推出。
当后验标度功效= 400 时,对控制中头部的灵敏度
请注意,这个决策分析层比“统计能力”的概念有用得多,因为它让我们非常直接地进入决策对话。
最后,让我们看看改变我们的先验对分析有什么影响。让我们回过头来为实验组和对照组选择不知情的先验。我们会发现我们根本不应该发射任何规模的能量。下面的敏感性分析显示了这一点。
先验一致时的灵敏度
对称先验也讲述了一个类似的故事。实验组中没有足够的点击量来证明一次发布是合理的。
先验对称时的灵敏度
因此,我们可以看到,决策分析 A/B 测试允许我们整合先前的直觉,并做出与协同工作的决策,而不是违背我们的直觉。这种方法的美妙之处在于,夸张是绝对没有价值的。如果我们对自己的过去过于乐观,或者过于悲观,我们的决定就会因此而有所偏差。这种数学方法让我们能够说出直觉的全部真相,并据此进行学习。作为一名产品负责人,我希望您能理解这为您与数据科学团队的合作开辟了新的前景。数学允许他们从你的直觉中学习,让你的思维变得透明。你的主观性没有被取缔;相反,这个过程允许你和你的感受进行严格的交流,这样你和其他人可以互相学习,做出更好的决定。
我怀疑现有的 A/B 测试软件系统会发现很难从哲学上支持这种转变,而且这需要一些时间。这不仅仅是实现新的方程式。它是关于促进透明和强有力的对话。希望本文中提到的开源工具可以让您至少尝试一下本文中讨论的推理和决策,直到您的系统赶上这种思维。
感谢斯坦福大学的 Ronald A. Howard 教授在 1970 年如此果断地解决了这个问题*,感谢加州大学洛杉矶分校的 Thomas Ferguson 教授开源了他的* 不完整的 beta 函数和 log gamma 实现 (这是我的工具用来产生置信区间的工具),他将塞西尔·黑斯廷斯的 归功于他 1955 年的著作 where 如果这篇文章中使用的决策分析(清晰度试验、千里眼相赠)引起你的兴趣,这里是的出处。这里是工具 的 Github 页面。本文附带的 Excel 模型 在CC0下获得许可,可用于任何目的,无需署名。
数据标注策略的决策框架
现实世界中的数据科学
打破关于数据标注工作流程和预算的常见误解,提供一个现实的决策框架,将您的数据标注策略从有缺陷变为完美。
[版权所有 Playment 公司]
去年,在 2019 年 CVPR 上,我与特斯拉人工智能高级总监 Andrej Karpathy 进行了一次短暂的会面。在我们的谈话中,我问了他一个相当天真的问题,“Andrej,你如何估计在特定场景下训练和验证自动驾驶汽车所需的标记数据量?”他停顿了一会儿,然后笑着说,“嗯,378 小时的数据。明天再问我吧,我的数字可能会更大方。”接下来的两分钟,我们一直在笑。
今天,众所周知,我们需要大量高质量的标记数据来训练和验证 ML 模型。但在见过数百名人工智能团队领导和多个处于人工智能发展旅程不同阶段的人工智能初创公司 CXO 后,我观察到市场对标记数据的获取有不平衡的理解。
大多数处于人工智能成熟度曲线高端的 ML 团队认为标签数据获取是他们的主要优先事项之一,并理解过程中涉及的不同层次的复杂性。然而,大多数玩家在远端为他们短暂的项目找到了一些变通方法。此外,我还观察到,几乎所有的 ML 公司都经历了一个自我实现的周期,即忽略数据管道的这一方面,最终构建大规模的软件和运营力量来处理他们标记的数据需求。
因此,可以肯定地说,当前人工智能生态系统中的一个大问题是,“如何经济高效地访问大量多样化和高质量的标记数据?”
数据标注过程固有的过度简化
数据标记操作:感知与现实
首先,将流程过度简化为一个简单的“租用-注释-支付”模型只会为实现自动化目标设置更多的障碍。任何功能性 ML 模型最重要的先决条件是高质量的标记数据。成本妥协只会让你陷入更深的困境。数据标签操作:感知与现实
标签预算通常被认为是每个人工注释者 7 美元的固定成本和所需的注释工时数的乘积。这种方法是完全不正确的,因为他们没有考虑 ML 工程师在设置注释过程中产生的各种隐藏成本。
数据标注过程中忽略的因素
让我们通过一步一步的过程来理解实际预算是如何超过简单的数学公式的。
**步骤 1:**ML 工程师首先创建指南,清晰地定义注释的类别和每个类别的期望设定点,以训练人类注释者。这一步重复几次,因为现实中,没有人第一次就做对了;指南需要多次迭代。
**第二步:**接下来,他/她需要发现或创建支持其数据格式的注释工具,生成高度精确的像素级注释,并提供可伸缩性以适应其大型数据集。这个评估/开发过程可能需要几天或几周时间。
步骤 3: 然后,工程师从第三方那里找到合适数量的有技能的人类注释者,或者雇佣兼职注释者。寻找合适的劳动力需要一个设计良好的试点计划和对多种劳动力的评估,然后是合适劳动力的谈判、签约(与财务和法律团队合作)。
步骤 4: 接下来,他/她建立工具基础设施,培训注释者使用工具,并提供注释需求作为任务。他们还创建和管理注释任务的截止日期。此外,他们还定期跟踪注释器的进度。
**第五步:**工程师然后设置工作流、逻辑或脚本来测试输出的准确性,向违约者提供反馈,并重新分配错误的标签以便返工。对每批注释重复此步骤。
步骤 6: 间歇地,他们重复上一步,直到标记的数据达到他们期望的精度水平。整个过程耗时耗力。
通常,数据标签预算并不包括每一个步骤的额外成本因素。真正的预算包括 ML 工程师的时间和精力成本,100 美元/小时或以上,加上注释者的成本——两者都比 7 美元/小时高 10 倍。
随着要注释的数据的特殊性、多样性和数量的增加,工具基础设施、劳动力和项目管理的复杂性也在增加。有效管理这些复杂的流程对于实现高质量的产出变得极其重要。
说实话,ML 工程师最好做他们最擅长的事情,而不是纠结于这些操作流程。
数据标注策略的现实决策框架
数据标记策略的决策框架[Copyright Playment Inc.]
对于这个框架的广泛应用,我使用了人工智能开发周期的三个阶段,以及三个主要的数据标记功能作为决策的基础。除了解释开发周期每个阶段中功能的复杂程度,我还额外提供了大概的预算,以简化决策者的类别评估。
我已经确定了设置过程的复杂性和数据标签所涉及的预算的真实性。现在让我们深入研究这些函数。在游戏中,我们将之前提到的六步流程分为三个重要功能(见上图):
- 注释工具
- 劳动力
- 项目管理
这些功能的复杂程度取决于为注释收集的数据量,以及所需的人工注释者的数量。例如,根据数据量,注释工具可以是 100%手动的,也可以是非常复杂的,带有各种自动验证检查或人工智能辅助,以最大限度地减少错误并确保更快的数据吞吐量。
工作人员可以 100%来自内部或外包,这取决于注释的数据量。当注释器需求超过 1000 个注释器时,您也可以选择多供应商模型。
10 个和 1000 个人类注释者的有效项目管理是非常不同的问题。前者几乎不需要任何东西,但后者需要复杂的软件和分析来训练标注者、分配标注任务、跟踪质量、速度等性能。这与监控装配线非常相似。
基于这个现实的框架,Playment 建立了一套复杂的技术和劳动力解决方案,以帮助小型、中型和大型公司无缝地为他们的数据管道提供燃料,以更快地激活人工智能应用程序。
结束语
这个决策框架符合大多数 ML 团队的要求。然而,数据安全性和自动化是在很大程度上影响架构决策的其他重要参数。它给这个原本简单的框架增加了一层额外的复杂性。欢迎在推特@ Playmentq上给 play ment 发 DM,或者发邮件给我们 hello@playment.io 讨论同样的问题。
我希望这个框架将有助于行业避免由于普遍的误解而导致的不正确的数据标签架构决策带来的陷阱;帮助 ML 社区以前所未有的速度构建高度精确的 AI 模型。
加速人工智能时代!
最初发表于 Playment 博客(【https://bit.ly/2Q6iqjm)和 LinkedIn(【https://bit.ly/2TM76vj)。
挖掘决策智能
数据科学
数据科学或如何决定如何决定
图片由 Unbox Science Pixabay 提供
谷歌的 Cassie Kozyrkov 一直在推广决策智能的理念。决策智能(Decision intelligence)这个术语是由 Kozyrkov 创造的,旨在将已知的决策方法、洞察力和最佳实践重新组合到一个公共的保护伞下。这些已知方法和见解的例子有:
- 分析学
- 统计学,频率主义者和贝叶斯
- 机器学习
- 决策科学
- 行为经济学
- 决策的心理学和神经学
上面的列表中有意省略了数据科学。数据科学是一个流行的术语,但没有很好的定义:所有的科学不都是数据科学吗?也许这篇文章是一个实验,看看术语决策智能是否更好地界定了一个连贯的兴趣领域。首先,决策智能的一个核心原则是,目前被称为数据科学的领域有很多都与决策有关;或大或小。一个人如何决定如何决定?这就是这篇文章的范围。
这种新划分的部分结果是,我们所知道的数据科学项目可以通过更精确地了解不同任务和所需角色的结构来更好地执行。
有没有决策架构或基础设施这样的东西,它看起来是什么样的?
这篇文章的目的是希望总结一下谷歌的 Kozyrkov 在不同博客和媒体上发布的大部分决策情报内容。总之,这是初步的,因为尽管它基于大量的博客文章,但它并不打算包含所有的内容。也不清楚是否所有信息都在网上公布。在这篇文章中,我将有目的地推动术语“决策智能”,作为一个实验,但也可以随意阅读“数据科学”。
这篇文章的概述
为了您的方便,这里列出了这篇文章中包含的部分和主题:
- 决策:从零到少到多
- 分析学
- 基于频率统计的假设检验
- 贝叶斯统计的一个例子
- 比较:分析、频率主义者和贝叶斯统计
- 机器学习
- 论可解释性、检验和偏见
- 做应用是可以的
- 决策智能过程
- 决策智能团队和决策者
- 一些附加的想法
- 最后的想法
决策:从零到少到多
游戏的名字是做出更明智的决定。在本节中,将介绍决策制定的初始分类,这将在下面的部分中详细阐述。
决策智能的一个中心思想是人们可以面对以下场景:
- 人们希望做出大规模的决策,大量的决策
- 人们希望做出一些具体的决定
- 一个人还没有准备好做决定,因为他缺乏洞察力
让我们从大规模决策开始。
机器学习符合这个法案。想估价几百万的房子?想把几十亿条推推荐给几百万人?想要给数十亿张照片添加标题吗?当前的信息革命在很大程度上是关于数据和决策的扩展,超出了以前的想象。在这场规模革命之前,决策的制定,更多的是在少数人的规模上,是统计学的领域,无论是频率主义者还是贝叶斯主义者。
统计有助于管理而不是消除基于人口样本数据而非全部人口信息做出决策所带来的不确定性。使用统计数据做出数百万个决策不符合该框架,需要使用例如 Bonferroni 校正来校正重复测试。但这有其局限性。更具体地说,对于频率主义者的方法,人们应该提出一个由零假设表示的默认行为过程。有规则要遵守,稍后会有更多。
最后,但同样重要的是,有时一个人只是还没有准备好如何思考手头的决定:需要的是灵感。在这种情况下,分析可以也应该有所帮助。
为了使这种分类更具实质性,我们将在接下来的章节中详细阐述这三个感兴趣的领域。
分析学
分析就是分析手头的数据,或多或少地忘记数据集之外的世界。一个优秀的分析师可以快速剖析数据集,并从数据中选择感兴趣的模式。分析是关于产生想法或产生更好的问题。统计学家可以在当前数据集之外使用另一个数据集提取其中一些问题进行归纳。在某些特定情况下,分析也足以推动决策,下一个例子将对此进行说明。
让我们假设一个人可以以相同的价格购买一批蓝色 t 恤或一批红色 t 恤在当地的集市上出售,但不能两批都买。没有既定的偏好,或默认的行动,一个随机询问周围的颜色偏好,以确定哪一批是更好的选择。如果在颜色上有任何多数票,那么在没有应用统计数据的情况下,采用多数票是可以的。为什么?因为你没有偏好,没有数学或统计学会让多数人的结果偏向少数人的结果。票数的差异可能毫无意义,但多数票仍然是最安全的赌注。
请注意,本例中没有任何政治信息,只是需要注意样品的采集地点与 t 恤的销售地点之间的关系。数学不会改变少数人投票的决定,但样本偏差的概念可以:但这不是一个数学问题。
使用假设检验来做决定。
基于频率统计的假设检验
在前面的示例中,没有默认操作。在很多情况下,有一个默认动作;这种默认操作通常是保持现状。无论是信任明智、相信明智还是投资明智,这种默认行为都有一定分量。(还有更多技术上的原因,后面会详细介绍。例如,一个人可能想知道一种特定的治疗是否值得。简而言之,在这种情况下,假设检验有助于在对人口样本进行处理后,形成关于人口参数的信念,即某种条件的存在与否。让我们更详细地阐述一下。
如果评估治疗,因果关系是很重要的。通常人们会使用随机试验,将人群样本分为治疗组和对照组。如果做得正确,这个实验包括一个要被证伪的零假设和另一个假设。在将治疗应用于对照组之后,基于两组的结果以及在它们之间发现的可能差异,可以计算出臭名昭著的 p 值或概率值。p 值是如果零假设为真,即如果没有影响,计算出的差异发生的概率。如果这个概率非常小,那么零假设被拒绝,取而代之的是另一个假设。
这个例子的目的不是深入假设检验的哲学细节,而是为了说明假设检验过程是为一个非常具体的目的而设计的。重复测试程序可能会产生类似的结果;强调客观事实和可重复性。该框架旨在用于必须做出少量明确决策的情况。增加决策的数量会遇到一些问题,这些问题只能在一定程度上得到解决。
如果决策不太明确,或者更复杂,贝叶斯统计可以提供一个很好的选择。虽然我在决策智能的上下文中没有看到很多关于贝叶斯统计的内容,但是由 Douglas Hubbard 定义的应用信息经济学(AIE)的框架可以提供一个很好的例子,作为与频繁主义统计的对比。
贝叶斯统计的一个例子
复杂的决策可能需要大量信息。这些信息有些可能就在手边,但有些可能没有。更一般地说,仅使用频率假设检验来制定复杂的决策可能被证明是不可克服的。不可能总是以严格的方式测试所有的东西。有时,预先的信念或专业知识是决策过程的一部分。贝叶斯统计允许你这样做。虽然先验信念的概念听起来可能模糊,但贝叶斯统计可能非常强大,因为人们可以使用观察来更新信念。希望下面的例子能让我们感受一下它的工作方式。请注意,这个贝叶斯统计的例子是有目的地偏向于一个应用的业务设置,并且非常平凡。
假设有人对建立一个系统感兴趣,任何系统。建立这个系统需要完成 1500 个单独的任务。先前的看法是,完成一项随机任务的小时数的 90%置信区间在 15 分钟到 7 小时之间。此外,先前的看法是,一小时工作的市场价格在 19.50 美元和 47.50 美元之间。使用这些信念,并假设两个信念的正态分布,可以通过运行蒙特卡罗模拟来计算系统人工成本超过 10.000 美元的概率。怎么会?人们可以从任务分布中抽取 1500 个样本,然后将每个样本乘以从小时率分布中抽取的样本,从而得到一个“实现”。通过多次重复这些步骤,可以创建人工成本的模拟概率分布;这种分布有助于推断可能的结果。
这种模拟之所以成为可能,是因为接受先验信念作为起点,这是贝叶斯统计的核心原则。尽管这个例子非常简单,但是这个框架允许复杂性扩展。为了表明我们没有践踏现实、观察和统计,我将进一步阐述 AIE 框架。在 AIE 框架内,提出了以下有科学证据支持的概念:
- 在一些训练之后,大多数人可以被训练来提供精确的/校准的概率或置信区间估计。
- 估计,虽然是一个很好的起点,但很容易受情绪和环境的影响。
- 估计中的任何不确定性都可以通过用样本观测值更新先验信念来减少。先验分布被转换成后验分布,其中证据被考虑在内。
- 减少分布不确定性所需的样本量小于预期;通常 5 到 100 个样本就能创造奇迹。
- 在不确定性最高的地方,观察的影响最大。
- 给定一些模型结果,就有可能评估添加额外信息的价值——表明哪些成本是合理的。
- 复杂决策的模块化使决策更可靠、更准确。
- 目标不一定是尽善尽美,而是击败当前的决策方法(通常只是专家建议)。
AIE 框架允许以显著的方式模块化和管理复杂的决策及其相关信息;这一切都有统计数据支持,尽管这个过程开始时可能只是一个思想实验。
是时候回顾和比较一下了。
比较:分析、频率主义者和贝叶斯统计
在前面的三个部分中,说明了三种不同决策框架的优点和缺点。在本节中,将讨论一些比较和对立,以增加更多的深度。
分析和频率统计通常共享共同的术语和计算,如均值、方差和 p 值。尽管如此,框架的目标是不同的,这可能会导致混乱。分析师可能会观察到一些统计数据中的差异,并获得 p 值。这个 p 值是什么意思?根据统计学家的说法,什么都没有。p 值属于假设检验的范畴,假设检验需要遵循一个明确定义的过程。统计学家可能就在这里。任何科学家获得一个数据集,把这个数据集翻个底朝天,获得一些统计数据的 p 值,然后声称已经验证了一个假设,都有可能丢掉工作。
人们不使用数据集作为灵感,然后使用相同的数据集进行假设检验。虽然拆分数据通常是可取的,但也只能起到这么大的作用。证明因果关系的受控实验设置如何?还是因果不相关?还是混淆了相关性?假设检验是否设置了显著性水平,该水平是如何设置的?是否针对测试的功效进行了调整?在用一组数据来检验一个假设之前,有许多问题需要回答。分析更多的是在过程的“商业”方面,可以提供有价值的见解,可以作为灵感;但是不要把它弄得乱七八糟。
另一方面,频繁假设检验的所有严格性都有其局限性。如果面对涉及大量信息的复杂决策,频率主义者的统计可能会有所欠缺。纯粹的数学严谨性并不是对所有情况都适用的。贝叶斯统计允许通过使用和验证关于当前问题的先验信念来调整决策。它允许分析哪些地方需要更多的信息或最有影响力,以及何时获取的成本与收益相称。任何数据计数都是有用的,在这种情况下,重要性不是关键问题。
在这个例子中,频率主义者和贝叶斯统计都专注于以严格的方式做出少量的决策。那么大规模决策怎么样,也就是机器学习?或者通俗点说就是 AI。
机器学习
人工智能这个术语是在上个世纪 50 年代引入的。从那以后,这个术语涵盖了许多方法。目前,它通常指的是机器学习,但肯定有更多的方法可以满足这一要求,并且在过去已经得到了应用。
科兹尔科夫把机器学习贴上标签,就是给事物贴标签。标签可以是各种各样的:猫、狗、数字、操纵杆运动。后一个例子表明,强化学习在机器学习下是错误的。如前所述,机器学习是大规模标注的首选工具。出于这个原因,机器学习可以更加软件密集型。这可能是对机器学习在计算机科学的羽翼下发展壮大这一事实的解释。
机器学习的主要考虑因素是偏差和方差。通过训练、验证和测试数据的概念来控制这些类型的错误。(或使用其变体。)从用户的角度来看,统计分布不太受关注。尽管在模型的优化和训练、验证和测试数据共享一个公共分布的假设中,这些仍然是相关的。
在机器学习中,非常强调模型性能。对于像预测性维护这样的纯技术应用,这并不奇怪,也没有理由担心。当涉及到对人类或其他动物做出决定时,道德问题很快就会出现。
论可解释性、检验和偏见
准确的说,算法永远不会有偏差,但数据可以。因此,使用这些算法和数据的模型的结果也可能有偏差。这是一个真正的问题。机器学习使得衡量决策变得非常容易。这也使得人们很容易犯大规模的错误。如果这些错误系统性地让大量人群处于不利地位,因为这个系统反映了最终创造者有时无意识的价值观,那么道德就岌岌可危,伦理讨论需要加入争论。但是让我们先来看一个关于偏见的小例子。
想象一下,一个系统可以识别技术人才的机器学习职位,为了做到这一点,系统会扫描简历并给简历打分。众所周知,区号可以作为许多隐藏变量的代理。随着学校教育变得越来越隔离,不难想象学校名称也会以同样的方式运作。让一个高级的 NLP 系统基本充当斯坦福、伯克利或者麻省理工的扫描仪有用吗?向一个已经缺乏多样性的行业添加更多相似的简介?在过程中的某一点上,模型的目标将必须被转换或形式化为一个函数,即可以被优化的目标函数。这种形式化和选择的数据一起引入了假设和无意识的偏见。最后一点,简历扫描仪不就是为了显示偏见而设计的吗?你必须知道你在做什么。
在欧洲,根据 GDPR,人们有权知道自动决策是如何计算出来的。至少可以说,在这个意义上,不是所有的模型都是透明的。而且很多根本不透明。如果条件不够完美,即使是简单的线性回归模型也会带来挑战。正是在这种背景下,SHAP 或石灰等方法被创造出来。这些方法旨在深入了解哪些特性对决策影响最大。这很有帮助。问题是这些方法提供了对底层算法的局部近似。这种解释可能是粗略的,或者不是普遍适用的。这引出了一个有趣的问题。
机器学习的全部意义在于,模型的工作太复杂,用手工编程太难。编程包括数据和规则输入和输出。机器学习由数据和答案组成,包括输入和排除。试图使规则透明化或多或少会违背初衷。如果这是可能的,那么人们应该对系统的规则进行编程。这并不意味着情况没有希望。另一种方法是严格测试模型的偏差。尽管测试一个模型可能无法捕捉到每一种形式的偏差,但它至少可以使它与一个可比较的过程一样公平。
如果到目前为止,所有的信息都让您有些眼花缭乱,那么没关系。整合所有不同的关注点并应用正确的方法是非常重要的,这是下一节的主题。
做应用是可以的
不同决策框架的实际应用,及其所有的含义,是相当复杂的。当它涉及机器学习时,还有繁重的工作、正常运行时间、监控、概念漂移,以及你在玩什么。突出所有的细节可能会很容易地填满课程中的一些学期,或者可能需要多个角色才能成功完成。这才是重点。
不一定要成为决策智能相关领域的科研人员。几乎相反,有足够的知识和考虑使应用决策智能成为一个专业。如何收集一些商业智慧?或者确切地了解决策智能在流程中的哪一点最有效?很容易融入更多的管理科学、行为经济学或心理学。
与此同时,科学目前在没有决策智能的情况下也做得很好。整个科学界已经想出了回答问题的方法。每个研究领域都有自己的一套公认的方法,旨在推动各自领域的决策。精算师、后勤学、心理测量学、生物学、流行病学,名单还在继续。这些领域中的许多方法是重叠的,但是每个领域中也有不同的方法。这些方法是为了应对这些领域中的特定挑战而开发的,并且在某种程度上与这些科学领域的背景相关联。决策智能是如何界定的,或者如何划定界限,这一点并不十分清楚。
决策智能过程
‘设计时要考虑到目的’,这个规则也适用于数据产品的设计;不是一切都变了。准确地指出数据产品的结果应该是什么,以及它如何准确地适应当前的过程,可以避免许多痛苦。弄清楚这一点后,我们可以看看可用的数据、算法,最后是要部署的合适模型。但是还有更多。
为产品设定性能标准怎么样?没有任何表演会。也许应用一些假设检验来确保这些标准得到满足?费用怎么样?知道了数据产品在过程中的位置和方式,人们应该能够估计其应用的好处。但是既然盈利是游戏,那么应该应用什么倍数来比较成本和收益呢?
目的是“让数据变得有用”。让我们把它分成三个不同的部分:
- make——决策智能过程旨在创造事物及其编码。虽然编码的最终结果很重要,但代码和/或框架(如 Tensorflow、sklearn 或 pandas)并不重要。
- 数据—如果处理数据,需要考虑分析和统计领域的一些方法方面。
- 有用—缩小一点,使数据有用需要设计适合业务的正确产品。这包括首先为什么这个模型如此伟大,产品背后的假设和价值是什么?
决定,决定,决定。这一切的决策者是谁?这就出现了一个问题,是选择独角兽数据科学家,还是创建数据产品的混合团队。让我们重温一下角色的话题。
决策智能团队和决策者
一个普遍的观点是,管理数据产品比管理大多数常规 IT 项目更难。数据科学工具和端到端平台的市场正在增长。在机器学习的情况下,很容易涉及相同数量的软件。除此之外,还有数据来源、模型验证和监控、模型偏差、数据标签等等。尽管如此,无所不能的数据科学家仍然很受欢迎。会不会是新兴的端到端平台能够将所有的复杂性缩减为独角戏?
端到端平台无疑提供了便利。不太引人注目的是,即使考虑到这些平台,仍然需要多样化的技能组合。在本节中,将列出一个可能角色的折衷列表。很少有人会雇佣所有这些角色,但是知道哪些角色被遗漏了是很好的:
- 领域专家
- 产品经理或产品所有者
- DevOps 和现场可靠性工程师
- 数据科学家
- 数据工程师
- 隐私专家/律师
- 伦理学家,律师
- 统计员
- 机器学习工程师
这是可能的角色的简短列表。这个列表有点重软件,这个团队可能涉及机器学习。这通常是大规模的。规模越大,责任越大。因此,虽然机器学习项目可以在小范围内执行,但扩大规模意味着增加责任。是的,数据科学家可以将模型部署到 SageMaker,但这通常不是目标,对吗?随着规模的变化,项目的性质也逐渐发生变化。这就是为什么其中一个角色被遗漏了,即决策者(决策科学术语)或数据科学领导者的角色。
在这篇文章中,数据智能项目中的问题越来越多。有人可能会说所有这些思考和细微差别都不是敏捷的。但是把敏捷和无知混为一谈只是明显的傲慢。GDPR 不是开玩笑的。拥有一个了解数据智能项目的机会和陷阱的应用专家迟早会变得非常方便。
是时候结束这一切了。
最后的想法
决策智能是关于重组当前的决策环境。虽然强调应用,但如果不理解理论和决策方法的深层机制,就不可能正确执行。这个问题既有实践的一面,也有理论的一面。如果更多的人对这些方法有一个更好的、更全面的和更深刻的理解,这将肯定有助于执行决策类型的项目。
属于决策智能的方法来自不同的研究领域,并且经常重叠。一些重复数据删除和清理肯定是有价值的。认识到决策制定中的共同模式,也许可以更好地将决策形式化,并通过这样做提高所有人的标准。
但是决策智能有明显的元特征。大多数决策方法都是达到目的的手段。方法经常被开发出来,因为特别需要一种新的看待事物的方式。这种需求是由经济学、生物学、物理学或工程学等领域驱动的。离开发明这些方法的背景,并不是所有的方法都有意义。决策方法本身并不是发明出来的:什么将推动决策智能领域的创新?决策智能提供了很好的起点,但是它是如何有界的呢?
话虽如此。我非常喜欢 Kozyrkov 的许多博客帖子以及这些帖子提供的宝贵见解。希望这篇文章能激发你的决策能力。
用 Python 实现多类问题的决策树算法
理解基尼指数、熵、信息增益、特征重要性和 CCP 阈值的数学
法托斯 Bytyqi 在 Unsplash 上的照片
介绍
决策树分类器是监督学习模型,在我们关心可解释性时非常有用。想象一下,通过在每一层基于多个问题做出决策来分解数据。决策树面临的最大挑战是理解后端算法,利用该算法,一棵树可以扩展为分支和子分支。在本文中,我们将更广泛地研究如何使用不同的杂质指标来确定每个节点的决策变量,如何确定重要的特征,更重要的是如何修剪树以防止模型过度拟合。要更好地理解决策树的工作原理,您可以参考下面的链接。
使用成本计算修剪构建、可视化和微调决策树的完整实践指南…
towardsdatascience.com](/decision-tree-classifier-and-cost-computation-pruning-using-python-b93a0985ea77)
概观
决策树由节点和分支组成。节点可以进一步分为根节点(树的起始节点)、决策节点(根据条件拆分的子节点)和叶节点(不会进一步分支的节点)。由于决策树遵循 if-else 结构,每个节点使用一个且仅一个自变量来分成两个或多个分支。自变量可以是分类的,也可以是连续的。对于分类变量,类别用于决定节点的分裂,对于连续变量,算法得出多个阈值作为决策者(Raschka,Julian and Hearty,2016 年,第 83、88、89 页)。
假设我们正试图为下面的数据集开发一个决策树。该数据集由学生 id、他们的性别信息、他们的学习方法和一个标识他们是否打板球的属性组成。我们可以区分预测变量和因变量与自变量或属性。因变量是“Plays Cricket”列,除了“Student ID”之外的其他属性将形成自变量集。
假设我们正试图为下面图 1 所示的数据集开发一个决策树。该数据集由学生 id、他们的性别信息、他们的学习方法和一个标识他们是否打板球的属性组成。我们可以区分预测变量和因变量与自变量或属性。因变量是“Plays Cricket”列,除了“Student ID”之外的其他属性将形成自变量集。
图一。包含学生信息和必要属性的表的快速概述。参考—由作者使用 PowerPoint 开发
决定分裂
作为这个问题的第一步,我们需要确定哪个独立变量可以用来分割根节点。我们用基尼杂质来决定学生在板球运动员和非板球运动员中的分支。我们将使用“性别”和“研究方法”来计算基尼系数,并考虑杂质分数最低的那个。请注意,决策树算法试图使每个节点尽可能同质。这与我们试图达到的结果是一致的,正确地预测学生是板球运动员还是非板球运动员。同质性是一种情况,在这种情况下,特定节点中的所有学生都属于其中一个类别,即他们要么是板球运动员(玩板球= Y),要么是非板球运动员(玩板球= N)。
图二。使用基尼指数和“性别”作为独立变量计算的加权平均杂质。参考—由作者使用 PowerPoint 开发
图 3。使用基尼指数和“研究方法”作为独立变量计算的加权平均杂质。参考—由作者使用 PowerPoint 开发
由于杂质是衡量节点同质性的指标,算法选择加权平均杂质分数最低的独立变量作为根节点的决策变量,在这种情况下,“性别”将用于创建决策树的第一次拆分。另外,请注意用黄色突出显示的数字,它们用于计算分割的信息增益。信息增益可以定义为杂质从父节点到各自子节点的变化,在这种情况下,我们需要检查根节点中的杂质是否高于分裂的加权杂质。如果信息增益大于 0,算法将继续使用决策变量分割节点。
我们如何修剪上面的树?
决策树通常会继续形成分支,直到每个节点变得同质。因此,该树可以很好地处理训练数据,但无法为测试数据生成高质量的输出。因此,这棵树应该修剪,以防止过度拟合。从上面的例子中,我们可以使用下面列出的因素来微调决策树。
- 标准 Python 使用基尼系数和熵。其他算法使用 CHAID(卡方自动交互检测器)、遗漏分类错误等。
- 从根节点/父节点到子节点,信息增益或最小杂质减少
- 每个节点中的样本数(最小或最大)
- 树的深度(算法应该形成多少个分支)
- 最大叶片数
使用 Python 的现实问题
了解基尼指数
问题陈述旨在开发一个分类模型来预测红酒的质量。关于问题陈述的细节可以在这里找到。这是一个多类分类问题的经典例子。我们不会研究代码,而是尝试使用 Python 中 sklearn.tree 的 DecisionTreeClassifier()来解释输出。
以下代码片段参考:Das,A. (2020)。使用 Python 的决策树分类器和代价计算剪枝。【在线】中等。可在:https://towards data science . com/decision-tree-classifier-and-cost-computing-pruning-using-python-b93a 0985 ea 77获得
#Reading the data
wine_df = pd.read_csv('winequality-red.csv',sep=';')# splitting data into training and test set for independent attributesfrom sklearn.model_selection import train_test_splitX_train, X_test, y_train, y_test =train_test_split(wine_df.drop('quality',axis=1), wine_df['quality'], test_size=.3,
random_state=22)
X_train.shape,X_test.shape#developing a model
clf_pruned = DecisionTreeClassifier(criterion = "gini", random_state = 100,
max_depth=3, min_samples_leaf=5)
clf_pruned.fit(X_train, y_train)#visualizing the tree
import iofrom io import StringIOfrom sklearn.tree import export_graphviz
# from sklearn.externals.six import StringIO
from IPython.display import Image
import pydotplus
import graphvizxvar = wine_df.drop('quality', axis=1)
feature_cols = xvar.columnsdot_data = StringIO()
export_graphviz(clf_pruned, out_file=dot_data,
filled=True, rounded=True,
special_characters=True,feature_names = feature_cols,class_names=['0','1','2'])from pydot import graph_from_dot_data
(graph, ) = graph_from_dot_data(dot_data.getvalue())
Image(graph.create_png())
图 4。使用基尼指数的决策树,深度=3,max_samples_leaves=5。请注意,为了处理等级不平衡,我们将葡萄酒分为品质 5、6 和 7。在上图中,5 对应于 class=0,6 对应于 class=1,7 对应于 class=2。
当我们看到一个多类算法时,我们不要对如何计算基尼指数感到困惑。在之前的例子中,我们用 P 和 Q 来代表打板球的学生和不打板球的学生。其中 P 是打板球的概率,Q 是不打板球的概率。在多类决策树的情况下,对于节点酒精< =0.25,我们将执行以下计算。
- p 代表葡萄酒质量为 5 的概率,即(514/1119) = 0.46
- q 代表葡萄酒质量为 6 的概率,即(448/1119) = 0.40
- r 代表葡萄酒质量为 7 的概率,即(157/1119) = 0.14
- 基尼指数= P+Q+R =(0.46)+(0.40)+(0.14)= 0.39
- 基尼系数= 1–0.39 = 0.61(见匹配)
上面的树被修剪了,这样我们可以更好地可视化模型。使用深度 3 或最大样本叶作为 5 没有统计学意义。
不使用 criterion = "gini ",我们总是可以使用 criterion= "entropy "来获得上面的树形图。熵的计算方法是-Plog§-Qlog(Q)。
图 5。使用熵的决策树,深度=3,max_samples_leaves=5。请注意,为了处理等级不平衡,我们将葡萄酒分为品质 5、6 和 7。在上图中,5 对应于 class=0,6 对应于 class=1,7 对应于 class=2。
了解功能重要性
特征重要性指的是为预测模型的输入特征分配分数的一类技术,该技术指示在进行预测时每个特征的相对重要性(Das,2020)。
## Calculating feature importancefeat_importance = clf_pruned.tree_.compute_feature_importances(normalize=False)feat_imp_dict = dict(zip(feature_cols, clf_pruned.feature_importances_))
feat_imp = pd.DataFrame.from_dict(feat_imp_dict, orient='index')
feat_imp.rename(columns = {0:'FeatureImportance'}, inplace = True)
feat_imp.sort_values(by=['FeatureImportance'], ascending=False).head()
图 6。自变量的特征重要性。
让我们试着理解下面的内容,以便更好地了解特性的重要性是如何决定的。
- 第一次分裂是基于酒精<=10.25; This variable with this threshold ensures minimum impurity of all other variables hence in the above table (Figure 5) you see that the feature importance is high
- The next split is based on sulphates
- When we look at the third level of the split, we see that there are three contenders, chlorides <=0.08, total sulfur dioxide <=88.5, volatile acidity <=0.87.
To decide which independent variable is important we need to understand the information gain by splitting these parent nodes into their respective child nodes.
Figure 7. Variables used to decide the split when depth =3.
Figure 8. Information Gain using volatile acidity≤0.87 as the threshold.
Figure 9. Information Gain using total sulfur dioxide≤88.5 as the threshold.
So, we see that the information gain by splitting Node “volatile acidity <=0.87” is higher than by splitting “total sulfur dioxide <=88.5” hence in the importance table “volatile acidity <=0.87” is placed above “total sulfur dioxide <=88.5”.
Understanding cost complexity
The cost complexity refers to the complexity parameter that is used to define the cost complexity measure Ra(T) of a given tree T. Ra(T) is written as:
Ra(T) = R(T) + a|T|
where |T| is the number of terminal nodes, R(T) is the total misclassification rate of the terminal node, and a is the CCP parameter. To summarise, the subtree with the highest cost complexity that is smaller than 【 will be retained. It is always good to select a CCP parameter that produces the highest test accuracy (Scikit Learn, n.d.).
Figure 10. Variation in train and test accuracy for different levels of alpha/a/CCP value.
Reference
- Raschka, S., Julian, D. and Hearty, J. (2016). Python:对机器学习的更深入的见解:利用使用 Python 的机器学习技术的好处:三个模块的课程。英国伯明翰:Packt 出版公司,第 83、88、89 页。
- sci kit-learn:python 中的机器学习,Pedregosa 等人,JMLR 12,第 2825–2830 页,2011 年。
- Scikit Learn (2019)。sk learn . tree . decision tree classifier—sci kit-learn 0 . 22 . 1 文档。[在线]Scikit-learn.org。可从以下网址获得:https://sci kit-learn . org/stable/modules/generated/sk learn . tree . decision tree classifier . html
- Scikit Learn(未注明)。后剪枝决策树与代价复杂度剪枝。【在线】可在:https://sci kit-learn . org/stable/auto _ examples/tree/plot _ cost _ complexity _ pruning . html # sphx-glr-auto-examples-tree-plot-cost-complexity-pruning-py。
- Das,A. (2020)。使用 Python 的决策树分类器和成本计算修剪。【在线】中等。可从以下网址获得:https://towards data science . com/decision-tree-classifier-and-cost-computing-pruning-using-python-b93a 0985 ea 77【2020 年 7 月 18 日获取】。
关于作者:高级分析专家和管理顾问,帮助公司通过对组织数据的业务、技术和数学的组合找到各种问题的解决方案。一个数据科学爱好者,在这里分享、学习、贡献;你可以和我在 上联系 和 上推特;
决策树和随机森林—解释
详细的理论解释和代码示例
决策树和随机森林是用于分类和回归问题的监督学习算法。这两种算法最好放在一起解释,因为随机森林是一堆决策树的组合。当然,在创建和组合决策树时,需要考虑某些动态和参数。在这篇文章中,我将解释决策树和随机森林是如何工作的,以及使用这些模型时需要考虑的关键点。
决策树建立在反复询问问题以划分数据的基础上。用决策树的可视化表示来概念化分区数据更容易:
这是给动物分类的决策树。第一次分割是基于动物的大小。虽然问题看起来是“动物有多大?”,以“动物大于 1m 吗?”因为我们想在每一步把数据点分成两组。随着树越来越深,问题也越来越具体。
你在每一步问什么是最关键的部分,并极大地影响决策树的性能。例如,假设数据集的“要素 A”范围为 0 到 100,但大多数值都在 90 以上。在这种情况下,首先要问的问题是“特征 A 大于 90 吗?”。问“特性 A 大于 50 吗?”是没有意义的因为它不会给我们太多关于数据集的信息。
我们的目标是在每次分区时尽可能增加模型的预测性,以便模型不断获得关于数据集的信息。随机分割要素通常不会给我们提供关于数据集的有价值的信息。增加节点纯度的分割更能提供信息。节点的纯度与该节点中不同类的分布成反比。要问的问题是以增加纯度或减少杂质的方式选择的。
有两种方法来衡量一个分裂的质量:基尼系数和熵。它们主要测量杂质,并给出相似的结果。Scikit-learn 默认使用基尼指数,但您可以使用标准参数将其更改为熵。
基尼杂质
正如在维基百科上所述,“基尼杂质是一种衡量从集合中随机选择的元素被错误标记的频率,如果它是根据标签在子集中的分布随机标记的话”。基本上就是杂质随着随机性增加。例如,假设我们有一个盒子,里面有十个球。如果所有的球都是同样的颜色,我们就没有随机性,杂质为零。然而,如果我们有 5 个蓝色球和 5 个红色球,杂质是 1。
熵和信息增益
熵是不确定性或随机性的度量。一个变量的随机性越大,熵就越大。均匀分布的变量具有最高的熵。例如,掷一个公平的骰子有 6 个概率相等的可能结果,所以它有均匀的分布和高熵。
熵 vs 随机性
选择导致更纯节点的分裂。所有这些都表明“信息增益”,这基本上是分裂前后熵的差异。
当选择一个特征进行分割时,决策树算法试图实现
- 更多的预测
- 杂质少
- 低熵
现在我们已经了解了问题(或拆分)是如何选择的。下一个话题是题数。我们要问多少问题?我们什么时候停止?什么时候我们的树足以解决我们的分类问题?所有这些问题的答案将我们引向机器学习最重要的概念之一:过拟合。模型可以一直提问,直到所有节点都是纯的。纯节点只包括来自一个类的数据点。
模型可以一直提问(或者拆分数据),直到所有的叶子节点都是纯的。然而,这将是一个过于具体的模型,不能很好地概括。它在训练集上实现了高精度,但在新的、以前看不到的数据点上表现不佳。
正如你在下面的可视化中看到的,在深度 5,模型明显过度拟合。类之间的狭窄区域可能是由异常值或噪声造成的。
深度= 5 ( 图源)
控制或限制树的深度以防止过度拟合是非常重要的。Scikit-learn 提供超参数来控制决策树的结构:
max_depth: 一棵树的最大深度。树的深度从 0 开始(即根节点上的深度为零)。如果未指定,模型会一直分割,直到所有叶子都是纯的,或者直到所有叶子包含的样本数少于 min_samples_split。
min_samples_split: 拆分内部节点所需的最小样本数。只要一个节点的样本(数据点)多于 min_samples_split 参数指定的数量,该算法就会一直拆分节点。
**最小杂质减少:**进行拆分的目的是减少杂质(或不确定性),但并不是所有的拆分都能同样达到这个目的。此参数设置进行分割的阈值。如果这种分裂导致杂质的减少大于或等于阈值,则节点将被分裂。
这里可以看到 DecisionTreeClassifier() 的所有超参数列表。
随机森林
随机森林是许多决策树的集合。随机森林是使用一种叫做 bagging 的方法构建的,其中每个决策树都被用作并行估计器。如果用于分类问题,结果基于从每个决策树接收的结果的多数投票。对于回归,叶节点的预测是该叶中目标值的平均值。随机森林回归取决策树结果的平均值。
随机森林降低了过度拟合的风险,并且准确性比单个决策树高得多。此外,随机森林中的决策树并行运行,因此时间不会成为瓶颈。
随机森林的成功高度依赖于使用不相关的决策树。如果我们使用相同或非常相似的树,总体结果将不会比单个决策树的结果有太大的不同。随机森林通过自举和特征随机性实现不相关的决策树。
- Bootsrapping 是从带有替换的训练数据中随机选择样本。它们被称为 bootstrap 样本。下图清楚地解释了这一过程:
- 通过为随机森林中的每个决策树随机选择特征来实现特征随机性。随机森林中每棵树使用的特征数量可通过 max_features 参数控制。
特征随机性
自助样本和特征随机性为随机森林模型提供了不相关的树。
随机森林引入了一个额外的参数:
n_estimators: 代表一片森林中的树木数量。在一定程度上,随着森林中树木数量的增加,结果会变得更好。然而,在某个点之后,添加额外的树不会改进模型。请记住,添加额外的树总是意味着更多的计算时间。
利弊
决策树
优点:
- 通常不需要归一化或缩放要素
- 适合处理混合的特征数据类型(连续、分类、二进制)
- 容易理解
缺点:
- 倾向于过度拟合,并且需要集合以便很好地概括
随机森林
优点:
- 针对许多不同问题的强大、高度精确的模型
- 像决策树一样,不需要标准化或缩放
- 像决策树一样,可以一起处理不同的特征类型
- 并行运行树,因此性能不会受到影响
缺点:
- 与快速线性模型(即朴素贝叶斯)相比,对于高维数据集(即文本分类)不是一个好的选择
使用 Scikit-Learn 的示例
决策树和随机森林也可以用于回归问题。我之前做过一个关于预测二手车价格的项目。我将跳过所有的预处理,数据清理和 EDA 部分,并显示模型部分。对于回归任务,我使用了线性回归和随机森林回归。毫不奇怪,随机森林回归器有更好的性能。
我从一个人们用来卖二手车的网站上搜集数据。经过探索性的数据分析,我决定用网站上 ad 上的车龄、公里数、发动机大小和时长。目标变量当然是汽车的价格。数据集包含 6708 个数据点。
我使用了一个 RandomForestRegressor(),max_depth 设置为 5。由于它不是一个非常大和复杂的数据集,我只使用了 10 个估计器(决策树):
一个简单的随机森林回归模型在训练和测试数据集上都达到了大约 90%的准确率:
如果不使用适当的超参数,随机森林也可能过度拟合。例如,如果我在 max_depth 设置为 20 的情况下运行同一个模型,该模型会过度拟合。它在训练数据集上取得了更好的准确性,但在测试数据集上表现不佳:
max_depth = 20 会导致过度拟合
感谢您的阅读。如果您有任何反馈,请告诉我。
我的其他帖子
参考文献
- https://jakevdp . github . io/python datascience handbook/05.08-random-forests . html
- https://sci kit-learn . org/stable/modules/generated/sk learn . tree . decision tree classifier . html
- https://en . Wikipedia . org/wiki/Bootstrapping _(statistics)
- https://www . researchgate . net/figure/An-example-of-bootstrap-sampling-Since-objects-is-sub-sampled-with-replacement-some _ fig 2 _ 322179244
决策图表
在我们的日常生活中,我们与各种机器学习应用程序进行交互,并在不知不觉中使用它。最好的例子是从任何一个在线购物门户购买东西,在那里我们可以根据我们购买的东西得到几个推荐。
一种类型的机器学习算法是决策树,它是监督分类下的一种分类算法。
决策树是我们可能有意或无意使用过的东西。考虑一下买车的情况。我们会在考虑预算、安全性、颜色和价格等各种因素后选择汽车。我们首先检查了低于 X 的价格,然后是颜色,最后是安全性,然后得出了一个结论。
作者图片
查看上图,我们可以定义 决策树 是一个树形图的图形表示,用于确定行动过程。树的每个分支代表一个决定。
决策树能解决的问题?
它可以解决两类问题。
- 分类:根据 if-then 条件进行分类。如果一种花的颜色是红色,那么它就是玫瑰色,如果是白色,那么它就是百合色。
- 回归:有连续数据时使用回归树。
决策树的优势
- 简单易懂。
- 在数据准备方面很少努力。
- 非线性参数不影响性能。
缺点:
- 过拟合:在数据中有噪声的情况下。
- 不稳定性:由于数据的变化,模型可能变得不稳定。
决策树中使用的重要术语。
- 熵:它是对数据集中不可预测性的度量。例如,我们有一桶水果。这里所有的东西都是混合的,因此它的熵非常高。
- 信息增益:熵值降低了。例如,如果我们有一桶 5 种不同的水果。如果所有信息都保存在一个地方,那么获得的信息是最少的。但是如果我们将所有 5 种水果分开,我们会看到熵最小,因为它没有混合,而获得的信息最大。
- 叶节点:它是承载信息的决策树的末端。在上图中,我们可以说“购买”是叶节点。
- 决策节点:它是决策树的中间节点,在这里出现两个或更多新的分裂。在上图中,颜色是一个决策节点,因为它进一步分裂为红色和蓝色。
- 根节点:它是图中最顶层的节点,所有的信息都存储在这里,或者具有最高的熵。在图中,“汽车”是根节点。
如前所述,决策树可用于两种情况。让我们检查一下回归环境中的使用情况。
决策树:回归
import pandas as pd
import numpy as np
import matplotlib.pyplot as plt
%matplotlib inline
df = pd.read_csv("../input/automobileEDA.csv")
df.head()
作者图片
作者图片
df.head()将给出每一列的前 5 行的详细信息。我们可以使用 df.tail()获得最后 5 行,类似地,使用 df.head(10)获得前 10 行。
数据是关于汽车的,我们需要使用上面的数据来预测汽车的价格
我们将使用决策树来预测汽车的价格。
df.dtypes
出局:
symboling int64
normalized-losses int64
make object
aspiration object
num-of-doors object
body-style object
drive-wheels object
engine-location object
wheel-base float64
length float64
width float64
height float64
curb-weight int64
engine-type object
num-of-cylinders object
engine-size int64
fuel-system object
bore float64
stroke float64
compression-ratio float64
horsepower float64
peak-rpm float64
city-mpg int64
highway-mpg int64
price float64
city-L/100km float64
horsepower-binned object
diesel int64
gas int64
dtype: object
dtypes 给出列的数据类型。
df.describe()
作者图片
作者图片
在上面的数据框中,列数据类型是 object、float 和 int64 的混合。因此,我们将只考虑那些数值为数字的列,并使所有的数字都浮动。
df.dtypes
for x **in** df:
if df[x].dtypes == "int64":
df[x] = df[x].astype(float)
print (df[x].dtypes)float64
float64
float64
float64
float64
float64
float64
float64
准备数据。
与分类任务一样,在本节中,我们将把数据划分为属性和标签,从而划分为训练集和测试集。我们将创建 2 个数据集,一个用于价格,另一个用于(df-price)。由于我们的数据框包含大量对象格式的数据,因此在本次分析中,我们将移除所有对象类型的列,对于所有 NaN 值,我们将移除该行。
df = df.select_dtypes(exclude=['object'])
df=df.fillna(df.mean())
X = df.drop('price',axis=1)
y = df['price']
这里,X 变量包含数据集中的所有列,除了标签“价格”列。y 变量包含“价格”列中的值,这意味着 X 变量包含属性集,y 变量包含相应的标签。
from sklearn.model_selection import train_test_split
X_train, X_test, y_train, y_test = train_test_split(X, y, test_size=0.3, random_state=0)
为了训练该算法,我们将使用 DecisionTreeRegressor 类和 fit 方法。
from sklearn.tree import DecisionTreeRegressor
regressor = DecisionTreeRegressor()
regressor.fit(X_train, y_train)
我们来预测一下价格。
y_pred = regressor.predict(X_test)
让我们检查实际值和预测值之间的差异。
df=pd.DataFrame({'Actual':y_test, 'Predicted':y_pred})
df
实际值和预测值
from sklearn import metrics
print('Mean Absolute Error:', metrics.mean_absolute_error(y_test, y_pred))
print('Mean Squared Error:', metrics.mean_squared_error(y_test, y_pred))
print('Root Mean Squared Error:', np.sqrt(metrics.mean_squared_error(y_test, y_pred)))
作者图片
import seaborn as sns
plt.figure(figsize=(5, 7)) ax = sns.distplot(y, hist=False, color="r", label="Actual Value")
sns.distplot(y_pred, hist=False, color="b", label="Fitted Values" , ax=ax) plt.title('Actual vs Fitted Values for Price')
plt.xlabel('Price (in dollars)')
plt.ylabel('Proportion of Cars')plt.show()
plt.close()
实际与预测
以上是实际值和预测值之间的曲线图。
决策树:分类
我们将使用决策树分类来预测模型的结果。
让我们导入所需的库。
import numpy as np
import pandas as pd
from sklearn.tree import DecisionTreeClassifier
关于数据:
这些数据是关于一系列疾病的患者名单。通过该模型,我们将预测应该向患者提供哪种药物。
df = pd.read_csv("../input/drug200.csv")
df.head()
作者图片
计算数据的大小。
np.size(df)
出局:
1200
准备数据
我们将选取一些分析所需的列。
X = df[['Age', 'Sex', 'BP', 'Cholesterol', 'Na_to_K']].values
X[0:5]
出局:
array([[23, 'F', 'HIGH', 'HIGH', 25.355],
[47, 'M', 'LOW', 'HIGH', 13.093],
[47, 'M', 'LOW', 'HIGH', 10.113999999999999],
[28, 'F', 'NORMAL', 'HIGH', 7.797999999999999],
[61, 'F', 'LOW', 'HIGH', 18.043]], dtype=object)
在上面的数组中,数据集中的一些值不是数值,例如性别或 BP。不幸的是,Sklean 决策树不能处理这些变量。因此,我们需要将其转换成数字。pandas.get_dummies()将非数字变量转换为虚拟/指示变量。
from sklearn import preprocessing
le_sex = preprocessing.LabelEncoder()
le_sex.fit(['F','M'])
X[:,1] = le_sex.transform(X[:,1]) le_BP = preprocessing.LabelEncoder()
le_BP.fit([ 'LOW', 'NORMAL', 'HIGH'])
X[:,2] = le_BP.transform(X[:,2]) le_Chol = preprocessing.LabelEncoder()
le_Chol.fit([ 'NORMAL', 'HIGH'])
X[:,3] = le_Chol.transform(X[:,3]) X[0:5]
出局:
array([[23, 0, 0, 0, 25.355],
[47, 1, 1, 0, 13.093],
[47, 1, 1, 0, 10.113999999999999],
[28, 0, 2, 0, 7.797999999999999],
[61, 0, 1, 0, 18.043]], dtype=object)
上面我们已经把数值改成了 0,1,2。
*#target value*
y = df["Drug"]
y
出局:
0 drugY
1 drugC
2 drugC
3 drugX
4 drugY
...
195 drugC
196 drugC
197 drugX
198 drugX
199 drugX
Name: Drug, Length: 200, dtype: object
我们将在我们的决策树中使用训练/测试分割。让我们从 sklearn.cross_validation 导入 train_test_split。
from sklearn.model_selection import train_test_splitX_train, X_test, y_train, y_test = train_test_split(X, y, test_size=0.3, random_state=3)
我们将创建一个测试和训练数据
我们将首先创建一个名为 Tree 的决策树分类器实例。
Tree = DecisionTreeClassifier(criterion="entropy", max_depth = 4)
Tree *# it shows the default parameters*
出局:
DecisionTreeClassifier(ccp_alpha=0.0, class_weight=None, criterion='entropy',
max_depth=4, max_features=None, max_leaf_nodes=None,
min_impurity_decrease=0.0, min_impurity_split=None,
min_samples_leaf=1, min_samples_split=2,
min_weight_fraction_leaf=0.0, presort='deprecated',
random_state=None, splitter='best')
让我们预测一下我们的价值观。
pred =Tree.predict(X_test)
pred
在外
array(['drugY', 'drugX', 'drugX', 'drugX', 'drugX', 'drugC', 'drugY',
'drugA', 'drugB', 'drugA', 'drugY', 'drugA', 'drugY', 'drugY',
'drugX', 'drugY', 'drugX', 'drugX', 'drugB', 'drugX', 'drugX',
'drugY', 'drugY', 'drugY', 'drugX', 'drugB', 'drugY', 'drugY',
'drugA', 'drugX', 'drugB', 'drugC', 'drugC', 'drugX', 'drugX',
'drugC', 'drugY', 'drugX', 'drugX', 'drugX', 'drugA', 'drugY',
'drugC', 'drugY', 'drugA', 'drugY', 'drugY', 'drugY', 'drugY',
'drugY', 'drugB', 'drugX', 'drugY', 'drugX', 'drugY', 'drugY',
'drugA', 'drugX', 'drugY', 'drugX'], dtype=object)
让我们检查测试并预测值。
print (pred [0:5])
print (y_test [0:5])
出局:
['drugY' 'drugX' 'drugX' 'drugX' 'drugX']
40 drugY
51 drugX
139 drugX
197 drugX
170 drugX
Name: Drug, dtype: object
让我们检查模型的准确性。
from sklearn import metrics
import matplotlib.pyplot as plt
print("DecisionTrees's Accuracy: ", metrics.accuracy_score(y_test,pred))
出局:
DecisionTrees's Accuracy: 0.9833333333333333
创建一个决策树并将其可视化。
from sklearn import tree
plt.figure(figsize=(25,10))
tree.plot_tree(Tree,filled=True,
rounded=True,
fontsize=14);
作者图片
实际代码可在以下位置查看:
https://www . ka ggle . com/adityakumar 529/决策树分类
决策树:使用 Python 构建、修剪和可视化决策树
构建和调整机器学习模型,一步一步地解释
布兰登·格林的照片
B 二叉树是计算世界中最常见和最强大的数据结构之一。机器学习工程师如此喜欢决策树的主要原因是,它的处理成本很低,而且真的很容易理解(它是透明的,与神经网络的“黑箱”相反)。它使用分支方法来检查每个特性及其不同的结果,以找到目标值的模式。关于决策树和不同分支方法的更详细的解释,请看托马斯·普拉平格的这篇文章。
我们开始吧!
决策树模型
我们将使用来自卡格尔的泰坦尼克号数据集来预测幸存者。我们将导入数据并选择一些要使用的要素。“幸存”是我们的目标价值。
data = pd.read_csv(‘path_or_link/train.csv’)
data = data.loc[:,(‘Survived’,’Pclass’,’Sex’,’Age’,’SibSp’,’Parch’,’Fare’)]
数据样本
缺失值 我们有一些“年龄”的缺失值。为了解决这个问题,我们可以运行一些预测分析并填充这些点,但这不是本文的目标,所以我们将在以后的文章中讨论。现在,让我们只删除那些缺少值的行。
编码分类特征 为了将所有特征保持为数字格式,我们将对“性别”进行编码,这意味着将值从“女性”和“男性”转换为 0 和 1。
data.dropna(inplace=True)
#'inplace=True' applies the code to the 'data' object.from sklearn.preprocessing import LabelEncoder
le = LabelEncoder()
data.Sex = le.fit_transform(data.Sex)
将数据集分为训练集和测试集
x = data.iloc[:,1:] # Second column until the last column
y = data.iloc[:,0] # First column (Survived) is our targetfrom sklearn.model_selection import train_test_split
#this function randomly split the data into train and test setsx_train, x_test, y_train, y_test = train_test_split(x, y, test_size=.3)
#test_size=.3 means that our test set will be 30% of the train set.
构建决策树分类器 来自 sklearn 的 decision tree classifier()是一个很好的现成的机器学习模型,可供我们使用。它有 fit()和 predict()方法。
**fit()**方法是建模过程的“训练”部分。它找到算法的系数。然后, predict() 方法将使用训练好的模型对一组新数据(测试集)进行预测。
dtree = DecisionTreeClassifier()
dtree.fit(x_train, y_train) #train parameters: features and target
pred = dtree.predict(x_test) #parameter: new data to predict
准确性 为了确定我们的模型有多好,我们使用 sklearn 的另一个包来给它一个度量:
from sklearn.metrics import accuracy_score
accuracy_score(y_test, pred)#parameters: targets to be predicted and predictions from new data used before
准确度:0.75
这意味着我们的预测有 75%的准确度。
可视化树
我们可以绘制树来查看它的根、分支和节点。我们将使用一组新的库来完成这项工作。
from sklearn.tree import export_graphviz
from sklearn.externals.six import StringIO
from IPython.display import Image
import pydotplusdot_data = StringIO()
export_graphviz(dtree, out_file=dot_data)
graph = pydotplus.graph_from_dot_data(dot_data.getvalue())
graph.write_png('/tree.png')
Image(graph.create_png())
StringIO() :创建一个对象(本例中为空)来接收一个点(图形描述语言)格式的字符串缓冲区(树将首先创建为字符串,然后创建为图像)。
export_graphviz() :该函数以点格式导出树,生成决策树的表示,并写入‘out _ file’。
graph _ from _ dot _ data():将使用 DOT 对象创建图形。
【Image():使用原始数据返回图像(png、jpeg、gif)。
决策图表
这棵树似乎很长。让我们改变几个参数,看看对精度是否有任何影响,并使树更短。
- 标准:定义将使用什么函数来测量分割的质量。选项有“基尼”和“熵”。
- Max_depth :定义树的最大深度。如果它是“无”,树将尽可能长,这时所有的叶子都是纯的(过度拟合模型的风险)。
dtree = DecisionTreeClassifier(criterion='gini')
dtree.fit(x_train, y_train)
pred = dtree.predict(x_test)
print('Criterion=gini', accuracy_score(y_test, pred))dtree = DecisionTreeClassifier(criterion='entropy')
dtree.fit(x_train, y_train)
pred = dtree.predict(x_test)
print('Criterion=entropy', accuracy_score(y_test, pred))
准确度结果:
标准=基尼:0.735
标准=熵:0.716
基尼系数法比熵值法略有改进。现在,让我们检查使用 max_depth 修剪树是否能给我们带来更好的结果。在下面的代码块中,我创建了一个简单的函数,使用不同的 max_depth 值(从 1 到 30)来运行我们的模型,并可视化其结果,以查看每个值的精确度有何不同。
max_depth = []
acc_gini = []
acc_entropy = []
for i in range(1,30):
dtree = DecisionTreeClassifier(criterion=’gini’, max_depth=i)
dtree.fit(x_train, y_train)
pred = dtree.predict(x_test)
acc_gini.append(accuracy_score(y_test, pred))
####
dtree = DecisionTreeClassifier(criterion=’entropy’, max_depth=i)
dtree.fit(x_train, y_train)
pred = dtree.predict(x_test)
acc_entropy.append(accuracy_score(y_test, pred))
####
max_depth.append(i)d = pd.DataFrame({‘acc_gini’:pd.Series(acc_gini),
‘acc_entropy’:pd.Series(acc_entropy),
‘max_depth’:pd.Series(max_depth)})# visualizing changes in parameters
plt.plot(‘max_depth’,’acc_gini’, data=d, label=’gini’)
plt.plot(‘max_depth’,’acc_entropy’, data=d, label=’entropy’)
plt.xlabel(‘max_depth’)
plt.ylabel(‘accuracy’)
plt.legend()
在这种情况下,gini 似乎对较长的树效果最好(正如我们在前面的精确度中看到的),但熵对较短的树效果更好,而且更精确(接近 0.82)。所以我们来画 max_depth=7,criterion=entropy 的树,看看是什么样子。
dtree = DecisionTreeClassifier(criterion=’entropy’, max_depth=7)
dtree.fit(x_train, y_train)pred = dtree.predict(x_test)
accuracy_score(y_test, pred)#Accuracy: 0.814
标准= ‘熵’,最大深度=7
我们通过改变函数来创建分支并限制树以避免过度拟合,从而从 0.75 的准确度提高到 0.81。每个案例都是不同的,测试不同的参数以找到最适合您的场景是一个很好的实践。当你学习新的函数和机器学习模型时,不要犹豫阅读文档。它将为您提供更广泛的选项来根据您的需求定制模型。
现在,去吧,使用你的新技能,通过种一棵树来拯救地球。
使用 Python 实现决策树分类器和成本计算剪枝
使用 Python 中的成本计算修剪构建、可视化和微调决策树的完整实践指南
介绍
决策树分类器是监督学习模型,在我们关心可解释性时非常有用。想象一下,通过在每一层基于多个问题做出决策来分解数据。这是广泛使用的处理分类问题的算法之一。为了更好地理解它,让我们看看下面的例子。
用于决定特定一天的活动的示例决策树。改编自《Python 对机器学习的更深刻见解》(Raschka,Julian and Hearty,2016,第 83、88、89 页)
决策树通常包括:
- 根节点 —代表被进一步分成同类组的样本或总体
- 拆分——将节点分成两个子节点的过程
- 决策节点 —当一个子节点根据某种条件分裂成更多的子节点时,称为决策节点
- 叶节点或终端节点 —不再进一步分裂的子节点
- 信息增益 —为了使用条件(比如最具信息性的特征)来分割节点,我们需要定义一个可以优化的目标函数。在决策树算法中,我们倾向于最大化每次分裂的信息增益。在测量信息增益时,通常使用三种杂质测量。它们是基尼杂质、**熵、**分类和误差
带有树叶和树枝的决策树示例。参考—由作者使用 Lucid Chart 开发
5 编码嗅探如果你在数据科学行业工作,你必须知道
towardsdatascience.com](/are-your-coding-skills-good-enough-for-a-data-science-job-49af101457aa)
理解数学
为了理解决策树是如何开发的,我们需要更深入地理解如何在每一步使用一个杂质度量在每一步最大化信息增益。让我们举一个例子,我们有训练数据,包括学生信息,如性别、年级、因变量或分类变量,用于识别学生是否是美食家。我们有以下概述的信息。
- 学生总数— 20 人
- 被归类为美食家的学生总数— 10
- 不属于美食家的学生总数— 10 人
- p(吃货),一个学生成为吃货的概率= (10/20) = 0.5
- q(不是美食家,或 1-P),学生不是美食家的概率= (10/20) = 0.5
让我们将基于性别的学生分为两个节点,重新计算上述指标。
男同学(节点 A)
- 学生总数— 10 人
- 被归类为美食家的学生总数— 8
- 不属于美食家的学生总数— 2
- p(吃货),一个学生成为吃货的概率= (8/10) = 0.8
- q(不是美食家,或 1-P),学生不是美食家的概率= (2/10) = 0.2
女学生(节点 B)
- 学生总数— 10 人
- 被归类为美食家的学生总数— 4
- 不属于美食家的学生总数— 6
- p(吃货),一个学生成为吃货的概率= (4/10) = 0.4
- q(非美食家,或 1-P),学生非美食家的概率= (6/10) = 0.6
基尼指数(GIn) 对于节点 A 或男生= P + Q,其中 P 和 Q 分别是一个学生成为美食家和非美食家的概率。GIn(节点 A) = 0.8 + 0.2 = 0.68
基尼系数(GIp) 对于节点 A = 1-基尼系数= 1–0.68 = 0.32
Gini Index (GIn) 对于 Node B 或女学生= P + Q,其中 P 和 Q 分别是学生成为美食家和非美食家的概率。GIn(节点 B) = 0.4 + 0.6 = 0.52
基尼系数(GIp) 对于节点 B = 1-基尼系数= 1–0.52 = 0.48
我们在上面观察到的是,当我们根据学生的性别(男性和女性)将他们分别分成节点 A 和 B 时,我们分别有两个节点的基尼不纯度分数。现在,为了决定性别是否是将学生分为美食家和非美食家的正确变量,我们需要一个加权基尼杂质分数,该分数是使用下面列出的公式计算的。
**加权基尼杂质=(节点 A 总样本数/数据集中总样本数)基尼杂质(节点 A) +(节点 B 总样本数/数据集中总样本数)基尼杂质(节点 B)
使用此公式计算上述示例的加权基尼系数,根据性别划分学生时的加权基尼系数= (10/20)*0.32 + (10/20)*0.48 = 0.4
分类问题涉及多个独立变量。变量可以是分类的,也可以是连续的。决策树非常适合处理不同数据类型的变量。决策树算法在决定每个节点的分裂时考虑了所有可能的变量。使用 的变量可以获得最大的加权杂质增益,被用作特定节点 的决策变量。
在上面的例子中,使用“性别”作为决策变量的加权杂质增益是 0.4,然而,假设使用“等级”作为决策变量,我们设法实现 0.56 的加权杂质增益,算法将使用“等级”作为决策变量来创建第一个分离。所有后续步骤都遵循类似的方法,直到每个节点都是同类的。
关于决策树算法的快速事实
- 随着算法继续将节点分割成子节点,直到每个节点变得同质,决策树易于过度拟合
- 与测试集相比,训练数据的准确性要高得多,因此应该修剪决策树以防止模型过度拟合。修剪可以通过控制树的深度、每个节点中样本的最大/最小数量、要分裂的节点的最小杂质增益以及最大叶子节点来实现
- Python 允许用户使用基尼杂质或熵作为信息增益标准来开发决策树
- 可以使用网格搜索或随机搜索 CV 对决策树进行微调。CV 代表交叉验证
三种不同杂质标准的目视比较
下面概述的代码片段提供了不同杂质标准的直观比较,以及它们如何随着不同的概率值而变化。注意下面的代码改编自 2016 年 S.Raschka,D.Julian 和 J . heartful 的《Python:对机器学习的更深刻见解》。
import matplotlib.pyplot as pltimport numpy as np#-----Calculating Gini Index
def gini(p):
return (p)*(1 - (p)) + (1 - p)*(1 - (1-p))#-----Calculating Entropy
def entropy(p):
return - p*np.log2(p) - (1 - p)*np.log2((1 - p))#-----Calculating Classification Error
def classification_error(p):
return 1 - np.max([p, 1 - p])#----Creating a Numpy Array of probability values from 0 to 1, with an increment of 0.01
x = np.arange(0.0, 1.0, 0.01)#---Obtaining Entropy for different values of p
ent = [entropy(p) if p != 0 else None for p in x]#---Obtaining scaled entropy
sc_ent = [e*0.5 if e else None for e in ent]#--Classification Error
err = [classification_error(i) for i in x]#--Plottingfig = plt.figure();
plt.figure(figsize=(10,8));
ax = plt.subplot(111);for i, lab, ls, c, in zip([ent, sc_ent, gini(x), err], ['Entropy', 'Entropy (scaled)','Gini Impurity',
'Misclassification Error'],['-', '-', '--', '-.'],
['black', 'darkgray','blue', 'brown', 'cyan']):
line = ax.plot(x, i, label=lab,
linestyle=ls, lw=2, color=c)
ax.legend(loc='upper center', bbox_to_anchor=(0.5, 1.15), ncol=3, fancybox=True, shadow=False)
ax.axhline(y=0.5, linewidth=1, color='k', linestyle='--')
ax.axhline(y=1.0, linewidth=1, color='k', linestyle='--')
plt.ylim([0, 1.1])
plt.xlabel('p(i=1)')
plt.ylabel('Impurity Index')
plt.show()
不同概率值的杂质变化。参考—上述代码片段的输出
动手练习
问题陈述旨在开发一个分类模型来预测红酒的质量。关于问题陈述的细节可以在这里找到。这是一个多类分类问题的经典例子。请注意,所有机器学习模型对异常值都很敏感,因此在构建树之前,应该处理由异常值组成的特征/独立变量。
不同特征/独立变量的一个重要方面是它们如何相互作用。皮尔逊相关可用于确定数据集中两个特征之间的关联程度。然而,对于像决策树这样基于决策的算法,我们不会丢弃高度相关的变量。
#---------------------------------------------Importing Required Libraries-----------------------------------
%matplotlib inlineimport numpy as np
import pandas as pdfrom sklearn.tree import DecisionTreeClassifierimport numpy as np
import pandas as pd
import seaborn as snssns.set(color_codes=True)from matplotlib import pyplot as plt
from sklearn.model_selection import train_test_split #--------------splitting data into test and train
from sklearn.tree import DecisionTreeClassifier #-----------Building decision tree modelfrom sklearn import metrics
from sklearn.metrics import accuracy_score,f1_score,recall_score,precision_score, confusion_matrix #-----model validation scores
%matplotlib inlinefrom IPython.display import display #---------------------for displaying multiple data frames in one outputfrom sklearn.feature_extraction.text import CountVectorizer #DT does not take strings as input for the model fit stepimport missingno as msno_plot #--------------plotting missing valueswine_df = pd.read_csv('winequality-red.csv',sep=';')
数据的快速描述性统计
wine_df.describe().transpose().round(2)
的输出。describe()函数
检查缺失值
#-------------------------------------------Barplot of non-missing values--------------------------------
plt.title('#Non-missing Values by Columns')
msno_plot.bar(wine_df);
说明数据集中非缺失值计数的图
异常值检查和处理
#--Checking Outliers
plt.figure(figsize=(15,15))
pos = 1
for i in wine_df.columns:
plt.subplot(3, 4, pos)
sns.boxplot(wine_df[i])
pos += 1
说明数据中存在异常值的箱线图
col_names=['fixed acidity', 'volatile acidity', 'citric acid', 'residual sugar',
'chlorides', 'free sulfur dioxide', 'total sulfur dioxide', 'density',
'pH', 'sulphates', 'alcohol']display(col_names)for i in col_names:
q1, q2, q3 = wine_df[i].quantile([0.25,0.5,0.75])
IQR = q3 - q1
lower_cap=q1-1.5*IQR
upper_cap=q3+1.5*IQR
wine_df[i]=wine_df[i].apply(lambda x: upper_cap if x>(upper_cap) else (lower_cap if x<(lower_cap) else x))
上面的异常值使用 Q1-1.5 * IQR 和 Q3+1.5*IQR 值进行了 winsorized 化。Q1、Q3 和 IQR 分别代表四分位数 1、四分位数 3 和四分位数间范围。
sns.pairplot(wine_df);
说明不同变量相互作用的配对图
理解不同变量之间的关系。注意—在决策树中,我们不需要删除高度相关的变量,因为仅使用一个独立变量将节点划分为子节点,因此即使两个或更多变量高度相关,产生最高信息增益的变量也将用于分析。
plt.figure(figsize=(10,8))
sns.heatmap(wine_df.corr(),
annot=True,
linewidths=.5,
center=0,
cbar=False,
cmap="YlGnBu")
plt.show()
说明不同属性相关性的热图
分类问题对阶级不平衡很敏感。类别不平衡是指相关属性中 1 的比例高于 0 的比例,反之亦然。在多类问题中,当其中一个类值的比例非常高时,就会出现类不平衡。类别平衡是通过组合属性“质量”的值来诱导的,该属性是本问题陈述中的因变量。
plt.figure(figsize=(10,8))
sns.countplot(wine_df['quality']);
该图显示了不同葡萄酒质量的记录计数
wine_df['quality'] = wine_df['quality'].replace(8,7)
wine_df['quality'] = wine_df['quality'].replace(3,5)
wine_df['quality'] = wine_df['quality'].replace(4,5)
wine_df['quality'].value_counts(normalize=True)
数据被分为训练集和测试集,以检查模型的准确性,并寻找过度拟合或欠拟合(如果有的话)。
# splitting data into training and test set for independent attributesfrom sklearn.model_selection import train_test_splitX_train, X_test, y_train, y_test =train_test_split(wine_df.drop('quality',axis=1), wine_df['quality'], test_size=.3,
random_state=22)
X_train.shape,X_test.shape
决策树模型是使用基尼标准开发的。注意,为了简单起见,我们将树修剪到最大深度为 3。这将有助于我们将树形象化,并将它与我们在最初部分中涉及的概念联系起来。
clf_pruned = DecisionTreeClassifier(criterion = "gini", random_state = 100,
max_depth=3, min_samples_leaf=5)
clf_pruned.fit(X_train, y_train)
请注意,可以调整以下参数来改善模型输出(Scikit Learn,2019)。
- 标准 —基尼系数用于决定变量,基于该变量,根节点和随后的决策节点应该被分割
- class_weight —无;所有类别都被赋予权重 1
- 最大深度—3;修剪完成。当“无”时,表示节点将被扩展,直到所有叶子都是同类的
- max_features —无;在决定一个节点的分裂时,考虑所有的特征或独立变量
- max_leaf_nodes —无;
- 最小杂质减少量—0.0;仅当分裂确保杂质减少大于或等于零时,才分裂节点
- 最小 _ 杂质 _ 分裂 —无;
- min _ samples _ leaf—1;叶子存在所需的最小样本数
- min _ samples _ split—2;如果 min_samples_leaf =1,则表示右节点和左节点应该各有 1 个样本,即父节点或根节点应该至少有两个样本
- 分割器——‘最佳’;用于在每个节点选择分割的策略。最好确保在决定分割时考虑所有特征
from sklearn.tree import export_graphviz
from sklearn.externals.six import StringIO
from IPython.display import Image
import pydotplus
import graphvizxvar = wine_df.drop('quality', axis=1)
feature_cols = xvar.columnsdot_data = StringIO()
export_graphviz(clf_pruned, out_file=dot_data,
filled=True, rounded=True,
special_characters=True,feature_names = feature_cols,class_names=['0','1','2'])from pydot import graph_from_dot_data
(graph, ) = graph_from_dot_data(dot_data.getvalue())
Image(graph.create_png())
图示为深度=3 时的决策树模型
preds_pruned = clf_pruned.predict(X_test)
preds_pruned_train = clf_pruned.predict(X_train)print(accuracy_score(y_test,preds_pruned))
print(accuracy_score(y_train,preds_pruned_train))
该模型对训练和测试数据的准确率分别为 0.60 和 0.62。
特征重要性指的是为预测模型的输入特征分配分数的一类技术,这些分数指示了在进行预测时每个特征的相对重要性。
## Calculating feature importancefeat_importance = clf_pruned.tree_.compute_feature_importances(normalize=False)feat_imp_dict = dict(zip(feature_cols, clf_pruned.feature_importances_))
feat_imp = pd.DataFrame.from_dict(feat_imp_dict, orient='index')
feat_imp.rename(columns = {0:'FeatureImportance'}, inplace = True)
feat_imp.sort_values(by=['FeatureImportance'], ascending=False).head()
影响决策树拆分的五大特征
DecisionTreeClassifier()提供诸如 min_samples_leaf 和 max_depth 之类的参数来防止树过度拟合。可以把它想象成一个场景,我们明确定义了树的深度和最大叶子数。然而,最大的挑战是确定一棵树应该包含的最佳深度和叶子。在上面的例子中,我们使用 max_depth=3,min_samples_leaf=5。这些数字只是一个例子,用来观察树的行为。但是,如果在现实中我们被要求处理这个模型并得出模型参数的最佳值,这是具有挑战性的,但不是不可能的(决策树模型可以使用 GridSearchCV 算法进行微调)。
另一种方法是使用成本复杂性修剪(CCP)。
成本复杂性修剪提供了另一种选择来控制树的大小。在决策树分类器中,这种修剪技术由成本复杂性参数 cost 来参数化。CCPα值越大,修剪的节点数越多。
简单来说,成本复杂性是一个阈值。只有当模型的整体杂质被提高了大于该阈值的值时,模型才进一步将节点分裂成子节点,否则它停止。
CCP 越低,杂质越少。怎么会?
当 CCP 值较低时,即使杂质没有减少很多,模型也会将一个节点分割成子节点。随着树的深度增加,这一点很明显,也就是说,当我们沿着决策树往下走时,我们会发现分裂对模型的整体杂质的变化没有多大贡献。然而,较高的分割确保了类别被正确分类,即准确性更高。
当 CCP 值较低时,会创建更多的节点。节点越高,树的深度也越高。
下面的代码(Scikit Learn,n.d .)说明了如何调整 alpha 以获得具有改进的准确度分数的模型。
path = model_gini.cost_complexity_pruning_path(X_train, y_train)
ccp_alphas, impurities = path.ccp_alphas, path.impuritiesfig, ax = plt.subplots(figsize=(16,8));
ax.plot(ccp_alphas[:-1], impurities[:-1], marker='o', drawstyle="steps-post");
ax.set_xlabel("effective alpha");
ax.set_ylabel("total impurity of leaves");
ax.set_title("Total Impurity vs effective alpha for training set");
显示杂质随α值变化的图像
让我们来理解深度和节点数随 alpha 的变化。
clfs = clfs[:-1]ccp_alphas = ccp_alphas[:-1]node_counts = [clf.tree_.node_count for clf in clfs]depth = [clf.tree_.max_depth for clf in clfs]fig, ax = plt.subplots(2, 1,figsize=(16,8))ax[0].plot(ccp_alphas, node_counts, marker='o', drawstyle="steps-post")
ax[0].set_xlabel("alpha")
ax[0].set_ylabel("number of nodes")
ax[0].set_title("Number of nodes vs alpha")
ax[1].plot(ccp_alphas, depth, marker='o', drawstyle="steps-post")
ax[1].set_xlabel("alpha")
ax[1].set_ylabel("depth of tree")
ax[1].set_title("Depth vs alpha")
fig.tight_layout()
该图显示了深度和节点数随 alpha 值的变化
理解当α增加时精度的变化。
fig, ax = plt.subplots(figsize=(16,8)); #-----------------Setting size of the canvas
train_scores = [clf.score(X_train, y_train) for clf in clfs]
test_scores = [clf.score(X_test, y_test) for clf in clfs]ax.set_xlabel("alpha")
ax.set_ylabel("accuracy")
ax.set_title("Accuracy vs alpha for training and testing sets")
ax.plot(ccp_alphas, train_scores, marker='o', label="train",
drawstyle="steps-post")
ax.plot(ccp_alphas, test_scores, marker='o', label="test",
drawstyle="steps-post")
ax.legend()
plt.show()
该图显示了当 alpha 值增加时准确度分数的变化
i = np.arange(len(ccp_alphas))
ccp = pd.DataFrame({'Depth': pd.Series(depth,index=i),'Node' : pd.Series(node_counts, index=i),\
'ccp' : pd.Series(ccp_alphas, index = i),'train_scores' : pd.Series(train_scores, index = i),
'test_scores' : pd.Series(test_scores, index = i)})ccp.tail()ccp[ccp['test_scores']==ccp['test_scores'].max()]
上面的代码提供了在测试数据中产生最高精确度的成本计算修剪值。
参考
- s .拉什卡、d .朱利安和 j .哈特(2016 年)。 Python:深入了解机器学习:利用 Python 的机器学习技术优势:三个模块的课程。英国伯明翰:Packt 出版公司,第 83、88、89 页。
- sci kit-learn:python 中的机器学习,Pedregosa 等人,JMLR 12,第 2825–2830 页,2011 年。
- Scikit Learn (2019)。sk learn . tree . decision tree classifier—sci kit-learn 0 . 22 . 1 文档。[在线]Scikit-learn.org。可从以下网址获取:https://sci kit-learn . org/stable/modules/generated/sk learn . tree . decision tree classifier . html
- Scikit Learn(未注明)。后剪枝决策树与成本复杂度剪枝。【在线】可在:https://sci kit-learn . org/stable/auto _ examples/tree/plot _ cost _ complexity _ pruning . html # sphx-glr-auto-examples-tree-plot-cost-complexity-pruning-py。
关于作者:高级分析专家和管理顾问,帮助公司通过对组织数据的商业、技术和数学的组合找到各种问题的解决方案。一个数据科学爱好者,在这里分享、学习、贡献;你可以和我在 上联系 和 上推特;
每位数据科学家必备的决策树
图片来自我的图片是 CC0。作曲时: Pixabay 的
决策树介绍
决策树是一种非常有用的分类方法,非常适合用最少的代码启动和运行。
我使用了某种形式的决策树来预测客户流失的可能性、客户转换、新产品采用、新功能采用,以及许多其他有用的应用。
这个简短的介绍将让你了解使用决策树作为分类工具的主要好处和局限性。
我还将带您完成构建您自己的决策树的步骤,同样重要的是,测试它的性能。
何时以及为何使用决策树
说到分类,使用决策树分类器是最容易使用的方法之一。
为什么要使用决策树
- 非常容易理解
- 它可以很好地处理丢失的数据和异常值,因此需要更少的前期清理
- 您可以放弃分类变量编码,因为决策树可以很好地处理分类!
- 无需深入递归划分的细节,决策树就能够模拟非线性关系。
为什么不使用决策树呢
尽管有这么多好处,但它们并不总是完美的选择。
- 同样,它们可能很简单,也可能过于复杂,几乎无法概念化或解释。
- 更进一步说,如果一个树过于偏向或复杂,它可能会太好地迎合其训练数据,结果是过度拟合。
模特培训
说到这里,让我们开始吧。我不会谈论交叉验证或训练,测试分裂,但会张贴下面的代码。如果你想得到更多的解释,一定要发表评论。
首先,我们将数据分成训练集和测试集。
还要注意,我们将使用经典的泰坦尼克号数据集,它包含在 base R 中。
n <- nrow(Titanic)n_train <- round(0.8 * n)set.seed(123)
train_indices <- sample(1:n, n_train)
train <- Titanic[train_indices, ]
test <- Titanic[-train_indices, ]
现在我们将使用rpart
包中的rpart
函数来训练模型。这里需要注意的关键是,我们想要预测的变量是存活的,所以我们想要根据一些数据了解任何给定个体存活的可能性。可以由解释为*;换句话说,让我们理解一些变量的存在。如果在后面有一个。这意味着我们想用数据集中的其他变量来预测存活。或者,如下所示,我们可以明确地调用我们想要使用的变量。*
另外要注意的是,method
是class
。这是因为我们希望创建一个预测分类结果的分类树,而不是用于数字结果的回归树。最后,我们用来训练模型的数据是train
。
model <- rpart(formula = Survived ~ Pclass + Sex + Age + SibSp + Parch + Fare + Embarked,
data = titanic_train,
method = "class")
可解释性
如前所述,决策树如此容易使用的原因之一是它非常容易解释。你可以沿着树的不同分支走向不同的结果。
rpart.plot(model)
在那里阅读有点困难,但是如果你放大一点,你会看到如果有人可能在泰坦尼克号上生活或死亡的第一个标准是你是否是男性。如果你是男性,你移到左边的分支,向下两个节点,不管你是成年人还是你的兄弟姐妹/配偶。因此,如果你是一个单身男人,你的生存几率非常小。
性能赋值
在我们分解指标之前,让我们预测一下测试集的值。与训练调用类似,您选择数据和预测类型。核心区别在于型号规格。
test$pred <- predict(object = model,
newdata = test,
type = "class")
在理解决策树的功效时,有各种各样的性能评估指标会非常方便。
准确(性)
这个指标很简单,你的预测有多少是正确的。caret
的混淆矩阵函数就包含了这个。
混淆矩阵
caret
包中的confusionMatrix
功能非常有用。用于评估分类模型性能。加载这个包,把你的预测和实际数据传给它。
library(caret)
confusionMatrix(data = test$pred,
reference = test$Survived)
这个函数向你展示的第一件事就是所谓的混淆矩阵。这将向您显示一个预测值和实际值如何匹配的表格。所以预测值和参考值相同的对角线单元格代表我们得到的正确值。将这些记录加起来 149 (106 + 43)并除以记录总数,178;我们达到了 83.4%的准确率。
True positive:象限中引用和预测都为 1 的单元格。这表明你预测了存活,而他们确实存活了下来。
假阳性:这里你预测为阳性,但你错了。
真阴性:当你预测为阴性,并且你是正确的。
假阴性:当你预测为阴性,而你是不正确的。
需要记住的几个关键指标是灵敏度和特异性。敏感度是您正确预测的真实记录的百分比。
另一方面,特异性是衡量实际错误记录中你正确预测的部分。
在不平衡数据集上进行预测时,要记住特异性。一个非常常见的例子就是对垃圾邮件进行分类。99%的情况下它不是垃圾邮件,所以如果你预测没有垃圾邮件,你有 99%的准确率,但你的特异性是 0,导致所有的垃圾邮件都被接受。
结论
总结我们对决策树的讨论,我们知道它们非常有用,因为它们非常容易解释,只需要最少的预处理,它们可以模拟非线性关系,并且它们具有可以轻松修复不平衡分类问题的功能。不平衡数据集
另一方面,当对更复杂的关系建模时,决策树可能非常难以理解,并且很容易过度拟合。
当您开始利用这种建模技术时,请记住这一点。
我希望你喜欢这堂关于决策树的快速课。让我知道你是否想要更多的信息,或者你是否想要我在另一篇文章中报道一些事情。
祝数据科学快乐!如果你喜欢这个,来看看 datasciencelessons.com 的其他帖子吧!
决策树基础
学习基尼系数、熵以及如何构建决策树
当谈到决策树的时候,我总是想象当我的女朋友不知道她晚饭想吃什么的时候,我会问她一系列的问题:你想吃点面条吗?你想花多少?亚洲人还是西方人?健康还是垃圾食品?
制作一个问题列表来缩小选择范围,本质上是决策树背后的思想。更正式地说,决策树是一种算法,它根据观察值的特征将它们划分为相似的数据点。
决策树是一种监督学习模型,具有树状结构,即包含根、父/子节点、叶。决策树可用于分类或回归问题。下图是我用来判断她要不要快餐的二叉分类树的简短版本。
快餐还是非快餐决策树
I)如何构造决策树?
有两种流行的树构建算法:分类和回归树(CART) 和 ID3 。这两个模型之间的主要区别是它们使用的成本函数。成本函数决定问哪个问题以及如何分割每个节点。构建决策树的伪代码是:
- 选择一个具有最佳索引的特征。使用我将在下一节介绍的成本函数来计算指数
- 基于所选要素分割数据集
- 重复这个过程,直到它到达叶子(或满足停止标准)
在这篇文章中,我们将讨论两个成本函数:基尼系数和熵值
(二)基尼系数和基尼系数
1)基尼不纯
基尼系数是在 CART 方法中使用的损失函数。基尼系数衡量一个类别有多少噪音**。首先,每个数据特征可能包含许多类别**。例如,天气特征可以有类别:下雨、晴天或下雪;一个数字特征如等级可分为两个块:< 70 或≥70。基尼系数可以通过以下公式计算:
基尼杂质公式
注意最大基尼系数是 0.5。这可以用一些微积分知识来检验。我创建了一个玩具数据集,以更好地说明成本函数对决策树的影响。
import pandas as pd
classification=['Freshman','Freshman','Sophomore','Junior','Freshman','Sophomore']
hour_of_practice=['>2h','>2h','>2h','<2h','>2h','<2h']
pass_the_quiz=['Yes','Yes','Yes', 'Yes', 'No','No']
df=pd.DataFrame({'Classification':classification,
'hour of practice':hour_of_practice,
"Pass the quiz":pass_the_quiz })
df
**观察:**大一(F)3 人,大二(S)2 人,大三(J)1 人。从数据来看,大一大二学生学习 2h 以上通过测试,学习 2h 以下不及格。学弟骗系统,一直过关。
让我们计算分类栏的基尼系数:
基尼值告诉我们数据集中存在的噪声值。在这种情况下,初级没有噪声,因为我们知道所有初级都将通过测试。另一方面,大二学生的噪音最大。
2)基尼指数
基尼指数将类别噪声结合在一起得到特征噪声。基尼指数是基尼系数的加权总和,基于该类别在特征中的相应分数。公式是:
基尼指数公式
将基尼指数应用于分类我们得到:
特征“分类”的基尼指数
你应该能够手工计算出学习时间的基尼指数。为了多样化,我创建了下面的代码来计算基尼系数和基尼系数:
# Input Format(df, feature name, category name ,target name, list of all classes)
# where df is the current node observationdef gini(df,feature,category,target,classes_list):
df=df[df[feature]==category]
def P_i_K(i):
return len(df[df[target]==i])/len(df)
result=1-sum([(P_i_K(i))**2 for i in classes_list])
return result# Input Format(df, feature name, target name, list of all classes)def Gini_index(df,feature,target,classes_list):
def P_k_a(category):
return len(df[df[feature]==category])/len(df)
result=0
for category in df[feature].unique():
gini_value=gini(df,feature,category,target,classes_list)
P_k_a_value=P_k_a(category)
result+=gini_value*P_k_a_valuereturn resultprint("Gini Index of Classification",
Gini_index(df,"Classification","Pass the quiz",['Yes','No']))
print("Gini Index of hour of practice",
Gini_index(df,"hour of practice","Pass the quiz",['Yes','No']))>>> Gini Index of Classification 0.38888888888888884
>>> Gini Index of hour of practice 0.41666666666666663
由于分类比小时练习噪音小,所以第一次分割针对分类特征*。在讨论完熵的概念后,我们将把树形象化。*
III)熵和信息增益
1)熵
在物理学中,熵代表随机变量的不可预测性。公平硬币中出现头或尾或尾的几率为 50/50,因此其熵值为 1,这是随机性的最高值。另一方面,具有值 0 表示相应的事件是命中注定的。熵与基尼系数相似,都表明了类别的不可预测性。熵的公式是:
熵公式
将此公式应用于大一、大二和大三学生,我们得到:
特征“分类”的熵
如上所述,二次熵的行为就像一枚公平的硬币,所以它有最高的价值。新生的值非常接近 1,因为它的类是不平衡的。
信息增益
在获得每个类别的熵之后,我们可以将它们组合起来,以获得特征的信息增益值。我们获得的信息越多越好。公式是:
信息增益公式
将此公式应用于我们的“分类”功能会产生:
我还提供了计算熵和信息增益的代码:
# Input Format(df,feature name K,category name,target name, list of all classes)
# Pass feature, category None if want to find the entropy of the whole observation
import math
def entropy(df,feature,category,target,classes_list):
if (feature!=None)|(category!=None):
df=df[df[feature]==category]
def P_i_k(class_):
return len(df[df[target]==class_])/len(df)
result=0
for class_ in classes_list:
P_i_k_value=P_i_k(class_)
if P_i_k_value!=0:
result+=P_i_k_value*math.log(P_i_k_value,2)
return -1*result# Input Format(df,feature name K,category name,target name,list of all classes)
def InfoGain(df,feature,target,classes_list):
H_T=entropy(df,None,None,target,classes_list)
def P_i_a(category,feature):
return len(df[df[feature]==category])/len(df)
result=0
for category in df[feature].unique():
result+=P_i_a(category, feature)*entropy(df,feature,category,target,classes_list)
result=H_T-result
return resultprint("Information Gain of Classification",
InfoGain(df,'Classification','Pass the quiz',['Yes','No']))
print("Information Gain of hour of practice",
InfoGain(df,'hour of practice','Pass the quiz',['Yes','No']))>>>Information Gain of Classification 0.12581458369391152
>>>Information Gain of hour of practice 0.044110417748401076
因此,分类有更多的信息,所以这将是我们的第一次分裂。
IV)可视化树
在这两种方法中,分类是首选。第二个分割是剩余的特性,小时的学习,我们得到下面的树:
我们数据集的决策树
注意,这个树是极端有偏差的,因为数据集只有 6 个观察值。真实数据上的决策树要大得多,复杂得多。
v)停止分裂树的标准
随着数据变得越来越复杂,决策树也在扩展。尽管如此,如果我们保持树的增长,直到所有的训练数据被分类,我们的模型将会过度拟合。因此,学会何时停止是非常重要的。让我们来看看一些常用的标准:
***节点中的观测值数量:*理想的上限是总训练数据集的 5%。
***节点的纯度:*基尼指数显示当前数据集的每个特征有多少噪声,然后选择噪声最小的特征来应用递归。我们可以在这里设置基尼系数的最大值作为停止标准,通知分行是时候做决定了。
***树的深度:*我们可以预先指定深度的限制,这样树在面对复杂数据集时不会过度膨胀。
最大特征:由于树是按特征分割的,减少特征的数量将导致树的大小减小。只有选择具有高信息增益或低基尼系数的特征才是好主意。
六)结论
当我们看到树是如何构造的以及它是如何调整的,我们可以得出一些关于决策树的结论:
- 很容易解释。决策树类似于人类做决策的方式。因此,决策树是一个简单的模型,可以为企业带来巨大的机器学习透明度。
- 它不需要缩放/标准化数据,因为没有涉及使用数据值的计算。
- 未必创造出最好的树。原因是决策树背后的构造只关注每个节点的最优特征。不能保证最终结果是最优解。
- 也许过度拟合。很难阻止树的子样本停留在某些节点上。拥有一个从特定群体中学习的树会导致过度拟合。
你可以访问我的 GitHub 库下载代码。感谢阅读!
决策树:永远记住的 6 件关键事情
我们不需要深入算法背后的数学知识就能了解决策树。
在本帖中,我们将介绍决策树背后的基本原理以及一个实际的实现。
决策树是通用且强大的机器学习算法,可以执行分类和回归任务,甚至多输出任务。决策树也是随机森林的基本组件,是当今最强大的机器学习算法之一。
下面你会发现一个决策树的基本实现(如何训练模型并可视化其分裂),这是使用著名的 IRIS 数据集完成的。
**# Importing the necessary libraries**
import pandas as pd
import matplotlib.pyplot as plt
%matplotlib inline
from sklearn.datasets import load_iris
from sklearn import tree
from sklearn.tree import DecisionTreeClassifier**# Load iris**
iris=load_iris()
X= iris.data[:,:2]
y= iris.target**# Creating the decision tree object**
decision_tree= DecisionTreeClassifier(max_depth=2)**# Training the Model**
classifier=decision_tree.fit(X,y)
可视化决策树和拆分
**# Visualizing the decision tree**
plt.figure(figsize=(15,10))
tree.plot_tree(classifier, filled=True)
决策树及其分裂的可视化
print(tree.export_text(classifier))
打印决策树拆分
Scikit-Learn 使用 CART(分类和回归树)来训练决策树,后者只产生二叉树:非叶节点总是有两个子节点。
其思想是决策树使用一个单一特征 k 和一个阈值 tk (例如 X[0] < 5.45)将训练集分成两个子集。
如何选择 k 和 tk ?
它通过寻找(k,t k )的最佳对来产生最纯粹的子集(根据它们的大小加权)。
CART 算法试图最小化的成本函数是:
Cart 训练算法(成本函数)“按作者分类的图像”
然而,其他算法,如 ID3,可以生成具有两个以上子节点的决策树(Quinlan 1986)
”还没等龚转发一个小故事来消消气,就已经是相当的焦头烂额了。我从一位教授那里学到了这个著名的算法(ID3 ),这让我着迷,而这位教授正是这个算法的发现者😊"
计算复杂度
即使在处理较大的训练集时,预测也非常快,这是因为决策树需要从根到叶遍历整个树,因为它们通常是平衡的,遍历它们大约需要遍历:
(决策树的计算复杂性)“作者图片”
熵还是基尼杂质?
考虑到决策树及其家族的众多特性之一,它们需要很少的数据准备,它们根本不需要特征缩放。
然而,非常重要的是要注意这种差异。
(基尼系数杂质和熵方程)“作者图片”
大多数情况下,这并没有很大的区别,它们往往导致类似的树。但是,主要区别是:
- 基尼杂质计算起来略快(等式 1)。然而,当它们不同时,基尼系数分离出它自己分支中最常见的类别
- 熵(等式 2)产生稍微更平衡的树。
在 Scikit-learn 中,默认情况下,模型是用基尼系数杂质设置的。
决策树参数
(CCP _ 阿尔法=0.0,类 _ 重量=无,标准= ‘基尼’,
最大深度=2,最大特征=无,最大叶节点=无,
最小杂质 _ 减少=0.0,最小杂质 _ 分离=无,
最小样本 _ 叶=1,最小样本 _ 分离=2,
最小重量 _ 分数 _ 叶=0.0,预排序= ‘已弃用’,
随机状态=无
正则化超参数
对训练数据做了一些假设:假设数据是非线性的。在大多数情况下,如果决策树不受约束,树结构将非常适合数据集,过度适合数据,不能很好地推广到测试数据。
作为一个非参数模型,它有很多参数。但是因为参数的数目在训练之前没有确定,所以模型可以自由地坚持训练数据。为了避免过度拟合训练数据,我们需要在训练过程中限制决策树的自由度(正则化)。
这可以通过限制决策树的最大深度数来实现,特别是在 Scikit 中,通过设置 max_depth 超参数 (默认设置为 none: Unlimited)来实现学习。减少后者将使模型规范化,并降低过度拟合的风险
来自:数据科学堆栈交换
从上图中我们可以看到,拥有一个 max_depth 为 5 ,会产生一个方差很大的模型,而限制决策树的最大深度对减少模型的过拟合起着关键作用。当然,将它减少到两个对更好地规范模型有巨大的影响。
此外,决策树喜欢制作正交边界(所有分割都垂直于轴),如上图所示,这使它们对训练数据中的小变化非常敏感,并使模型非常不稳定。防止这种情况的一种方法是采用**随机森林,**后者可以通过对许多树进行平均来限制这种不稳定性,这个模型将在未来的帖子中详细分析。
来源:Takashi J. OZAKI via KDnuggets
该算法的 6 个关键要点:
- 易于解释(非参数模型),功能强大,用途广泛。
- 使用少量训练数据进行有效学习,但是对训练数据的微小变化非常敏感。
- 不需要功能缩放。
- 关于训练数据的假设很少(数据是非线性的)。
- 很可能会对训练数据进行过度拟合(没有很好地推广)。
- 喜欢正交决策边界。
希望这个简短的 ML 故事能提供信息!谢谢你
决策树:构建 DTs 的逐步方法
马里乌斯·马萨拉尔在 Unsplash 上的照片
介绍
决策树(DTs) 是一种用于分类和回归的非参数监督学习方法。目标是创建一个模型,通过学习从数据特征推断的简单决策规则来预测目标变量的值。决策树通常用于运筹学,特别是决策分析,以帮助确定最有可能达到目标的策略,但也是机器学习中的一种流行工具。
语境
在本文中,我们将讨论以下主题
- 通常什么是决策树
- 决策树的类型。
- 用于构建决策树的算法。
- 构建决策树的逐步过程。
什么是决策树?
图 1-基于是/否问题的决策树
上图是一个简单的决策树。如果一个人是非素食者,那么他/她吃鸡肉(最有可能),否则,他/她不吃鸡肉。一般来说,决策树会问一个问题,并根据答案对人进行分类。该决策树基于是/否问题。在数字数据上构建决策树同样简单。
图 2-基于数字数据的决策树
如果一个人开车时速超过 80 英里,我们可以认为这是超速,否则不是。
图 3-分级数据的决策树
这里有一个更简单的决策树。该决策树基于分级数据,其中 1 表示速度太高,2 表示速度较低。如果一个人超速超过等级 1,那么他/她就是严重超速。如果这个人在速度等级 2 之上但在速度等级 1 之下,那么他/她超速了,但没超速那么多。如果这个人低于速度等级 2,那么他/她在速度限制内驾驶得很好。
决策树中的分类可以是类别的,也可以是数字的。
图 4-复杂 DT
这里有一个更复杂的决策树。它结合了数字数据和是/否数据。在很大程度上,决策树很容易使用。你从顶端开始,一路向下,直到你无法再前进。样本就是这样分类的。
树的最顶端被称为 根节点 或者仅仅是 根。 中间的节点称为 内部节点 。内部节点有指向它们的箭头和远离它们的箭头。末端节点被称为 叶节点 或者仅仅是 叶节点 。叶节点有指向它们的箭头,但没有远离它们的箭头。
在上面的图中,根节点用矩形表示,内部节点用圆形表示,叶节点用倒三角形表示。
构建决策树
构建决策树有几种算法。
- CART-分类和回归树
- ID3-迭代二分法 3
- C4.5
- CHAID 卡方自动交互检测
我们将只讨论 CART 和 ID3 算法,因为它们是主要使用的算法。
手推车
CART 是一种 DT 算法,根据因变量(或目标变量)是分类变量还是数值变量,分别生成二进制 分类或回归树。它以原始形式处理数据(不需要预处理),并且可以在同一个 DT 的不同部分多次使用相同的变量,这可以揭示变量集之间复杂的相互依赖关系。
图 5-样本数据集
现在我们将讨论如何从原始数据表中构建决策树。在上面给出的例子中,我们将建立一个决策树,使用胸痛、良好的血液循环和阻塞动脉的状态来预测一个人是否患有心脏病。
我们必须知道的第一件事是哪个特性应该在树的顶部或根节点中。我们先来看看胸痛是如何预测心脏病的。
图 6-胸痛作为根节点
有两个叶节点,分别对应胸痛的两种结果。每一个叶子包含有心脏病和没有心脏病的患者的数目,用于对应的胸痛条目。现在我们对良好的血液循环和阻塞的动脉做同样的事情。
图 7-良好的血液循环作为根节点
图 8-阻塞的动脉作为根节点
我们可以看到,这三个特征都不能很好地区分心脏病患者和非心脏病患者。值得注意的是,在所有三种情况下,患有心脏病的患者总数是不同的。这样做是为了模拟真实数据集中存在的缺失值。
因为没有一个叶节点不是 100% '有心脏病’就是 100% ‘没有心脏病’,所以都认为 不纯。 为了决定哪种分离最好,我们需要一种方法来测量和比较 杂质。
CART 算法中用于测量杂质的指标是 基尼杂质分数 。计算基尼系数很容易。我们先来计算一下胸痛的基尼杂质。
图 9-胸痛分离
对于左边的叶子,
**Gini impurity = 1 - (probability of ‘yes’)² - (probability of ‘no’)²**
= 1 - (105/105+39)² - (39/105+39)²
Gini impurity = 0.395
类似地,计算右叶节点的 Gini 杂质。
**Gini impurity = 1 - (probability of ‘yes’)² - (probability of ‘no’)²**
= 1 - (34/34+125)² - (125/34+125)²
Gini impurity = 0.336
现在我们已经测量了两个叶节点的基尼系数,我们可以计算总基尼系数,用胸痛来区分有和没有心脏病的患者。
叶节点不代表相同数量的患者,因为左叶代表 144 名患者,而右叶代表 159 名患者。因此,总 Gini 杂质将是叶节点 Gini 杂质的加权平均值。
Gini impurity = (144/144+159)*0.395 + (159/144+159)*0.336
= 0.364
同样,“血液循环良好”和“动脉阻塞”的总基尼系数计算如下
Gini impurity for ‘good blood circulation’ = 0.360
Gini impurity for ‘blocked arteries’ = 0.381
“良好的血液循环”在树中具有最低的杂质分数,这象征着它最好地分离了患有和未患有心脏病的患者,因此我们将在根节点使用它。
图 10-根节点处良好的血液循环
现在我们需要弄清楚“胸痛”和“动脉阻塞”如何区分左淋巴结的 164 名患者(37 名有心脏病,127 名无心脏病)。
就像我们之前所做的那样,我们将把这些‘胸痛’患者分开,并计算基尼杂质值。
图 11-胸痛分离
基尼系数为 0.3。然后我们对“堵塞的动脉”做同样的事情。
图 12-阻塞动脉分离
基尼系数为 0.29。由于“阻塞的动脉”具有最低的基尼系数,我们将在图 10 的左侧节点使用它来进一步分离患者。
图 13-阻塞动脉分离
我们只剩下“胸痛”,所以我们将看到它如何很好地分离左侧淋巴结中的 49 名患者(24 名有心脏病,25 名无心脏病)。
图 14-左侧淋巴结的胸痛分离
我们可以看到胸痛在区分病人方面做得很好。
图 15-最终胸痛分离
这些是树的这个分支左边的最后的叶子节点。现在,让我们看看当我们尝试使用“胸痛”来分离具有 13/102 个患者的节点时会发生什么。请注意,这个节点中几乎 90%的人没有心脏病。
图 16-右侧淋巴结的胸痛分离
这种分离的基尼系数为 0.29。但是在使用胸痛来分离患者之前,母节点的基尼不纯度是
Gini impurity = 1 - (probability of yes)² - (probability of no)²
= 1 - (13/13+102)² - (102/13+102)²
Gini impurity = 0.2
如果我们不使用“胸痛”来区分患者,杂质会更低。所以我们将使它成为叶节点。
图 17-左侧已完成
此时,我们已经完成了树的整个左侧。按照相同的步骤,计算出树的右侧。
- 计算基尼系数。
- 如果节点本身得分最低,那么就没有必要再分离患者,它就变成了一个叶节点。
- 如果分离数据导致改进,则选择杂质值最低的分离。
图 18-完整的决策树
ID3
除了用于测量纯度/杂质的方法之外,使用 ID3 算法构建决策树的过程几乎类似于使用 CART 算法。ID3 算法中用于测量纯度的度量被称为 熵 。
熵是一种度量样本子集中某个类的不确定性的方法。假设项目属于子集 S,具有两个类别正和负。熵被定义为表示 x 是正还是负所需的位数。
熵总是给出一个介于 0 和 1 之间的数。因此,如果使用属性分离后形成的子集是纯的,那么我们将需要 0 位来判断是正还是负。如果所形成的子集具有相等数量的正项和负项,那么所需的位数将是 1。
图 19。熵与 p(+)的关系
上图显示了熵和正类概率之间的关系。正如我们所看到的,熵达到 1,这是最大值,这时一个项目有相等的机会成为正的或负的。当 p(+)趋于零(象征 x 为负)或 1(象征 x 为正)时,熵最小。
熵告诉我们每个子集在分裂后有多纯或不纯。我们需要做的是汇总这些分数,检查拆分是否可行。这是通过信息增益完成的。
图 20。构建 ID3 树
考虑我们上面讨论的 CART 算法的这部分问题。我们需要从**chest pain**
和**blocked arteries**
中决定使用哪个属性来分离包含 164 个患者(37 个患有心脏病,127 个没有心脏病)的左侧节点。我们可以将分裂前的熵计算为
让我们看看**chest pain**
如何区分病人
图 21-胸痛分离
可以计算左侧节点的熵
类似地,右边节点的熵
使用**chest pain**
分裂后熵的总增益
这意味着,如果在当前情况下,如果我们选择**chest pain**
来分割患者,我们将获得关于患者是否患有心脏病的 0.098 比特的确定性。对**blocked arteries**
、**、**做同样的事情,得到的增益是 0.117。既然用**blocked arteries**
分裂给了我们更多的确定性,那就摘了吧。我们可以对所有节点重复相同的过程,以基于 ID3 算法构建 DT。
注意:可以通过对所需增益值施加最小阈值来决定是将节点分成 2 个还是将其声明为叶节点。如果获得的增益高于阈值,我们可以分裂节点,否则,将其作为叶节点。
摘要
以下是这篇文章的要点
- 决策树背后的一般概念。
- 决策树的基本类型。
- 构建决策树的不同算法。
- 使用 CART 算法构建决策树。
- 使用 ID3 算法构建决策树。
参考
- 参考 youtube 上的这个播放列表,了解更多关于使用 CART 算法构建决策树的细节。
2.关于使用 ID3 算法构建决策树的更多细节,请参考 youtube 上的这个播放列表。
PS:-我将很快发布另一篇关于回归树和随机森林的文章。 敬请期待 😃
请在这里查看我关于数据科学和机器学习的其他文章。欢迎在评论和LinkedIn上寻求更深入的讨论。
决策树解释
学习机器学习决策树的所有知识
来源: Unsplash
在这篇文章中,我将简单地解释决策树。它可以被认为是一个傻瓜帖子的决策树,然而,我从来没有真正喜欢过这个表达。
在我们开始之前,这里有一些额外的资源,可以让你的机器学习生涯一飞冲天
*Awesome Machine Learning Resources:**- For* ***learning resources*** *go to* [***How to Learn Machine Learning***](https://howtolearnmachinelearning.com/books/machine-learning-books/)*!
- For more awesome Data Science news, tools, educative articles and platforms* [***subscribe to my newsletter***](https://z-ai.medium.com/subscribe)!
订阅我的专属列表!获取你喜欢的所有新鲜文章<3! By signing up, you will create a Medium…
z-ai.medium.com](https://z-ai.medium.com/subscribe)
Introduction and Intuition
In the Machine Learning world, 决策树是一种**非参数模型,**可用于分类和回归。
这意味着决策树是灵活的模型,不会随着我们添加更多的特征而增加它们的参数数量(如果我们正确地构建了它们),并且它们可以输出分类预测(像植物是否属于某种类型)或者数字预测(像房子的价格)。
它们由两种元素构成:节点和分支。在每个节点上,我们会评估数据的一个特征,以便在训练过程中拆分观察值,或者在进行预测时使特定的数据点遵循特定的路径。
在每个节点,对一个变量进行求值,以决定走哪条路径。
构建决策树时,通过 递归 评估不同的特征,并在每个节点使用最能拆分数据的特征来构建决策树。这个后面会详细解释。
也许开始解释的最好方法是看看决策树是什么样子的,以建立如何使用它们的快速直觉。下图显示了这些树的一般结构。
决策树的图形。来源。
在该图中,我们可以观察到三种节点:
- **根节点:**是开始图的节点。在普通的决策树中,它评估最能分割数据的变量。
- **中间节点:**这些是评估变量的节点,但不是进行预测的最终节点。
- **叶节点:**这些是树的最终节点,在这里进行类别或数值的预测。
好了,现在我们对什么是决策树有了一个大致的概念,让我们看看它们是如何构建的。
决策树的训练过程
正如我们之前提到的,决策树是通过递归分割训练样本来构建的,使用的是最适合特定任务的数据特征。这是通过评估某些指标来完成的,如分类决策树的 基尼指数 或 熵 ,或回归树的 残差或均方差 。
如果我们在节点处评估的特征是离散的或连续的,则过程也是不同的。对于 离散特征对其所有可能值进行评估,从而为每个变量计算出 N 个度量,N 为每个分类值的可能值的数量。对于连续特征,训练数据的每两个连续值(从最低到最高排序)的平均值被用作可能的阈值。
对于某个节点,该过程的结果是变量列表,每个变量具有不同的阈值,以及每个变量/阈值串联的计算度量(Gini 或 MSE)。然后,我们选择变量/阈值组合,该组合为我们提供用于结果子节点的特定度量的最高/最低值(度量中的最高减少或增加)。
我们不会深入研究这些指标是如何计算的,因为这与这篇介绍性文章的主题无关,但是如果你感兴趣,我会在最后留下一些资源供你深入研究。目前,只要把这些度量(分类树的基尼系数和回归树的均方误差)想象成某种我们想要减少的误差。
让我们看一个两个决策树的例子,一个分类决策树和一个回归决策树,以更清楚地了解这个过程。下图显示了为著名的鸢尾数据集构建的分类树,其中我们试图使用花瓣宽度、长度、萼片长度等特征来预测三种不同花朵的类别
为 Iris 数据集构建决策树
我们可以看到,根节点从三个类别中的每一个的 50 个样本开始,并且基尼指数(因为它是分类树,所以基尼指数越低越好)为 0.667。
在该节点中,最好地分割不同类别的数据的特征是以 cm 为单位的 花瓣宽度 ,使用值 0,8 作为阈值。这产生了两个节点,一个具有 Gini 0(只有一种花的完美纯节点),另一个具有 Gini 0.5,在那里两种其他种类的花被分组。
在这个中间节点(来自根节点的错误路径)中,使用阈值 1,75 来评估相同的特征(是的,这可能发生,并且如果该特征很重要,它实际上经常发生)。现在这导致了另外两个子节点,它们不是纯粹的,但是基尼系数很低。
在所有这些节点中,对数据的所有其他特征(萼片长度、萼片宽度和花瓣长度)进行评估,并计算其结果基尼指数,然而,给我们最好结果(最低基尼指数)的特征是花瓣宽度。
树没有继续增长的原因是因为决策树总是配置一个停止增长的条件,否则它们会一直增长,直到每个训练样本都被分成它自己的叶节点。这些停止条件是树的最大深度、叶节点中的最小样本或误差度量的最小缩减。
现在让我们检查一下回归树,为此,我们将使用 波士顿房价 数据集,结果如下图:
为波士顿住房数据集构建的决策树
从上图可以看出,现在我们没有基尼指数,而是有了 MSE (均方差)。与前面的基尼系数示例一样,我们的树是使用最大程度地减少这种误差的特征/阈值组合来构建的。
根节点使用阈值为 9.725 的变量LSTAT(%区域中人口的下层状态)对样本进行初始划分。我们可以看到,在根节点我们有 506,我们分为 212(左子节点)和 294(右子节点)。
左边的子节点使用阈值为 6.631 的变量 RM ( 每个住所的房间数),右边的节点使用阈值为 16.085 的相同的 LSTAT 变量,产生了四个漂亮的叶节点。像以前一样,在每个节点上评估所有其他变量,但这两个变量是最好的数据分割变量。
厉害!现在我们知道决策树是如何构建的。让我们来学习它们是如何被用来做预测的。
用决策树做预测
使用决策树预测新样本的类别或数值目标值非常容易。这是这类算法的主要优点之一。我们所要做的就是从根节点开始,查看它所评估的特性的值,并根据该值转到左边或右边的子节点。
重复这个过程,直到我们到达一个叶节点。当这种情况发生时,根据我们面对的是分类问题还是回归问题,可能会发生两种情况:
a) 如果我们面临一个分类问题,预测的类别将是该叶节点上的类别的模式。还记得在分类树中,我们在中间的叶节点上有 value = [0,49,5]吗?这意味着到达该节点的测试样本最有可能属于在该节点上具有 49 个训练样本的类,因此我们将其分类。
b) 对于一棵回归树,我们在最后做出的预测是目标变量在这个叶节点上的值的平均值。在我们的住房示例中,如果叶节点有 4 个价格为 20、18、22 和 24 的样本,则该节点的预测值将是 21,这是在此结束的 4 个训练示例的平均值。
在下图中,我们可以看到如何为先前的回归树预测一个新的测试样本(一栋房子)。
注: 仅显示树中使用的房屋特征。
特定样本遵循的路径和给定预测的值。来自平面图标的图标。
好吧!现在我们知道如何使用决策树进行预测。让我们通过学习他们的优点和缺点来结束。
决策树的利与弊
优势:
- 决策树的主要优势是如何容易解释**。当其他机器学习模型接近黑盒时,决策树提供了一种图形和直观的方式来理解我们的算法做什么。**
- 与其他机器学习算法相比,决策树需要更少的数据来训练。
- 它们可用于分类和回归。
- 他们是简单的。
- 他们容忍缺失值 s。
不足之处
- 他们很容易使过度拟合训练数据,并且对异常值敏感。
- 他们是弱学习者:单个决策树通常不会做出很好的预测,因此多棵树经常被组合起来形成“森林”以产生更强的集成模型。这将在以后的文章中讨论。
订阅我的专属列表!获取您喜欢的所有新鲜文章<3! By signing up, you will create a Medium…
z-ai.medium.com](https://z-ai.medium.com/subscribe)
Conclusion and additional resources
决策树是简单而直观的算法,正因为如此,在试图解释机器学习模型的结果时,它们被大量使用。尽管很弱,但它们可以结合起来产生非常强大的 bagging 或 boosting 模型。在接下来的文章中,我们将探索其中的一些模型。
如果你想知道构建一棵树的完整过程,可以看看下面的视频:
就这些,我希望你喜欢这个帖子。随时 在 Twitter 上关注我 在***@ jaimezorno****。还有,你可以看看我在数据科学和机器学习上的帖子**这里 。好好读!*
关于机器学习和数据科学的更多资源,请查看以下资源库: 如何学习机器学习 !有关职业资源(工作、事件、技能测试),请访问AIgents.co——数据科学家的职业社区&机器学习工程师 。
还有,更多类似这样的帖子关注我上媒 ,敬请关注!**
还有,你可以订阅我的邮箱列表在这里获取最新更新和独家内容: 订阅邮箱列表 。
最后,为了更深入地了解决策树和机器学习,看看下面文章中描述的书:
让你的机器学习知识更上一层楼
towardsdatascience.com](/the-book-to-really-start-you-on-machine-learning-47632059fd0e)
非常感谢您的阅读,祝您有美好的一天!**