固定效应数据分析示例1 —投资与市场价值
公司投资的主要驱动力是什么?有大量的文献讨论了其驱动因素。Grunfeld认为,公司的市场价值是投资的主要解释和预测指标。在以下练习中,我将使用Grunfeld数据集(可在statsmodels.datasets中获得)来演示固定效果模型的使用。顺便说一句,Grunfeld数据集是计量经济学中的知名数据集,就像Machine Learning中的虹膜数据集一样。这篇学术文章“ 50岁时的Grunfeld数据”指出了它的广泛用途。
该数据包含11家公司中每家20年的数据:IBM,通用电气,美国钢铁,大西洋炼油,钻石比赛,西屋电气,通用汽车,固特异,克莱斯勒,联合石油和美国钢铁。在面板数据中,将“确定”和“年份”设置为索引。固定效果模型指定如下,其中单个公司因子为𝝆_i或在以下代码中称为`entity_effects
。时间因子是𝝋_t或称为time_effects
。
或如下所示,其中D_j是公司i的虚拟变量,而I_t是t年的虚拟变量。
from statsmodels.datasets import grunfeld data = grunfeld.load_pandas().data data = data.set_index(["firm","year"]) print(data.head())
模块linearmodels
提供PandelOLS进行固定效果模型。entity_effects=True
表示模拟企业特定因素。这意味着为11家公司创建10(N-1)个虚拟变量。下面我展示了两种回归方法的代码。两者产生相同的结果。
# Coding method 1 from linearmodels.panel import PanelOLS import statsmodels.api as sm exog = sm.add_constant(gf[['value','capital']]) grunfeld_fe = PanelOLS(gf['invest'], exog, entity_effects=True, time_effects=False) grunfeld_fe = grunfeld_fe.fit() print(grunfeld_fe) # Coding method 2 grunfeld_fe = PanelOLS.from_formula("invest ~ value + capital + EntityEffects", data=gf) print(grunfeld_fe.fit())
“value”的系数在95%时具有统计学意义上的0.1101。因此,Grunfeld得出了因果关系,即高投资是由高市场价值驱动的。
下面的代码同时指定了公司特有的效果和时间效果。结论保持不变。
# Coding method 1 from linearmodels.panel import PanelOLS import statsmodels.api as sm exog = sm.add_constant(gf[['value','capital']]) grunfeld_fet = PanelOLS(gf['invest'], exog, entity_effects=True, time_effects=True) grunfeld_fet = grunfeld_fe.fit() print(grunfeld_fet) # Coding method 2 grunfeld_fet = PanelOLS.from_formula("invest ~ value + capital + EntityEffects + TimeEffects", data=gf) print(grunfeld_fet.fit())
固定收益数据分析示例2 –交通死亡率与啤酒税
更高的啤酒税是否有助于减少交通致死率?许多州降低了啤酒税,交通事故死亡率更高。我们可以说降低啤酒税会导致更高的死亡率吗?这种因果关系具有深远的政策含义。我将使用Stock&Watson广为接受的书籍“计量经济学概论”中的死亡数据集。
import pandas as pd import numpy as np import seaborn as sns fatalities = pd.read_csv('/fatality.csv') fatalities.head()
- mrall = 车辆总死亡率
- beertax = 酒精税
- mlda = 最低法定饮酒年龄
- jaild = 强制性入狱
- comserd = 强制性社区服务
- vmiles = 每位驾驶员的平均里程
- unrate = 失业率
- perinc = 人均个人收入
我将每年的数据生成平均值,以显示每年的平均啤酒税和死亡率。1982–1984年的平均啤酒税高于1986–1988年的啤酒税。
avg = fatalities.groupby('year')['mrall','beertax'].mean()
avg
我将使用`seaborn
来显示相关性。
sns.set(style="darkgrid") g = sns.jointplot("beertax", "mrall", data=avg, kind="reg", color="m", height=6)
我们可以建立任何因果关系吗?我将使用固定效果模型进行测试。下面,我演示了两个固定效果模型并用于讨论和汇总OLS。
- 模型 1: 实体效果+时间效果
- 模型 2: Entity_effects
- 模型 3: 汇总OLS
或如下所示,其中D_j是状态i的虚拟变量,而I_t是状态t的虚拟变量。
下面对州的不随时间变化的变量(例如州文化,州居民对饮酒的态度(可能是不随时间进行变化)等)进行控制。对所有州随时间变化的遗漏变量的时效控制。例如,宏观经济条件或联邦政策措施在所有州都是通用的,但会随时间而变化。
您可能会询问如何确认需要固定效果的模型规范。这是通过可合并性测试(Poolability Test)完成的。许多模块已经包含测试结果。用于F-test for poolability
并显示输出。这是对没有固定效果的原假设的检验。模型1中的F-test是40.158,p值是0.0,因此我们可以拒绝原假设,并得出固定效果模型规格合适的结论。
模型1:实体效果+时间效果
# Coding method 1 from linearmodels.panel import PanelOLS import statsmodels.api as sm exog = sm.add_constant(fatalities[['beertax','mlda','jaild', 'comserd','vmiles','unrate','perinc']]) fe = PanelOLS(fatalities['mrall'], exog, entity_effects=True, time_effects=True) fe = fe.fit() print(fe) # Coding method 2 from linearmodels.panel import PanelOLS fe = PanelOLS.from_formula("mrall ~ beertax + mlda + jaild + comserd + vmiles + unrate + perinc + EntityEffects + TimeEffects", data=fatalities) print(fe.fit())
模型1告诉我们,啤酒税与死亡率之间存在负相关关系(啤酒税系数为-.4649)。因此,我们可以得出因果关系,即较高的啤酒税会导致较低的死亡率。
模型2:Entity_effects
如何理解三个模型中的R-squared值?模型1中的R-squared为0.3577,高于模型2中的R-squared0.1286。这意味着模型1的拟合效果更好。模型3中的0.4662怎么样?尽管它比模型1和2的模型高得多,但是合并的OLS是一个错误指定的模型,如上面的公式(1)和(2)所述。由于模型3无法解决内生性问题,因此它无法帮助我们得出啤酒税和死亡率之间的因果关系。
# Coding method 1 from linearmodels.panel import PanelOLS import statsmodels.api as sm exog = sm.add_constant(fatalities[['beertax','mlda', 'jaild','comserd','vmiles','unrate','perinc']]) fe2 = PanelOLS(fatalities['mrall'], exog, entity_effects=True, time_effects=False) fe2 = fe2.fit() print(fe2) # Coding method 2 from linearmodels.panel import PanelOLS fe2 = PanelOLS.from_formula("mrall ~ beertax + mlda + jaild + comserd + vmiles + unrate + perinc + EntityEffects", data=fatalities) print(fe2.fit())
模型3:汇总OLS
# Coding method 1 from linearmodels.panel import PanelOLS import statsmodels.api as sm exog = sm.add_constant(fatalities[['beertax','mlda', 'jaild','comserd','vmiles','unrate','perinc']]) pooledOLS = PanelOLS(fatalities['mrall'], exog, entity_effects=False, time_effects=False) pooledOLS = pooledOLS.fit() print(pooledOLS) # Coding method 2 from linearmodels.panel import PanelOLS pooledOLS = PanelOLS.from_formula("mrall ~ beertax + mlda + jaild + comserd + vmiles + unrate + perinc ", data=fatalities) print(pooledOLS.fit())