两组回归系数是否真的不同:交互项与Wald检验示例
论文里最常见的一句错话是:「男性样本中 X 的系数显著,女性样本中不显著,说明 X 对男性的影响更大。」
这句话推不出结论。两组分别回归、一组 p < 0.05、另一组 p > 0.05,只能说明「在男性样本里我们没能拒绝零假设」,不能说明「两个系数不相等」——两组系数的差异本身可能完全不显著。要回答「是否真的不同」,得把这个差异当成一个待检验的参数,而不是比较两个 p 值。
为什么「一组显著、一组不显著」推不出差异显著
两组分开回归时,各自的标准误只用到自己那部分样本。样本量小的一组,置信区间宽,p 值容易偏大;这不代表它的系数更小,只代表估计更不确定。当两个系数各自的置信区间都覆盖真值时,它们的差完全可能为零。
更要命的是,两个系数并不独立——如果两组共享同一批控制变量、同一时期的宏观冲击,两个估计量之间存在协方差。分开跑两个模型,软件不会给你这个协方差,你也就没法算出差的标准误。所以「比较 p 值」这条路的根本问题是缺少协方差信息,不是阈值选得不对。
正确做法:合并样本,把「差异」变成一个系数
把两组数据合并,加一个分组虚拟变量 G(0/
1),再让它与核心解释变量 X 相乘,回归式写成:
Y = β0 + β1·X + β2·G + β3·(X×
G) + 控制变量 + ε
此时 β1 是基准组(G=0)的斜率,β1+β3 是另一组的斜率,而 β3 正好就是两组斜率之差。检验「两组是否不同」等价于检验 H0: β3 = 0——一个系数的 t 检验就够了,而且这个检验自动用上了合并样本的完整协方差结构。
这个等价关系是整件事的关键:它把「两个模型的比较」降维成「一个模型里的一个系数」。分组变量本身(β
2)也要留在模型里,否则交互项的系数会吸收两组截距的差异,估计出乱七八糟的东西。
Python 里怎么写:三行核心代码
用 statsmodels 的公式接口最省事,分组变量用 0/1 数值或分类变量都行:
x * g 在公式语法里会同时展开主效应与交互项,等价于 x + g + x:g。如果只想看交互项而不想要主效应(一般不该这么做),用 x:g。
再用 Wald 检验把同一个假设验一遍,顺便拿到 F 统计量:
statsmodels 文档对这个方法的定义是:Compute a Wald-test for a joint linear hypothesis。也就是说它可以一次检验多个线性约束,不止一个系数。
wald_test 的三种 r_matrix 写法
wald_test(r_matrix, cov_p=None, invcov=None, use_f=None, df_constraints=None, scalar=True) 的第一个参数有三种形态,各有适用场景:
第一种是字符串,直接写假设,例如 "x:g = 0",或同时写多条 "x:g = 0, z = 0"。日常用这种最直观。
第二种是数组(r×k 矩阵,r 是约束个数、k 是回归元个数)。文档说明这种写法下「It is assumed that the linear combination is equal to zero.」——即数组形式只表达「等于零」的零假设,要检验「等于某个非零值」得换第三种。
第三种是元组 (R,
q),R 是约束矩阵、q 是约束值(标量或长度为 p 的行向量)。要检验 β3 = 0.5 这类非零假设时用这种。
两个参数容易踩坑。use_f:文档写明「If use_f is None, then the F distribution is used if the model specifies that use_t is True.」,也就是说 OLS 默认走 t 分布,use_f=None 会落到 F 分布上;显式设 use_f=False 则用渐近的卡方分布,样本大时两者接近,样本小的时候 F 更保守。cov_p:不传就用模型自带的协方差矩阵;如果你用了聚类稳健标准误,务必确认这里用的是同一个稳健协方差,否则 Wald 统计量与前面的 t 检验会对不上。
还有一个前提写在文档的 Notes 里:The matrix r_matrix is assumed to be non-singular.。约束矩阵秩亏(比如同一约束写了两遍、或与其它约束线性相关)时结果没有意义。
用模拟数据验证一次
光看公式不容易相信,跑一遍模拟最直接。构造两组样本,让两组斜率真相同,重复 1000 次,看交互项显著的比例是不是接近 5%:
第一行是检验的水平(size),第二行是功效(power)。如果第一行跑出 0.2 这种数,说明代码或模型设定有问题,不是数据的问题。
再用两组分开回归做一个对照,你会看到「一组显著一组不显著」在 b3 = 0 时同样经常出现——这正是那句错话的来源。
四个常见错法
第一,分开跑两个模型然后比 p 值。缺少协方差,差异的标准误无从计算。
第二,只报「显著/不显著」的分类结论,不报系数差与置信区间。审稿人要看的是差值多大、区间多宽,而不是两个星号。
第三,交互项模型里漏掉分组主效应。漏掉之后交互项会同时承载截距差异,系数解释跟着变。
第四,用 x:g 代替 x*g 又忘了主效应,导致「基准组斜率」无法解释,读者不知道 β3 相对于谁。
适用边界
这套做法限定在线性回归(含 OLS、加权最小二乘)与线性假设上:交互项结构与 Wald 检验都依赖模型是线性的。换成 logit、probit 这类非线性模型时,交互项的系数不等于「两组边际效应之差」,需要算平均边际效应再作差(statsmodels 里可用 get_margeff 或 marginaleffects 一类工具),Wald 检验也要作用在边际效应上而不是原始系数上。
另外,如果你的标准误是聚类稳健的(比如按省份聚类),交互项的协方差必须用同一套聚类方差估计,wald_test 的 cov_p 要显式传入
m.cov_params(),否则会出现「t 检验显著、Wald 检验不显著」的假矛盾。
────────────────
回复本帖,可见 statsmodels 这份 wald_test 文档的官方入口与相关方法(f_test、t_test、t_test_pairwise)链接、r_matrix 三种写法的完整示例代码、稳健与聚类协方差的传参写法,以及水平与功效两段模拟脚本的完整版本,方便你把上面的检验套到自己的分组回归上。
把经管之家装进你常用的 AI 智能体中 一键快捷安装经管之家 MCP/技能,让 AI 帮你查教程、找数据、读论坛帖子。 检索、阅读公开帖子不收费,安装可申请领取:3 通用积分+100 论坛币+3 元论坛资金 请点击查看安装教程与福利 → 说明: AI 算力按所用平台规则计算;附件按原帖条件获取;福利领取条件以活动页面为准。 |