前言
恋人不行真好看吧
第十五章
15.1 规则学习
在之前的学习中我们的模型大多数都是黑箱模型:我们不知道模型内部到底做了什么运算得到的答案,于是我们希望可以得到一种解释性强的模型,这就是规则学习解决的问题。
我们自然需要定义什么是规则及其组件,
- 规则:总的来说它是一个符合逻辑表述的语句,大家熟悉的形式可能为
IF……THEN……,- IF部分被称为前提或者规则体,它由一个或多个逻辑文字的合取(逻辑且)构成
- THEN 部分被称为结论 或规则头。它指定了当前提满足时得出的结论
- 逻辑文字:即原子命题及其否定,通常为一个属性-值对最终为一个bool表达式,可以形象的理解为条件
- 规则长度: 规则前提中包含的文字数量
- 覆盖: 一条规则的前提所能匹配的数据样本集合。我们会说,这条规则覆盖了这些样本
- 规则集: 由多条规则构成的集合,整个模型就是这个规则集
- 冲突:当一个样本同时被多条规则覆盖,而这些规则给出了不同的结论时就发生了冲突,而为了解决这些冲突,我们需要一些策略进行冲突消解
- 有序规则集:中的规则之间存在优先级,优先级高的规则被匹配就是结果,忽略后续优先级低的冲突,类似程序中的
if-elif-else规则 - 无序规则集:中的规则之间没有优先级,需要使用其他方法消解
- 投票法:少数服从多数
- 元规则法:根据领域知识事先制定的规则的规则,如的规则在冲突中胜利
- 有序规则集:中的规则之间存在优先级,优先级高的规则被匹配就是结果,忽略后续优先级低的冲突,类似程序中的
- 默认规则: 对于所有未被规则集中任何规则覆盖的样本,需要有一条默认规则来给出预测。可以被视为一种元规则。
规则一般还被分为两类:命题规则和一阶规则
- 命题规则:这是最基础的规则形式,由原子命题、逻辑关系以及蕴含组成的简单陈述句
- 一阶规则(关系型规则):这种规则引入了谓词 和变量,极大地增强了表达能力。例如,谓词
父亲(X, Y)可以表示“X是Y的父亲”这一关系。 一阶规则可以表达的含义更多,因此会比命题规则复杂得多。
15.2 序贯覆盖
序贯覆盖是一种常见的规则学习方法,它采用分治策略,将复杂的整体学习任务分解为多个较简单的子问题。该方法每次只学习一条规则,并通过迭代逐步完善,具体过程如下:
- 算法从完整的训练数据集开始,旨在为特定类别(称为目标类或正例,例如“好瓜”)构建一组可靠的识别规则。
- 在每次迭代中,算法的核心目标是在当前数据集上寻找并确定一条最佳规则。这条规则应尽可能准确地覆盖一部分尚未被覆盖的正例。
- 一旦找到这条最佳规则,算法便视该规则所覆盖的所有样本(包括正例和反例)为已处理。因此,这些样本会从当前数据集中移除。
- 算法重复执行第2步和第3步,在持续缩减的数据集上继续寻找下一条最佳规则。此过程循环进行,直到数据集中不再有正例样本需要覆盖,最终终止。
通过上述步骤,我们得到一个有序规则集。在进行预测时,新样本会按该规则集的顺序逐一检验,第一个匹配前提条件的规则将决定预测结果。可见,整个迭代过程的核心在于如何找到最佳规则,这本身是一个巨大的搜索问题。在实际操作中,我们通常采用两种贪心策略:
- 自顶而下:从最一般的规则开始,逐渐添加逻辑文字以缩小覆盖范围,直到满足条件为止。
- 这种方法也称为生成-测试法,通常具有更好的泛化性能。
- 自下而上:从某种特殊的规则开始,逐渐删除逻辑文字以扩大覆盖范围,直到满足条件为止。
- 这种方法也称为数据驱动法,适合样本数较少的情形。 由于自顶而下的方法泛化性能更好,我们一般优先采用它。以下以自顶而下为例,展示如何找到最佳规则:
- 搜索始于一条最宽泛、最一般的规则。这条规则的体为空(或为“真”),头是我们希望预测的目标类。例如:
好瓜(是) ← TRUE。这条初始规则覆盖了当前数据集中的所有样本。 - 接下来,算法尝试通过向规则的“体”中添加逻辑文字 来使规则变得更具体、更精确。在每一步细化中:
- 算法遍历所有可能的候选文字(例如
(色泽=青绿)、(根蒂=蜷缩)等)。 - 对于每个候选文字,算法临时将其加入当前规则的“体”中,形成一条新的、更具体的候选规则。
- 然后,算法需要一个评估标准来判断哪个文字的加入能最大程度提升规则的“质量”。
- 算法遍历所有可能的候选文字(例如
- 选择评估标准时,不能单纯使用准确率,因为它在覆盖样本很少时极不稳定,容易被偶然现象误导。一般可以选择信息增益或m-估计平滑等方法。
- 停止条件包括:
- 覆盖的样本中不再包含任何反例。
- 已没有候选文字的加入能够提升规则在评估函数上的表现。
- 满足其他预设的停止条件。
15.3 剪枝优化
正如我们所说,序贯覆盖本质就是一个贪心算法,那么就像决策树一样,我们也可以使用预剪枝和后剪枝的方法来优化模型的泛化能力——贪心算法的一大问题就是容易过拟合。 我们先看预剪枝:我们在规则生长的每一步都进行评估,一旦发现某步生长是无益的,就立刻停止。 我们将介绍CN2算法采用的评估标准似然比统计量 (LRS),LRS的核心作用是衡量一条规则所覆盖的样本的类别分布,与整个训练集的类别分布之间的差异性。 其中符号:
- : 当前正在评估的规则。
- : 规则 在训练集上覆盖的样本总数。
- : 在这 个被覆盖的样本中,属于正类的数量。
- : 在这 个被覆盖的样本中,属于负类的数量。显然,。
- : 整个训练集的样本总数。
- : 整个训练集中,属于正类的样本总数。
- : 整个训练集中,属于负类的样本总数。显然,。 我对公式进行了一点修改,方便说明,其中
- 是从整个训练集中随机抽取一个样本,这个样本恰好被规则 覆盖的概率的估计
- 分母是如果我们不考虑规则 的任何筛选作用,在它覆盖的 个样本中,我们期望看到的正类样本数量
- 比较的是实际观察到的正例数 () 与随机期望的正例数之间的比值
- LRS值越大,说明这两个分布差异越大,规则 的引入使得类别分布变得与原来不同,那么这个是我们想要的规则 因此,预剪枝的策略是:设定一个LRS阈值,只有当添加新文字后计算出的LRS值超过该阈值时,才执行添加操作,否则停止当前规则的生长。
预剪枝虽然高效,但其贪心的本质可能会有短视问题。而后剪枝则允许算法先生成一条可能过拟合的完整规则,然后再回过头来,从一个更全局的视角对其进行简化。其中最常用的方法叫减错剪枝 (Reduced Error Pruning, REP),
其流程为
- 将原始训练数据划分为新的训练集 和验证集
- 在 上生成一条完整的、可能过拟合的规则
- 依次尝试从规则 的前提中删除一个文字,生成一系列候选的、更泛化的规则
- 在验证集 上评估原规则 和所有候选规则 的性能
- 选择在 上性能最好的规则。如果这个最佳简化规则的性能不低于原规则 ,则用它替换
- 对替换后的新规则,重复步骤3-5,直到无法通过简化来提高在验证集上的性能为止
REP通常很有效,但他的时间复杂度是,为了优化这部分,我们考虑两个更好的方法:IREP 与 RIPPER
IREP (Incremental Repetitive Pruning): 它将“生长”和“剪枝”更紧密地结合。每生成一条规则,就立即对其进行后剪枝。生成一条规则 -> 立即用验证集对其剪枝 -> 将剪枝后的规则加入规则集 -> 在剩余的训练样本上重复此过程。它的评估标准一般用的是准确率,而一旦考虑用作为性能度量,其中 和 是规则在验证集上覆盖的正确和错误样本数。剪枝的目标是最大化这个 值。这就是IREP*算法
而RIPPER在IREP*的基础上,增加了一个全局优化阶段。在得到一个初步的规则集 后,它会遍历其中的每一条规则 ,并尝试用两种方式对其进行优化:
- 替换规则: 完全放弃 ,在当前环境下重新生成一条全新的规则 来替代它
- 修订规则: 在原有规则 的基础上,尝试增加文字使其更精确,然后再对其进行剪枝,得到修订版 那么到底用哪个呢?当然是基于我们的评估标准比较原始规则 、替换规则 和修订规则 的优劣,这个标准一般是最小描述长度原则。
15.4 一阶规则学习
之前我们学习了命题逻辑规则,但这种规则表达能力有限:他只能表达单个事物的属性,而无法表达多个事物之间的关系,而这个世界上充满了关系,为了得到表达关系的规则,我们需要引入更强大的规则——一阶规则。 举个例子,如果我们只用命题逻辑规则来表示“色泽和根蒂颜色相同的西瓜是好瓜”,那我们就必须穷举出所有可能的颜色组合,例如:
- (色泽=青绿) ∧ (根蒂颜色=青绿) → 好瓜
- (色泽=乌黑) ∧ (根蒂颜色=乌黑) → 好瓜
- …… 这根本无法实现,且也并没有清晰的表达出关系,我们注意到我们需要解决两个问题:穷举和表达关系。因此我们引入两个概念:
- 谓词:可以看作是一个返回真/假的函数,来描述属性或关系
- 变量:用大写字母表示,如 ,可以指代论域中的任何对象 利用这些工具,我们可以将前面那个复杂的判断简洁地表达为一条一阶规则:
那么有了一阶规则后,我们该如何学习出这样的规则呢?一种经典的算法是FOIL (First-Order Inductive Logic),它是序贯覆盖算法的改进且采用自顶而下策略,但在之前C2算法中我们只考虑属性的增减,现在拥有谓词和变量后就不能这么简单的处理了,我们现在需要修改评估函数,FOIL采用FOIL增益来选择文字。注意到体中增减的文字从属性值对变成了谓词,继续设:
- 和 分别为原规则 所覆盖的正、反例数。
- 和 分别为增加候选文字后,新规则 所覆盖的正、反例数。 则 FOIL 增益 计算为: 公式中明显代表着正例的纯度,因此添加规则前后纯度的变化就是一个很好的衡量标准,最前面的作为权重,通过这个加权项,算法会更加关注那些能够保留住更多正例的文字,这是因为在一阶规则学习中,正例的数量往往远少于反例。
15.5 归纳逻辑程序设计
归纳逻辑程序设计(Inductive Logic Programming, ILP)是本章的最终目标。其核心在于构建一种学习机制,既能像传统机器学习算法那样从样例中自动学习模式,又能以一阶逻辑规则的形式输出人类可理解的知识表示。这种结合符号推理与数据驱动的方法,使得所学知识具备良好的解释性与可验证性。
在上一节中介绍的 FOIL 算法是 ILP 的一个代表性成果。我们可以将 ILP 问题形式化为如下四个组成部分:
- 背景知识 ():一个已知为真的逻辑理论,通常由一组一阶逻辑的事实和规则构成(在 Prolog 中称为事实库和规则库)。
- 正例 ():一组希望被目标理论所覆盖(即能够推导出)的实例。
- 反例 ():一组希望被目标理论所排除(即不能推导出)的实例。
- 假设 ():待学习的逻辑规则集合,用于补全背景知识以满足对正反例的处理要求。 ILP 的任务是寻找一个合适的假设 ,使得以下两个条件同时成立:
- 完备性(或后验满足性):结合背景知识 与假设 后,必须能够逻辑蕴涵所有正例,即
- 一致性(或后验一致性):结合 与 后,不能蕴涵任何反例,即 此外,通常隐含一个必要性条件:
即仅靠背景知识本身无法解释所有正例,因此必须通过学习引入新的规则 。
该过程本质上是从具体实例中提炼普遍规律的过程——这正是归纳的本质,亦可视作演绎推理的逆向操作。正如前文所述,ILP 主要有两种策略:自顶向下与自底向上。下面我们将介绍两种代表性的算法框架:最小一般泛化(LGG)与逆归结(Inverse Resolution)。
最小一般泛化 (Least General Generalization, LGG)
LGG 是一种典型的自底向上归纳学习方法,其思想源于从具体的正例出发,逐步泛化以发现共性。该方法的核心操作是计算两个逻辑表达式的“最小一般泛化”,即最特化的共同上界。
我们定义:子句 是子句 的泛化,记作 ,当且仅当 ,即 可由 通过逻辑蕴涵推导得出。在实践中,这一关系常通过 -蕴含判断:存在某个置换 ,使得 ,其中 表示将 应用于 所得的结果。
置换(Substitution) 定义为一个变量替换的有限集合,形式为 ,表示“将变量 替换为项 ”,其中 可为常量、变量或函数项。
最小一般泛化(LGG) 的目标是在所有能同时泛化两个子句 和 的候选子句中,找到那个最特化的泛化者。形式上, 是满足以下条件的子句 :
- 且 ;
- 对任意其他满足 且 的子句 ,均有 。
该过程可通过递归构造实现:
- 对于项:
- 若两子项为相同函数符号:
- 若两子项为不同常量或函数符号(如 与 ),则其 LGG 为一个新引入的变量 ,用于抽象表示该差异对。
- 若两子项为相同函数符号:
- 对于文字:只有当两个文字具有相同的谓词符号和极性(是否被否定)时,才能计算其 LGG。例如:
- 对于子句:两个子句 和 的 LGG 是它们各自文字之间所有可计算的 LGG 文字的并集:
LGG 提供了一种系统化、可计算的方式,从具体实例中提取共性规则,从而实现知识的归纳。著名的 ILP 系统 Golem 即基于此机制构建。
逆归结 (Inverse Resolution) 逆归结是自顶向下归纳学习的理论基础,其基本思想是将逻辑演绎中的归结原理逆向应用,从而实现从结论反推前提的归纳过程。 首先回顾标准归结原理:给定两个子句 和 , 因为 和 不能同时为真,所以 或 至少有一个必须为真
该过程体现了“若 成立则 成立,若 不成立则 成立,故无论如何 成立”的演绎逻辑。
逆归结则提出如下问题: 已知归结式 和其中一个父句 ,能否反推出另一个父句 ? 这构成了一个典型的归纳推理:试图通过已有结论与部分前提,推测出缺失的规则。
归结的正式形式为: 设 包含文字 , 包含文字 ,若存在替换 使得 ,则归结结果为:
相应地,逆归结操作可形式化为: 给定结论 和父句 ,欲恢复另一个父句 ,可执行以下步骤:
- 找到一个子集 和一个替换 ,使得 。
- 则剩余部分为 。
- 恢复被消去的文字对:令 ,则对应的文字应为 。
- 构造候选父句: 其中 为 的逆置换(即变量恢复操作),用于保持变量一致性。由于可能存在多个匹配方式,逆归结本质上是一个搜索过程,需在假设空间中探索合理的 。
在逆归结的实际实现中,合一(Unification) 是关键步骤。给定两个逻辑表达式(文字),合一的目标是寻找一个置换 ,使得二者在应用 后完全相同。这一过程为逆归结提供了变量匹配的基础。
为了支持归纳过程,逆归结算子发展出四种典型操作模式,以下采用 形式表示:
-
吸收(Absorption)
- 此为一个泛化操作。
- 当规则 的前提中包含另一个规则 的全部条件时,说明 。
- 因此可用 替代 ,得到更一般的规则 。
- 输出保留 作为泛化的依据。
-
辨识(Identification)
- 此为一种特化与概念引入的操作。
- 当两个关于同一结论 的规则共享前提 ,但其余前提分别为 和 时,系统可做出归纳假设:在当前语境下, 成立时 也可能成立。
- 因此“发明”新规则 。
- 输出包含该新规则及一条原始规则,体现了对隐藏概念的发现。
-
内构(Interiorization)
- 这是谓词发明的关键机制,适用于同一结论的多条规则。
- 当多个规则共享前置条件 ,但后续条件不同(如 , )时,系统推断 与 可能属于某个更高层次的抽象概念。
- 因此引入新谓词 ,并定义 和 。
- 原规则被重构为 ,实现了知识压缩与抽象表达。
-
互构(Mutualization)
- 另一种谓词发明机制,适用于不同结论的规则之间。
- 当规则 和 共享子条件 时,系统识别出 是一个可复用的中间结构。
- 发明新谓词 来表示该结构,定义 。
- 原规则被重写为 和 。
- 此操作类似于软件工程中的“提取公共函数”,提升了知识的模块化程度与可重用性。
综上,逆归结通过逆向演绎机制,为归纳学习提供了严密的逻辑基础。尽管其计算过程复杂且涉及搜索,但它确保了所生成假设的逻辑正当性,并支持包括泛化、特化与概念发明在内的多种学习行为,极大增强了 ILP 系统的表达能力与泛化性能。