案例 · 用户提交方向,已匿名
核心问题:在一个真实的、带时间戳与敌意标记的社交交互图上,给定 5% 的节点扰动预算,一个只从历史日志里学的离线强化学习策略,能不能比平凡启发式更多地降低意见极化方差?还是说单步贪心(挑当前最极端的节点)已经把能拿的都拿走了?
本轮判定:未判定 · 详见正文与原始结果。
数据:{'dataset': 'SNAP soc-redditHyperlinks-body.tsv — Reddit Hyperlink Network, Kumar et al., WWW 2018', 'download': 'https://snap.stanford.edu/data/soc-redditHyperlinks-body.tsv(匿名游客直连,无需注册 / API key / DUA)', 'sha256_body_tsv': '9bbf57511dc0da7369c2e896d865b68f170136def4f223f4c9e9e10818f4bfb5', 'n_nodes': 247, 'induced_edges': 44623, 'induced_negative_edges': 8040, 'induced_negative_fraction': 0.180176, 'n_windows': 40, 'train_window_range': ['2014-01', '2015-12'], 'eval_window_range': ['2016-01', '2017-04']}
真跑了:3 个噪声种子 · 纯 CPU 0 秒 · 代码/日志/原始结果全部随附

真实时变社交图上的离线强化学习去极化基准

数据集:SNAP Reddit Hyperlink Network(Kumar et al., WWW 2018) 算力:纯 CPU 单机,约 6 分钟机时,全程无 GPU


0. 先说结论

在这张真实的 Reddit 时变交互图上,离线强化学习没能打过平凡启发式,而且输得很干净。

在 12 个留出评估种子上,离线 RL(Fitted Q Iteration)相对「不干预」把留出期末的极化方差降低了 15.87%(中位数),而一个只挑「当前意见最极端的节点」的单步贪心启发式降低了 34.99%。 两者预算完全相同(96 次节点扰动)。12 个种子无一例外,贪心都更低: 配对差值中位数 −0.02508,配对 Wilcoxon 符号秩双侧精确 p = 0.00049,rank-biserial = −1.00。 换成全程 AUC 口径,结论不变(同样 0/12,p = 0.00049,rank-biserial = −1.00)。

预注册的 H1 假设是「离线 RL 会更好」。H1 被推翻。

这不是尺子坏了。跑之前就预注册的两项尺子对照都通过了:

而且所有干预臂都确实打得过「什么都不做」这个零模型(每一个都 12/12,p = 0.00049), 说明这套环境与指标是能测出干预效果的 —— 它只是同时告诉我们,离线 RL 在这个设定里 拿到的那部分效果,明显少于一行贪心代码。

为什么输,我们查到了具体位置(下面第 5 节,事后探索):不是节点挑错了,是钱花错了时候。 离线 RL 与贪心选中的节点有 81.8% 重合,两者出手的月份数也完全一样(都是 8 个月), 但离线 RL 把 96 次预算连续压在留出期的前 8 个月,后 8 个月一次都没出手;贪心是隔月出手、 摊满 16 个月。前 8 个月里离线 RL 其实赢(12/12 种子上极化更低),后 8 个月扰动随锚定衰减、 方差反弹,12/12 种子上输回去,终点和全程两个口径都输。

这一轮不能支持的推断

  1. 不能说「Reddit 上的真实极化被降低了 X%」。这张图是真的 —— 拓扑、每条交互的真实时刻、 每条交互是否敌意,都来自数据集原始字段。但节点的「意见」数值是模拟的:该数据集不含任何 节点观点标签,我们也实测确认没法从它的符号结构里诚实地提取一条立场轴(见第 2 节)。 本轮的极化是在真实图上按明确写死的规则演化出来的受控量,不是真实人群的真实观点。
  2. 不能说「离线 RL 做不了去极化」。本轮只证伪了一个具体组合:这个数据集、这个扰动算子、 这个预算结构、这个 FQI 实现。换算子或换预算结构,结论可能反过来(第 7 节给了方向)。
  3. 不能把输的原因单独归给「离线 RL 这个方法」。训练日志来自 2014-01..2015-12,评估在 2016-01..2017-04,Reddit 这段时间自身在变,分布漂移与方法本身在本轮拆不开。
  4. 不能外推到更大规模。本轮 247 个节点、44623 条边。
  5. 不做多数据集 benchmark,不做超参搜索 —— 超参是跑前锁定的那一组,只跑过这一组。

1. 这一轮的问题设定

在公开的真实时变社交交互图上,评估离线强化学习在节点级扰动下能把极化方差降低多少,并给出策略轨迹。

