- 决策树将决策建模为一系列连锁问题,熵和信息增益指导分类和回归中分割的选择。
- 增强决策树回归(如 Azure 机器学习中的 LightGBM 所实现的)构建小型树的集成,通过迭代纠正残差误差。
- 决策树的过拟合问题可以通过修剪以及深度、叶子大小和学习率等参数来控制,而随机森林和提升等集成方法可以提高鲁棒性。
- 设计师可以使用原生 JavaScript 构建交互式决策树原型,方法是将节点构建为对象,管理导航(包括返回操作),然后连接到已学习的模型。
如果你是一名已经接触过 HTML、CSS 和原生 JavaScript 的设计师,那么构建决策树或回归模型一开始可能会感觉像是一种神秘的魔法。 你可能在纸上画出了清晰的决策流程,甚至可能画出了一个不错的 Figma 原型,但是当需要将这种逻辑转化为交互式 Web 组件或小型预测模型时,突然发现一切都不像你画的图那么简单了。
好消息是,决策树是您可以使用 JavaScript 实现和可视化的最直观的机器学习模型之一,即使您的编码经验有限。 此外,Azure 机器学习或 LightGBM 等工具中使用的强大提升回归树也遵循相同的概念:一系列问题逐步改进数值预测。在本指南中,我们将把您想要构建原型的可视化决策树、底层机器学习概念(熵、信息增益、剪枝、提升)以及您可以立即编写的实用 JavaScript 代码联系起来。
在接触 JavaScript 之前,先了解决策树。
从宏观层面来说,决策树只是一种结构化的提问方式,每个答案都会引导你沿着不同的分支向下思考,直到最终做出决定。 想象一下走进一家餐厅:你饿了吗?如果饿了,你想吃点清淡的还是油腻的?如果想吃清淡的,菜单上有沙拉吗?如果有,你最终点了一份沙拉。这个心理过程其实就是一棵决策树:每个问题都是一个节点,每个答案都是一个分支,最终的选择(沙拉、汉堡、什么都不点)就是一个叶子。
在机器学习中,我们使用数据来编码这个相同的概念:数据集中的每一行都是一个示例,每一列都是一个属性,目标是我们想要预测的内容。 树学习算法能够自动发现哪些问题(基于属性的分割)最有助于将数据划分成同质组。对于分类问题,叶节点存储类别标签;对于回归问题,叶节点存储数值(例如,价格、分数或概率)。
树木之所以如此吸引人,尤其对设计师和初学者而言,是因为它们本身就具有很强的可诠释性。 你可以从上到下把这棵树解读成一系列规则:“如果环境条件差且无风,则预测游戏=肯定。”这种透明度是许多其他模型(例如深度神经网络)所不具备的。
为了构建一个好的决策树,算法需要一种方法来决定先问哪个问题,再问哪个问题,依此类推,这就需要用到一些简单的数学知识了。 别担心:你不需要在 JavaScript 代码中手动推导公式,但理解熵和信息增益背后的概念将有助于你理解树是如何构建的,以及为什么有些分支会以它们的方式出现。
熵与信息增益:树木如何选择正确的问题
熵是衡量数据集中不确定性或混乱程度的指标,对于 ID3 或 C4.5 等经典决策树算法如何决定其分割至关重要。 如果子集中的所有样本都属于同一类,则熵为零:节点完全纯净,不存在任何不确定性。如果类别均匀混合(例如,50% 为“是”,50% 为“否”),则熵最大,这意味着我们非常不确定随机元素的标签是什么。
形式上,如果我们有几个类和 pi 是第 i 类样本所占的比例,集合 S 的熵 H(S) 为: H(S) = – ∑ pi * 日志2(pi当一个阶层占据主导地位时,它的pi 当接近 1 时,对数项会变得很小,熵也会下降。当类别平衡时,更多项的贡献会变得显著,对于二元情况,熵会趋近于 1。
信息增益衡量的是,如果我们使用特定属性分割数据集,熵会下降多少,而这正是决策树在每个节点上选择最佳问题的方式。 对于可以取不同值 v 的属性 A,我们考虑其子集 S。v 仅包含 A = v 的样本。信息增益 IG(S, A) 等于 H(S) 减去各子集熵的加权和。信息增益最高的属性能提供最清晰的分离,因此被选为分割点。
这就是为什么在许多与天气相关的示例中,你经常会在树的根部看到“环境”或“展望”等属性。 在特定情况下,“环境”变量的信息增益可能最大(例如,约为 0.246),这意味着它能最好地区分“进行比赛”和“不进行比赛”的决策。然后,根据“环境”变量,算法可能会进一步考虑风力、湿度或温度,以进一步细化区分。
检查训练好的树时,你可能会看到如下路径:如果环境 ≤ 1.5,则检查风;如果没有风,则预测 play = yes,熵为 0.0,样本数为 5。 如果有风,节点的熵可能达到 1.0,包含两个正样本和两个负样本,因此不确定性较高,可能会出现进一步的分支。在其他分支中,当环境因素 > 1.5 时,决策树可能会考虑湿度,并且只有当湿度不低时才会检查温度,以排除一些棘手的情况。
从简单的决策树到回归树
到目前为止,我们主要讨论的是分类,但你也可以使用完全相同的树结构进行回归,其中输出是数值而不是离散标签。 回归树不是在每个叶子节点存储“玩”或“不玩”,而是存储一个数字,通常是落入该叶子节点的训练样本的平均目标值。
在回归树中,分裂准则不再依赖于熵,而是依赖于方差减少或平方误差最小化等度量。 每次拆分都力求创建目标值尽可能相似的子节点,从而使每个叶节点的预测更加准确。换句话说,该算法会问:“如果我根据这个属性拆分数据,我可以将每个子集中目标值的变异性降低多少?”
这些回归树是许多高级方法的基础,包括梯度提升框架(如 LightGBM),这些框架在 Azure 机器学习等平台上被广泛使用。 在这些系统中,通常不会构建一个单一的整体树,而是构建一个树的集合,每一棵树都试图纠正前一棵树的错误。
作为 JavaScript 开发人员或设计师,您可以将每个回归树视为手绘流程图的更智能版本,其中叶子上的“答案”是数字(如价格、分数或概率),而不是文本标签。 你仍然可以将逻辑可视化为一棵树,但其强大之处在于如何组合和调整这些树。
提升型决策树回归:集成方法如何提高准确率
Boosting 是一种经典的集成方法,它构建许多弱模型(如小型回归树),并将它们组合起来形成一个具有更高准确度的强预测器。 与 bagging 或随机森林中独立训练所有树不同,boosting 是逐一添加树,其中每棵新树都专注于先前树留下的残差误差。
在提升决策树回归中(Azure 机器学习通过 LightGBM 等算法实现的就是这种回归),每一棵新树都会通过学习残差来纠正当前集成模型的错误。 首先,建立一个简单的模型,可能只是一个常数预测值;然后计算该预测值与实际值之间的差异(残差)。接下来,训练下一棵决策树来预测这些残差,并以一定的学习率将其添加到模型中。随着这个过程的不断重复,整体预测效果会越来越好。
这个过程被称为梯度提升,而 MART(多重加性回归树)是 Azure 机器学习用于提升树的一种众所周知的实现方式。 算法在每一步都使用可微损失函数(例如平方误差)来计算误差梯度,并决定如何调整下一棵树。实际上,最终会得到许多小树的集成模型,每棵树都对最终的数值输出做出少量贡献。
虽然提升算法通常能提高预测准确率,但如果不注意超参数(例如树的数量、最大深度或学习率),它可能会降低覆盖率或泛化能力。与此相关的情况 过拟合与欠拟合. 首先,建立一个简单的模型,可能只是一个常数预测值;然后计算该预测值与实际值之间的差异(残差)。接下来,训练下一棵决策树来预测这些残差,并以一定的学习率将其添加到模型中。随着这个过程的不断重复,整体预测效果会越来越好。
这个过程被称为梯度提升,而 MART(多重加性回归树)是 Azure 机器学习用于提升树的一种众所周知的实现方式。 算法在每一步都使用可微损失函数(例如平方误差)来计算误差梯度,并决定如何调整下一棵树。实际上,最终会得到许多小树的集成模型,每棵树都对最终的数值输出做出少量贡献。
虽然提升算法通常会提高预测准确率,但如果不注意超参数(例如树的数量、最大深度或学习率),它可能会降低覆盖率或泛化能力。 树的数量过多或树的规模过大会导致训练数据过拟合,而学习率过小且树的数量过少则可能导致拟合不足,无法捕捉到重要的模式。
需要注意的是,提升决策树回归是一种监督学习方法,这意味着您必须提供一个带有数值目标列的标记数据集。 标签(目标)必须是数值型的,因为该算法优化的是连续损失函数;如果你有类别,你可以将它们转换为数字,或者改用提升树的分类变体。
Azure 机器学习增强树的关键配置选项
当您在 Azure 机器学习的设计器中使用增强决策树回归组件时,您实际上是在配置如何构建和训练树的集成。 该组件封装了一个高效的基于 LightGBM 的实现,但以友好的用户界面公开了最重要的参数,以便即使您不直接在该环境中编写代码,也可以进行实验。
您面临的第一个选择是训练器创建模式,它决定您是设置单个配置还是探索一系列超参数。 在“单参数”模式下,您可以手动选择学习率、叶节点数和树数等参数值:如果您已经对想要的结果有了大致的想法,这将非常方便。在“参数范围”模式下,您可以为每个参数指定一个区间,然后由一个单独的组件(例如“调整模型超参数”)自动尝试所有组合,以找到性能最佳的组合。
另一个关键设置是每棵树的最大叶子数,它有效地控制了集成中每棵树的复杂性。 更多的叶子节点意味着更多的终端节点和更详细的规则。这可以提高训练数据的准确率,但也增加了过拟合的风险并延长了训练时间。较少的叶子节点可以使每棵树更简单,并能提高泛化能力,但代价是可能会错过一些细微的模式。
您还需要确定每个叶节点所需的最小样本数,这将决定您的规则可以细化到什么程度。 默认值为 1 时,即使只有一个训练样本也能形成一个新的叶节点,这可能导致模型记忆噪声。将此最小值提高到例如 5,则强制每条规则至少覆盖五个具有相同条件的样本,从而使模型更加平滑,并通常能提高其泛化能力。
学习率是一个介于 0 和 1 之间的值,它指定了每个新树在纠正先前集成中的错误时所采取的步长。 较大的学习率能使模型快速学习,但容易偏离最优解;较小的学习率能使训练更稳定,但可能需要更多的决策树和更长的训练时间。找到合适的平衡点是构建强大模型的关键。
构建的树的数量控制着提升步骤重复的次数,也就是最终模型中合并的弱学习器的数量。 通常情况下,较高的数值可以带来更好的覆盖率,但也会增加过拟合的风险并增加计算成本。将其设置为 1 会禁用 boosting,只留下一个回归树,虽然回归树可能更容易解释,但通常准确度较低。
Azure 机器学习还允许您设置随机种子进行初始化,这对于使用相同数据和参数进行多次运行以获得可重复的结果非常有用。 如果将其保留为默认值 0,平台会根据系统时钟生成随机种子,因此每次训练运行都可能生成略有不同的决策树。使用固定的随机种子,可以更轻松地调试和比较模型。
配置好组件后,训练模型只需将其连接到带标签的数据集,然后根据所选模式使用“训练模型”组件或超参数调优组件即可。 训练完成后,您可以将生成的模型插入“评分模型”组件中,以对新输入进行预测,并且您可以将训练好的模型注册到组件树中,以便在其他管道中重复使用它,而无需重新训练。
过度拟合、修剪以及树木为何会变得过于聪明
在使用决策树时,无论是以原始形式还是作为提升森林或随机森林集成模型的一部分,最大的风险之一是过拟合,而理解这一点至关重要。 偏差-方差权衡 这有助于解释为什么模型会变得如此复杂,以至于它会记住训练数据而不是学习一般规则。 理论上,一棵树可以不断分裂,直到每个叶子都对应一个训练样本,在已知数据上达到完美的准确率,但在未见过的样本上表现很差。
修剪是解决决策树过拟合的标准方法,其本质是砍掉树枝或限制树的生长,使模型保持相对简单。 许多库和框架都提供诸如最大深度、每个叶节点的最小样本数或每次分裂的最小样本数等参数,用于控制新分支的创建方式和时间。提高这些阈值会迫使决策树在分裂行为上更加保守。
例如,在 Python 的 scikit-learn 中,经常会看到 max_depth、min_samples_leaf 和 min_samples_split 等参数用于规范树。 较小的 `max_depth` 值限制了决策树可以提出问题的层级数。较大的 `min_samples_leaf` 值确保每个叶节点代表的样本组足够大,具有统计意义。较大的 `min_samples_split` 值可以防止模型从样本量极少的节点创建新分支。
即使你没有在 JavaScript 中直接使用 scikit-learn,但如果你实现自己的树逻辑或手动设计决策结构,同样的思路也适用。 你应该始终扪心自问,新的分支究竟代表的是稳定的模式,还是仅仅是数据中的噪声。在面向用户的决策树中,过深或过于具体的分支也可能令用户感到困惑,使界面更难理解。
增强模型和集成模型通过组合许多弱学习器来缓解一些过拟合问题,但如果超参数过于激进,它们仍然可能过拟合。 在 Azure 机器学习等生产环境中,控制决策树的数量、深度、学习率和正则化项至关重要。对于交互式体验设计而言,无论从用户体验角度还是从系统健壮性角度来看,通常越简单越好。
从单一决策树到随机森林
如果说单个决策树功能强大但脆弱,那么随机森林就像一个由多棵树组成的委员会,它们共同投票以得出更稳定的预测结果。 思路很简单:训练多个决策树,每个决策树处理略有不同的数据子集和属性,然后汇总它们的输出。对于分类问题,它们投票选出出现频率最高的类别;对于回归问题,则对它们的数值预测结果取平均值。
随机森林通过两种主要方式引入随机性:有放回地对训练样本进行抽样(自助抽样)以及为每次分裂选择一个随机的属性子集。 这种随机性使得每棵树都略有不同,因此它们不会重蹈覆辙,犯同样的错误。当组合起来时,各个树的错误往往会相互抵消,从而形成一个更稳健的模型。
从过拟合的角度来看,随机森林通常比单个深度树具有更好的泛化能力,因为每棵树所看到的内容和分裂方式都是有限的,最终的预测是多个角度的平均值。 换句话说,模型的方差减小了,并且在不同的数据集上表现得更加稳定。
对于有设计背景的人来说,你可以把随机森林想象成一组由不同的设计师创建的略有不同的决策图,每个设计师使用略有不同的标准,然后一个聚合器查看所有这些决策图并选择共识答案。 没有哪一张地图是完美的;智慧来自于群体。
虽然本文主要关注决策树和提升回归的一般概念,但随机森林背后的直觉在你以后探索更高级的 JavaScript 或 Python 库(这些库公开了森林和集成 API)时会非常有帮助。 核心组成部分始终相同:那就是你现在所理解的决策树。
学习决策树:技能、徽章和结构化培训
一些机器学习相关的学习路径和课程,其内容都明确地围绕决策树构建,完成所有活动后通常会颁发徽章或证书。 这些课程通常从介绍决策树开始,然后逐步讲解如何使用熵、基尼指数或信息增益找到最佳分割,如何以及为什么要修剪决策树,以及决策树与线性模型的比较等主题。
在此过程中,您可能会了解到用于分类的决策树、用于回归的决策树,以及模型简单性和预测能力之间的权衡。 对许多学习者来说,决策树是进入机器学习领域的入门算法,因为它符合人们自然而然的思维方式——分支和规则。将训练好的决策树可视化,可以清晰地展现模型做出特定选择的原因,这对于培养直觉非常有效。
中级课程通常会将概念解释与使用 scikit-learn 等库的 Python 等语言的实际编码练习相结合。 你可以先用一个小型天气数据集实现一个决策树,手动计算熵和信息增益,然后让库来处理繁重的计算工作并可视化最终的结构。这些操作有助于你将数学理论与实际的模型行为联系起来。
即使你最终的目标是在 JavaScript 中实现决策逻辑或回归树,用 Python 做一些练习也会非常有启发性,因为目前大多数学习资源和解释都是用 Python 编写的。 一旦你掌握了要领,将核心思想移植到原生 JS(或从前端调用后端服务)就会变得更加容易。
完成此类课程通常意味着您能够理解熵、信息增益、剪枝策略、分类树与回归树,并了解树何时优于简单的线性模型以及何时它们可能不是最佳选择。 在生产环境中构建更复杂的集成模型(如提升树、随机森林或梯度提升决策树)之前,这些基本技能正是你所需要的。
使用原生 JavaScript 构建可点击的决策树
让我们回到你的具体问题:你已经画出了一棵决策树,现在想要一个纯 JavaScript 的可点击原型,不使用任何框架,理想情况下,最好是像 CodePen 那样可以进行调整的东西。 许多人会发现一些演示程序,例如一些可以可视化树状结构并提供“显示父级”或“返回”等用户体验功能的旧程序,但当删除某些代码行导致整个树状结构突然消失时,他们会感到困惑。
当你剥离看似无关的部分时,树状图消失的主要原因是这些部分通常负责初始化、渲染或更新可视化效果。 例如,你可能会删除设置事件监听器或调用渲染函数的代码,以为它们只是为了提供额外的 UI 选项,但实际上该函数也会在页面加载时构建初始树状图。删除它之后,屏幕上就无法再绘制图表了。
如果你只需要一个简单的“返回”按钮来浏览节点,实际上你并不需要复杂的库;你只需要一种简洁的 JavaScript 方法来表示你的树,以及少量的 DOM 操作。 一种常见的模式是将树状结构存储为一个嵌套对象,其中每个节点包含一个问题或标题、一个子节点列表,以及(可选的)父节点引用。然后,使用一个变量跟踪当前节点,并在用户每次点击时重新渲染问题和答案。
要实现“返回”功能,您可以将用户已走过的路径存储在一个数组(栈)中,并在单击按钮时弹出上一个节点。 或者,每个节点可以直接引用其父节点,这样只需设置 `currentNode = currentNode.parent` 并重新渲染即可返回上一级。这种方法使用简单的数据结构,却能提供你想要的用户体验。
如果您正在修改现有的 CodePen,请注意页面加载时运行的任何初始化代码以及附加到按钮或链接的任何事件处理程序。 删除函数之前,请先查找它的使用位置:如果它是唯一调用树形图绘制例程的地方,则需要保留它或用其他方法替换它。您还可以重构代码,将纯粹的渲染逻辑提取到一个单独的函数中,并在页面加载和导航事件中调用它,同时安全地移除诸如“显示父级”之类的无关功能。
既然你提到想要用原生 JS 实现一个极简的东西,可以考虑从一个非常小的原型开始,这个原型只需要渲染文本节点和选择按钮。 一旦核心导航完美运行且“返回”按钮按预期工作,就可以逐步增强它:添加 CSS 样式,添加节点之间的 SVG 连接器,然后再探索库以实现更高级的布局。
从原型 UI 树到实际回归模型
UI决策树(用户需要点击才能执行的硬编码决策树)与真正的回归树模型(可以从数据中学习)之间存在重要的区别,但它们共享相同的概念结构。 这两种情况下,你都会有带有条件的节点、基于答案的分支,以及输出结果的叶子节点,结果可以是推荐或数字。
对于手工打造的界面,您可以自己设计所有问题和结果,有效地扮演学习算法的角色。 相比之下,在机器学习领域,像梯度提升这样的算法会根据熵、信息增益或方差缩减等准则,从数据集中学习这些分割点。你无需直接指定决策树的结构;相反,你只需提供示例,让算法自行发现其结构。
一个实用的工作流程是,首先实现与您当前对问题的理解相符的 UI 树,然后,随着您收集到真实世界的数据,用学习到的模型替换手动设计的逻辑。 该模型可以使用 Python 或 Azure 机器学习进行训练,导出为 JSON 或其他可移植格式,然后由您的 JavaScript 应用加载。每个决策树或集成模型都可以表示为嵌套对象,您的前端会遍历这些对象以生成预测结果或为用户提供解释。
在某些产品中,团队会将这两种方法结合起来:使用学习模型来计算数值分数或建议,以及使用单独的人工设计的树来构建界面中提问的方式。 例如,您的模型可能会估计成功的概率,而 UI 树则以用户感觉自然的方式组织问题,并与您从用户研究中得出的心理模型相匹配。
理解理论方面——熵、信息增益、梯度提升、过拟合和剪枝——可以帮助你了解你的 UI 结构何时可能具有误导性,或者学习模型的树何时过于复杂而需要约束。 有了这些知识,你就可以设计出不仅看起来美观,而且还能忠实反映底层模型如何做出决策的可视化效果和交互方式。
总而言之,决策树在视觉设计、直观推理和严谨的机器学习之间架起了一座特别友好的桥梁,这也是为什么它们在课程、徽章和 Azure 机器学习等平台中如此突出的原因。 一旦你掌握了基础知识,并通过一些简单的 JavaScript 原型进行练习,你就能更好地探索更高级的集成模型,例如提升回归树和随机森林,并将这些模型集成到现实世界的 Web 应用程序中,而不会感到迷茫。
