MENU

【無料プレゼント付き】学会発表・論文投稿に必要な統計を最短で学ぶことができる無料メルマガ

Full Information Maximum Likelihood (FIML) による欠損データ処理:概要とRでの実践


データ分析を行う際、欠損データは避けて通れない課題の一つである。単純な欠損処理方法では情報が失われたり、結果に偏りが生じたりする可能性がある。そこで注目されるのが、Full Information Maximum Likelihood(FIML)である。FIMLは、欠損データを統計的に最も適切に扱う方法の一つとして、特に構造方程式モデリング(SEM)などの多変量解析で広く利用されている。本ブログ記事では、FIMLの基本的な考え方から、具体的な適用例、さらには統計ソフトウェアRを用いた計算例までを詳しく解説する。

>>もう統計で悩むのは終わりにしませんか? 

↑1万人以上の医療従事者が購読中

目次

FIMLの概要

FIMLは、欠損データを含むデータセット全体から、モデルパラメータを推定する最尤推定の一種である。従来の欠損処理方法(リストワイズ削除や平均値補完など)とは異なり、FIMLは観測されたすべての情報(完全な観測データと部分的に欠損した観測データ)を最大限に活用する。

基本的な考え方は以下の通りである。

  1. 尤度関数の最大化: FIMLは、データが特定のモデルから生成される確率(尤度)を最大化するようなパラメータを推定する。欠損データが存在する場合でも、観測されている部分の尤度を考慮して全体の尤度を計算する。
  2. 多変量正規分布の仮定: 多くの場合、FIMLはデータが多変量正規分布に従うと仮定する。この仮定のもとで、観測されたデータパターンごとに尤度を計算し、それらを合計して全体の尤度とする。
  3. 情報損失の最小化: リストワイズ削除のように欠損を含むケースを丸ごと削除するのではなく、観測された情報を全て利用するため、統計的効率性が高く、推定量のバイアスが少ないという利点がある。

FIMLは、特に欠損がランダムに発生している場合(MAR: Missing At Random)に有効であるとされている。MARとは、欠損の有無が、モデルに含まれる他の観測された変数に依存するが、欠損している値そのものには依存しない状態を指す。


具体例

ここでは、FIMLがどのように適用されるかを理解するために、簡単な例を考えてみる。

例:学力と勉強時間の関係

ある学校の生徒について、「数学の点数」「国語の点数」「勉強時間」の3つの変数を調査したとする。しかし、一部の生徒で「数学の点数」が欠損していたり、「国語の点数」が欠損していたりするデータが得られた。

データ構造の例:

生徒ID数学の点数国語の点数勉強時間
1807510
290欠損12
3欠損858
470607
5858011

このデータを使って、「勉強時間が数学の点数と国語の点数に与える影響」を分析するモデルを構築したいとする。もしリストワイズ削除を行うと、生徒2と3のデータは分析から除外されてしまい、貴重な情報が失われる。平均値補完では、欠損値に人為的な値を代入することになり、標準誤差が過小評価される可能性がある。

FIMLを用いると、欠損パターンごとに異なる尤度関数を適用し、すべての観測データを分析に含めることができる。例えば、生徒2のデータでは「国語の点数」が欠損しているが、「数学の点数」と「勉強時間」のデータは利用できる。FIMLはこれらの利用可能な情報を最大限に活用して、パラメータを推定する。


>>もう統計で悩むのは終わりにしませんか? 

↑1万人以上の医療従事者が購読中

具体例の 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)

コードの説明:

  1. library(lavaan): lavaanパッケージを読み込む。
  2. データ生成と欠損作成: rnorm()関数で正規乱数を生成し、架空の「勉強時間」「数学の点数」「国語の点数」データを作成する。その後、sample()関数を使ってランダムにNA(欠損値)を挿入する。
  3. モデル定義: model変数に、SEMのモデル構文を文字列で定義する。ここでは、「math_scorestudy_timeによって予測される」「japanese_scorestudy_timeによって予測される」という回帰モデルを指定している。
  4. FIMLによる推定: sem()関数を用いてモデルを推定する。data = dfで作成したデータフレームを指定し、missing = "fiml" を指定することがFIMLを適用するポイントである。
  5. 結果の要約: summary()関数で推定結果を表示する。standardized = TRUEを指定すると、標準化された推定値も表示され、異なる変数の影響度を比較しやすくなる。
  6. リストワイズ削除との比較: 参考に、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の適用をぜひ検討してほしい。

よかったらシェアしてね!
  • URLをコピーしました!
  • URLをコピーしました!

リサーチクエスチョン探し?データ分析?論文投稿?、、、で、もう悩まない!

第1章臨床研究ではなぜ統計が必要なのか?計画することの重要性
  • 推定ってどんなことをしているの?
  • 臨床研究を計画するってどういうこと?
  • どうにかして標本平均を母平均に近づけられないか?
第2章:研究目的をどれだけ明確にできるのかが重要
  • データさえあれば解析でどうにかなる、という考え方は間違い
  • 何を明らかにしたいのか? という研究目的が重要
  • 研究目的は4種類に分けられる
  • 統計専門家に相談する上でも研究目的とPICOを明確化しておく
第3章:p値で結果が左右される時代は終わりました
  • アメリカ統計協会(ASA)のp値に関する声明で指摘されていること
  • そうは言っても、本当に有意差がなくてもいいの…?
  • なぜ統計専門家はp値を重要視していないのか
  • 有意差がない時に「有意な傾向があった」といってもいい?
  • 統計を放置してしまうと非常にまずい
第4章:多くの人が統計を苦手にする理由
  • 残念ながら、セミナー受講だけで統計は使えません。
  • インプットだけで統計が使えない理由
  • どうやったら統計の判断力が鍛えられるか?
  • 統計は手段なので正解がないため、最適解を判断する力が必要
第5章:統計を使えるようになるために今日から何をすれば良いか?
  • 論文を読んで統計が使えるようになるための5ステップ
第6章:統計を学ぶために重要な環境
  • 統計の3つの力をバランスよく構築する環境

以下のボタンをクリックして、画面に出てくる指示に従って、必要事項を記入してください。

この記事を書いた人

統計 ER ブログ執筆者

元疫学研究者

コメント

コメントする

目次