设定要素本轮做的在哪
公开时变社交网络交互数据集SNAP Reddit Hyperlink Network,286562 条带秒级时间戳的真实超链接,匿名可直连下载第 2 节
极化话题子图取「关联敌意边最多」的 250 个 subreddit 的冲突核,共 247 个节点、44623 条边、18.0% 为敌意边第 2 节
离线强化学习Fitted Q Iteration + ExtraTrees,日志一次采完即冻结,训练期间零环境交互第 3 节
节点级扰动每窗最多扰动 12 个节点(4.86% ≤ 5%),x ← 0.5·x第 3 节
极化方差降低幅度逐臂给出第 4 节
策略轨迹出手时机、每窗规模、被扰动节点清单与重合度第 5 节

全程在真实图上跑,没有替换成合成图。


2. 数据:真的是哪一部分,模拟的是哪一部分

真实的部分

soc-redditHyperlinks-body.tsv,sha256 9bbf5751…8f4bfb5,286562 条 subreddit 间超链接, 2013-12-31 至 2017-04-30,每条带秒级时间戳和一个 ±1 的敌意标记(LINK_SENTIMENT,由原论文 的文本分类器给出)。匿名 curl 直接下载,无需注册、无需 API key、无需 DUA。

本轮的子图构建规则在任何实验之前固定,且与实验结果无关:

模拟的部分,以及为什么必须模拟

这个数据集不含任何节点观点标签。我们先试了能不能从它自己的符号结构里把「两大阵营」的立场轴 提出来,结论是不能,而且有明确证据:

所以我们不伪造立场轴。意见 x_i ∈ [−1,1] 是定义在真实图上的受控状态变量, 规则在 claims.json 里跑前写死:

初值取随机而不是人工设计,是为了让极化结构完全由真实的敌意边与真实时序产生, 而不是由我们预先摆好的两个阵营产生。代价写在第 0 节:本轮的意见值不对应任何真实立场。

真实的敌意结构确实在起作用,不是摆设。我们跑了图零模型:保持拓扑、时间戳次序、正负边总数 完全不变,只把全部边的 ±1 符号全局随机置换,结果零模型臂的留出期末极化方差从 0.1226 降到 0.1141(12/12 种子,p = 0.00049)。也就是说,真实敌意边落在哪些边上,本身就额外支撑了 约 7% 的极化水平;换成随机符号,同一张图撑不住这么高的极化。


3. 方法

环境与预算

每个留出窗开始时,策略选一个节点集合 A_t(|A_t| ≤ b = 12,占 247 个节点的 4.86%, 满足「受控节点 ≤ 5%」的设定),对 i ∈ A_t 执行 x_i ← 0.5·x_i,把该节点当前表达拉向中性 一半。扰动只作用于表达意见,不改内在意见,所以效果会在 FJ 锚定下逐窗衰减 —— 这正是「何时花预算」成为一个真问题的原因。

全部干预臂共享同一总预算 B = 12 × 16 / 2 = 96 次「节点×窗」动作,等价于「只能在一半的月份里 满额出手」。逐臂实际花费全部核对过:8 个臂每个种子都恰好花满声明预算,无一超支(第 6 节)。

臂

臂类型说明
null_no_intervention零模型完全不干预,花费 0。所有降幅的参照系
random_budget_matched平凡基线隔月随机挑 12 个节点
degree_top_b平凡基线度中心性优先(传统启发式)
extremity_top_b主对照挑当前 \x_i\最大的 12 个节点
extremity_double_budget正对照同上但预算翻倍(192)
offline_rl_fqi实验臂离线 Fitted Q Iteration

把 extremity_top_b 定为主对照不是随便挑的:对方差这个目标,单步扰动的收益恰好是 (1−(1−η)²)·x_i²,所以挑最极端的节点是可证明的单步最优。离线 RL 唯一可能赢的地方, 只剩长程效应和出手时机 —— 这一点在跑之前就写进了预注册。

离线强化学习

Fitted Q Iteration(Ernst et al., JMLR 2005)+ ExtraTrees 函数逼近。离线的含义是严格的: 行为策略(50% 随机 + 50% 极端度贪心)在训练期 8 个种子 × 3 次回放上一次性采出 142272 条转移,采完即冻结;FQI 的 5 轮迭代全部是在这个固定数据集上做回归, 学习过程中一次都没有与环境交互。训练日志一条都不来自留出期。

留出协议与配对

两层留出同时成立:训练窗口与评估窗口不相交(2015-12 之前 / 2016-01 之后), 训练种子与评估种子不相交(1-8 / 101-112)。

配对方式:每个评估种子先用「完全不干预」从 2014-01 热身到 2015-12 末,得到该种子的留出期起点; 所有臂从同一个起点、在同一套真实边流、同一条噪声序列上跑留出期 16 窗。 因此臂之间可以做配对检验,臂间差异不含起点差异。


