做联盟营销的都知道一个痛点——投放预算批下去了但这一波能带来多少新客、多少成交往往是“看运气”。活动结束后复盘要么押中了爆款推广者吃到了远超预期的流量红利要么遇冷预算烧完了传播链路却根本没滚动起来。作为算法工程师我过去几年一直在这个场景里做预测建模。今天想跟大家分享一个我们近期完成并投稿到CIKM’25的研究方案在联盟营销场景下基于时空动态网络的两阶段传播规模预测。标题看着有点长拆开就是三件事业务场景是联盟营销技术路线是时空动态网络建模预测目标是多层传播的规模。这套方案解决的核心问题不是“这个广告主该投多少钱”而是“投放之后传播会扩散到多大规模峰值会出现在什么时间点”这两件事在预算分配和风险控制上都是硬需求。这个问题的难点不在于单点内容的质量评估而在于传播是一个网络现象。单篇推文发出去谁能看见、谁愿意转发、转发之后第二层第三层还能不能继续滚这取决于推广者之间的关系结构、粉丝重叠度、内容品类的匹配度以及时间维度上用户活跃节奏的共振。传统的机器学习方案要么做内容侧的CTR/CVR预估要么做社交网络的静态结构分析两者都没法同时抓住“结构”和“时间”两个维度的耦合。所以我们在方案设计上做了一个比较关键的决策把预测任务拆成两个阶段分别建模一级传播响应和网络级联放大再用时空动态网络把这两个阶段的特征统一起来。这篇文章把整套方案的设计逻辑、关键细节和踩过的坑展开聊一遍希望能给做类似业务的同行一个参考。1. 内容整体设计与思路拆解1.1 联盟营销场景里的传播规模预测到底是什么问题先简单交代一下业务背景。联盟营销的典型链路是这样的广告主品牌方在联盟平台上发布推广计划设置佣金比例联盟客推广者可能是KOC、KOC群体、社群主理人、比价站点等挑选自己擅长或受众匹配的商品生成专属推广链接分发到自己的渠道里消费者通过这个链接完成浏览、加购、下单联盟客就能拿到佣金。这个模式下广告主最关心的不是单个推广者的佣金成本而是整体传播规模——因为传播规模决定了流量天花板和销售额天花板。传播规模预测从内容上看和传统的“社交网络影响力最大化”问题接近但有一个显著差异影响力最大化是要找到一组能带来最大覆盖的种子节点是选人优化问题而我们的任务是给定一群候选的种子推广者预测从他们出发、在动态变化的关系网络中经过多层传播最终能触达多少人、产生多少转化。也就是说前者做Selection后者做Estimation。这个区别直接决定了模型设计上不能走贪心模拟的老路。另外联盟营销场景还有一个独有的特点传播链路的曝光是多源叠加的。同一个用户很可能同时看到推广者A的动态、推广者B的评论、还有品牌官方账号的信息流广告。这就导致“转化”这件事很难归因到单一传播路径上。我们在建模过程中没有强行做最后一跳归因而是把多源触达作为一种网络中的信息冗余来建模让模型去学习不同路径的边际贡献。这块在后文会详细展开。1.2 为什么选择两阶段建模而不是端到端预测最初我们尝试过一个端到端的方案把种子推广者集合的特征、网络结构特征、时间特征全部拼起来直接回归一个总触达规模和总GMV。实验做下来效果不理想误差率徘徊在比较高的水平。复盘时我们发现了一个被忽略的问题——传播规模预测这个目标内部其实是两个分布差异很大的子问题第一阶段是一级传播种子推广者直接发出的内容能在多长时间内获得多少曝光、点击和转化。这个阶段主要取决于推广者自身的历史量级、粉丝活跃度、内容关键词与当前热点的匹配程度本质上是一个“个体响应预测”问题。第二阶段是多级传播网络中的其他节点看到内容后是否转发、是否二次创作、是否以其他形式跟进从而让传播半径继续向外扩散。这个阶段主要取决于节点之间的连接强度、内容在社群间的跨圈层传播能力本质上是一个“网络级联预测”问题。这两个子问题的特征体系和影响因子几乎不重叠。强行放在一个模型里神经网络会倾向于学习量级信号更强的一级传播多级传播的部分就被当成噪声忽略掉了。这正是我们拆成两阶段的根本原因——让每个阶段专注于各自的特征空间再通过一个中间层把两者衔接起来。两阶段不是简单地把两个模型串起来。我们设计了一个共享时空编码器的级联结构底层同一个时空动态图编码器输出节点的动态表示第一阶段在这个表示上做种子传播力评分第二阶段则把第一阶段产出的评分作为一种“节点激活度”注入到图传播过程中再预测整个级联规模。这样既不会让两个任务互相干扰又能利用共享表示让第二阶段感知到第一阶段的不确定性。1.3 基线方案对比评估做方案选型时我们拉了几条基线做了预研对比这里把思路列一下大家做技术选型时可以参考方案类型核心思路预研表现主要问题单模型回归特征拼接后直接预测GMV/触达误差大尤其在爆款场景下严重低估多级传播信号被一级传播淹没因果推断方案用uplift model估计投放增量方向正确但预测的不是规模而是增量对绝对规模预测能力弱传统时序预测对历史传播曲线做时间序列外推冷启动失效无法处理新推广者完全忽略网络结构信息静态图神经网络GCN/GAT编码网络结构后回归比MLP好但无法刻画传播的时间节奏网络结构动态变化被丢弃本方案两阶段时空动态网络时空动态编码 两阶段级联预测总体误差率比单模型降低较多实现复杂度偏高训练需要更细致调参从预研结果来看两阶段方案带来的收益是实打实的尤其在有跨圈层传播能力的案例上预测精度提升非常明显。代价是工程复杂度上升了一个台阶训练时长和调参难度都有增加。这个取舍在后面具体做工程部署时需要权衡但从效果出发我们认为值。2. 核心细节解析与实操要点2.1 时空动态网络的构建从业务数据到图数据做图模型的第一步永远是把业务数据映射成图结构。这块听起来基础但我在实际项目里看到太多翻车案例映射逻辑不对后面模型再强也救不回来。我们的图网络构建分三个层次节点这里有个细节图里不是只有推广者和消费者两类节点。我们把“商品”也作为一类节点放进来了因为联盟营销的传播往往是围绕商品展开的商品本身携带品类属性、价格区间、佣金比例等信息。节点类型多了之后边关系也丰富起来推广者-推广者之间的关注关系或粉丝重叠度、推广者-商品之间的推广历史、消费者-商品之间的购买关系、消费者-消费者之间的社交关系每条边都赋予动态权重。边权动态化边不是静态的。推广者A和推广者B之间今天可能因共同推广同一个爆品而连接增强明天可能因为品类变化而减弱。我们把边权定义为一个随时间变化的函数输入是两个节点在时间窗口内的行为共现频次、内容相似度、转化互引系数输出归一化到0-1之间的连接强度。这比直接使用社交网络里的关注关系更贴近业务本质因为“实际传播”不等于“理论上能看见”。时间切片图结构按小时切片构建动态图序列。联盟营销的内容传播节奏非常快一个爆品的传播周期可能在48小时以内。采用天粒度会丢失传播高峰的精确位置采用分钟粒度则数据过于稀疏。经过对比实验小时粒度在覆盖率和计算代价之间是平衡点。每个时间片内的图结构、节点特征、边权构成一个快照序列输入模型。2.2 时空编码器的选择与改造图神经网络编码器这块我们参考了时空图预测领域的成熟思路但没有直接搬现成的模型。原因在于联盟营销传播图和交通流预测、气象预测这类经典时空图场景有两个本质区别。第一交通流预测里的图结构一般是固定的路段连接关系短期内不变而我们的图结构本身是高频动态变化的。这意味着模型不能只对节点特征做时序建模还需要对图结构的变化做建模。第二物理场预测中节点是规则格点而我们的节点是异质的推广者节点的特征维度、稀疏程度和消费者节点完全不同。所以我们采用了一个异质图注意力的时空编码器在空间维度上用异质图注意力聚合邻居信息不同类型节点映射到不同特征空间后再计算注意力权重在时间维度上用门控循环单元GRU风格对时间序列做递推编码每个时间片更新一次隐藏状态。空间编码和时间编码交替进行——先做一次空间聚合再把结果送入时序模块。这里有一个实操细节值得展开。异质图注意力里我们针对“推广者-推广者”这种同构关系用了传播力感知的注意力也就是两个推广者之间的注意力权重不只取决于内容相似度还会乘以双方在历史上发生过的转化互引频次来作为先验偏置。这个设计让模型在一开始就能区分“强传播连接”和“弱社交连接”而不是让注意力权重从头学起。实验对比显示加了先验偏置之后收敛速度提升了约30%最终精度也有小幅提高。2.3 两阶段预测头的具体设计第一阶段预测头做的是种子推广者的传播力评分。这里的“传播力”不是过去常说的历史GMV而是标准化后的单位时间触达增量。具体做法取过去一段时间内该推广者每次推广行为的曝光和点击数据用半衰期加权的方式构造收益标签。为什么用半衰期加权因为联盟营销里推广者发布一条内容之后曝光量通常在前几个小时快速爬升之后缓慢衰减。半衰期加权能够让模型学到“峰值前移”的内容特征而不是只学总量。第二阶段是一个级联传播预测头输入是时空编码器的输出、第一阶段的种子传播力评分、以及一个传播时间预算T我们想预测未来T小时内的累计传播规模T是可配置的实验中一般取24小时、48小时、72小时三档。输出是三个值预计触达人数、预计转化数、传播峰值时间。第三个别小看它业务上非常有用——如果预测峰值将发生在凌晨3点运营团队可以提前调整客服排班广告主也可以决定要不要在那之前追加预算。两个阶段的损失函数分开计算第一阶段用MAE第二阶段用pinball loss分位数损失。为什么分阶段用不同损失第一阶段传播力评分的分布相对集中MAE就对所有样本一视同仁地优化第二阶段级联规模的分布是典型的长尾——绝大多数推广者传播规模小极少数爆款能带来几十倍于均值的流量pinball loss可以让模型输出多个分位数的预测区间而不是只给一个均值这样业务侧就能用“P50预测”做保守预算、用“P90预测”做风险预案。2.4 训练策略与温度调节两阶段联合训练时一个很实际的坑是梯度不平衡。第一阶段传播力评分的loss量级一般在几十第二阶段级联规模的loss量级在几万甚至几十万。直接相加的话第一阶段的信号完全被淹没了。我们的做法是给两个loss分别加可学习的权重初始化时让级联规模loss的权重小两个数量级训练过程中自动调节。这个机制在几个框架里都有现成实现不需要自己写。另外要多说一句温度调节。由于第二阶段要利用第一阶段的评分而第一阶段评分本身有噪声训练早期直接把它当硬标签会放大误差。我们给第一阶段输出加了温度系数训练初期温度调高让评分分布变平滑降低高频噪声的影响训练后期温度逐步降到1让模型使用更锐利的评分分布。这个设计和知识蒸馏里的温度退火思路相似但目的是控制噪声而不是迁移知识。3. 实操过程与核心环节实现3.1 数据准备与样本构造数据是整个方案的地基。我们从联盟平台的日志系统中抽取了三个数据源推广行为日志谁在什么时间推广了什么商品、消费者行为日志曝光、点击、加购、成交、关系网络数据推广者之间的关注/合作/粉丝重叠关系。时间跨度取了可用的完整9个月数据按时间切分前7个月训练中间1个月验证最后1个月做线上模拟回测。样本的构造方式需要重点说明一下。给定一批种子推广者集合S我们要构造一个样本预测“从S出发的传播规模”这意味着每个样本其实是一个推广事件组合而不是单条推广行为。具体做法把一个自然周内、推广同一商品或同一商品集合的所有推广者合并为一个传播事件样本取事件前14天的数据做特征窗口事件后72小时的数据作为标签窗口。在每小时的图快照上把种子推广者按需标记出来作为第一阶段模型的输入。样本不平衡问题在标签阶段就需要处理。大传播事件触达超过某个阈值的在样本里占比不到2%如果直接训练回归模型模型会把资源几乎全部花在优化中低量级样本上。我们用了一个加权采样的策略构造损失函数时给大传播事件样本一个梯度放大系数系数和真实传播规模的log值成正比。这样既不改变样本整体分布又能让模型对大事件保持敏感。3.2 特征工程的三个关键维度特征工程这块我按三个维度组织节点静态特征、动态时序特征、拓扑结构特征。不把精力花在堆砌上百个特征上而是精选十几个经过业务验证、可解释性强的核心特征。节点静态特征包括推广者所在品类一级类目和二级类目、历史推广频次分层、粉丝量级区间、历史平均佣金率。这些特征主要用来刻画“这个节点是谁”对冷启动尤为重要。动态时序特征是我们整个方案的重头戏。每个节点维护一个状态向量包含过去24小时内的推广频次、内容互动率点赞评论转发的加权和、成交产出率、以及与当前推广商品的品类相似度。时序特征在进入模型前经过一个半衰期衰减层越久远的行为权重越低。这个设计和人类信息传播的“遗忘曲线”是吻合的——晚近的行为对当前传播力的影响远大于早期行为。拓扑结构特征包含节点在当前时间片的度中心性、PageRank值、所在社群规模以及和已激活节点集合的平均距离。最后这个特征对第二阶段很重要如果种子推广者周围都是高活跃节点且这些节点已被部分激活那么传播的扩展阻力就小级联规模预期会更大。我们把这个距离特征作为图编码器初始向量的一部分注入。3.3 模型训练配置与超参调优记录训练配置上图编码器用了两层异质图注意力隐藏维度256时间序列模块的循环步长设为48两天的小时数dropout设为0.2优化器用AdamW初始学习率2e-4batch size设128。训练轮数早期版本跑80轮后来加了早停策略patience8后一般在第35到50轮之间收敛。有一个调参经验想单独提醒图邻居采样数不要设太大。我们一开始采样50个邻居显存直接爆掉而且效果并没有优势。后来发现联盟营销场景下每个节点的有效传播邻居其实比想象中少很多——大部分传播沿着少数强连接扩散弱连接虽然存在但在传播中贡献很低。最终把采样数压到15训练显存降了60%精度反而略微提升。超参调优上最敏感的参数是两阶段loss的初始权重比其次是温度退火的衰减速度。这两个参数对最终误差的影响能差到8%以上建议大家在各自数据上做网格搜索。其他参数如隐藏维度、dropout相对不敏感默认配置就行。3.4 评估指标与离线回测方法评估传播规模预测任务不能只看MAE或MAPE。因为传播规模的量级跨度太大一个误差500的样本和一个误差50000的样本在MAE里权重不同MAPE又会把低量级样本的误差无限放大。我们最终使用了三个指标组合加权绝对误差给每个样本的误差乘以权重系数权重随真实传播规模的对数值增长。这个指标对大事件更敏感适合衡量业务核心场景的预测能力。对数误差对真实值和预测值都取log后再算MAE。这个指标对全量样本更均衡适合衡量整体模型质量。峰值时间误差预测传播峰值时间和真实峰值时间的小时差这在运营排期场景里是独立关注的。离线回测时还有一个重要细节训练和评估必须区分“时间”而不是随机切分。传播是一个时序过程如果随机分割相当于让模型看到了未来的信息回测结果会虚高。我们用严格的滚动时间窗口模型只使用过去数据预测未来评估集的每一天都不参与训练。4. 常见问题与排查技巧实录4.1 冷启动新推广者几乎没有历史行为冷启动是我们实际落地时遇到的第一个拦路虎。评论区、社群里很多推广者是刚注册的新人没有任何历史数据动态时序特征全部是空值。一开始模型对这类节点的预测基本等同随机单独拿出来看误差非常大。解决办法分两层。第一层是特征降级当节点没有历史行为时动态特征直接用全网同类目推广者的均值填充同时增加一个“是否冷启动”的掩码特征让模型知道这个填充不可靠从而降低对这类节点的信心。第二层是邻居代理冷启动节点在图上不是孤立的——它可能和某些老推广者有合作/关注关系我们通过它的邻居节点特征来构建代理表示。在实操中第二层效果更明显因为联盟推广者的冷启动通常不是完全从零开始而是依附在某个社群或某个机构上邻居特征能有效补充信息。4.2 传播链断裂中间层节点未被观测到日志系统只能记录带推广链接的曝光和点击这就带来一个天然缺陷如果传播过程中有人在社交软件里直接转发了文本内容而没有带链接这段传播在数据里完全观测不到。这个问题会导致多级传播被系统性低估。我们尝试过几种修复方法基于用户重合度推断隐藏传播、用内容语义匹配估计无链接传播比例、甚至在部分流量上做抽样调研来校准。最后效果最好的方案是引入一个未观测传播补偿模块在第二阶段预测时根据种子推广者的历史“观测传播规模/估计真实传播规模”的比例系数对预测值做动态校准。这个比例系数是随时间和品类变化的需要定期更新。4.3 长尾分布的边界爆款预测的两难长尾问题是所有传播预测模型的宿命。绝大多数样本的传播规模集中在低量级少数爆款会贡献绝大部分GMV。这导致模型在“均值附近”表现不差但在“极端值”上损失惨重——而极端值恰恰是业务最关心的地方。我们的做法是接受“均值预测与极值预测不可兼得”的现实用分位数输出的方式把选择权交给业务。模型不仅输出点预测值还输出P10、P50、P90三个分位数预测。业务决策时预算充足且风险偏好高就用P50预算紧张就用P90做风险控制。在给广告主的报表里我们也会明确标注预测区间而不是单一数值减少业务方的错误预期。4.4 离线评测和线上表现为什么经常对不上这是我们做完第一次A/B之后最痛的一次复盘。离线回测误差率表现非常好上线后效果却明显变差。排查了一圈发现问题出在特征在线和离线的口径不一致。离线训练时我们用了日志里的最终数据也就是已经完成归因和清洗的数据。但线上预测时模型拿到的特征是实时的、未归因的、甚至有些字段还没到位。数据分布的不同直接导致模型输出偏差。解决方案是建一个专门的在线特征管道确保线上使用的特征和离线训练时在口径上完全一致。这个工程改造花了我们将近两周时间但改造完成后线上效果恢复了离线水平。给大家的提醒就是模型不是上线就完事特征口径一致性检查必须作为上线前的固定环节。4.5 常见问题速查表现象可能原因检查顺序和方法第一阶段传播力评分全部趋同特征里存在强主导信号网络被单特征支配检查特征标准化重点看是否直接放入了GMV类特征第二阶段级联规模严重低估未观测传播链路多补偿系数过低检查补偿系数的更新周期抽样调研校准峰值时间预测过早时间窗口特征权重过高模型学到“早发布早高峰”检查半衰期衰减参数调长时间衰减冷启动节点预测偏差大填充特征噪声过大检查冷启动掩码是否生效降低邻居采样的噪声离线好线上差特征口径不一致或线上链路有延迟优先排查特征管道而不是调模型最后分享一个我在这个项目里体会最深的一点。传播规模预测做到最后模型架构反而不是最大的难点最难的是把“业务传播机制”翻译成“数据表示”。两阶段拆分、半衰期加权、动态边权、未观测传播补偿每一个设计背后都对应着联盟营销场景里一个具体的业务规律。如果只是拿一个通用图神经网络跑数据很难抓住这个场景的核心结构。后续这个方案还打算在两个方向上扩展一是加入内容语义向量让文本信息参与传播力评估二是把预测窗口从72小时延长到7天做更长周期预算规划。如果你们也在做类似的传播预测场景欢迎一起交流。