Open5
Synthetic Control Methodについて
合成コントロール法についてまとめる。
参考文献
概要
- 処置前の処置群の
について、処置前の比較群のy_t, x_t の重み付き平均でモデリングする。y_t, x_t - 重み
の条件は以下の通りw_i \sum_i{w_i} = 1, w_i \ge 0
- 重み
- 上述の重みを条件付き回帰で求める。
- 求めた重みを使って処置後の処置群の反実仮想を求める。
- 算出した反実仮想と処置後の処置群の実測値を比較して因果効果を算出する。
注意点
- 共変量は介入の影響を受けてないものを使用する
- プラセボの分布を確認して、得られた差分が有意なものかどうかを確認すべき、とのこと
Pythonでの実装
-
- コードを見る感じ、sklearnのLasso, Ridge回帰で係数を求めているっぽい?
-
OscarEngelbrektson/SyntheticControlMethods
- 2021年で更新が止まっているが、SparseSCよりもstarは多いっぽい
- scipyのoptimizeを使って係数を求めている。
-
- pymcベースな因果推論パッケージ。合成コントロール以外の手法も実装されている。
SparseSCの実装1
ここではSparseSCでの実装を紹介する。
特徴量を用いずに被説明変数のみで反実仮想の生成を行う場合は、SparseSC.fit_fast
が利用しやすい。
データセットは以下のように、行がユニット、列が時間、値が被説明変数となる行列(ピボットテーブル)を渡す必要がある。
import SparseSC
event_start_date = '2024-04-01'
features = data.iloc[:, data.columns < event_start_date].values
targets = data.iloc[:, data.columns >= event_start_date].values
treated_units = [idx for idx, val in enumerate(data.index.values) if 'test_unit' in val]
sc_model = SparseSC.fit_fast(features=features, targets=targets, treated_units=treated_units)
# 反実仮想の予測
y_pred = sc_model.predict(data.values)[treated_units, :][0]
SparseSCの実装2
ここでは被説明変数に加えて、共変量を利用して反実仮想の生成を行う。この際は SparseSC.estimate_effects
を利用する。
必須となる引数について補足する。
- outcomes (np.array or pd.DataFrame with shape (N,T)) -- Outcomes
ユニット数 x 期間の行列を指定する。
- unit_treatment_periods (np.array or pd.Series with shape (N)) -- Vector of treatment periods for each unit (if a unit is never treated then use np.NaN if vector refers to time periods by numerical index and np.datetime64('NaT') if using DateTime to refer to time periods (and thne Y must be pd.DataFrame with columns in DateTime too)) If using a prospective-based design this is the true treatment periods (and fit will be called with pseudo-treatment periods that are T1 periods earlier).
ユニット数の配列を用意します。処置を受けたユニットは処置が始まった期間を、処置を受けていないユニットはNanとなります。
covariates (np.array or pd.DataFrame with shape (N,K), Optional) -- Additional pre-treatment features
必須ではないですが、共変量を利用する際はcovariatesで指定します。ユニット数 x 共変量の数の行列を指定します。
import SparseSC
res = SparseSC.estimate_effects(
outcomes=y
, unit_treatment_periods=np.array([event_start_date, np.nan, np.nan, np.nan, np.nan, np.nan])
, covariates=X
)