4. 结果

极化方差降低幅度(主指标)

留出期末(2017-04)的极化方差,12 个评估种子的中位数:

臂极化方差 P_end相对零模型降幅预算实际花费
零模型(不干预)0.12263—00
度中心性优先0.11878+2.89%9696
随机(预算匹配)0.11060+10.72%9696
离线强化学习 FQI0.10384+15.87%9696
极端度贪心(主对照)0.07897+34.99%9696
极端度贪心·预算翻倍(正对照)0.06310+48.88%192192

图:figs/polarization_trajectories.png(16 个月的完整轨迹)、 figs/reduction_vs_null.png(逐种子降幅)。

预注册假设的判定

假设判定计数配对差值中位数配对 Wilcoxon 双侧精确 prank-biserial
H1 主对照:RL 优于极端度贪心(终点)推翻0/12−0.025080.00049−1.00
H1 次要:RL 优于极端度贪心(全程 AUC)推翻0/12−0.001640.00049−1.00
H2 零模型:随机 优于 不干预成立12/12+0.012920.00049+1.00
H2 零模型:度中心性 优于 不干预成立12/12+0.003840.00049+1.00
H2 零模型:极端度贪心 优于 不干预成立12/12+0.043340.00049+1.00
H2 零模型:离线 RL 优于 不干预成立12/12+0.020430.00049+1.00
H3 正对照:预算翻倍 优于 单倍成立12/12+0.016880.00049+1.00
H4 负对照:两个随机变体无差异成立6/12+0.000230.73340+0.13

每一条计数式说法(「N/12 个种子」)旁边都并列给出了配对 p 值、配对差值中位数与效应量, 这是预注册里写死的报告要求。n=12 的配对 Wilcoxon 精确检验,双侧 p 的下限是 2/2¹² = 0.00049, 上表里几个 0.00049 都已经顶到这个下限,即「12 个种子全部同向」在这个检验下能给出的最强证据。

图:figs/primary_paired_difference.png(主对照逐种子配对差值)。


5. 策略轨迹报告

图:figs/policy_trajectory.png · 数据:work/results/policy_trajectory.json

出手时机 —— 这就是输的地方

离线 RL极端度贪心
出手的月份留出期第 1–8 月,连续满额第 1,3,5,7,9,11,13,15 月,隔月满额
出手月份数88
每次出手节点数1212
总花费96 / 9696 / 96
碰过的不同节点数201156
与对方选中节点的重合度81.8%—

两者花的钱一样多、出手的月份数一样多、选的节点还有 81.8% 重合。唯一的实质差别是 把预算摊在哪些月份:离线 RL 全压在前半程,贪心摊满全程。

机制(事后探索,非预注册,不参与任何判据)

数据:work/results/exploratory_post_hoc.json

阶段离线 RL 平均极化极端度贪心 平均极化RL 更低的种子数
第 1–8 月(RL 在花钱)0.07040.079812/12
第 9–16 月(RL 没钱了)0.08730.07460/12

离线 RL 在花钱的那 8 个月里确实更有效率 —— 连续满额出手把方差压得比隔月出手更低, 12 个种子无一例外。但扰动只作用于表达意见,会在 FJ 锚定下衰减;预算用光之后的 8 个月里 方差一路反弹,12 个种子无一例外地被贪心反超。终点和全程 AUC 两个口径上都输。

这正是离线 RL 的一个经典失败模式(Levine et al. 2020 综述第 4 节):价值函数在数据覆盖不到的 区域被高估,策略于是倾向于尽早、尽多地出手,把远期收益贴现掉。另有一个可以直接核对的实现层原因:`horizon_left_frac` 这个特征训练时以 24 窗为分母、评估时以 40 窗为分母,留出期第一窗的特征值只有 0.40,落在训练分布里「时程将尽」那一段——策略因此开局就按「快到期」的方式把预算花光。训练日志里 84.4% 的状态-动作对优势为正,也符合价值高估。这两个都是候选解释,不是已验证的机制:本轮没有把 RL 的选点固定到隔窗日程、没有核对 Q 值与实际回报、也没有把特征口径改齐重训。

被扰动最多的节点

离线 RL 累计扰动次数最高的是 clashofclans(26)、shitamericanssay(23)、aznidentity(23)、 skeptic(19)、civcraft(19);极端度贪心是 hearthstonecirclejerk(37)、aznidentity(31)、 clashofclans(25)、metanarchism(25)、shitgreeddisastersays(24)。完整前 20 名两份清单都在 work/results/policy_trajectory.json。注意:这些节点被选中是因为它们在模拟意见空间里数值 极端,不代表这些社区在现实中更极端。


6. 敌意复核:两项核心

① 这把尺子能不能测出已知的差距

