統計的因果探索の勉強を始めたので、その基本的な手法であるLiNGAMを理論に沿って整理します。
数学的な議論は厳密なものではありません。詳しく知りたい方は以下の参考文献を参照してください。
間違っている箇所や気づいたことがあればご指摘いただけると幸いです。
参考文献
LiNGAMモデルの元論文
https://www.jmlr.org/papers/volume7/shimizu06a/shimizu06a.pdf清水昌平 「統計的因果探索」, 講談社
www.kspub.co.jp
上論文のFirstAutherである清水昌平先生によって書かれた著書です。LiNGAMモデルを含む統計的因果探索の基礎を極めて丁寧に解説されています。適応型Lasso回帰の元論文
http://users.stat.umn.edu/~zouxx019/Papers/adalasso.pdfLiNGAMのライブラリ
https://github.com/cdt15/lingam
LiNGAMの仮定
LiNGAMモデルでは以下の構造方程式について考えます。
は観測変数、は観測変数の個数、は観測変数がに及ぼす直接的な影響の大きさを表す係数、は誤差変数を表しています。
これは行列表現で
と書けます。
LiNGAMはの分布を入力としての値を一意に推定できます。
また、LiNGAMは次のような仮定を置いています。
- 各変数は連続変数である。
- は互いに独立である(=未観測共通原因が存在しない)かつ非ガウス分布に従う。
- 観測変数が他の観測変数と誤差変数の線形和で表現される。
- 観測変数は非巡回である。
データ生成過程
説明に用いるデータ生成過程の例は以下のものとします。
DAGは以下のようになります。
独立成分分析の導入
を求めるために、まずは行列式をについて解きます。
をと置いて
さらにの逆行列をとして
となり、がわかればをもとめることができそうです。
これを解くために独立成分分析(Independent component analysis, ICA)という手法を援用します。
ICAは主に信号源分離に用いられている計算手法です。
観測変数ベクトルが、非ガウス分布に従う独立成分ベクトルと係数によって生成されるというモデルを以下のように定義します。
係数行列を用いて行列式に書き直すと次のようになります。
ICAはこのから
の形に復元することができます。 式中のが非ガウス分布に従う独立ベクトルであることに注目して、LiNGAMの式に適応できます。 ここで注意しないといけないのは、ICAによって復元されたは、本来の混合行列と列の順序と尺度が異なる可能性があるということです。 つまり、ICAで得られたの逆行列は、本来のと単位行列からとして得られた真のと比べ、列の順序と尺度が異なる可能性があります。 したがって、との関係は、置換行列と対角行列を用いて次のように表せます。
ここから,を推定しての値を求めたいです。独立成分分析において,は識別不可能です。しかしLiNGAMモデルにおいてはの性質を考慮することによって,を求めることができます。
因果的順序と非巡回性の行列表現
LiNGAMモデルでは 4.観測変数は非巡回 という仮定を置いたのでした。これについて考えてみましょう。
初めに観測変数の因果的順序について説明します。因果的順序とは観測関数のデータが生成される順番のことです。
今回のデータ生成過程においては、まずはじめに非ガウス分布に従ってが生成されます。これはほかの観測変数に依存しない独立な変数で、このことは係数行列の行の成分がすべてであることからも確認できます。次に、は生成されたに係数をかけたものと、非ガウス分布によって生成された誤差変数の線形和として生成されます。以降、同様にして、,,,と生成されます。
したがって、このデータの因果的順序の一つは,,,,,となります。この因果的順序の順番にデータが生成される過程はDAGを見ても直感的に理解出来るかと思います。以降は観測変数の因果的順序をとあらわすことにします。
非巡回とは、データの生成過程で因果的順序が下流の変数が上流の変数と自分自身の値に影響を及ぼさない状態のことです。
さて、データ生成の行列表現は式です。
式で観測変数,誤差変数を因果的順序,に並び替え、それに対応して係数ベクトルをに変換します。
とデータ生成過程を確認します。非巡回は自分自身の値に影響しませんから、それぞれの行において観測変数自身にかかる係数成分は0です。したがっての対角成分は0となります。では行列式に生成したデータを代入します。
式を因果的順序に並び変えてみます。
観測変数は因果的順序が自身よりの下流の変数の影響を受けない(=係数成分が0)であるためそれぞれの行で対角成分をなす成分より右の成分は0となることがわかります。したがって、係数行列は厳密な下三角を成します。
続いて を考えます。の対角成分は0ですからの対角成分はすべて1となります。具体例で確認します。
この条件を用いて置換行列と対角行列を推定します。
置換行列は行の順序を変更するのでした。行の順序が正しくない場合、変換後の行列の対角成分のいずれかが0になることが知られています。なので、によって変更された順序を、すべての対角成分が0ではないような順序へ戻すような置換行列を考えます。
を式の右からかけます。であることを利用して
となり、行の順序がと同じになるように復元できます。(復元する順序はの順序であって因果的順序に並び替えたの順序ではありません。)
また、実際の対角成分の値が0であっても計算によって生じる推定誤差により0とならない場合があるため、置換行列は対角成分ができるだけ0から離れた値になるような推定値を以下のように求めます。
次にを復元します。これは復元行列の対角成分は1なので、のそれぞれの行の対角成分は行の尺度の値とわかります。したがって式]の左から対角行列の逆行列をかけて
となります。
あとはからが推定できます。以降ではこの推定値をと表記します。
以上より独立成分分析によって得られた式
のみでは識別不可能だった,が、LiNGAMモデルにおける因果的順序の非巡回性の仮定を条件に識別可能となり、結果としてからを求め、の推定値を推定することができました。
この時点では推定値として復元されていますが、の成分は本当の値が0であったとしても推定誤差のために0ではないため、このままだと巡回な関係となります。
なので、前述した因果的順序を推定し、並び替えたの上三角部分の成分を0とすることで厳密な下三角とし、本来の非巡回の関係を推定します。
具体的な手順は次の通りです。の上三角成分の値がすべて0ということは、の個の成分のうち、すくなくとも対角成分の個数個と、残りの成分の半分にあたる個の合計個の成分の値が0である必要があります。なのでの成分のうち絶対値が小さい順に個の成分を0で置き換えます。そしてが厳密な下三角になるような並び替えが可能かを調べます。もし可能なら並び替え後の行列を とし、不可能であれば成分のうち次に絶対値が小さい値一つを0としてもう一度並び替えを調べます。これを厳密な下三角が出来るまで繰り返し、因果的順序およびを推定します。
適応型Lasso回帰による冗長性の排除
上の手順で推定したの下三角にはまだ、本来の値は0であるが推定誤差によって0になってない値があるかもしれません。観測変数の線形回帰によって正しい値を求めたいところですが、最小二乗法といった単純な線形回帰分析を行っても残されてしまいます。
適応型Lasso回帰の式を成り立ちを最小二乗法による線形回帰から軽く見ていきます。なお、適応型Lasso回帰について詳しく知りたい方は参考文献の元論文を参考にしてください。
まずは最小二乗法の式からです。
この式の時点で行っていることは係数の推定のみで、推定誤差による冗長な因果関係を排除できていません。
Lasso回帰では、右辺の目的関数にL1正則化項を足し合わせたものになります。
L1正則化項が最小となるのはすべての係数が0となるときですから、最小化をしていくと係数が0に近づいていくことが直感的にわかります。実際いくつかの係数は0となるので、本来の値が0である係数を0とすることができます。イメージとしては本当に重要な係数だけが選択され0ではない値として生き残る感じです。
つまり、Lasso回帰は係数の推定と同時に、変数の選択(=因果関係の選択)を行っていることになります。
Lasso回帰では係数の選択に一貫性が無い場合があるためさらに発展させた適応型Lasso回帰を導入します。
適応型Lasso回帰では、L1正則化項に含まれていた係数ベクトルそれぞれに重みを掛け合わせます。
一般的に、この係数は推定値 とパラメータを用いて次のように定義します。
書き直して最終的な適応型Lasso回帰の式を得ます。
やってみる!
以上を踏まえて実際に推定をしてみましょう。サンプルサイズは10000としました。
import numpy as np import pandas as pd import graphviz import lingam from lingam.utils import print_causal_directions, print_dagc, make_dot x2 = np.random.uniform(size=10000) x1 = 2.0*x2 + np.random.uniform(10000) x0 = 4.0*x2 + 5.0*x1 +np.random.uniform(size=10000) x5 = 1.5*x0 + np.random.uniform(size=10000) x4 = 3.0*x0 + np.random.uniform(size=10000) x3 = 2.0*x2 + 1.0*x4 + np.random.uniform(size=10000) X = pd.DataFrame(np.array([x0,x1,x2,x3,x4,x5]).T, columns=['x0','x1','x2','x3','x4','x5']) X.head()
model = lingam.ICALiNGAM() model.fit(X) model.causal_order_
B_ord = model.adjacency_matrix_ B_ord
make_dot(model.adjacency_matrix_)
結果のDAGを見ると、想定していたDAGが正しい因果的順序で高い精度で復元できていることがわかります。
異なっている箇所はからへの有向辺ですが、推定係数は0.02と小さい値でおさまっていると思います。
それからに対するの有向辺の表記が異なりますが、想定しているDAGではの単位量の変化がに及ぼす影響はからの直接の係数とを経由して及ぼす間接的な係数の合計(=4.00+2.005.00=14.00)で、これは復元したDAGでのからを経由してにかかる係数(2.007.00=14.00)一致しています。
感想など
めちゃ面白い分野です。因果推論/探索の他のアプローチやLiNGAMから派生した手法も理解していこうと思います。