lavaanのsem関数について―デフォルト値とか変数間の共分散・相関とか―

構造方程式モデリングをやるパッケージとして有名なlavaan。
lavaan最大のメリットとしては、いろんなことを裏で自動的に行ってくれるのでユーザーが指定する必要はないことが挙げられます。ただ、実際、そのゴニョゴニョやってくれることが何なのか詳しくわかってなかったので備忘録として自分用にまとめておきます。

まず、lavaanで推定に使う関数は以下の4つ。
基本的には、lavaan()が原型で、それ以外の3つは、lavaan()でわざわざオプションを設定しなくても推定してくれるようにしたユーザーフレンドリー的な関数。

lavaan() …以下の3つの関数の一般系。自分であれこれ設定しないといけない。

sem()…共分散構造分析用に、lavaan()のオプションのデフォルト値を変えたもの。

cfa()…確認的因子分析用に、lavaan()のオプションのデフォルト値を変えたもの。

growth()…成長曲線モデル用に、lavaan()のオプションのデフォルト値を変えたもの。

で、実際何が変わっているのかというと、ヘルプのDetail欄に書いてあるので参照。
例えば、sem関数では、

“The sem function is a wrapper for the more general lavaan function, using the following default arguments: int.ov.free = TRUE, int.lv.free = FALSE, auto.fix.first = TRUE (unless std.lv = TRUE), auto.fix.single = TRUE, auto.var = TRUE, auto.cov.lv.x = TRUE, auto.th = TRUE, auto.delta = TRUE, and auto.cov.y = TRUE.”

とあり、これらのデフォルト値が設定されていて動かせませんよー、動かしたいならlavaan()を使ってくださいねということです。 lavaan()ではこれらの変数がFALSEになっていたり、”default”という値になっていたりします。つまり、sem()はlavaan()の面倒くさい設定をオートでやってくれる関数ということ。ありがたい。cfa() もgrowth() もヘルプを見れば書いてあると思います。

それぞれの引数の意味ですが、ov = observed variable, lv = latent variable, int = intercept, cov = covariance, x = 外生変数, y =内生変数, std = 標準偏差, th = threshold, と考えるとだいたい分かるようになっています。ちなみに、covarianceは外生変数間だとそのまま共分散という意味になるけど、内生変数間だと残差共分散(residual covariance) という意味になるので注意。
→内生変数間の共分散は、ふつう、内生変数を説明している変数が担っているため。ここにわざわざ共分散パスを引くことはない(足立, 2006, p57 を参照) 余談ですが、足立先生のこの本は統計にあんまり詳しくない私にみたいな文系にフレンドリーなのでおすすめです。足立先生、最近はイグノーベル賞を受賞されました。

というわけでHELPを読みながら訳すと以下のようになります(わからないところは英語そのままです。統計には疎いためご了承ください。)。

int.ov.free: 観測変数の切片を自由にするか(FALSEなら0に固定)
int.lv.free : 潜在変数の切片を自由にするか(FALSEなら0に固定)
auto.fix.first : TRUEなら潜在変数の第1番目のパスを1に固定する
auto.fix.single: If TRUE, the residual variance (if included) of an observed indicator is set to zero if it is the only indicator of a latent variable.
auto.var : TRUEなら自動的に誤差分散を設定
auto.cov.lv.x : TRUEなら自動的に外生変数である潜在変数間の共分散を設定
auto.th : If TRUE, thresholds for limited dependent variables are included in the model and set free.
auto.delta : If TRUE, response scaling parameters for limited dependent variables are included in the model and set free.
auto.cov.y : TRUEなら内生変数間の残差共分散を自動的に設定

以上のオプションについて、何もしなくても自動的に扱ってくれるのがどうやらsem()関数とのこと。とても便利ですね。

ただ、ここで1つ気になることが。
auto.var,  auto.cov.y はあるのになぜ auto.cov.x はないのだろうか。外生変数間の共分散についてはどうなっているのだろう。lavaanは外生変数間の共分散は仮定されると聞いたことがあるけど、なぜかそのオプションがないと気づきました。

ちょっと調べてみたところ、以下のQ&A を見つけました。google groupのQ&Aだけど、どうやら回答しているのはlavaanの開発者であるYves。信憑性は高そう。
how to “switch off” the covariance between two exogenous variables (not latent variables) in lavaan?

ざっくりまとめると以下のような感じ

Q: 外生変数間の共分散(相関)をなくすにはどうすればよいでしょうか?

A: そもそも、デフォルトで外生変数間の共分散は推定していない。

外生変数間の共分散(相関)は自動で仮定されるというのは今まで聞いていましたし、実際semPlot()で描画させても相関係数が確かに外生変数間に引かれているしどういうことなのか最初よくわかりませんでした。ただ、何度も読み返していると段々書いてあることがわかるように。

Yves 曰く、fixed.xというオプションが、外生変数間の共分散の仮定にあたるとのこと。ただ、このオプションは外生変数間の共分散を0にするか否かという話ではないそうです。 TRUE であれば、外生変数間の相関は推定されない。その代わり、共分散の値を、実際のデータから単に取ってきているだけとのことです。つまり、観測値の値で外生変数間の値を固定(fix) するみたいです。だからfixed.x なのか。なるほど。一方、fixed.x = FALSE であれば、外生変数間の共分散が自由なパラメータとして推定されるそうです。

つまり、lavaanは外生変数間の共分散勝手に行ってくれる外生変数間の相関の仮定は、
①単に観測値の共分散を引っ張ってくる、
②共分散を自由なパラメータとして推定する

という2つのパターンがどうやらあるらしいです。fixed.x = TRUE では①であり、FALSEでは②になるとのこと。確かに、冷静に考えれば、共分散は推定なんてしなくても算出できるということに気づきました。
lavaan() の出力に、Covariance という欄があるが、その欄に出てくるのもどうやら、②の共分散だけらしい。今まで、lavaan()は外生変数間の共分散を仮定するのになぜ値がでないのだろうと思っていたが、その謎が解決しました。lavaan()の出力は Estimateされた値だけなので、そもそも推定していないパラメータはここには出力されないのだけなのです。まあよく考えたらlavaanの出力欄にはEstimateって書いてありますね。(内生変数間の残差共分散は推定値なのでちゃんとCovariance欄に出力される)

このことを踏まえると、モデル式にわざわざ外生変数間の共分散を付け足すということは、その共分散を実測値ではなくパラメータとして推定しろということらしい。知らなかった。それを示すようにちゃんと共分散をモデル式で仮定してあげるとCovariance欄に出力される。

ちなみに無相関を仮定したいなら x1 ~~0*x2 のように書けばOK。ただし、そのような強い仮定があることはほとんどないので、とりあえず共分散を仮定しておくことをYves はおすすめしている。

以上、lavaan使用時の備忘録でした。私は統計の専門家ではありませんので、何か間違ってたら教えてくださると助かります……。

引用文献

足立 浩平 (2006). 多変量データ解析法―心理・教育・社会系のための入門 ナカニシヤ出版

コメントを残す

メールアドレスが公開されることはありません。 * が付いている欄は必須項目です