StatModeling Memorandum

StatModeling Memorandum

StanとRとPythonでベイズ統計モデリングします. たまに書評.

SEMとベイジアンネットワークとBUGS/Stanの関係

自分用のメモです。

SEM

Structural Equation Modelingの略で「構造方程式モデリング」と和訳されています。共分散構造分析は構造方程式モデリングSEM)の古い名称です。共分散以外の行列も扱えるので、共分散構造分析という名称は適当ではないということで、最近では構造方程式モデリングという言い換えのほうが主流とのことです。心理統計やアンケート解析でよく使われる因子分析と多重回帰分析(パス解析)の拡張となっており、因果関係によりフォーカスしたモデル体系と言えるでしょう。

BUGS/Stanで何でもありのモデリングに比べた時の制約は次の通りです。

  • 使える分布はnormal()multi_normal()のみ。応答変数は説明変数の線形結合の回帰式で表され、リンク関数がidentityのみ。

しかしながら、この制約のおかげで決定係数、検定を用いた適合度、そしてパスの係数から直接効果や間接効果などを算出することができて、モデル選択や因果関係を議論する文化が存在します。パラメータの推定としては最尤推定がよく使われるようです。

SEMを実行できるソフトウェアはパス図(モデル)が簡単に描けたり高機能で有料なものがほとんどです。その1つであるMplusはstatistical modeling programと記載のあるように、SEMの範囲だけではなくポアソン分布・カテゴリカルデータ・非線形の関係も扱えるし、ベイズ推定もできるようです。しかしながら有料であることを考えるとMCMC計算がダントツで速いなどのメリットがない限りは使うのがためらわれます。

Rのパッケージでは{lavaan}が良さそうです。カテゴリカルデータが扱えるようです(内部的にどういう計算しているかは不明です)。現状ではパラメータの推定は最尤推定のみです。

ベイジアンネットワーク

一般的にベイジアンネットワークと言えば、確率変数がDAG構造(親が複数ありうるツリー、ただし循環はナシ)を持つグラフィカルモデルのことを指します。

しかしながら応用上は「全てのノードが離散分布に従う」もしくは「全てのノードが正規分布に従う」ベイジアンネットワークがよく使われます。PRMLの第8章グラフィカルモデル、8.1.3 離散変数から引用しますと、「有向グラフの親子対が共役関係になるように分布を選べば、そのモデルは非常に良い性質を持つ。(中略)特に重要なのは、親ノードと子ノードとが共に離散変数であるおよび、親ノードと子ノードが共にガウス変数である場合である。なぜ重要かというと、これら2つの場合には親ノードと子ノードとの関係を階層的に拡張して任意の複雑な有向非循環グラフが構築できるためである。」とあります。従って上記の場合にはよく研究されており、様々な定理や速い計算アルゴリズムが充実しています。そのためベイジアンネットワークという名前で実装されたソフトウェアやライブラリでは基本的には上記の条件を満たすベイジアンネットワークのみ扱えるという状況が多いです。結果として巷で見かける応用例は「全てのノードが離散分布に従う」もしくは「全てのノードが正規分布に従う」ベイジアンネットワークであふれることになります。正規分布の数学的な性質が好ましく、統計や検定と言えば正規分布に由来するものばかり出てくるような状況と似ているかなと感じました。

さて例として全てのノードが離散分布に従うベイジアンネットワークについて、BUGS/Stanで何でもありのモデリングに比べた時の制約は次の通りです。

  • 確率変数がDAG構造。使える分布はbernoulli()categorical()のみ。各ノードごとに(全ての)入力の値が決まるとどの出力がどんな確率で現れるかをCPT(conditional probability table)で定める。

CPTの例はこの有名な例を参照。典型的にはネットワーク構造を決めておいてデータからCPTを最尤推定します。bernoulli()categorical()の引数であるthetaを推定するのに相当します。連続値を持つデータは適当に閾値を決めて離散化する必要があります。推定後には、あるデータを説明するのに各nodeがどの内部状態をとっているとみなすのが最も確率が高いかを示すMPE(most probable explanation)を求めるのが1つの目的です。

また、100個ぐらいの確率変数たちの因果関係(ネットワーク構造)がよく分かっていない時に、探索的に色々構造を変えて尤度やAICなどを求めることで最終的な因果関係(ネットワーク構造)を推定する、というのもよく行われます。結果は面白いのですが成功している例をなかなか見たことがありません。やっぱり難しい問題なのでしょう。

Rのパッケージでは{bnlearn}が良さそうです。ネットワーク構造の推定の関数も充実しています。目的によっては{bnlearn}も使っていきたいと思いました。

Rに注力するようになる前はNetica APIを使っていました。Wekaではフリーズしておしまいというパターンが多かった覚えがあります。GUIではSamiamが使いやすかった覚えがあります。