图数据建模必知:从转导式到归纳式学习的范式切换实践 前阵子接手一个图数据的用户行为预测项目最初跑得挺顺后来每来一批新用户模型效果就肉眼可见地掉。一开始我以为只是特征没做好调了一周才意识到问题出在我用的学习范式上——我一直在一张静态图上做转导式Transductive学习而业务早就进入了需要归纳式Inductive能力的阶段。这次把“AI 从转导向归纳范式转变”的过程完整拆开讲包括概念、动因、实操案例和踩坑记录希望对正在处理动态图数据或者打算切换模型范式的朋友有点参考价值。1. 从两个词说起转导与归纳到底在争什么1.1 一个很容易被忽视的边界很多做机器学习的朋友对“训练集、验证集、测试集”这套划分非常熟悉却很少意识到这套划分方式本身默认了一种归纳式学习假设——我们学到的规则要能应用到“从未见过”的数据上。但在真实项目里尤其在做图数据、半监督学习时我见过太多团队其实是在做转导式学习只是没意识到这个名字。转导式学习的特点是在训练阶段模型已经看到了所有测试样本的特征信息甚至可以利用测试样本之间的结构关系只是没看到测试样本的标签。比如经典的标签传播算法或者早期全图训练的图卷积网络它们把整张图的邻接矩阵和所有节点特征一次性喂给模型在训练时“偷看”了测试节点的特征和连接关系。归纳式学习则不同它要求模型从训练数据中提炼出一套通用规则学完之后可以独立面对任意一个新输入。这套规则不能依赖测试样本的额外信息也不能假设推理时还能访问训练图的全貌。1.2 用“开卷考试”和“解题能力”来类比我习惯跟团队同学这样解释两者的区别转导式学习像开卷考试考试范围就是那本固定的参考书题目再多你只需要在书里翻答案书没收录的内容你就没法答。归纳式学习像学会了数学解题方法不管题目怎么变只要题型在规则覆盖范围内你都可以现场推导。这带来一个非常实际的差异转导式模型在“当前这堆数据”上往往效果很好因为它隐式利用了测试样本的结构信息但一旦数据分布稍有变化比如新用户、新商品、新关系加入模型就没有任何办法——它没有学到“如何面对新样本”的规则。对比项转导式学习归纳式学习训练时是否接触测试特征是常见于图半监督、标签传播否测试样本在推理时才进入对新样本的处理一般需要重训或重推全图可直接用学到的规则推理适合场景静态图、小数据、标签稀缺动态数据、持续增长、在线服务代表方法标签传播、早期全图 GCNGraphSAGE、普通 MLP、CNN/Transformer严格来说这两种范式没有绝对的好坏。转导式在小规模、分布稳定的场景里实现简单效果也能打但如果你要做在线推理、要处理持续到达的新节点迟早得切换到归纳式。2. 为什么越来越多项目开始从转导走向归纳2.1 业务的动态性把转导式逼到了墙角我在做的那个用户行为预测项目数据是典型的内容社区场景。每天都有新用户注册、新内容发布用户之间不断产生新的关注、互动关系。最初团队用的是“全图标签传播 图嵌入”的方案每天凌晨定时跑全量数据把图嵌入算好再交给下游分类器用。上线初期效果不错准确率能到 83% 左右。问题出现在规模涨起来之后全图从几十万节点涨到几千万节点全量重算的耗时从半小时涨到十几个小时。更要命的是新用户当天产生的行为完全无法预测因为模型从来没有在新用户身上“见过”今天凌晨之后新增的边。这其实是转导式学习的结构性缺陷——它天然假设测试集是一个已经存在的、固定的集合。2.2 技术侧的变化从“全图”到“采样”技术上推动范式转变的力量同样明显。早期图神经网络比如 GCN训练时要依赖完整的邻接矩阵本质上是转导式它在训练时使用全图信息包括测试节点的连接。所以当图中出现新节点时邻接矩阵变了整个模型等于要重新学。后来出现的 GraphSAGE 等模型核心改进是不再依赖全图邻接矩阵而是通过采样邻居来逐节点计算表示。训练时模型学到的是“如何聚合邻居特征”的映射函数而不是“这张图里每个节点长什么样”。新节点进来时只需要按同样的方式采样它的邻居、聚合特征就能算出表示。这就是典型的归纳式学习。我们项目切换到 GraphSAGE 风格的结构后测试集准确率从 83% 提升到 87.5%——看起来提升不算夸张但新用户当天的推理响应时间从“等第二天凌晨重算”变成“毫秒级实时计算”这个体验差距是本质性的。2.3 大模型时代对“规则提取”的更高要求还有一个背景值得提当前 AI 行业对“模型学会了什么”这件事越来越在意。转导式模型容易被诟病为“记性好但理解差”它可能只是记住了训练图的结构模式并没有形成真正可迁移的规律。归纳式模型则强迫模型把知识压缩成参数化的规则训练时更接近“理解”而非“记忆”。在做这类切换时我并不建议为了赶时髦而换范式。**标准只有一个你的业务是否要求模型面对训练时不存在的新输入。**如果是那你迟早要走上从转导到归纳的这条路早切换比晚切换好。3. 一个完整的上手案例把图节点分类从转导改成归纳3.1 场景设定与数据切分方式的变化具体说说我是怎么改的。原始任务是把用户节点分成几类兴趣群体用于后面做推荐召回。原始转导式方案分三步构建全图节点是用户和内容边是互动行为。用标签传播算法给缺失标签的节点打上伪标签。在全图嵌入上训练一个多层感知机分类器。切换成归纳式方案后最重要的改变不是换了模型结构而是重写了数据切分逻辑。归纳式学习要求训练、验证、测试的节点集合互不重叠并且测试节点在训练期间完全不可见包括它们的特征和连边也不允许出现在训练邻域里。我按时间切分前 60 天的数据作为训练子图第 61 到 75 天作为验证子图第 76 到 90 天作为测试子图。这样切分能最大程度模拟线上“新节点在推理时才出现”的真实场景。注意如果只是随机切节点训练时仍然可能通过高阶邻居“间接看到”测试节点的信息导致评估结果虚高。按时间切分是最贴近业务的做法因为线上新用户本质上就是时间维度上新出现的节点。3.2 转导式做法标签传播与全图 GCN 的问题转导式方案里标签传播这一步最直观。核心逻辑是相似的节点应该有相似标签标签沿着边不断扩散。它的公式不复杂但有个致命问题——它需要对整张图的邻接矩阵做迭代运算每一次迭代都在使用测试节点的连接关系。当测试节点和训练节点比例发生变化时整个传播结果都会变。后来我们试过全图 GCN本质上也是转导式。因为 GCN 的层间传播公式里有归一化邻接矩阵这个矩阵包含了全部节点包括测试节点。训练过程中测试节点的特征会通过图卷积传播到训练节点上参与模型参数更新。这在学术实验里常被接受但在业务里会带来“评估过乐观、上线后效果缩水”的问题。当时我拿全图 GCN 做了一版离线 AUC 比标签传播高不少结果上线后新用户预测效果很差。后来排查发现问题就出在转导式评估和线上推理设置不一致离线时模型见过新节点的特征和邻居线上时新节点只有自己的特征和少量冷启动行为邻居还没长出来。3.3 归纳式实现GraphSAGE 风格的采样与聚合切换到归纳式方案我选择的是 GraphSAGE 风格模型核心代码逻辑大致如下import torch import torch.nn as nn import torch.nn.functional as F class SAGELayer(nn.Module): def __init__(self, in_dim, out_dim, aggregatormean): super().__init__() self.aggregator aggregator self.linear_self nn.Linear(in_dim, out_dim) self.linear_neigh nn.Linear(in_dim, out_dim) def forward(self, node_feats, neighbor_feats): # 聚合邻居特征 if self.aggregator mean: neigh_agg torch.mean(neighbor_feats, dim1) elif self.aggregator max: neigh_agg torch.max(neighbor_feats, dim1)[0] # 自身特征和邻居特征分别变换后拼接 h_self self.linear_self(node_feats) h_neigh self.linear_neigh(neigh_agg) return F.relu(h_self h_neigh) class GraphSAGE(nn.Module): def __init__(self, in_dim, hidden_dim, num_layers2): super().__init__() self.layers nn.ModuleList() self.layers.append(SAGELayer(in_dim, hidden_dim)) for _ in range(num_layers - 1): self.layers.append(SAGELayer(hidden_dim, hidden_dim)) def forward(self, node_feats, neighbor_lists): h node_feats for layer in self.layers: neighbor_feats [h[n_ids] for n_ids in neighbor_lists] neighbor_feats torch.stack(neighbor_feats, dim1) h layer(h, neighbor_feats) return h上面是示意代码实际工程里会用现成的图学习框架做采样避免手工维护邻居索引。关键的参数有三个采样邻居数量我最终设为 20即每一层最多采样 20 个邻居。采样数太少聚合出的表示方差大采样数太多训练速度下降明显。20 在这个数据规模下是性价比比较高的值。层数用了 2 层。层数越深感受野越大但在千万级图上做邻居采样时指数级扩张的邻居数量会很快让训练变慢。2 层已经能覆盖二阶邻居信息对用户兴趣分类足够。聚合器试过 mean、max、LSTM 三种mean 和 max 效果接近LSTM 训练慢一个量级且收益有限。最终选了 mean图结构稀疏时 mean 比 max 更稳定。3.4 训练与推理方式的差异归纳式模型的训练采用 mini-batch 方式每次随机采样一批中心节点再采样它们的多阶邻居形成一个子图。模型只在这个子图上计算表示和损失。这样做有两个好处一是显存占用不再和全图规模挂钩千万级图也能在单卡上训练二是每一步训练时模型根本看不到批外节点的信息和线上推理场景完全一致。推理时对新节点只用做一步操作把它的特征和它已有的邻居特征按同样方式采样、聚合得到表示过分类器。整个过程不涉及全图重算所以能够支撑在线实时推理。方案离线 AUC全量重算耗时新节点在线推理标签传播 MLP0.8112 小时以上不可扩展不支持全图 GCN0.868 小时以上显存受限基本不支持GraphSAGE 归纳式0.85无需全量重算毫秒级支持全图 GCN 离线分数最高但实际业务中并不能把新用户压进全图重算所以那个 0.86 是“看得见用不上”的分数。归纳式方案离线略低但线上新用户预测准确率反而更高原因就是训练和推理场景一致。4. 从转导到归纳的坑我都替你踩过4.1 推理阶段遇到没见过的邻居类型怎么办归纳式模型要求邻居特征在推理时可用但新用户在一开始往往只有极少邻居甚至一个邻居都没有。这时邻居采样会退化成空集合聚合结果不稳定模型容易给出偏高或偏低的预测分数。我们当时的处理办法是在训练阶段刻意加入“零邻居”样本——从训练集中随机挑一部分节点把它们的邻居信息置空只用自己的特征做预测。这样模型在训练时就见过“孤立节点”的情况线上推理遇到真正的新用户时行为不会太离谱。这个技巧说起来简单但确实把新用户冷启动预测的准确率提升了 5 个百分点左右。4.2 训练图与线上图的分布漂移切换成归纳式之后我一度以为只要模型是归纳式的就天然能泛化到未来数据。事实证明这是想多了。归纳式解决的是“新节点进入已有图结构”的问题但如果一段时间之后整个图的结构模式都变了比如互动关系从密集变为稀疏、内容传播路径明显改变模型学到的聚合规则同样会失效。我在第二个季度就踩过这个坑训练子图来自冬季数据测试子图来自来年春季数据两者在平均度、子图密度上差得比较多离线验证 AUC 一口气掉到 0.77。后来加了“时间衰减采样”——训练时越靠近当前时间的数据采样权重越高——才把离线指标拉回到 0.83。做归纳式图模型数据漂移监控要像监控模型分数一样常态化。4.3 半监督标签稀疏时转导式的优势不能忽略转导式方法最拿手的一个场景是标签极少。标签传播可以利用未标注节点的结构信息来辅助分类这在标注成本高的业务里非常诱人。切换到归纳式之后模型只能从有标签样本中学习如果标签数量太少效果往往不够好。我们的处理方案是“两阶段训练”先用转导式标签传播或者伪标签方法在整张图上生成一批高质量伪标签再把这些伪标签当作训练目标用归纳式模型去拟合。这本质上是把转导式的“答案”蒸馏成归纳式的“规则”。做了这一步之后标签稀疏场景下的归纳式模型 F1 提升明显从 0.68 到 0.75。5. 什么时候不该急着转归纳以及我现在的判断标准5.1 静态小数据的场景转导式仍然更香如果业务是一个固定的学术数据集、一张几年不变的知识图谱、或者一次性的离线分析我不建议引入归纳式模型的复杂度。转导式方案在静态图上通常训练更快、参数更少、效果也有保障。我自己在另一个小型内部项目中就保留了转导式方案因为那张图一年才更新两次做归纳式纯粹是给自己添麻烦。范式切换是有成本的数据切分要改、模型结构要改、训练流程要改、监控方式要改。如果业务不需要面对未知的新样本维持转导式是理性的选择。5.2 一个可以拿去用的决策检查清单面对要不要切换的问题我整理了一份检查清单基本能覆盖大多数情况你的测试数据是否在训练时已经已知如果测试集是固定且已知的转导式完全够用。线上是否存在实时到达的新样本不存在就不急存在就要考虑归纳式。全量重算的耗时是否已经影响业务节奏比如只能每天更新一次模型而业务要求分钟级响应那就是切换信号。团队是否有精力维护采样、批处理等更复杂的训练管线归纳式的工程复杂度确实高一些。离线评估方式是否和线上推理方式一致如果不一致优先修正评估方式再决定换不换模型。5.3 范式转变不是换模型而是重新定义问题最后想分享一个更抽象的体会。刚开始接触到“从转导向归纳”的时候我以为是换一个模型结构的事后来发现根本不是。真正变的是我们怎么定义问题以前我们问“这堆数据里有什么规律”现在问的是“来了新数据模型能不能立刻说点什么”。这个转变会连锁影响到特征工程、数据切分、评估体系、在线架构甚至团队分工。比如评估体系转导式时代我们习惯随机划分数据集这在归纳式范式下就是错的又比如特征工程转导式可以放心使用全图统计特征归纳式则必须保证推理时那些统计量能实时算得出来。任何一环没跟上模型切换都会打折扣。我个人的实操习惯是接到一个新的图数据任务时先问业务方三个问题——数据更新频率是多少、新样本是否要求实时推理、标注成本高不高。这三个问题的答案基本就决定了范式选型。还没想清楚之前不要急着上最复杂的模型想清楚之后也不要因为工程麻烦而继续在转导式的舒适区里耗着。这次项目做完以后我把“先定范式、再选模型”写进了团队的技术规范。回过头看那次从转导向归纳的转变真正解决的问题不是某个指标提升了多少而是让模型从“只能活在某一张图里”变成了“能面对不断变化的数据流”。这条路走下来踩了不少坑但也把图数据建模的很多底层逻辑想明白了希望这篇记录也能帮你少走几步弯路。