データ分析を行う際、欠損データは避けて通れない課題の一つである。単純な欠損処理方法では情報が失われたり、結果に偏りが生じたりする可能性がある。そこで注目されるのが、Full Information Maximum Likelihood(FIML)である。FIMLは、欠損データを統計的に最も適切に扱う方法の一つとして、特に構造方程式モデリング(SEM)などの多変量解析で広く利用されている。本ブログ記事では、FIMLの基本的な考え方から、具体的な適用例、さらには統計ソフトウェアRを用いた計算例までを詳しく解説する。
FIMLの概要
FIMLは、欠損データを含むデータセット全体から、モデルパラメータを推定する最尤推定の一種である。従来の欠損処理方法(リストワイズ削除や平均値補完など)とは異なり、FIMLは観測されたすべての情報(完全な観測データと部分的に欠損した観測データ)を最大限に活用する。
基本的な考え方は以下の通りである。
- 尤度関数の最大化: FIMLは、データが特定のモデルから生成される確率(尤度)を最大化するようなパラメータを推定する。欠損データが存在する場合でも、観測されている部分の尤度を考慮して全体の尤度を計算する。
- 多変量正規分布の仮定: 多くの場合、FIMLはデータが多変量正規分布に従うと仮定する。この仮定のもとで、観測されたデータパターンごとに尤度を計算し、それらを合計して全体の尤度とする。
- 情報損失の最小化: リストワイズ削除のように欠損を含むケースを丸ごと削除するのではなく、観測された情報を全て利用するため、統計的効率性が高く、推定量のバイアスが少ないという利点がある。
FIMLは、特に欠損がランダムに発生している場合(MAR: Missing At Random)に有効であるとされている。MARとは、欠損の有無が、モデルに含まれる他の観測された変数に依存するが、欠損している値そのものには依存しない状態を指す。
具体例
ここでは、FIMLがどのように適用されるかを理解するために、簡単な例を考えてみる。
例:学力と勉強時間の関係
ある学校の生徒について、「数学の点数」「国語の点数」「勉強時間」の3つの変数を調査したとする。しかし、一部の生徒で「数学の点数」が欠損していたり、「国語の点数」が欠損していたりするデータが得られた。
データ構造の例:
生徒ID | 数学の点数 | 国語の点数 | 勉強時間 |
1 | 80 | 75 | 10 |
2 | 90 | 欠損 | 12 |
3 | 欠損 | 85 | 8 |
4 | 70 | 60 | 7 |
5 | 85 | 80 | 11 |
このデータを使って、「勉強時間が数学の点数と国語の点数に与える影響」を分析するモデルを構築したいとする。もしリストワイズ削除を行うと、生徒2と3のデータは分析から除外されてしまい、貴重な情報が失われる。平均値補完では、欠損値に人為的な値を代入することになり、標準誤差が過小評価される可能性がある。
FIMLを用いると、欠損パターンごとに異なる尤度関数を適用し、すべての観測データを分析に含めることができる。例えば、生徒2のデータでは「国語の点数」が欠損しているが、「数学の点数」と「勉強時間」のデータは利用できる。FIMLはこれらの利用可能な情報を最大限に活用して、パラメータを推定する。
具体例の R 計算例
RでFIMLを実装する際には、lavaan
パッケージが非常に便利である。lavaan
は構造方程式モデリングを行うためのパッケージであるが、FIMLによる欠損データ処理をデフォルトでサポートしている。
まず、架空のデータを作成し、一部に欠損値を導入する。
R スクリプト例:
# 必要なパッケージのインストール (まだの場合)
# install.packages("lavaan")
# install.packages("mice") # 欠損作成のために使用
# パッケージの読み込み
library(lavaan)
library(mice)
# シードを設定して再現性を確保
set.seed(123)
# 架空のデータ生成
n_obs <- 100
study_time <- round(rnorm(n_obs, mean = 10, sd = 2))
math_score <- round(50 + 3 * study_time + rnorm(n_obs, mean = 0, sd = 5))
japanese_score <- round(40 + 2.5 * study_time + rnorm(n_obs, mean = 0, sd = 4))
# データフレームの作成
df <- data.frame(study_time, math_score, japanese_score)
# 意図的に欠損を作成 (ランダムに欠損させる場合)
# 数学の点数の約10%を欠損させる
df$math_score[sample(1:n_obs, size = round(n_obs * 0.1))] <- NA
# 国語の点数の約15%を欠損させる
df$japanese_score[sample(1:n_obs, size = round(n_obs * 0.15))] <- NA
# 欠損データの確認
summary(df)
# モデルの定義 (勉強時間が数学と国語の点数に影響を与える回帰モデル)
model <- '
math_score ~ study_time
japanese_score ~ study_time
'
# FIMLを用いたモデルの推定
# missing = "fiml" を指定することでFIMLが適用される
fit_fiml <- sem(model, data = df, missing = "fiml")
# 結果の要約
summary(fit_fiml, standardized = TRUE)
# リストワイズ削除の場合と比較
fit_listwise <- sem(model, data = df, missing = "listwise")
summary(fit_listwise, standardized = TRUE)
コードの説明:
library(lavaan)
:lavaan
パッケージを読み込む。- データ生成と欠損作成:
rnorm()
関数で正規乱数を生成し、架空の「勉強時間」「数学の点数」「国語の点数」データを作成する。その後、sample()
関数を使ってランダムにNA
(欠損値)を挿入する。 - モデル定義:
model
変数に、SEMのモデル構文を文字列で定義する。ここでは、「math_score
がstudy_time
によって予測される」「japanese_score
がstudy_time
によって予測される」という回帰モデルを指定している。 - FIMLによる推定:
sem()
関数を用いてモデルを推定する。data = df
で作成したデータフレームを指定し、missing = "fiml"
を指定することがFIMLを適用するポイントである。 - 結果の要約:
summary()
関数で推定結果を表示する。standardized = TRUE
を指定すると、標準化された推定値も表示され、異なる変数の影響度を比較しやすくなる。 - リストワイズ削除との比較: 参考に、
missing = "listwise"
を指定してリストワイズ削除を行った場合の推定結果も示している。これにより、FIMLとリストワイズ削除の結果の違いを比較できる。
結果解釈
実行結果:
> # 結果の要約
> summary(fit_fiml, standardized = TRUE)
lavaan 0.6-19 ended normally after 27 iterations
Estimator ML
Optimization method NLMINB
Number of model parameters 7
Number of observations 100
Number of missing patterns 4
Model Test User Model:
Test statistic 0.000
Degrees of freedom 0
Parameter Estimates:
Standard errors Standard
Information Observed
Observed information based on Hessian
Regressions:
Estimate Std.Err z-value P(>|z|) Std.lv Std.all
math_score ~
study_time 2.857 0.277 10.298 0.000 2.857 0.732
japanese_score ~
study_time 2.439 0.256 9.512 0.000 2.439 0.753
Covariances:
Estimate Std.Err z-value P(>|z|) Std.lv Std.all
.math_score ~~
.japanese_score 1.082 2.067 0.523 0.601 1.082 0.059
Intercepts:
Estimate Std.Err z-value P(>|z|) Std.lv Std.all
.math_score 51.017 2.883 17.695 0.000 51.017 7.259
.japanese_score 41.025 2.687 15.267 0.000 41.025 7.035
Variances:
Estimate Std.Err z-value P(>|z|) Std.lv Std.all
.math_score 22.900 3.414 6.707 0.000 22.900 0.464
.japanese_score 14.702 2.255 6.521 0.000 14.702 0.432
> # リストワイズ削除の場合と比較
> fit_listwise <- sem(model, data = df, missing = "listwise")
> summary(fit_listwise, standardized = TRUE)
lavaan 0.6-19 ended normally after 9 iterations
Estimator ML
Optimization method NLMINB
Number of model parameters 5
Used Total
Number of observations 76 100
Model Test User Model:
Test statistic 0.000
Degrees of freedom 0
Parameter Estimates:
Standard errors Standard
Information Expected
Information saturated (h1) model Structured
Regressions:
Estimate Std.Err z-value P(>|z|) Std.lv Std.all
math_score ~
study_time 2.823 0.358 7.893 0.000 2.823 0.671
japanese_score ~
study_time 2.570 0.265 9.684 0.000 2.570 0.743
Covariances:
Estimate Std.Err z-value P(>|z|) Std.lv Std.all
.math_score ~~
.japanese_score 1.131 2.142 0.528 0.597 1.131 0.061
Variances:
Estimate Std.Err z-value P(>|z|) Std.lv Std.all
.math_score 25.113 4.074 6.164 0.000 25.113 0.550
.japanese_score 13.836 2.244 6.164 0.000 13.836 0.448
>
summary(fit_fiml)
の出力には、以下のような情報が含まれる。
Estimates
: 各パス(関係性)の推定値である。例えば、math_score ~ study_time
の行には、勉強時間が数学の点数に与える影響の係数(回帰係数)が表示される。Std. Err
: 推定値の標準誤差である。z-value
: 推定値を標準誤差で割ったZ値で、係数の統計的有意性を評価するために使用される。P(>|z|)
: Z値に対応するp値である。一般的に、p値が0.05未満であれば、その関係性は統計的に有意であると判断される。Std.all
: 全てを標準化した推定値である。異なる尺度を持つ変数間の影響度を比較する際に有用である。
FIMLによる結果は、リストワイズ削除による結果と比較して、より多くのデータが利用されているため、推定量の標準誤差が小さくなる傾向がある(例:0.277 (FIML) vs. 0.358 (listwise) in Std.Err of math_score ~ study_time in Regressions)。これは、FIMLがより効率的な推定を行っていることを示唆する。また、欠損がランダムな場合には、FIMLによる推定値はリストワイズ削除よりも真のパラメータ値に近いと期待される。
例えば、Rの出力でstudy_time
からmath_score
へのパスの推定値が正であり、p値が十分に小さいので、「勉強時間が長いほど数学の点数が高くなる傾向がある」という結論を導き出すことができる。FIMLを用いることで、欠損データが存在しても、この結論の信頼性を高めることが可能になる。
まとめ
Full Information Maximum Likelihood(FIML)は、欠損データが存在する状況で、統計的に効率的でバイアスの少ないパラメータ推定を可能にする強力な手法である。特に、構造方程式モデリングなどの多変量解析において、その真価を発揮する。
FIMLは、欠損データを含むすべての観測情報を最大限に活用することで、情報の損失を最小限に抑え、より信頼性の高い分析結果をもたらす。Rのlavaan
パッケージを使えば、簡単にFIMLを適用することができ、複雑な統計モデルの分析を、欠損データに煩わされることなく実行できる。
データ分析の現場で欠損データに直面した際には、FIMLの適用をぜひ検討してほしい。
コメント