联邦学习下垂直分区知识图谱多跳问答技术解析
知识图谱问答KGQA在传统方案里往往默认一个前提所有数据已经汇聚到一张完整的大图中查询直接在中心图谱上执行。可一旦把场景切到多机构协作这个前提往往不成立。比如医院、药企、保险公司各自持有同一批患者的不同关系数据又想在不泄露原始数据的前提下回答“哪些糖尿病患者正在使用特定药物且有商业保险”这种跨机构多跳问题问题就变得非常棘手。FedV-KGQA 就是围绕这个方向展开的研究课题面向垂直分区Vertically Partitioned的知识图谱研究如何做多跳问答Multi-Hop Question Answering。本文会从背景概念讲起拆解问题定义、系统架构、核心模块并用一段可运行的 Python 教学模拟帮助大家直观理解跨机构多跳查询是怎么协作的。无论你是做知识图谱工程的读者还是正在学习联邦学习、想复现相关论文的研究者这篇文章都能给你一份比较完整的参考。1. 背景知识图谱问答为什么需要走向联邦场景1.1 知识图谱问答KGQA是什么知识图谱本质上是用图结构描述“实体—关系—实体”的知识库。实体是人、地点、疾病、药物这类对象关系是“患病”“服用”“位于”这类语义联系。知识图谱问答Knowledge Graph Question AnsweringKGQA要解决的事情是用户输入一句自然语言问题系统自动把问题映射成图上的查询最终返回答案。举个最简单的单跳例子问题周杰伦的夫人是谁图谱中存在三元组周杰伦夫人昆凌系统解析出实体“周杰伦”和关系“夫人”在图谱中查询后返回“昆凌”。一个典型的 KGQA 流程通常包含四个环节问题理解判断问题要问什么。实体链接识别问题中的实体词并映射到图谱节点。关系识别判断需要遍历哪些谓词或关系。查询生成与执行把语义转换成查询计划在图谱上执行并返回结果。如果采用深度学习方法还会用上图神经网络GNN、预训练语言模型等来做端到端的推理。但从工程落地的角度看“语义解析 图谱查询”仍然是最直观、最可控的一类方案。1.2 单跳问答与多跳问答的区别单跳问答只涉及一条边比如“周杰伦的夫人是谁”。多跳问答则需要在图谱上连续跨越多个关系才能得出答案。举例说明问题周杰伦的夫人出生于哪个城市这是一个两跳问题。推理路径周杰伦 -[夫人]- 昆凌 -[出生地]- 澳大利亚。再比如问题二甲双胍常见不良反应的缓解方式是什么推理路径二甲双胍 -[常见不良反应]- 胃肠道不适 -[缓解方式]- 调整用药时间。多跳问答难点在哪主要有三个问题中的路径是隐式的用户不会直接说出“请先查关系 A再查关系 B”。中间实体集合可能很大每一步候选扩大都会带来组合爆炸。每一步的解析错误会沿着路径累积第一跳错了后面基本全错。多跳推理在实际业务中非常常见比如医疗问药、供应链风险分析、企业知识库问答往往都需要三步以上的关联查询。1.3 数据不出域带来的新挑战传统 KGQA 方案能成立依赖中心化知识图谱。但现实的产业环境中很多知识不会放在一起而是按业务归属分散在不同机构。最典型的情况是同一批实体不同机构持有不同的属性或关系。医院A保存着“患者-疾病”关系药企B保存着“患者-用药”关系保险公司C保存着“患者-保险类型”关系。从逻辑上讲这些关系可以合并成一张完整图谱但从合规、数据安全、商业机密角度没有任何一个机构愿意把自己的原始图谱数据完全共享出去。于是出现一个矛盾多跳问答需要跨多个数据分片做关联推理但数据又必须“不出域”。FedV-KGQA 要解决的就是这个问题。它把联邦学习“数据不动模型动”的思想迁移到知识图谱问答上让每个参与机构保留本地图谱分区通过协作协议完成跨分片的多跳查询。2. FedV-KGQA 核心问题拆解2.1 水平分区与垂直分区先分清两种分布式场景在联邦学习里数据分区通常分为两种水平分区Horizontal Partitioning和垂直分区Vertical Partitioning。这个概念直接决定了 FedV-KGQA 的问题难度和技术路线。水平分区是指不同机构拥有相同的特征维度但样本 ID 不同。例如两家医院都记录“患者—诊断”关系字段一样只是各自接待了不同的患者。垂直分区是指不同机构拥有相同的样本 ID但各自保存不同的特征列或关系子集。例如同一批患者医院掌握诊断记录、药企掌握用药记录、保险公司掌握保单信息。实体集合大体重叠关系却不尽相同。维度水平分区垂直分区实体集合各机构持有不同子集各机构持有大体相同的实体集关系/属性schema 相同数据行不同关系子集不同需要互补典型对齐方式实体合并 / 求并集实体求交 / ID 对齐主要挑战跨机构实体识别与匹配跨机构多跳关联与隐私保护典型任务分布式图查询、知识补全联合多跳问答、联合特征计算FedV-KGQA 中的 “V” 代表 Vertically Partitioned也就是垂直分区。这是它和许多以“联邦 KGQA”为主题的工作最重要的区别之一。2.2 一个典型的垂直分区问答场景我们把场景设计得更具体一点。假设有三家机构机构A持有“患者—疾病”数据例如P01糖尿病机构B持有“患者—用药”数据例如P01二甲双胍机构C持有“患者—保险”数据例如P01商业保险用户提出一个问题“哪些糖尿病患者目前使用二甲双胍或胰岛素并且购买了商业保险”如果所有数据都在一张中心图谱里这个问题的查询路径非常清晰患者 -[患疾病]- 糖尿病患者 -[用药]- 二甲双胍患者 -[保险]- 商业保险。但在垂直分区场景下没有机构能看到完整路径。机构A只知道自己这边的疾病标签不知道用药和保险机构B只知道用药不知道疾病和保险。要回答这个问题三方只能通过协作完成一次次跨分片过滤。2.3 问题定义用更形式化的语言描述设全局知识图谱为 G它被垂直划分为 m 个分片 G₁, G₂, ..., Gₘ。每个分片由机构 i 维护包含原始三元组或图关系。实体集合在各分片之间通过某种方式对齐但关系集合不同。输入是一个自然语言问题 q输出是答案集合 A。在整个过程中需要满足约束原始三元组不出域各机构看不到其他机构的完整分片暴露给协调方或其它机构的中间信息尽可能少最终答案应尽量准确并且最好能给出可解释的推理路径。这个问题本质上是一个受限的分布式多跳推理问题。它不是简单地把各机构答案拼起来而是要在查询规划和中间结果传递上做全局优化。2.4 FedV-KGQA 要解决的三个核心矛盾从工程角度看这类题目永远是在三组矛盾之间找平衡第一隐私保护与答案精度之间的矛盾。中间候选集一旦过多传递就可能泄露各机构的数据分布但如果完全不传递中间结果很多多跳推理又无法完成。第二多跳搜索完备性与通信开销之间的矛盾。跳数越多、候选集合越大查询结果越完整但通信量也会线性甚至指数增长。第三可解释性与隐私保护之间的矛盾。理想情况下用户想知道答案是经过什么路径推出来的。但路径本身往往暗示着“某个机构在哪些关系上有哪些数据”过度解释可能就是隐私泄露。理解这三个矛盾基本就理解了 FedV-KGQA 的方向。3. 系统整体架构与核心流程3.1 整体架构从题目和这类联邦问答的通行做法来看FedV-KGQA 的整体架构可以抽象为三层用户接入层、协调推理层、数据分片层。用户问题 q │ ▼ ┌───────────────────────────────┐ │ 语义解析与查询规划模块 │ │ · 实体链接 │ │ · 关系抽取 │ │ · 查询图生成 │ └───────────────────────────────┘ │ 生成逻辑查询计划 ▼ ┌───────────────────────────────┐ │ 联邦推理引擎 │ │ ┌────────┐ ┌────────┐ │ │ │ 机构A │ │ 机构B │ ... │ │ │ 本地图谱 │ │ 本地图谱 │ │ │ └────────┘ └────────┘ │ │ 通过安全协议交换中间候选与结果 │ └───────────────────────────────┘ │ ▼ 答案集合 推理路径 置信度协调层不直接访问各机构的完整图谱它只负责把问题拆解成可以在各分片执行的子查询并编排执行顺序。3.2 核心流程拆解一个完整的联邦多跳问答流程大致可以分为四步。第一步查询解析。语义解析模块从自然语言问题中识别出实体、关系以及问题的查询目标。例如在“哪些糖尿病患者使用二甲双胍”中实体是“糖尿病”和“二甲双胍”关系是“患病”和“用药”。第二步查询规划。协调层决定每一跳在哪一个分片执行、执行顺序是什么、中间结果以什么形式传递。这一步对通信开销影响最大后面会详细展开。第三步联邦执行。各分片在本地执行查询返回候选 ID 集合。协调层把上一个分片的候选集传给下一个分片逐跳过滤直到完成所有跳数。第四步答案聚合。把最后一跳的结果汇总附加推理路径、置信度最终返回给用户。3.3 与传统集中式 KGQA 的核心区别传统集中式 KGQA 的问题在于“查询计划一旦生成就可以直接在中心图谱上执行”不需要考虑数据在哪。而 FedV-KGQA 多了一个物理分布维度。中心式查询可以随时回溯、随时换路径因为查询引擎持有全局图联邦查询则不行每一跳都可能需要和其他机构做一次网络交互中间结果一旦传出就很难撤回。中心式查询可以设计复杂的图搜索算法比如多路径召回联邦查询则必须考虑“通信轮次”和“中间结果敏感度”每一步都意味着延迟和安全风险。所以在 FedV-KGQA 相关的系统里查询规划的重要性甚至超过了语义解析。很多时候答案准不准不取决于模型理解得对不对而取决于每一步的执行顺序有没有把候选集缩到足够小。4. 关键模块技术解析4.1 实体链接与语义解析多跳问答的输入是自然语言第一步必须先把它转换成结构化的查询意图。比如输入问题“使用了二甲双胍的糖尿病患者中谁拥有商业保险”其中需要识别三组信息实体糖尿病、二甲双胍、商业保险关系患者-疾病、患者-用药、患者-保险变量患者需要返回的实体这一步常用的做法是先用预训练语言模型做命名实体识别NER和关系抽取再把识别结果映射到知识图谱的实体库。在联邦场景下实体库本身也分散在各机构所以有时需要混合使用本地实体匹配和全局实体链接。多跳问题往往包含不止一个实体因此除了单实体识别还需要构建查询图。查询图把“变量”和“约束条件”串起来相当于把自然语言变成一张带变量的图结构后续联邦推理就是在这张查询图上逐步填充。4.2 联邦查询规划查询规划负责决定每一跳落在哪个分片执行顺序中间候选集如何传递。查询规划的核心原则是“尽早缩小候选集”。假设要查询“糖尿病 二甲双胍 商业保险”三个条件如果先在机构C过滤商业保险候选患者范围可能仍然很大如果先在医院A过滤糖尿病再把候选集传给机构B过滤用药那么进入机构B的候选集会小很多。因此一个合格的查询规划模块应该能对各关系的“选择性”做预估。选择性越强、候选缩减越明显的谓词越应该放在前面执行。此外查询规划还要考虑各分片的网络延迟和负载。有些机构虽然选择性好但服务很慢把它放在第一步可能反而拖慢整个查询链路。4.3 跨分片多跳推理跨分片多跳推理是 FedV-KGQA 最核心的环节。它和单机图搜索最大的区别是不能一次性看到全局路径只能通过分片间的候选集传播逐步逼近答案。典型的做法是候选集传播用初始约束在第一跳分片查出一批候选实体把候选实体 ID 传递给下一跳分片下一跳分片只在这些候选实体上执行本地查询返回新的候选集合或最终答案。这个过程看起来简单但有两个难点。难点一候选集膨胀。如果每一跳都返回大量候选 ID网络传输量会迅速增加。假设第一跳返回 100 万患者 ID第二跳再传一遍通信量瞬间不可控。难点二实体对齐。不同机构对同一个实体的 ID 可能不一致比如医院用“病案号”保险公司用“保单号”。推理前必须把 ID 映射到统一标识。更复杂的情况是两个分片之间只能通过实体特征匹配这就要引入隐私保护的实体对齐技术。4.4 隐私保护机制FedV-KGQA 之所以难核心在于隐私约束。单纯做分布式查询并不难难在“不能让机构之间互相看到原始关系数据”。业界常用的技术组合包括隐私保护集合求交Private Set IntersectionPSI用于跨机构实体 ID 对齐只暴露交集不暴露未匹配实体。差分隐私Differential Privacy对查询结果加噪声使攻击者无法推测某个具体实体是否存在代价是答案精度下降。同态加密Homomorphic Encryption允许在密文上做计算但计算开销巨大。安全多方计算Secure Multi-Party Computation多个参与方协同计算函数但通信复杂度和计算复杂度较高。在真实系统中这些技术往往组合使用而不是只用一种。这里需要强调一点隐私保护不是“加层安全协议”就万事大吉。联邦场景里的中间候选集本身就可能携带敏感信息。比如某机构发现对方传过来的候选集正好是某个罕见疾病群体的完整名单即使没有看到疾病名称也可能从集合大小和组成推断出业务规律。因此查询计划不能只追求答案准确还要评估中间结果的泄露风险。4.5 答案融合与置信度评估最后一跳返回的候选实体还不是最终答案。系统通常需要做两件事路径评分和答案排序。多跳问题上同一个答案可能有不同推理路径。例如某患者在机构A通过“糖尿病”被召回在机构C通过“商业保险”被命中另一患者在机构B命中“二甲双胍”在机构C也命中“商业保险”。两条路径的置信度可能不同。置信度可以这样计算语义解析置信度实体识别和关系抽取的模型置信度实体链接置信度问题中的词映射到图谱实体的置信度各跳查询命中的确定性某些关系是硬约束某些关系存在概率性先验路径覆盖度如果一个答案候选被多条路径支持通常比单一路径更可靠。最终系统输出的是带置信度排序的 top-k 答案同时附上推理路径方便用户或审计人员验证。5. Python 教学模拟执行一次跨机构多跳问答为了更直观地理解 FedV-KGQA 的协作机制我写一段可以运行的 Python 教学模拟。这里不追求还原论文方案只用来演示“候选集传播”这个核心思想。5.1 安装依赖模拟只需要 networkx没有其它第三方依赖。如果环境里没有安装可以执行pip install networkx5.2 构造模拟数据我们把三个机构的数据分别建模为一张本地图节点是患者或属性值边表示关系。import networkx as nx # 机构A患者-疾病 org_a nx.Graph() disease_edges [ (P01, 糖尿病), (P01, 高血压), (P02, 糖尿病), (P03, 哮喘), (P04, 糖尿病), (P04, 冠心病), (P05, 高血压), (P06, 哮喘), ] org_a.add_edges_from(disease_edges) # 机构B患者-用药 org_b nx.Graph() drug_edges [ (P01, 二甲双胍), (P01, 阿司匹林), (P02, 胰岛素), (P03, 氨氯地平), (P04, 阿司匹林), (P05, 氨氯地平), (P06, 二甲双胍), ] org_b.add_edges_from(drug_edges) # 机构C患者-保险类型 org_c nx.Graph() insurance_edges [ (P01, 商业保险), (P02, 商业保险), (P03, 社保), (P04, 社保), (P05, 商业保险), (P06, 社保), ] org_c.add_edges_from(insurance_edges)这里三个机构共享同一批患者 ID在实际系统中这一步需要靠实体对齐完成模拟阶段我们直接视为已经对齐。5.3 定义本地查询函数每个机构对外提供的能力是“在给定候选集合内查询某个属性是否关联”。这样设计可以避免暴露全量数据。def local_query(graph, candidates, attribute_values): 在指定机构的分片内过滤出与 attribute_values 中任一属性关联的候选节点。 result set() for candidate in candidates: neighbors set(graph.neighbors(candidate)) if neighbors attribute_values: result.add(candidate) return result这个函数的核心逻辑是只在候选集合上遍历不扫描机构全部数据返回的是满足条件的节点 ID不是原始边数据。5.4 联邦多跳查询流程现在模拟回答一个问题“哪些糖尿病患者正在服用二甲双胍或胰岛素并且购买了商业保险”整体流程如下# 第 1 跳机构A 筛选糖尿病患者 candidates {node for node in org_a.nodes if 糖尿病 in set(org_a.neighbors(node))} print(第 1 跳机构A: 患者-疾病候选 , candidates) # 第 2 跳机构B 在候选集上继续筛选用药 candidates local_query(org_b, candidates, {二甲双胍, 胰岛素}) print(第 2 跳机构B: 患者-用药候选 , candidates) # 第 3 跳机构C 在候选集上继续筛选保险类型 candidates local_query(org_c, candidates, {商业保险}) print(第 3 跳机构C: 患者-保险候选 , candidates) print(最终答案, candidates)5.5 运行结果与分析运行上面的代码输出如下第 1 跳机构A: 患者-疾病候选 {P01, P02, P04} 第 2 跳机构B: 患者-用药候选 {P01, P02} 第 3 跳机构C: 患者-保险候选 {P01, P02} 最终答案 {P01, P02}这个结果背后的推理过程是P01糖尿病 二甲双胍 商业保险命中P02糖尿病 胰岛素 商业保险命中P04糖尿病 阿司匹林但没有使用二甲双胍或胰岛素中途被过滤P05有商业保险但没有糖尿病一开始就不会进入候选集。重点关注第 1 跳到第 2 跳的变化候选集合从 3 个缩减到 2 个。每一跳都在不断缩小范围这也是查询规划里“尽早过滤”原则的直观体现。如果第一步不做糖尿病过滤直接让机构B查所有用药患者候选集会庞大得多中间传递的数据量也会相应增加。5.6 这个模拟忽略了哪些真实难点教学模拟为了简洁省略了真实系统中非常关键的几个点实体对齐。代码里直接使用了统一患者 ID真实场景往往需要通过 PSI 或实体匹配先把 ID 映射到同一套标准。通信安全。中间候选 ID 直接明文打印真实系统会结合加密、差分隐私等手段降低泄露风险。语义解析。代码把自然语言问题提前人工拆解成了三个谓词真实任务需要模型自动完成。查询规划。执行顺序是手写的真实系统需要预估每个谓词的选择性再决定先查哪个机构。中间结果缓存。每跳只传一个集合真实场景还有多轮迭代、多路候选合并等复杂情况。虽然简化但核心机制是一样的各机构保留本地数据通过候选集传播协作完成多跳推理。6. 对比分析FedV-KGQA 的技术路线取舍6.1 FedV-KGQA 与集中式 KGQA 的对比对比维度集中式 KGQAFedV-KGQA数据前提图谱数据汇聚到中心数据分散在各机构不允许汇聚查询能力可以在全局图上自由搜索只能在分片间通过候选集传播推理效率单机图搜索无需跨网络多次跨机构通信延迟较高隐私风险数据集中单点