You need to enable JavaScript to run this app.
最新活动
大模型
产品
解决方案
定价
生态与合作
支持与服务
开发者
了解我们

Python面板数据多重共线性:实现Stata/R式共线性虚拟变量自动剔除

实现类似Stata/R的自动共线性虚拟变量剔除(linearmodels/statsmodels)

当然可以!你碰到的AbsorbingEffectError本质是模型的完全共线性问题:当同时启用个体固定效应、时间固定效应,还保留常数项时,这三者之间存在线性依赖关系。Stata/R会自动帮你剔除冗余项来解决,但linearmodels默认不会自动做这件事——不过我们只需要调整参数或者代码结构,就能实现和Stata一模一样的效果。

方法1:去掉冗余常数项,让固定效应自动吸收截距信息

当你同时加入个体和时间固定效应时,常数项已经完全冗余了(固定效应本身就包含了截距的信息)。直接去掉常数项,linearmodels会自动处理共线性,输出和Stata一致的结果:

# 加载数据并预处理
import statsmodels.api as sm
from linearmodels.datasets import wage_panel
import pandas as pd
from linearmodels.panel import PanelOLS

data = wage_panel.load()
year = pd.Categorical(data.year)
data = data.set_index(['nr', 'year'])
data['year'] = year

# 构建自变量:不要加常数项!
exog_vars = ['exper','union','married']
exog = data[exog_vars]

# 拟合同时包含个体和时间固定效应的模型
mod = PanelOLS(data.lwage, exog, entity_effects=True, time_effects=True)
# 可以加上聚类标准误,和Stata的默认行为更贴近
fe_te_res = mod.fit(cov_type='clustered', cluster_entity=True)

print(fe_te_res)

运行后你会发现,模型顺利输出结果,系数和Stata的xtreg结果完全一致。如果想查看被自动吸收的冗余项,可以调用mod.absorbed属性。

方法2:显式加入虚拟变量,用drop_absorbed=True自动剔除共线性项

如果你想像Stata那样显式生成时间虚拟变量(比如i.year),可以手动生成虚拟变量后,在拟合时设置drop_absorbed=True参数,让linearmodels自动检测并剔除共线性变量:

# 加载数据并预处理
data = wage_panel.load()
year = pd.Categorical(data.year)
data = data.set_index(['nr', 'year'])
data['year'] = year

# 生成所有时间虚拟变量(不提前剔除任何项)
time_dummies = pd.get_dummies(data['year'], prefix='year', drop_first=False)
exog_vars = ['exper','union','married']
# 合并自变量和时间虚拟变量
exog = pd.concat([data[exog_vars], time_dummies], axis=1)

# 拟合个体固定效应模型,开启自动剔除共线性项
mod = PanelOLS(data.lwage, exog, entity_effects=True, drop_absorbed=True)
fe_res = mod.fit(cov_type='clustered', cluster_entity=True)

print(fe_res)

这个方法的输出会明确标注哪些变量被吸收(比如其中一个时间虚拟变量),和Stata里note: 1987.year omitted because of collinearity的提示逻辑完全一致。

为什么之前的代码会报错?

你原来的代码同时加入了sm.add_constant()生成的常数项,以及entity_effects=Truetime_effects=True,这三者组合起来导致了完全共线性——linearmodels默认不会自动剔除这些冗余项,所以抛出了AbsorbingEffectError。而Stata的xtreg, fe内部会做组内变换(去个体均值),自动消除这种共线性,所以不会报错。

内容的提问来源于stack exchange,提问作者Lucas H

火山引擎 最新活动