はじめに
こちらの記事でSurrogate indexについて初めて知りました。
Netflixでも活用されていて、一定の成果を上げているようです。
業務で扱う課題を解決してくれる可能性があったため、理解しておきたいと思いました。
論文等を読みつつRで挙動などを確認していきます。
概要
元の論文はこちらです。
よりわかりやすい説明は冒頭のブログ記事を参照してください。
課題感
施策の因果効果を検討するときに、A/Bテスト等を行う場合があります。
しかし、この時に検証する因果効果は短期的なものであるときが多く、長期的な因果効果を測るのは難しい場合が多く存在します。
施策の長期的な影響を測るためには、時間がかかることや単純な中間指標を用いたような推定では不正確な場合があるためです。
そこで短期的な実験の結果を利用して、長期的な因果効果を算出することを考えています。
方針
基本的な方針は、短期に観測される中間指標を多く組み合わせた結果変数「代替指標(Surrogate index)」を作成し評価をしていきます。
この時に、それぞれの変数に統計的な代用性があるかには注目せずに、複数の中間変数があることが重要になります。
具体的には、複数の中間指標を説明変数とした線形回帰を用いて長期の結果の予測値を形成し、その予測値に対して治療効果を推定することになります。
多くの変数を組み合わせることで、処置から長期結果は生まれるまでの全ての因果経路を網羅する可能性が高まる。
これにより、長期的な治療効果をより迅速かつ正確に推定できる(標準誤差が小さくなる)可能性があります。
この時、もし処理の効果が短期的にはプラスであっても長期的にはマイナスであったり、先物喰いがある場合には短期の代替指標の長期結果への影響が小さく、長期の代替指標の長期結果への影響が大きく評価されることになる。
仮定
はじめに2つの異なるデータセットを持っていると仮定する。
これらのデータに対してルービンの因果モデルに従った潜在的な結果変数が二つ存在する。
今回は実験データセットにおける因果効果を推定したい。
しかし、実験開始から長時間が経過しないと得られないため、代理変数を用いることになる。
Surrogate indexを用いて因果関係を推定するには 3 つの仮定が必要となる
仮定1 強く無視できる割り当て条件
実験グループにおいて、処置に関する背景情報を調整することにより、処置の平均的な因果関係を推定できることを意味する。
ここでは、処置を受ける条件付き確率:傾向スコア。
仮定2 代理性
代理変数を用いて、処置効果を推定するためには、代理変数と結果変数の間の因果経路を補足している必要がある。
これは実験グループにおいて、効果処置とが代理変数や共変量により独立になることに対応する。
操作変数法における除外制約に相当する。
仮定3 互換性
以上の仮定に加えて実験サンプル()と観察サンプル()の関係を定義する必要があります。
の関係を推定するために、実験サンプルと観察サンプルにおける結果変数の条件付き確率分布が一致することが求められます。
この仮定は次のように言い換えることができます。
定義
Surrogate indexを用いて処理効果ATEを推定するには、いくつかの値の定義がされています。
Surrogate index:代理指数
代理指数)は、観察サンプルの中間変数と共変量を考慮した場合の結果変数の条件付き期待値です。
線形モデルでは、中間指標、共変量に対する主な結果の回帰からの予測値となる。
代理スコア:Surrogate Score
代理スコアは、代理指標と共変量の値が与えられた場合の処置を受ける条件付き確率
傾向スコアと同様に、代理スコアは多次元の統計的な情報をスカラーに変換し、他のサンプルとの比較を簡易的にできる。
Sampling Score
観察サンプルと実験サンプルを比較できるようにする重み。
潜在的条件付き期待値
治療前の変数とサロゲートが与えられた場合の潜在的な結果の条件付き期待も考えておく。
関係性
以上の定義と仮定から以下のような関係も導かれる
(i) 仮定2 が成り立つと仮定
(ii) 仮定3 が成り立つと仮定
(iii) 仮定2と3 が成り立つと仮定
因果効果の推定
最終的な平均処置効果の推定方法を3種類提案している。
複数の推定方法があることで、実験やデータの取得状況で推定方法を変えることができるため。
一つ目の表現は、実験サンプルにおいてSurrogate indexで推定されたものとコントロールとの間の違いを傾向スコアで調整している。
この表現では代替指数の推定が必要だが、代替スコアを推定する必要がない。
ここでは観測サンプルで得られた代理指標の確率分布/統計モデルである。 所謂IPWによる推定に対応している。
第二の表現では観察サンプルの結果 2 つの加重平均の差の期待値として書かれる。 重みは、実験サンプルとサンプリングスコアで推定された代理スコアの関数です。
この方法では代替スコアの推定が必要であるが、代替指数を推定する必要がない。
第三の表現では両方の推定が必要です。
は次のように定義される。
ここで は、実験サンプルと観測サンプルのどちらに該当するかを示すインデックスである。
仮定 1 ~ 4 が成立する場合、平均治療効果は、データの次の 3 つの推定可能な関数と等しくなります。
論文での適用事例
論文では、扶養家族手当の受給による雇用率の改善に関するデータに対して適用されています。
参加者のうち22%が雇用され、ランダム割り当て前の四半期の平均収入は453ドルでした。
処置グループには4405人、対照グループには1040人の参加者が含まれていました。
処置の割り当ての後9年間、失業保険データベースからの四半期ごとの雇用率と収益を測定し、研究参加者を追跡しています。
プログラムの雇用率と収益に対する処置効果は最初は大きかったものの、時間とともに低下していました。
そのため短期の雇用への影響を代理指標として使用することで、9年間の雇用全体への影響をより迅速に推定できる可能性があるかどうかを検証しています。
なお、結果変数の推定には線形回帰モデルを利用している、
そして、因果効果は次のように算出される
結果として推定された9年間の全体の雇用への影響は+6.2%であった。
Surrogate indexを利用した推定では、ナイーブな推定よりも早い段階でバイアスの小さい推定が行うことができている。 ナイーブな推定:処置実施後tステップ後の雇用率の単純な差
信頼区間の推定も可能。
Rで確認
Rでサンプルデータを作成してSurrogate indexを試してみました。
残念ながらパッケージはありませんでしたが、Susan Athey自身がRでの実行を解説しているページがありましたので、こちらのページを参考にしています。
データの生成
以下のようなデータを生成しました。
生成したサンプルは観測データ、実験データともに2000としています。
は設定しているそのタイミングの処置効果です。
そして観測期間は10ステップとして、9ステップ目まではそれまでの結果変数の平均値を中間指標、10ステップ目までの平均値を結果変数としている。
推定
推定には、単純な観測時刻の期待値からの算出を行うナイーブな場合、 Atheyのコードに習った回帰モデルを用いたSurrogate Indexを用いる場合、 Surrogate Indexを用いたIPW推定型を用いる場合の3パターンを試した。
なかなかのクソコードです。
y_reg = list() surrogate_index = list() surrogate_score = list() sampling_score = list() propensity_score = list() naive_index = list() emp_weight_p = list() emp_weight_se = list() for (i in 1:10) { if (i >1){ example_df[,paste("Y", i, sep="")] = example_df[,paste("Y", i, sep="")] + example_df[,paste("Y", i-1, sep="")] observed_df[,paste("Y", i, sep="")] = observed_df[,paste("Y", i, sep="")] + observed_df[,paste("Y", i-1, sep="")] } } all_df = bind_rows(example_df, observed_df) ## Store regressions for (i in 1:9) { y_reg[[i]] = lm(formula = S_eq(i), data = observed_df) #%>% step(direction = "both") emp_weight_p[[i]] = as.matrix(y_reg[[i]]$coefficients) emp_weight_se[[i]] = confint(y_reg[[i]]) example_df[,'y_surrogate'] = predict(y_reg[[i]], newdata = example_df) surrogate_index[[i]] = lm("y_surrogate ~ W", data = example_df) surrogate_score[[i]] = glm(formula = SS_eq(i), data = example_df, family = binomial(link = "logit")) #%>% step(direction = "both") sampling_score[[i]] = glm(formula = SP_eq(i), data = all_df, family = binomial(link = "logit")) example_df[, paste('surrogate_index',i, sep="")] = predict(y_reg[[i]], newdata = example_df) observed_df[, paste('surrogate_score',i, sep="")] = predict(surrogate_score[[i]], newdata = observed_df, type="response") observed_df[, paste('sampling_score',i, sep="")] = predict(sampling_score[[i]], newdata = observed_df, type="response") if(i ==1){ propensity_score_model = glm(W ~ X1+X2+X3+X4+X5, data = example_df, family = binomial(link = "logit")) #%>% step(direction = "both") observed_df[,'obs_propensity_score'] = predict(propensity_score_model, newdata = observed_df, type="response") example_df[,'exp_propensity_score'] = predict(propensity_score_model, newdata = example_df, type="response") } }
初めに処置の割り当てはランダム()といして、いくつかのパターンで確認した。
各グラフにおける棒グラフは、設定していたそれぞれの段階での因果効果である。
1番上が処置実施直後は効果が高くその後緩やかに低下してく場合、2番目が先物喰いの状態、3番目が処置実施直後はマイナス効果でありその後プラス効果に転じる場合、4番目が施策効果は経過時間によらず一定の場合という仮定である。
この時、先物喰い状態の実験における代理指標を表現する回帰係数を確認すると、設定した効果とは異なる傾向があることが確認できる。
多重共線性が強いために推定が安定していないためだと考えられる。
本来ならRedge回帰などを用いる方がよさそう。(論文でもそのように提案している)
次に、処置の割り当てが共変量により影響を受ける場合を確認した。
処理の割り当て確率は以下のように共変量に基づいて決まるとした。 Zに誤差項を設定しなくてもよかったが、傾向スコアに偏りシミュレーションの結果が安定しない状態を避けるために入れている。
こちらも1番上が処置実施直後は効果が高くその後緩やかに低下してく場合、2番目が先物喰いの状態、3番目が処置実施直後はマイナス効果でありその後プラス効果に転じる場合、4番目が施策効果は経過時間によらず一定の場合という仮定である。
IPWタイプの推定だと、比較的バイアスの少ない推定ができている。 しかし、詳細は割愛するが推定された傾向スコアの分布が極端な場合(0or1付近に山がくる状態)に近づくと推定が安定せずバイアスが大きい状態になった。
所感
直近の結果に引っ張られすぎない保守的な結果を示す傾向があると言えるのではないでしょうか。
具体的な効果の大きさを判断するにためにはある程度の観測期間が必要ですが、効果の最低レベルを推定することができるため、明らかに負の影響がある場合にテストの早期停止などが可能だと考えます。
また3つの仮定を満たしているかを確認することは難しいため、実際に利用するには比較的定常性のある時系列の指標に対するA/Bテストに限られるかもしれません。