其实我根本就没用过DID,也是第一次听说安慰剂检验,完全Follow的这一篇文章:模型系列-DID入门(附Stata操作)
摘抄一下里面安慰剂检验的部分:
安慰剂检验核心思想即即虚构处理组进行回归。
第一步:选取政策实施之前的年份进行处理,例如,政策发生在2014年,研究区间为2013-2015年。我们可以把研究区间向前移动到2011-2013年,并假定政策实施年份为2012年,然后进行回归。
第二步:选取已知的并不受政策实施影响的群组作为处理组进行回归。
如果不同虚构方式下的DID估计量的回归结果依然显著,说明原来的估计结果很有可能出现了偏误。
此外还可以利用不同不同的对照组进行回归,看研究结论是否依然一致。或者选取一个完全不受政策干预影响的因素作为被解释变量进行回归,如果DID估计量的回归结果依然显著,说明原来的估计结果很有可能出现了偏误。
注:以上如果回归结果显著,说明原结果是一定有问题的,而如果回归结果不显著,并不一定能表明原结果没问题。
好像和叶老师上课讲的差不多。
Python实现(面板数据):
import pandas as pd from linearmodels import PanelOLS import numpy as np from matplotlib import pyplot as plt def random_treat_and_year(data, year): # 随机设定控制组,这个0.3是我随便设定的,可以让我的控制组数量和随机前相比差不多 arr = np.where(np.random.randn(data['id'].max())>0.3,1,0) mapping = lambda x: arr[x-1] data['Treatment'] = data['id'].map(mapping) mapping = lambda x: 1 if x >= year else 0 data['Post'] = data['year'].map(mapping) data = data.set_index(['id', 'year']) data['Treatment_Post'] = data['Treatment'] * data['Post'] return data # 返回一次结果的年份、p值、系数、标准差 # 包含固定效应 # y为因变量,X为自变量 def get_a_result(data, year): model = PanelOLS(data.y, data[X], entity_effects=True, time_effects=True) result = model.fit() return {'year': year, 'pvalue': result.pvalues[0], 'beta': result.params[0], 'se': result.std_errors[0]} # 每个年份随机抽N次 def work(data, start, end, n): li = [] for year in range(start, end): for i in range(n): data = random_treat_and_year(data, year) li.append(get_a_result(data, year)) data = data.reset_index() df = pd.DataFrame(li) return df # 读取数据 data = pd.read_excel('data.xlsx', sheet_name='data') start = 2010 end = 2018 n = 100 df = work(data, start, end, n) print(df.groupby('year').mean()) # 简易画图 plt.scatter(df.beta, df.pvalue) plt.show()
Comments | 4 条评论
博主 1185713860
你好,请问能提供一下data文件的格式嘛?我尝试按照您的代码操作,但我发现我并不能跑出结果,应该与id有关系,我不是很理解您这里面的id代表着什么,假如我有2个组100条数据,id是只有0和1,还是说id从1到100?如果是前者,arr数组里永远只有一个元素,因为np.random.randn至多生成1个数,所以arr[x-1]只有一个数
博主 傲娇的小基基
@1185713860 前几天阳了,都没力气打开电脑了……
博主 天迹
您好,我想知道data文件的结构是什么样的,我按照您的代码操作报错了,我发现问题可能在于data[id],我不太理解这个id指的是什么,我现在有2个组别一共100条数据,那id是0或1,还是从1-100呢?如果是前者的话,arr数组中就只有一个元素,arr[x-1]就永远是那个一个元素,这会非常的奇怪
博主 傲娇的小基基
@天迹 抱歉,这个数据我都不知道去哪里了……
id就是按顺序的从0开始的编号而已,没什么特别的
arr = np.where(np.random.randn(data['id'].max())>0.3,1,0)
这里面的
np.random.randn(data['id'].max())
只是生成了data[‘id’].max()个正态分布随机数,然后再把大于0.3的那几个赋值为1,当成treatment组