简介:一份聚焦人工智能证据理论方向的课件资料,源自浙江大学研究生《人工智能》课程,由计算机学院教师编写,适合希望系统掌握D-S证据理论的研究生、工程师与AI方向学习者。课件以Dempster-Shafer证据理论为主线,梳理了1967年Dempster提出证据理论、1976年Shafer专著出版、1981年Barnett引入AI领域等关键发展节点,并详细讲解经典证据理论的核心概念、证据函数、证据空间构造,以及基于DS理论的不确定性推理与计算举例,可帮助读者从理论源头到实际应用建立完整认知。整个资源为1个pptx文件,大小约2.4MB,排版规范,适合课堂学习、备课或自学回顾。目前已有175人学习下载,对于需要梳理证据理论脉络、厘清概率推理与DS推理异同的读者具有直接的参考价值。
1. 从贝叶斯到证据理论:一条“未知”驱动的技术升级路线
做多传感器信息融合或者专家系统推理的工程师,大概率会遇到这样一个场景:两个传感器对同一目标给出了不同的类别判断,一个说“目标可能是坦克,概率 0.7”,另一个说“目标可能是装甲车,概率 0.6”。直觉上我们想做个加权平均或者直接用贝叶斯公式更新,但贝叶斯框架有个硬约束——所有假设的概率之和必须等于 1,这意味着你必须把“我不知道它是什么”这种状态强行分配到一个具体的假设上。浙江大学徐从富老师的这份《人工智能》课件第五章,恰恰点出了 D-S 证据理论(Dempster-Shafer Evidential Theory)在这个问题上的核心突破:它允许你把信度赋给假设的任意子集,并且显式地表达“不知道”。
换句话说,贝叶斯方法要求你对世界有完整的先验认知,而 D-S 理论允许你在证据不足时保持“无知”,并且用 Dempster 合成规则把多条独立证据按某种代数结构融合起来。本课件覆盖了从 Dempster 1967 年的奠基论文到 Smets 的 TBM 模型、再到刘大有等人的国内扩展工作,内容结构完整,适合做信息融合、AI 不确定性推理的研究生和工程技术人员用来建立理论坐标系。我第一次读完这章课件的感觉是:它不只是把公式列出来,而是把“为什么需要这套理论”讲透了。
2. 核心概念拆解:mass 函数、信任函数与似然函数的逻辑链条
任何接触过证据理论的人都知道,这套体系的入门门槛在于三个看起来很像但物理含义完全不同的函数:基本概率分配(BPA/mass 函数)、信任函数(Belief)、似然函数(Plausibility)。课件在 5.2 节用非常紧凑的篇幅把三者的数学定义和关系讲清楚了,但如果你是第一次接触,光看公式很容易绕晕。
2.1 识别框架与 mass 函数:把“不知道”变成一种合法输入
设 (\Theta) 为识别框架,即所有可能假设的完备集合。在经典证据理论中,mass 函数是一个从 (2^\Theta) 到 ([0,1]) 的映射 (m),满足两个条件:
[ m(\emptyset) = 0, \quad \sum_{A \subseteq \Theta} m(A) = 1 ]
这里的核心点是:mass 函数分配的对象不是单个元素,而是 (\Theta) 的所有子集。举例来说,假设识别框架是 ({坦克, 装甲车, 卡车}),一个传感器给出的 mass 可以是:
| 焦元 A | mass m(A) | 含义 |
|---|---|---|
| ({坦克}) | 0.6 | 60% 的信度认为目标是坦克 |
| ({装甲车}) | 0.2 | 20% 的信度认为目标是装甲车 |
| ({坦克, 装甲车}) | 0.1 | 10% 的信度认为目标在坦克和装甲车之间,无法区分 |
| (\Theta) | 0.1 | 10% 的信度完全不确定 |
注意最后两行——这正是 D-S 理论与概率论的本质区别所在。在贝叶斯框架里,如果你对“坦克 vs 装甲车”无法区分,你只能把概率按某种先验比例拆开;但在 D-S 框架里,你可以把信度直接赋给一个集合 ({坦克, 装甲车}),表达“我确定它是装甲车辆,但具体是哪种不知道”。
2.2 信任函数与似然函数:信度的下界与上界
基于 mass 函数,课件给出了两个核心定义:
[ Bel(A) = \sum_{B \subseteq A} m(B) ]
[ Pl(A) = \sum_{B \cap A \neq \emptyset} m(B) ]
信任函数 (Bel(A)) 表示所有分配到 A 的子集上的信度之和,它衡量的是“支持 A 的最低信度”;似然函数 (Pl(A)) 表示所有与 A 有交集的焦元上的信度之和,它衡量的是“不反对 A 的最大可能信度”。于是我们有 (Bel(A) \leq Pl(A)),两者构成一个信度区间 ([Bel(A), Pl(A)]),这正好对应 Dempster 最初提出的“上、下限概率”(upper and lower probabilities)思想。
我在实际项目中通常用这个区间来判断决策的风险:如果 (Bel(A)) 很高而 (Pl(A)) 也很高,说明证据对 A 的支持是充分且一致的;如果 (Bel(A)) 很低但 (Pl(A)) 很高,说明现有证据不足以排除 A,但也没有充分支持 A,这时应该继续收集证据而不是做决策。
2.3 Dempster 合成规则:多个证据的代数组合
证据理论最核心的贡献是 Dempster 合成规则。给定同一识别框架上的两个 mass 函数 (m_1) 和 (m_2),它们的正交和定义为:
[ (m_1 \oplus m_2)(A) = \frac{\sum_{B \cap C = A} m_1(B) m_2(C)}{1 - K} ]
其中 (K = \sum_{B \cap C = \emptyset} m_1(B) m_2(C)),表示两个证据之间的冲突程度。当 (K = 1) 时,合成规则无定义,说明两个证据完全冲突,无法融合。
课件里引用了 Barnett 1981 年的 IJCAI 论文作为“第一篇将证据理论引入 AI 领域”的标志,后续又在发展概况中提到 Voorbraak、Dubois & Prade、Tessem 等人的近似方法——这些都是在解决合成规则的计算复杂度和奇异行为问题。理解合成公式的原始形态,是后续理解这些改进工作的基础。尤其是 (K) 这个冲突因子,它既是合成规则合理性的关键,也是 Zadeh 悖论的爆发点。
3. 从公式到代码:一个可复现的 D-S 合成实现
理论知识落到工程实践,最直接的需求就是写一个 Dempster 合成规则的实现。课件本身没有给代码,但基于我对证据理论在目标识别和信息融合项目中的应用经验,一个完整的实现至少需要包含焦元存储、冲突系数计算和合成后 mass 分配三个部分。
3.1 用 Python 实现基本 BPA 结构与合成
from collections import defaultdict from itertools import product def combine(m1, m2): """ Dempster 合成规则的核心实现 m1, m2: dict, key 为焦元(用 frozenset 表示), value 为 mass 值 返回合成后的 mass 函数 dict """ # step 1: 计算冲突系数 K conflict = 0.0 # step 2: 存储合成后的 mass combined = defaultdict(float) for focal1, mass1 in m1.items(): for focal2, mass2 in m2.items(): # 两个焦元的交集 inter = focal1 & focal2 product_mass = mass1 * mass2 if inter: # 交集非空,累加到对应焦元 combined[inter] += product_mass else: # 交集为空,累加到冲突系数 conflict += product_mass # step 3: 归一化处理 if conflict >= 1.0: raise ValueError("完全冲突,Dempster 合成规则无定义") normalized = {} for focal, mass in combined.items(): normalized[focal] = mass / (1 - conflict) return normalized这段代码的处理逻辑是:先遍历两组 mass 函数的全部焦元组合,计算每对焦元的交集;交集非空时,将两个 mass 的乘积累加到交集焦元上,交集为空时累加到冲突系数 K。最后将合成后的 mass 值除以 (1-K) 完成归一化。值得注意的是,代码里用frozenset作为字典键,这是为了避免 Python 中普通set类型不可哈希的问题,同时保证焦元集合中的元素顺序不影响比较结果。
3.2 单元素焦元场景下的降级验证
当所有焦元都是单元素集合时,D-S 合成规则应当退化为某种接近贝叶斯更新的行为。下面这个验证案例可以确认实现是否正确:
# 传感器的输出:目标为坦克、装甲车或卡车的 mass sensor1 = { frozenset({'坦克'}): 0.6, frozenset({'装甲车'}): 0.2, frozenset({'坦克', '装甲车'}): 0.1, frozenset({'坦克', '装甲车', '卡车'}): 0.1 } sensor2 = { frozenset({'坦克'}): 0.7, frozenset({'卡车'}): 0.2, frozenset({'坦克', '装甲车'}): 0.1 } result = combine(sensor1, sensor2) conflict = 1 - sum(result.values()) print("冲突系数 K =", conflict) print("合成结果:") for focal, mass in sorted(result.items(), key=lambda x: -x[1]): print(f" {set(focal)}: {mass:.4f}")在这个例子中,sensor1是一个典型的“部分无知”证据——它把 10% 的信度放在“坦克或装甲车”上,10% 放在整个识别框架上;sensor2则明确否定装甲车而倾向坦克和卡车。运行合成后,你观察到的第一件事是:{坦克}的 mass 被显著放大,而{装甲车}的 mass 几乎被压制到零——这是因为两个传感器都没有直接支持装甲车,但sensor1中{坦克, 装甲车}的 0.1 与sensor2中{坦克}的 0.7 产生了交集{坦克},从而把部分原本“模糊”的信度导向了坦克。
3.3 参数讨论与常见坑
实现完成后有几个参数和边界情况需要特别注意:
- 识别框架必须保持一致:两个 mass 函数的识别框架如果不同,合成结果无意义。实际项目中应该做一个前置断言,检查所有焦元是否都是同一潜在集合的子集。
- 空集处理:课件中提到 (m(\emptyset)=0) 是基本概率分配的前提。但在开放世界假设下,Smets 的 TBM 模型允许 (m(\emptyset)>0) 表示“假设空间不完备”。我在实际融合场景中处理未知目标类别时,会刻意保留一个非零的空集 mass 作为“类别外目标”的指示器。
- 浮点精度问题:当焦元数量较多时,乘积累加可能带来浮点误差。工程上一般设定一个容差阈值,归一化后对小于阈值的 mass 做截断处理,但要注意截断后重新归一化。
4. Zadeh 悖论与冲突证据的处理策略:合成规则之外的出路
课件 5.1 节中花了相当篇幅引用 Zadeh 对证据理论的质疑,核心即“Zadeh 悖论”。这个经典案例是:两个目击证人 (W_1) 和 (W_2) 对谋杀案三名嫌疑人 Peter、Paul、Mary 做出指认,(W_1) 给出 mass (m_1(Peter)=0.99, m_1(Paul)=0.01),(W_2) 给出 (m_2(Mary)=0.99, m_2(Paul)=0.01)。按理说,两个证人都给了 Paul 一个微弱的 1% 支持,但直觉上 Paul 恰恰是那个最应该被怀疑的人——两个证人都没有排除他。用 Dempster 合成规则计算,理论上 (m_{12}(Paul)=1.00),完全认定 Paul 是凶手,而 Peter 和 Mary 都被彻底清零。
4.1 悖论的本质是什么
问题不出在合成公式的推导逻辑,而出在归一化这一步。两个证人的证据高度冲突((K = 0.9900 \times 0.99 + 0.99 \times 0.99 + 0.01 \times 0.99 + 0.99 \times 0.01),几乎接近 1),归一化因子 (1-K) 接近 0,把两个微弱的 1% 信度放大成了决定性的 100%。这是 Dempster 合成规则在高冲突场景下的经典失效模式:将局部的一致性放大为整体的确定性。
4.2 改进方案一:放弃归一化(Smets 的 TBM 模型)
Smets 在 1990 年和 1994 年的两篇论文中提出,冲突本身应该被保留而不是被归一化消除。在他的可传递信度模型(Transferable Belief Model)中,合成规则不使用归一化因子,冲突质量 (m(\emptyset) = K) 被保留下来作为“开放世界”的证据——表示识别框架中没有包含真实目标。工程上的直接收益是:当你把冲突质量保留下来,Zadeh 悖论中 Paul 的合成 mass 仍然很小,远不足以认定他完全就是凶手,系统会提示你“证据冲突过大,需要补充信息”。
def combine_open_world(m1, m2): """ 开放世界假设下的 D-S 合成:不归一化,保留冲突质量 Smets TBM 模型的基础实现 """ combined = defaultdict(float) for focal1, mass1 in m1.items(): for focal2, mass2 in m2.items(): inter = focal1 & focal2 product_mass = mass1 * mass2 if inter: combined[inter] += product_mass else: combined[frozenset()] += product_mass # 冲突质量保留 return dict(combined)对比上一节的combine函数,这段代码的唯一区别是去掉了归一化步骤,并且把交集为空时的乘积累加到空集焦元上。这个改动带来的行为差异是本质性的:归一化版本的合成结果中所有 mass 之和仍为 1,而开放世界版本的合成结果中 (m(\emptyset)=K),剩余信度之和为 (1-K)。在处理传感器故障或识别框架不完备的场景时,我通常直接使用开放世界版本,避免高冲突时合成结果偏离直觉。
4.3 改进方案二:冲突重新分配
李岳峰、孙全等人的国内工作提出了各种冲突重新分配策略,核心思想是不把冲突质量完全丢弃或完全保留,而是按某种权重重新分配给相关焦元。常见做法是按各焦元的平均信度加权分配冲突。这种方法的工程价值在于它保留了对目标类别的判断力,不像 TBM 那样把所有冲突都归给“未知”。
4.4 实现层面的选择建议
在我的实际代码里,通常会同时实现上述两种模式,并在合成前计算冲突系数 (K) 做预判:
- (K < 0.3):证据基本一致,使用经典归一化合成。
- (0.3 \leq K < 0.7):证据存在中度冲突,尝试用冲突重新分配方法。
- (K \geq 0.7):证据高度冲突,直接使用开放世界模型并标记“需要人工干预”。
这个经验阈值不是理论推导出来的,而是在多传感器目标识别项目中试出来的——低于 0.3 时归一化合成和 TBM 的结果差异极小,而高于 0.7 时归一化合成频繁出现违反直觉的结果。阈值本身可以根据你的领域做调整,但分档处理的思想值得保留。
5. 工程视角下的证据理论选型与调试技巧
课件列出的参考文献从理论奠基到近似算法覆盖相当全面,但对工程实现而言,最关心的始终是三个问题:计算量可控吗?参数怎么设?结果怎么验证?最后这部分结合实际使用经验,给几条可操作的方案。
5.1 焦元数量爆炸与 Bayes 近似方法
证据合成的一个经典痛点是:随着传感器数量和焦元数量的增加,合成过程的候选焦元集合呈指数增长。课件引用的 Voorbraak 工作提供了一种 Bayes 近似思路:用一个概率分布来近似信任函数,使得焦元数量不超过识别框架中元素个数。实际操作是令每个单元素假设的概率等于该元素的 mass 值加上所有包含它的焦元的 mass 按某种均匀或加权方式摊分:
def plausibility_transform(m, frame): """ 将 mass 函数转换为 pignistic 概率分布(Smets 提出的转换方法) frame: 识别框架中的全部单元素集合 """ pignistic = {} for element in frame: prob = 0.0 for focal, mass in m.items(): if element in focal: prob += mass / len(focal) # 按焦元大小平均分摊 pignistic[element] = prob return pignistic这里len(focal)是焦元的势。如果焦元是{坦克, 装甲车},那么它包含两个元素,mass 值就被平均分成两份分别加到坦克和装甲车上。转换完成后的概率分布可以直接用于决策层——比保留完整 mass 结构做进一步合成计算要轻量得多。我的经验是:当焦元数超过 50 个之后继续做全量合成性能收益很低,直接用 pignistic 转换做决策更划算。
5.2 参数敏感性分析与冲突预检
任何在实际系统里跑过 D-S 合成的人都该意识到:mass 函数的取值直接影响合成结果的敏感度和稳定性。两个传感器给出的 mass 如果只是在某个焦元上有 0.1 的差异,合成后目标类别的排序就可能翻转。建议在融合系统上线前做一轮参数敏感性分析,思路是:对每个传感器的 mass 值施加 ±10% 的扰动,观察合成结果是否仍然保持相同的类别排序。若排序频繁翻转,说明当前证据组合处在决策边界附近,应考虑增加传感器或调整阈值。
另一个实用的预检是冲突矩阵可视化。对每个传感器对,先单独算出它们的 K 值,做成一个上三角矩阵。K 值过大的传感器对,要么直接不参与融合,要么用第 4 节的分档策略单独处理。这样比直接堆叠所有传感器做一遍全量合成容易诊断问题。
5.3 与神经网络特征输出的接口设计
当前很多 AI 系统的分类器输出是 softmax 概率,如果想用 D-S 做多分类器融合,直接把 softmax 输出当作 mass 函数使用是不严谨的——softmax 强制所有类别概率之和为 1,丢弃了“不知道”的可能性。工程上常见做法是在 softmax 输出后面增加一个“不确定类”(doubt class),把分类器在验证集上预测置信度低的样本聚合为一个额外的 mass 项,赋予它包含所有类别的全集 (\Theta) 或某个领域相关的超类集合。这个“不确定项”的设计,恰好是 D-S 理论相较于直接对概率做加权平均的最大优势——你在融合层显式地建模了每个分类器“有多确定自己知道什么”。
这套从理论到代码再到工程策略的理解,基本都是在反复修改索引结构、调试合成边界和调参的过程中逐一落地的。课件给了理论框架的出处和关键文献的导向,具体到系统里怎么取舍,还是得回到你自己的数据上做实证。
本文还有配套的精品资源,点击获取