Product Experimentation with Instrumental Variables: Unconfounding LLM Routing Decisions in Python

TL;DR · AI 摘要
工具变量分析能消除LLM路由决策中的混淆因素,通过速率限制回退等基础设施信号提取真实因果效应。
核心要点
- 传统回归会混淆模型质量与查询复杂度,导致14%的性能提升可能被高估
- 速率限制触发的回退是理想的工具变量,与查询质量无关但影响路由决策
- 两阶段最小二乘法(2SLS)可分离因果效应,需验证第一阶段F统计量有效性
结构提纲
按章节快速跳转。
思维导图
用一张图看清主题之间的关系。
查看大纲文本(无障碍 / 无 JS 友好)
- 工具变量分析在LLM路由中的应用
- 问题诊断
- 路由混淆因素
- 传统回归缺陷
- 解决方案
- 工具变量选择
- 2SLS方法
- 实现步骤
- F统计量检验
- 局部平均处理效应估计
金句 / Highlights
值得收藏与分享的关键句。
标准回归将查询难度与模型质量混淆,导致14个百分点的提升可能被高估
速率限制触发的回退是独立于查询质量的随机工具变量
2SLS通过第一阶段F统计量检验工具变量强度,第二阶段估计局部平均处理效应
使用工具变量进行产品实验:在 Python 中消除 LLM 路由决策的混淆因素
2026 年 7 月 29 日
/
#product experimentation
Rudrendu Paul
对于负责多模型网关的数据科学领导者和产品经理而言,衡量模型质量的标准回归方法存在根本性缺陷。
无论你是否意识到,你都在进行因果推断实验,而你的路由规则正在悄悄污染性能估计。
考虑一个网关,它根据置信度阈值将传入查询路由到高级模型或更快、更便宜的替代模型。置信度评分低于特定阈值的查询会被路由到高级模型,而高于该阈值的查询则会被路由到低价模型。
你提取日志,对任务完成情况进行回归分析,发现高级路由带来了 14 个百分点的提升。基于这个数字,你的基础设施团队可能会开始起草一个提案,将所有查询都路由到高级模型。
在发送该提案之前请停下来。路由规则与查询复杂度高度相关,而查询复杂度直接决定了任务是否完成。复杂查询更难处理且更容易失败,无论使用哪种模型。
当你将任务完成情况回归到高级路由时,你同时测量了两个纠缠的现象:将查询发送到高级模型的因果效应,以及每个模型接收到的查询在难度上的固有差异。
标准回归将这两个信号合并为一个系数,观察到的提升同样反映了查询难度,而不仅仅是模型质量。
当分配规则与查询特征相关时,就会出现路由混淆因素,这在任何正常工作的路由系统中都是预期的。分配规则确保两个处理组包含系统性不同的查询,从而使朴素比较无法作为因果估计。
工具变量分析是打破这种僵局的方法。你需要一个第三变量,它影响路由的原因与查询质量完全无关。
限流触发的回退机制正是这样的变量。当高级模型达到限流时,网关会将查询重定向到更便宜的模型,无论查询本身的特性如何。限流是由于基础设施原因触发的,与用户实际提出的问题无关。这种随机性是一个工具变量,而两阶段最小二乘法(2SLS)可以从中提取出干净的因果估计。
本教程将逐步演示 Python 中完整的诊断到修复流程:解释路由混淆因素如何使 OLS 偏倚,如何通过两个链式回归从头构建 2SLS,如何使用第一阶段 F 统计量检查工具变量强度,以及如何恢复 2SLS 实际估计的局部平均处理效应(而不是误认为是平均处理效应)。到结束时,你将知道如何在自己的日志中识别混淆的路由决策,如何从限流回退等基础设施信号中构建有效的工具变量,并生成具有正确置信区间的因果估计,而不是默认的过自信手动 2SLS 估计。
配套笔记本:本文中的每个代码块都可以在 companion repo 的 iv_demo.ipynb 中端到端运行,地址为 github.com/RudrenduPaul/product-experimentation-causal-inference-genai-llm/tree/main/11_instrumental_variables/ 。
目录
- 为什么路由会使回归分析变得复杂
- 什么是工具变量
- 先决条件
- 构建工作示例
- 第1步:朴素OLS(有偏基准线)
- 第2步:从零开始构建两阶段最小二乘法(2SLS)
- 第3步:弱工具变量诊断
- 第4步:LATE才是你真正关心的指标
- 第5步:Bootstrap置信区间
- 当工具变量失效时
- 接下来该怎么做
为什么路由会使回归分析变得复杂
路由系统会做出相关决策。置信度低、token数量多或包含复杂多步骤意图的查询会被路由到高级模型。而简短、清晰且明显属于廉价模型能力范围的查询则会被路由到廉价模型。这种相关性正是路由层设计的核心目的。
问题在于驱动路由决策的特征也会影响你关心的结果。
无论由哪个模型处理,复杂查询的完成难度都更高。当你构建 task_completed ~ routed_to_premium + controls 这个回归模型时,controls项可以吸收可观测的复杂性维度:查询长度、用户参与等级以及你记录的其他变量。
不可观测的复杂性维度则会嵌入到 routed_to_premium 系数中,导致估计值出现向下偏移(复杂查询被路由到高级模型时完成率更低,使高级模型看起来比实际情况更差)或向上偏移,具体方向取决于混杂因素的方向。
在本教程使用的合成数据集中,OLS估计值为+3.3个百分点,尽管真实的因果效应是+6个百分点。这种2.7个百分点的向下偏差完全由未观测到的查询复杂性驱动。
回归结果看起来很有信心,p值看起来显著,标准OLS输出中没有任何内容能指出问题。这就是这种失效模式危险的原因:它在标准回归诊断中完全隐形。
2SLS正是为了解决这种结构问题。你需要一个与查询质量无关的路由外部变异源。限流触发的降级机制正好提供了这种变异。
图1:IV因果结构。工具变量(Z = 限流降级)满足相关性(Z预测路由)、排他性(Z到结果没有直接路径)和独立性(Z与未观测的查询复杂性无关)。虚线红箭头显示了导致朴素OLS偏差的混杂路径。
什么是工具变量
工具变量是一个能改变内生变量(路由决策)但又不通过其他路径直接影响结果变量(任务完成)的变量。
四个假设定义了有效的工具变量。
相关性
工具变量必须真正影响内生变量。在15%的高级模型资格查询中触发的限流降级指标会显著影响这些查询是否被路由到高级模型。
这个假设是可检验的:通过第一阶段F统计量进行验证。传统阈值是F > 10(Staiger and Stock, 1997),对应最坏情况下2SLS估计值相对于OLS的偏差不超过10%。
需要注意的是,Andrews、Stock和Sun(2019)的最新研究指出,在样本量较小或使用多个工具变量的场景中,这个阈值可能过于宽松。对于生产环境分析且降级数据有限的情况,应将F > 10视为最低标准,并通过额外敏感性检验验证后再报告结果。当F值低于10时,工具变量明显薄弱,估计结果不可靠。
排除限制
工具变量必须仅通过其对路由的影响来作用于结果。限速回退机制完全通过改变处理查询的模型来完成任务,不存在其他直接路径。
这一假设需要逻辑层面的商业推理,无法仅通过数据验证。由基础设施整体负载触发的限速回退与用户的具体请求内容或任务难度无关。
独立性
工具变量必须独立于所有混杂因素。限速事件由整体API流量驱动,与任何单个查询的特征无关。某个查询触发限速回退的概率与查询复杂度、用户等级或其他任何混杂因素均无关联。这一假设同样需要逻辑论证。
单调性
工具变量必须使所有受影响单元向同一方向变化。对于限速回退而言,所有受影响查询都会从高级模型切换到低成本模型,但不会因回退而从低成本模型切换到高级模型。这排除了存在反向行为的个体,也是LATE解释成立的必要条件。
当上述四个条件均满足时,2SLS方法可通过仅使用工具变量生成的路由外生变化,提取路由对任务完成的因果效应估计值。
先决条件
你需要:
- Python 3.11 或更新版本
- 熟悉 pandas 和 statsmodels OLS
- 对线性回归有基本了解(2SLS 是两个 OLS 回归的串联)
安装本教程所需的包:
pip install numpy pandas statsmodels scipy这将安装教程中使用的四个包。statsmodels 提供 OLS 和公式 API,scipy 用于自助法步骤中的统计计算。
克隆配套仓库以获取合成数据集:
git clone https://github.com/RudrenduPaul/product-experimentation-causal-inference-genai-llm.git
cd product-experimentation-causal-inference-genai-llm
python data/generate_data.py --seed 42 --n-users 50000 --out data/synthetic_llm_logs.csv你将克隆配套仓库并使用固定种子重新生成包含50,000个用户的合成数据集,使你的结果与本文预期输出一致。
构建工作示例
本教程在共享数据集的用户协变量基础上添加三个模拟变量,通过代码构建完整的IV因果图:
- rate_limit_fallback : 工具变量 Z。作为纯伯努利(0.15)采样,完全独立于所有查询特征。
- routed_to_premium_actual : 内生处理变量 D。路由由查询置信度(可观测)和查询复杂度(不可观测)共同驱动,因此OLS存在偏差。
- task_completed_iv : 结果变量 Y。根据包含已知+6个百分点高级路由效应的IV因果图重新模拟,使你能够验证估计器能否恢复真实值。
透明性说明:在真实生产分析中,限速回退事件来自你的API网关日志。你的用户遥测表中不会包含这些数据。你需要将这两个来源合并以构建工具变量。
此处的模拟保留了真实工具变量的结构特性:它因基础设施原因触发,独立于查询质量,无需生产网关日志。
import numpy as np
import pandas as pd
import statsmodels.formula.api as smf
np.random.seed(42)
df = pd.read_csv("data/synthetic_llm_logs.csv")
rng = np.random.default_rng(99)
n = len(df)
未观察到的混杂因素:复杂查询更可能路由到高级服务但完成率更低
query_complexity = rng.normal(0, 1, n)
内生路由:依赖于query_confidence(可观测)
和query_complexity(不可观测):这是混杂结构
log_odds = -2.0 + 4.0 * (1.0 - df["query_confidence"]) + 0.6 * query_complexity premium_prob = 1.0 / (1.0 + np.exp(-log_odds)) df["routed_to_premium_iv"] = rng.binomial(1, premium_prob).astype(int)
工具变量:纯伯努利(0.15)分布,独立于所有查询特征
df["rate_limit_fallback"] = rng.binomial(1, 0.15, n)
实际路由:若意图路由到高级服务,除非降级机制覆盖
df["routed_to_premium_actual"] = ( df["routed_to_premium_iv"] * (1 - df["rate_limit_fallback"]) ).astype(int)
结果:已知因果结构,高级服务有+0.06效果
engagement_base = np.where(df.engagement_tier == "heavy", 0.70, np.where(df.engagement_tier == "medium", 0.55, 0.35)) completion_prob = np.clip( engagement_base + 0.06 * df["routed_to_premium_actual"] # 真实因果效应
- 0.04 * query_complexity # 未观察到的混杂因素
+ rng.normal(0, 0.02, n), 0.01, 0.99 ) df["task_completed_iv"] = rng.binomial(1, completion_prob).astype(int)
将参与度层级编码为虚拟变量
df = pd.get_dummies(df, columns=["engagement_tier"], drop_first=True) tier_dummies = [c for c in df.columns if c.startswith("engagement_tier_")] covariate_str = " + ".join(["query_confidence"] + tier_dummies)
print(f"限流降级比例: {df.rate_limit_fallback.mean():.3f}") print(f"实际高级路由比例: {df.routed_to_premium_actual.mean():.3f}") print(f"降级=1时置信度均值: {df[df.rate_limit_fallback==1].query_confidence.mean():.3f}") print(f"降级=0时置信度均值: {df[df.rate_limit_fallback==0].query_confidence.mean():.3f}")
预期输出:
限流降级比例: 0.151 实际高级路由比例: 0.271 降级=1时置信度均值: 0.716 降级=0时置信度均值: 0.715
在上述代码中,降级=1组和降级=0组之间几乎相同的置信度均值证实了工具变量与可观测路由信号的独立性。这是对任何候选工具变量都可以执行的独立性假设检验。query_complexity在该模拟中是可用的,但在生产环境中将是不可观测的。回归分析永远无法获取到它。
## 第一步:简单OLS(有偏基准)
首先运行标准回归可以建立一个基准,这个基准是你在未考虑混杂结构时会遇到的有偏估计。大多数工程团队会报告这个数值,却未意识到它在数学上是存在缺陷的。
ols_formula = f"task_completed_iv ~ routed_to_premium_actual + {covariate_str}" ols_model = smf.ols(ols_formula, data=df).fit(cov_type="HC3")
ols_coef = ols_model.params["routed_to_premium_actual"] ols_se = ols_model.bse["routed_to_premium_actual"] ols_pval = ols_model.pvalues["routed_to_premium_actual"] print(f"高级路由效果的OLS估计: {ols_coef:+.4f}") print(f"HC3标准误: {ols_se:.4f}") print(f"P值: {ols_pval:.4f}")
高级路由效果的OLS估计: +0.0327 HC3标准误: 0.0050 P值: 0.0000
以下是发生了什么:OLS 恢复了 +3.3 个百分点(概率单位,因为 task_completed_iv 是线性概率模型中的 0/1 二元结果)。真实的因果效应是 +6.0 个百分点。2.7 个百分点的偏差来自未观察到的查询复杂度路由:更难的查询被路由到高级服务,而它们的完成率更低,这是一个向下混淆机制。p 值看起来显著,标准误差看起来精确。这个输出中的任何内容都不会告诉你这个估计是错误的。
记住这个数字:第 2 步中的 2SLS 结果将揭示差距。
## 第 2 步:从零开始构建两阶段最小二乘法(2SLS)
两阶段最小二乘法通过隔离由限流回退生成的外生路由变化来纠正偏差,仅使用这种变化来估计因果效应。
### 第 1 阶段:从工具变量和协变量预测路由。
stage1_formula = f"routed_to_premium_actual ~ rate_limit_fallback + {covariate_str}" stage1 = smf.ols(stage1_formula, data=df).fit(cov_type="HC3")
print(f"Stage 1 instrument coefficient: {stage1.params['rate_limit_fallback']:+.4f}") print(f"p-value: {stage1.pvalues['rate_limit_fallback']:.4f}")
df["rtp_hat"] = stage1.fittedvalues
Stage 1 instrument coefficient: -0.3190 p-value: 0.0000
在这段代码中,你将内生路由变量对工具变量和第 2 阶段将使用的相同观测协变量进行回归。
拟合值 rtp_hat 包含两个部分:工具变量解释的外生变化,以及协变量解释的外生变化。
内生部分(与未观察到的查询复杂度相关的变异)保留在残差中,并从 rtp_hat 中被排除。rate_limit_fallback 的负系数验证了相关性假设:当回退触发时,高级路由概率下降约 32 个百分点。
### 第 2 阶段:用预测路由回归结果。
stage2_formula = f"task_completed_iv ~ rtp_hat + {covariate_str}" stage2 = smf.ols(stage2_formula, data=df).fit(cov_type="HC3")
tsls_coef = stage2.params["rtp_hat"] tsls_se = stage2.bse["rtp_hat"] print(f"2SLS estimate: {tsls_coef:+.4f}") print(f"Stage-2 SE (underestimate): {tsls_se:.4f}")
2SLS estimate: +0.0599 Stage-2 SE (underestimate): 0.0188
这里发生了什么:用 rtp_hat 替换 routed_to_premium_actual 去除了路由变化的内生部分。第 2 阶段系数(+0.0599)是高级路由对任务完成的因果效应的 2SLS 估计值,几乎正好是 +0.06 的真实值。
关于标准误差的一个重要注意事项:手动 2SLS 生成的第 2 阶段标准误差过小。第 2 阶段 OLS 将 rtp_hat 视为固定已知的回归变量,但实际上它是在第 1 阶段从数据中估计的。这种估计误差会增加一个方差成分,而第 2 阶段的残差永远无法看到这个成分。
在向利益相关者报告任何结果时,请使用 linearmodels.IV2SLS(见“下一步该怎么做”),它会计算正确的夹心方差。
### 并排比较 OLS 和 2SLS:
print(f"OLS estimate (biased): {ols_coef:+.4f}") print(f"2SLS estimate (IV): {tsls_coef:+.4f}") print(f"True premium effect: +0.0600") print(f"OLS bias: {ols_coef - 0.06:+.4f}")
OLS estimate (biased): +0.0327 2SLS estimate (IV): +0.0599 True premium effect: +0.0600 OLS bias: -0.0273
此处,OLS 低估了真实效应 2.7 个百分点(45% 的低估)。2SLS 将其恢复到仅差 0.01 个百分点的范围。误差方向与混淆机制一致:未观测到的查询复杂性会将困难查询路由到高级服务并降低其完成率,从而拉低 OLS 系数。
图 2:在 50,000 用户的合成数据集上的数据驱动结果。左图:按回退组划分的路由率验证了第一阶段关系:回退=0 的查询以 39.1% 的概率路由到高级服务,回退=1 的查询为 0%(完全覆盖)。右图:OLS 置信区间(红色)完全遗漏了真实 +0.06 个百分点的效果。2SLS 置信区间(绿色)覆盖了该效果。更宽的 2SLS 区间反映了仅依赖工具变量外生变异所带来的方差成本。
## 第 3 步:弱工具变量诊断
对结果影响微弱的有效工具变量属于弱工具变量。弱工具变量会导致 2SLS 估计值方差极大,在小样本中估计值会向 OLS 估计值漂移,这违背了工具变量的初衷。标准诊断方法是第一阶段 F 统计量。
stage1_restricted = smf.ols( f"routed_to_premium_actual ~ {covariate_str}", data=df ).fit()
f_stat, f_pval, _ = stage1.compare_f_test(stage1_restricted) print(f"第一阶段 F 统计量(工具变量):{f_stat:.2f}") print(f"p 值: {f_pval:.4f}")
if f_stat > 10: print("工具变量为强工具(F > 10)。2SLS 估计值可靠。") elif f_stat > 4: print("工具变量为临界弱工具(4 < F < 10)。需谨慎解释。") else: print("工具变量为弱工具(F < 4)。2SLS 估计值不可靠。")
print(f"\n第一阶段工具变量系数: " f"{stage1.params['rate_limit_fallback']:+.4f}")
第一阶段 F 统计量(工具变量):3780.94 p 值: 0.0000 工具变量为强工具(F > 10)。2SLS 估计值可靠。
第一阶段工具变量系数: -0.3190
在上述代码中,您通过 F 检验将完整的第一阶段模型(包含工具变量)与受限模型(不包含工具变量)进行比较。3780 的 F 值远超 Staiger-Stock 的经验法则。对 50,000 个观测值应用 15% 的回退率产生了大且估计精确的第一阶段效应。
在真实生产数据集上,若回退率较低或数据集较小,F 统计量会更低。如果 F 统计量低于 10,要么寻找更强的工具变量,要么在得出结论前增加更多回退数据。
工具变量强度与排除有效性之间存在权衡关系,这一点值得特别指出。您可以通过提高回退率使工具变量更强,但如果回退率过高影响用户体验,回退会通过满意度和重试行为直接影响任务完成度,这会违反排除限制。同时满足相关性和排除限制的强工具变量才是目标。
内生性方向检查:
gap = ols_coef - tsls_coef print(f"OLS 减去 2SLS 的差距:{gap:+.4f}") if abs(gap) > 0.005: print("差距表明 OLS 存在内生性偏差。") else: print("小差距:OLS 和 2SLS 大致一致。") print("如需正式的豪斯曼内生性检验,请使用 linearmodels IV2SLS。")
OLS 减去 2SLS 的差距:-0.0272 差距表明 OLS 存在内生性偏差。 如需正式的豪斯曼内生性检验,请使用 linearmodels IV2SLS。
以下是技术内容的中文翻译:
这里的关键在于:OLS与2SLS之间的差距是诊断内生性的指标。2.7个百分点的差距证实了路由变量确实与未观测的混杂因素存在相关性,且OLS吸收了部分混杂因素的影响。
要进行形式上有效的Hausman检验(即能生成具有已知分布的卡方统计量的检验),请使用linearmodels.IV2SLS内置的检验方法。上述方向性检查仅是一种快速诊断手段。
## 第4步:LATE才是你真正关心的指标
2SLS估计的是局部平均处理效应(LATE),也称为依从者平均因果效应(CACE)。LATE仅适用于依从者:即那些在工具变量触发时实际改变路由的特定查询子集。限流降级机制仅影响有资格获得高级服务且发生降级的查询,因此LATE特指该子群体。
compliers_mask = df["rate_limit_fallback"] == 1 complier_count = compliers_mask.sum() complier_pct = complier_count / n * 100
print(f"Approximate complier population: {complier_count:,} ({complier_pct:.1f}% of queries)") print(f"\nComplier mean confidence: {df[compliers_mask]['query_confidence'].mean():.3f}") print(f"Non-complier mean confidence: {df[~compliers_mask]['query_confidence'].mean():.3f}") print(f"\n2SLS LATE estimate: {tsls_coef:+.4f}") print("This is the causal effect of premium routing for queries rerouted") print("by rate-limit fallbacks, not all queries in the dataset.")
Approximate complier population: 7,575 (15.2% of queries)
Complier mean confidence: 0.716 Non-complier mean confidence: 0.715
2SLS LATE estimate: +0.0599 This is the causal effect of premium routing for queries rerouted by rate-limit fallbacks, not all queries in the dataset.
在该代码中,依从者群体包含7,575个查询(这些查询经历了限流降级并从高级路由切换到廉价路由)。他们的平均置信度(0.716)与非依从者群体(0.715)几乎完全一致,证实了降级机制与查询特征无关。
当依从者在可观测变量上看起来是全体查询的代表性样本时,LATE通常可以作为平均处理效应(ATE)的合理近似。
可观测变量的代表性满足最低诊断标准。正式的LATE到ATE条件要求要么所有单元的处理效应具有同质性,要么为总体中每个单元都存在有效工具变量。如果你的路由效应在查询类型间存在异质性(例如高级路由对复杂查询的帮助远大于简单查询),即使依从者与非依从者的平均置信度相似,LATE也可能与ATE产生显著偏差。
对于战略容量规划,这正是你需要的度量指标。当你考虑是否要投资扩大高级模型容量或调整限流策略时,你实际上是在询问当前受基础设施约束的查询的具体问题。2SLS能直接回答这个问题。
## 第5步:引导法置信区间
如第2步所述,手动2SLS生成的第2阶段标准误过小。引导法置信区间无需推导正确的解析方差公式,即可提供可靠的不确定性估计。引导法会同时对完整的两阶段过程进行重采样,捕捉两个阶段的抽样方差。
rng_boot = np.random.default_rng(7) ols_boot, tsls_boot = [], []
for _ in range(500): samp = df.sample(len(df), replace=True, random_state=int(rng_boot.integers(1_000_000_000)))
OLS bootstrap
ols_b = smf.ols( f"task_completed_iv ~ routed_to_premium_actual + {covariate_str}", data=samp ).fit() ols_boot.append(ols_b.params["routed_to_premium_actual"])
2SLS bootstrap (two stages together)
s1b = smf.ols( f"routed_to_premium_actual ~ rate_limit_fallback + {covariate_str}", data=samp ).fit() samp = samp.copy() samp["rtp_hat"] = s1b.fittedvalues s2b = smf.ols( f"task_completed_iv ~ rtp_hat + {covariate_str}", data=samp ).fit() tsls_boot.append(s2b.params["rtp_hat"])
ols_ci = (np.percentile(ols_boot, 2.5), np.percentile(ols_boot, 97.5)) tsls_ci = (np.percentile(tsls_boot, 2.5), np.percentile(tsls_boot, 97.5)) true_eff = 0.0600
print(f"OLS 95% CI: [{ols_ci[0]:+.4f}, {ols_ci[1]:+.4f}]") print(f"2SLS 95% CI: [{tsls_ci[0]:+.4f}, {tsls_ci[1]:+.4f}]") print(f"Ground truth: +{true_eff:.4f}") print(f"OLS CI covers ground truth: {ols_ci[0] <= true_eff <= ols_ci[1]}") print(f"2SLS CI covers ground truth: {tsls_ci[0] <= true_eff <= tsls_ci[1]}")
OLS 95% CI: [+0.0227, +0.0426] 2SLS 95% CI: [+0.0247, +0.0969] Ground truth: +0.0600 OLS CI covers ground truth: False 2SLS CI covers ground truth: True
在此代码中,OLS 的 95% 置信区间([+0.023, +0.043])完全未覆盖真实的 +0.06 效应。该区间内的所有值都低于真实值:OLS 的结果是明确错误的。而 2SLS 的置信区间([+0.025, +0.097])覆盖了真实值。它比 OLS 区间更宽,反映了工具变量估计的方差成本:你必须以精度为代价来换取有效性。
自助法在每次迭代中都会对两个阶段进行重采样,因此不确定性能够正确反映两阶段结构。在手动实现 2SLS 时报告结果时,应使用自助法置信区间,因为它们比第二阶段的参数化标准误更可靠。
## 当工具变量失效时
工具变量分析的失效模式比倾向得分或回归不连续性更隐蔽,因为四个假设中有两个无法仅通过数据验证。
### 弱工具变量
第一阶段的 F 统计量低于 10 表明存在严重的识别问题。弱工具变量会导致 2SLS 估计量方差增大,并在有限样本中向 OLS 偏移,重复有偏的基线结果,同时看似进行了更复杂的操作。在解释任何工具变量结果之前,请检查 F 统计量。
如果 F 小于 10,应寻找更强的工具变量,或在明确标注弱工具变量警告的情况下报告估计值。此处的工具变量较强(F = 3780),因为 15% 的回退率应用于 50,000 次查询,产生了 7,500+ 次路由变更。
### 排除限制违反
如果限流回退通过除路由决策以外的任何渠道影响任务完成,排除限制就会失效。
可能存在两种合理的违反情况:回退事件在高流量期间聚集,此时用户更可能执行复杂的批量作业,导致工具变量与查询难度相关。或者用户在经历回退后注意到响应质量下降并放弃会话,通过用户挫败感形成 Z 到 Y 的直接路径。
这两种情况都会违反排除限制,同时保持相关性。无法通过数据验证这些情况,必须依靠系统知识进行论证。
### LATE 与 ATE 的混淆
使用LATE估计来证明广泛的路由策略变更在合作者具有典型性时是错误的。如果限速回退对复杂查询造成不成比例的影响(因为复杂查询耗时更长且更可能在会话中途触发限速),LATE估计仅覆盖了对复杂查询子群体的高级路由因果效应。
将其报告为ATE会夸大所有查询都采用高级路由的收益。第4步中的合作者特征表是诊断依据:如果合作者和非合作者在可观测变量上相似,LATE是对ATE的可信近似。
### 违背者与单调性假设
LATE解释需要单调性假设:工具变量使所有受影响单元向同一方向移动。对于限速回退而言,这几乎必然成立,因为回退总是降低受影响查询的高级路由概率。
如果存在某种补偿机制(例如回退:一个查询触发下一个查询的优先级提升),就会出现违背者,单调性假设将被打破。在信任LATE之前需验证方向一致性。
## 下一步行动
本教程的手动2SLS实现虽然机制透明但会产生错误的标准误。对于任何向利益相关者报告或包含在发表分析中的结果,请使用linearmodels.IV2SLS:
生产级2SLS实现(标准误正确)
pip install linearmodels
from linearmodels.iv import IV2SLS
exog_vars = ["query_confidence"] + tier_dummies iv_model = IV2SLS.from_formula( f"task_completed_iv ~ 1 + {' + '.join(exog_vars)} " f"[routed_to_premium_actual ~ rate_limit_fallback]", data=df ).fit(cov_type="robust")
print(iv_model.summary)
以下是实现原理:linearmodels计算考虑两阶段结构的正确2SLS方差,执行完整的初阶段诊断摘要,并提供正式的Hausman内生性检验。语法通过[D ~ Z]括起内生变量和工具变量。
完整实现(包括引导置信区间和图2的可视化)见配套笔记本:github.com/RudrenduPaul/product-experimentation-causal-inference-genai-llm/tree/main/11_instrumental_variables/。克隆仓库、生成合成数据集并运行iv_demo.ipynb可完整复现所有代码块。
关于何时使用IV的最后提示:如果系统支持强制路由随机化(无论置信度如何随机分配部分查询到高级路由),标准A/B测试更简单且能提供全舰队ATE估计。
当随机化不可行时IV才是合适工具:当路由规则已嵌入生产逻辑、无法承担故意次优路由的代价,或需要使用历史观测数据时。如果能运行真实实验,请优先选择实验。
任何优化路由系统都存在混杂因素的结构性默认。标准回归将模型质量与查询固有难度合并为单一系数,在需要分离两者时同时测量两者。
限速回退提供了干净的自然工具变量,能过滤基础设施噪声并提取路由信号。这种方法为团队提供了可辩护的因果估计,准确衡量模型架构如何驱动商业价值。
我是应用人工智能/机器学习和营销测量科学领域的领导者,拥有15年以上在世界500强企业构建和扩展应用AI及机器学习产品的经验。我专注于因果推理、实验设计、智能体AI系统和企业级AI战略,研究领域涵盖零售媒体网络(RMN)、广告、广告技术、营销技术、消费品(CPG)和电子商务。我是Springer Nature、Elsevier、ICML(顶级AI/ML会议)和IEEE的出版作者,也是多家领先AI/ML和分析领域出版物的常驻撰稿人(观点仅代表个人)
如果这篇文章对你有帮助,请分享它。
免费学习编程。freeCodeCamp 的开源课程已帮助超过40,000人成为开发者。立即开始
广告