正对照通过。 预算从 96 翻到 192,尺子测出来了:12/12 种子,配对差值中位数 +0.01688, p = 0.00049。方向已知的差距,尺子抓得住。

负对照通过。 两个只有内部随机数不同的随机策略互比:6/12,配对差值中位数 +0.00023, p = 0.73340,rank-biserial +0.13。不该有差异的地方,尺子没有虚报。

两项都过,所以 H1 被推翻不能赖到「测不出来」头上。

② 最要命的那个混杂:预算与起点不对齐

一个偷偷多花预算、或者从更低方差起点出发的臂会无条件赢。这是本轮设计里最容易翻车的地方, 事先用三条措施消掉,事后逐条核对过:

  1. 同一起点:每个种子的留出期起点由同一次无干预热身产生,全部臂共用。
  2. 同一随机性:全部臂在同一套真实边流、同一条噪声序列上跑。
  3. 预算是作废开关:逐臂逐种子记录实际花费。核对结果 —— 8 个臂在 12 个种子上全部恰好 花满声明预算,无一超支(analysis.json 的 budget_accounting,audit_delivery.py 会重算)。

本轮不做独立复算之外的第三方重跑;但头条数字本身走了两条独立实现: 主分析用 scipy(Python 3.12),复算用纯标准库对 2¹²=4096 种符号翻转做全枚举(Python 3.14, 不依赖 scipy/numpy)。两条路径的 p 值、配对差值中位数、效应量、计数全部一致, audit_delivery.py 每次跑都会重新比对。

其他已声明的混杂(跑前就写在 claims.json 里)


7. 这个结果对下一步意味着什么

第一,问题出在预算的时间分配,不在节点选择。 两个策略选的节点 81.8% 重合,差别几乎全在 「哪几个月出手」。这把后续工作的范围收窄了很多:要让离线 RL 在这个设定里赢,得先让它学会等, 而不是换更大的网络或更多特征。

第二,几条具体的、有判据的下一步(按我们判断的性价比排序):

  1. 把预算约束显式写进状态与目标。现在 FQI 只在特征里放了「剩余预算比例」,价值函数没有被 强制满足预算守恒,所以它贪早。改成带预算维度的有限时程动态规划、或在奖励里对早花钱加惩罚, 是最直接的一刀。判据就用本轮同一套:能不能在留出期把配对差值的符号翻过来。
  2. 换扰动算子。本轮的扰动只改表达意见、会衰减,所以摊薄比集中好,贪心天然占便宜。 如果改成部分中和内在意见(效果不衰减),或者改成加/删边这类结构性干预, 长程规划的价值才有机会体现出来,RL 与贪心的差距结构会完全不同。
  3. 换成需要预测未来冲突的设定。真正能让 RL 拉开差距的,是那些「必须提前预判下个月哪里要爆」 的任务 —— 本轮数据集里每条边都带敌意标记和时间戳,完全支持把目标改成「在冲突爆发前抢先 干预」。这是我们看下来最有可能出现 RL 优势的方向。
  4. 保守派离线 RL(CQL / IQL 之类)压住价值高估。本轮观察到 84.4% 的状态-动作优势为正, 是典型的高估症状,这类方法就是为它设计的。

第三,本轮的负结果本身是有用的。 它把「在真实时变图上用离线 RL 做节点级去极化」这条路上 最省事的那个版本排除掉了,而且给出了排除的理由和位置。如果没跑这一轮, 上面第 1、2 条改动很可能会被当成「锦上添花」而不是「必须先解决的问题」。


8. 怎么复现

``bash bash work/code/00_download_data.sh ./raw # 匿名下载 SNAP 原始文件 python work/code/01_build_temporal_graph.py ./raw work/data python work/code/03_offline_rl.py # 离线 FQI 训练,约 220 秒 python work/code/04_evaluate.py # 留出期评估,约 49 秒 python work/code/05_analyze.py # 主分析(需 scipy) python3 work/code/06_recheck.py # 独立复算(纯标准库) python work/code/07_figs.py # 出图 + 策略轨迹报告 python3 audit_delivery.py # 包内自检 ``

依赖:numpy、scipy、scikit-learn、matplotlib(05/07 需要);06_recheck.py 与 audit_delivery.py 只用标准库。全部随机性都由显式种子控制,同机重跑逐位可复现。

主结果图
主结果图(本轮实验的关键对比)。原图见随附 figs/ 目录。

随附材料(点开即看,不用下载)

打包下载全部材料(.zip)
口径与边界。这些限制与负结果均保留在原始材料中。
本案例源自一位研究者通过公开表单提交的方向,已隐去其姓名、单位与一切可定位信息。结论与代码可复查、可反驳。
← 全部案例 · JouleBeat · DeepGraph