未定の部屋

主にデータサイエンス関係の記事を書きます

Pythonで因果分析

※2021年5月に書いた記事を再投稿したものです

内容

今回は『つくりながら学ぶ! Pythonによる因果分析 ~因果推論・因果探索の実践入門 (Compass Data Science)』(小川雄太郎)という本を読みました。

概要

因果推論については、以前『岩波DS vol.3』でざっと触れたことがあったのですが、実際に実装した経験はなく、何となく知っている程度でした。 この本は因果推論と因果探索についての入門的内容が幅広く含まれていて、さらにはPythonによる実装もあったので、自分の痒い所に手が届くような内容でした。

因果推論

因果推論の部分は、因果効果の指標(ATE、ATT、ATU)、介入、バックドア基準、因果ダイアグラムといった基礎となる概念的な説明と、具体例を交えた実装に分かれていました。

概念の部分で気になったのは、「強い意味での無視可能性」というワードがなかったことです。岩波では明確に説明があって、RCT(ランダム化比較実験)ができない場合に観測値から因果効果を推定するために必要な仮説といった書かれ方をしています。この本では、こういった因果推論をする際の前提条件みたいな部分に対する記述が少なく、読みやすくはありますが業務で実際に適用するときは仮説や前提条件について慎重に検討していく必要性を感じました。

実装は、回帰分析での実装、傾向スコアを用いた逆確率重み付け法(IPTW法)での実装、Doubly Robust法(DR法)での実装、機械学習を用いた実装の紹介がされていました。

重回帰の実装では処置群と対照群を区別せずに回帰分析をしていました。本書では記述がなかったのですが、恐らく前述の強い意味での無視可能性に加えて、処置群と対照群で共変量→結果変数の影響度が同じという仮定をしているのだと思います。

IPTW法は、傾向スコアの逆確率で重みを付けて平均を取ると結果変数の推定値になる、という部分がスッキリと飲み込めないんですよね。岩波DSと本書ではATEの推定値の導出の流れが違うのですが、どちらを読んでも完璧にはスッキリできませんでした。どちらの書籍もしっかりとした式の導出ではなく一部飛躍があるので、しっかり理解するにはさらに別の因果推論の書籍などを参照する必要がありそうです。自分がググれた範囲だと、Nが十分大きいときに、

\displaystyle{\frac1{N} \sum_{i=1}^n \frac{z_i}{e(x_i)} → 1}

\displaystyle{\frac1{N} \sum_{i=1}^n \frac{1-z_i}{1-e(x_i)} → 1}

(e(x_i): 被験者iの傾向スコア, z_i: インディケータ変数)

となるらしく、この式がATEの推定に関わってきそうだな~という感じはするのですが、今の時点でこれ以上分かりませんでした。

DW法は、回帰分析とIPWの式を組み合わせていて、回帰モデルの予測値か傾向スコアの推定値のどちらか一方が正しければ推定できる方法で、よりロバストな推定と言えます。これに関しても式の導出や意味合いは雰囲気でしか分かっていません。

機械学習を用いた実装は、線形回帰の代わりにランダムフォレストを用いた回帰分析の話をした後に、Meta-Learnersの実装やDoubly Robust Learnersの実装が記述されていました。機械学習部分はランダムフォレストで実装していますが、他の手法でも良いみたいです。機械学習での因果推論は、非線形な処置効果や因果推論にも使えるのでより適用範囲が広そうだと思いました。また、この章では処置群と対照群でモデルを分けていることもあり、前述のような一つのモデルで線形回帰する場合に比べて弱い仮定でも適用できる感じがします。Meta-Learnersの中には傾向スコアのを利用するものと、利用せず単に回帰モデルの式が非線形になったバージョンがありました。Doubly Robust LearnersはDW法を機械学習でやったバージョンなのですが、ITE(個別の因果効果)の式がDW法のATE(全体の因果効果)の式と少し異なっているのが腑に落ちなかったです。ITEとATEだから違うのか、モデルや仮定が若干違うのか、この辺りはよく分かりません。

因果探索

因果探索の部分は、因果推論の部分よりさらにざっとした説明で、雰囲気を掴むことを目標としている感じでした。なので、数式や原理の理解というよりはこんなこともできるんだ∼くらいの認識で読み進めました。因果探索は、その名の通り、変数間の因果関係を探索することを指していて、因果推論の前段階の話、に該当すると思います。

因果探索の種類として、本書ではLiNGAM(Linear Non-Gaussian Acyclic Model)、ベイジアンネットワーク、ディープラーニングの3つの手法での実装例が紹介されています。

LiNGAMは誤差項が非正規分布に従う、因果効果は線形である、ということを仮定した因果探索で、独立成分分析利用して上手く行列を作り、因果関係を明らかにするといった内容でした。

ベイジアンネットワークは構造方程式の代わりに条件付き確率表を使うという特徴があり、DAG(Directed Acyclic Graph;有向非循環グラフ※)を探索する過程でスケルトン(無向グラフ)、PDAG(Partially DAG;一部が有向になったグラフ)を構築します。この本では、独立性の検定を繰り返してスケルトンを構築し、その後オリエンテーションルールによって方向付けを行う手法が実装されていました。スケルトンを構築する部分はPCアルゴリズムと呼ぶらしいです。この章の最後に、変数消去アルゴリズムを使って推定したベイジアンネットワークから未知データを推論する例も紹介されていました。 ※各変数間が矢印の関係でむすばれており、変数同士で循環しない、いわゆる因果ダイアグラムの説明でよく見かける図

ディープラーニングでの実装は、画像生成などで使われているGAN(Generative Adversarial Networks)を因果探索に応用したSAM(Structural Agnostic Model)が解説されていました。ざっくりと言うならば、データを識別する機構と生成する機構をそれぞれ作り、識別器は観測データと生成データを識別できるように、生成器はより観測データにちかいデータを生成するように更新されていきます(これはGANのアルゴリズムと同じです)。このとき、生成器の中に因果ダイアグラムを推定する構造を追加し、学習させることで因果探索を行います。

自分の解釈ですが、生成器と識別器を更新していって精度を上げていくと生成器の中の因果ダイアグラムもよりモデルとして精度が上がっていくので、学習が終わった時の因果ダイアグラムを推定する部分を取り出すことで因果探索ができるのだと思います。また、損失関数として、識別器・生成器の学習を促す関数・因果ダイアグラムがDAGになるように促す関数・なるべくシンプルな因果ダイアグラムになるように促す関数の3種類を導入することで上手く学習させているというような理解をしました。

Pythonによる実装もあったのですが、この章の実装はさっぱり分かりませんでした。

感想と今後

全体的に浅く広く入門するといった内容でしたが、本のコンセプトの割にはそれなりに深く読み込んで行けたかなと思います。どんなことをやっているのか、Pythonで具体的にどんな感じで実装をするのか、といったことは何となく理解できました。 社会人になって二か月が経ちましたが、独学環境ではなくなり、研修内容や先輩方、同期を通してデータサイエンスやビジネス関連の読みたい本や学びたいトピックが大幅に増えました。一人で勉強するより圧倒的に視野が広がった感じがしてすごく嬉しいです。 今後はいよいよ実務でデータ分析をやっていくと思うので、業務内容を鑑みながら学びたいトピックに優先順位をつけて上手く業務に活かしていけたらなと思っています。学んだトピックは、アウトプットとしてちょくちょくブログで発信していきたいです。

ではでは~