論文一覧に戻る 📚 用語集トップ 🗺 概念マップ
📚 用語解説
📚 用語解説
欠損メカニズム
Missing Data Mechanism
データ処理
別称: 欠損の種類

🔖 キーワード索引

欠損メカニズムMissing Data Mechanismデータ処理欠損の種類

本ページは 欠損メカニズム(Missing Data Mechanism)を多角的に解説します。 上のチップは、 検索・関連語の手がかりです。

💡 30秒で分かる結論

📍 文脈 — どこで使う概念か

欠損メカニズム(Missing Data Mechanism)は、 統計学・データサイエンスの 基礎理論です。 アンケート、 医療データ、 センサー測定値など 欠損のないデータはまずないのが現実。 ところが「とりあえず平均で埋める」「行ごと削除」といった素朴な対応は、 メカニズムによっては 結果を大きく歪めることが知られています。

🎨 直感で掴む — 具体例で理解する

3 つのメカニズムを具体例で:

分類意味対処
MCAR(完全ランダム)欠損が完全に偶然機器故障で一部測定不能削除 or 平均補完 OK
MAR(観測値依存)他の観測値で欠損確率が決まる男性が体重欄を空欄にしがち多重代入法 推奨
MNAR(欠損値自身依存)欠損値自身の値で欠損が決まる高所得者ほど所得欄を空欄にモデル化が必要・困難

例:健康診断データで 「肥満気味の人ほど体重欄を空欄」にすると、 これは MNAR。 単純に「他の人の体重平均」で埋めると、 全体の平均体重を 過小評価してしまいます。

📐 定義・数式

3 メカニズムの数学的定義($Y$ = 観測したい値、 $M$ = 欠損指示子、 $X$ = 他の観測変数):

【MCAR】
$$P(M | Y, X) = P(M)$$
欠損確率は他の何にも依存しない
【MAR】
$$P(M | Y, X) = P(M | X)$$
欠損確率は観測値 $X$ にのみ依存
【MNAR】
$$P(M | Y, X) \text{ は } Y \text{ にも依存}$$
欠損確率が欠損値自身に依存。 観測データだけからは特定不能

🔬 記号・要素の読み解き

$Y$
本当は観測したい値(一部欠損)
$M$
欠損指示子(1 = 欠損、 0 = 観測済)
$X$
欠損のない別の変数
MCAR
「欠損確率が全く独立」 ─ 理想的だが現実にはまれ
MAR
$X$ を制御すれば MCAR と見なせる ─ 多重代入法の前提
MNAR
欠損値自身に依存 ─ 外部情報やモデル仮定が必要

🧮 数値例・実値計算

例:所得アンケートで「年収 1000万以上の人ほど無回答」(MNAR)の場合:

処理方法推定平均年収真値からの偏り
真の平均(理論値)650 万円0
欠損行を削除(CCA)520 万円−130 万(過小評価)
観測値の平均で補完520 万円−130 万(過小評価)
多重代入法(MICE)540 万円−110 万(改善するが不十分)
選択モデルで対処620 万円−30 万(仮定を入れて補正)

MNAR では どの方法も完全な不偏推定にならない。 ベストエフォートとして選択モデルや感度分析が使われます。

🐍 Python 実装例

最小コードで動かしてみる例:

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
import pandas as pd
from sklearn.experimental import enable_iterative_imputer
from sklearn.impute import IterativeImputer

df = pd.read_csv('data/raw/SSDSE-B-2026.csv', encoding='utf-8', skiprows=1)
print('欠損率:', df.isnull().mean())

# 多重代入法(MICE) — MAR を仮定
imputer = IterativeImputer(max_iter=10, random_state=0)
df_filled = imputer.fit_transform(df.select_dtypes(include='number'))

⚠️ よくある落とし穴

❌ メカニズム判定の困難さ
MAR と MNAR は 観測データだけからは区別できない。 ドメイン知識で推測するしかない。
❌ Listwise Deletion の濫用
「欠損があれば行ごと削除」は MCAR 以外ではバイアスを生む。 多重代入法を検討。
❌ 単一補完の罠
平均値や中央値で埋めるのは簡単だが、 分散を過小評価し標準誤差が小さく出る。
❌ 欠損自体が情報
「無回答」という事実が予測に有用なことも。 欠損フラグを特徴量に追加する手法(指示子変数)も検討。
❌ ドメインによる感度
医療データでは MNAR が多い(重症者ほど欠損)。 統計分析より臨床判断が必要。

🔖 索引・このページの読み方

本ページは 欠損メカニズム(Missing Data Mechanism)を 12+ セクションで多角的に解説します。

💡 30秒📍 文脈🎨 直感📐 数式🔬 記号🧮 計算🐍 Python⚠️ 落とし穴🌐 関連手法🔗 関連用語📚 グループ教材🎓 深掘り

📂 分野:データ処理 / 関連語:MCAR / MAR / MNAR / 多重代入法 / Heckman

💡 30秒で分かる結論(拡張)

📍 文脈 — どこで使う概念か(詳説)

Rubin (1976) で定式化された統計理論。 「なぜ欠損したのか」によって、 削除・補完・モデル化のいずれが正当化されるかが決まります。

SSDSE-B(47都道府県統計)でも欠損は普通で、 MAR/MNAR の見極めが結論を左右します。 scikit-learn の Imputer 群、 R の mice、 SAS の PROC MI — どれもこの 3 分類が前提。

典型場面:(a) Methods 節で「12% 欠損を多重代入で対処」、 (b) 因果推論でサンプル選択バイアスを議論、 (c) 機械学習データパイプライン設計、 (d) アンケート設計時の必須設問判断。

🎨 直感で掴む(詳説)

「データが穴あきになる原因」を 3 つに分類します。

メカニズム定義具体例削除はOK?
MCAR欠損確率が全変数と独立印刷ミスでランダム欠落○ バイアスなし
MAR欠損確率が観測値に依存農村県で IT 指標欠損△ MICE
MNAR欠損確率が欠損値自身に依存高所得世帯が回答拒否× 補正困難

🎭 比喩 — アンケートの茶封筒

1000 通配って 200 通無回答のとき:

仮定の強さ:MCAR ⊂ MAR ⊂ MNAR。 強い仮定ほど分析は楽だが、 現実は MNAR 寄り。

📐 数式・定義(詳説)

$Y$ = 観測したい変数、 $M$ = 欠損指示子、 $X$ = 補助変数。 各メカニズムは $P(M\mid Y,X)$ の依存性で定義:

【MCAR】
$$P(M \mid Y, X) = P(M)$$
【MAR】
$$P(M \mid Y, X) = P(M \mid X)$$
【MNAR】
$$P(M \mid Y, X) \neq P(M \mid X)$$

MICE が正当化されるのは MAR まで。 MNAR では Heckman 選択モデルが必要。

尤度関数

完全データを $(Y, M)$ とすると、 $p(Y_{obs}, M \mid \theta, \psi) = \int p(Y \mid \theta) p(M \mid Y, \psi) dY_{mis}$。 MAR では $\psi$ を無視できる(ignorable)。

🔬 記号・要素の読み解き

$Y$ — 観測したい完全データ
$Y = (Y_{obs}, Y_{mis})$ と分解。
$M$ — 欠損指示子
$M_{ij}=1$ で欠損。
$X$ — 補助変数
MAR では「条件付ければ $Y$ と独立」。
$\theta$ — 推定対象
母平均、 回帰係数など。
$\psi$ — 欠損モデル係数
MNAR で同時推定が必要。
ignorable
MCAR・MAR は無視可、 MNAR は不可。
識別性
観測データのみで MAR/MNAR を統計検定不能。
Rubin's rules
多重代入を統合する公式。

🧮 数値例・実値計算

所得アンケート(真平均 650万、 高所得 MNAR):

方法推定平均ズレ備考
真の平均650±0参照
Listwise520−130高所得が抜けたまま
平均補完520−130分散も過小
KNN (k=5)535−115近傍依存
MICE (m=20)545−105MAR 仮定
Heckman620−30 ✓仮定要

Rubin's rules で 3 個の補完統合

$\hat\theta_1=540, \hat\theta_2=555, \hat\theta_3=548$、 各分散 $U_k=900,950,920$。

$\bar\theta = 547.67$、 $\bar U = 923.3$、 $B = 56.3$、 $T = \bar U + (1+1/m)B = 998.4$、 $SE \approx 31.6$、 95% CI = $(485.7, 609.6)$

🐍 Python 実装(4+ サンプル)

① 欠損パターン可視化

1
2
3
4
5
6
7
8
9
import pandas as pd
import numpy as np
import missingno as msno
import matplotlib.pyplot as plt

df = pd.read_csv('data/raw/SSDSE-B-2026.csv', encoding='utf-8', skiprows=1)
print('欠損率:', df.isnull().mean().sort_values(ascending=False).head(10))
msno.matrix(df); plt.savefig('figures/missing_matrix.png', dpi=120)
msno.heatmap(df); plt.savefig('figures/missing_heatmap.png', dpi=120)

② 簡易 MCAR 検定

1
2
3
4
5
6
7
from sklearn.linear_model import LogisticRegression
num = df.select_dtypes(include='number')
miss_flag = num.isnull().astype(int)
for col in num.columns[num.isnull().any()][:5]:
    others = num.drop(columns=col).fillna(num.mean())
    lr = LogisticRegression(max_iter=500).fit(others, miss_flag[col])
    print(col, '説明力:', lr.score(others, miss_flag[col]))

③ 補完 3 種比較

1
2
3
4
5
6
7
from sklearn.experimental import enable_iterative_imputer
from sklearn.impute import SimpleImputer, KNNImputer, IterativeImputer
imp_mean = SimpleImputer(strategy='mean').fit_transform(num)
imp_knn  = KNNImputer(n_neighbors=5).fit_transform(num)
imp_mice = IterativeImputer(max_iter=10, random_state=0).fit_transform(num)
result = pd.DataFrame({'元':num.mean(),'平均':pd.DataFrame(imp_mean,columns=num.columns).mean(),'KNN':pd.DataFrame(imp_knn,columns=num.columns).mean(),'MICE':pd.DataFrame(imp_mice,columns=num.columns).mean()})
print(result.head(10))

④ 多重代入 m=20

1
2
3
4
5
import statsmodels.api as sm
from statsmodels.imputation.mice import MICE, MICEData
mice_data = MICEData(num)
mice = MICE('death_rate ~ aging_rate + medical_cost', sm.OLS, mice_data)
print(mice.fit(n_burnin=5, n_imputations=20).summary())

⑤ 欠損フラグを特徴量化

1
2
3
imp = SimpleImputer(strategy='median', add_indicator=True)
X = imp.fit_transform(num)
print('元の列数:', num.shape[1], '/ 補完後:', X.shape[1])

⚠️ よくある落とし穴(5+)

❌ MCAR と決め打ち
実データで MCAR は稀。 必ず MAR を仮定するか MNAR を議論。
❌ 単一補完で SE 過小
平均値補完は分散を縮め、 p 値が不当に小さくなる。
❌ MAR/MNAR を検定で判定
原理的に区別不能。 ドメイン知識と感度分析。
❌ MICE 1 回しか回さない
max_iter=10 程度必須。
❌ 欠損フラグを特徴に含めない
indicator 変数を追加。
❌ カテゴリの欠損を 0 で埋める
専用の Missing カテゴリを作る。
❌ 時系列に iid 補完
ffill/bfill / Kalman を使う。
❌ テストに訓練統計量を使わない
補完器も fit/transform を分離。

🌐 関連手法・派生

📜 歴史・背景

Donald B. Rubin (1976) "Inference and Missing Data" で体系化。 それ以前は「削除か平均補完」が標準。 Rubin は MCAR/MAR/MNAR の 3 分類と ignorable 概念を導入。 1987 年の著書で多重代入法が確立。

2000 年代に Schafer・van Buuren が MICE を実装し、 R の mice パッケージで普及。 scikit-learn の IterativeImputer もこの系譜。 GAIN, MIWAE, MissForest など深層補完も活発。

主要文献:Rubin (1976) Biometrika; Little & Rubin (2019) 第 3 版; van Buuren (2018) Flexible Imputation; Heckman (1979) Econometrica; Schafer & Graham (2002) Psychological Methods。

🌍 ケーススタディ

SSDSE-B-2026 では一部指標(小規模県の専門医療、 離島部の通信指標)が欠損。 単純削除では 8 県が消え n=39 に。 MAR と見て多重代入すれば 47 県全部を活用可能。

MIMIC-III 集中治療データベース例:患者症状が重いほど検査値未記録 → 典型的 MNAR。 単純補完では推定が楽観的すぎる。 indicator 変数の追加や重症度モデルとの同時推定が必要。

論文記述例(コピペ用)

Methods:「データの 12.3% に欠損があり、 Little の MCAR 検定で p < 0.001 となったため MCAR は棄却。 観測共変量で説明可能と判断し、 MICE(m=20)を適用した(van Buuren, 2018)。 全推定は Rubin's rules で統合した。」

Results:「補完前後で主係数の符号と統計的有意性は不変だったが、 SE は 12% 増加した(補完の不確実性を適切に反映)。」

Limitations:「MAR 仮定は検証不能であり、 MNAR の可能性を排除できない。 感度分析として欠損値に ±20% の系統的ズレを仮定した場合でも結論は不変。」

❓ FAQ

Q. 欠損率 5% 未満なら無視していい?
A. MCAR と確信できるなら listwise でも問題ありませんが、 機械学習では「欠損自体が情報」のことがあるので indicator 列追加が安全。
Q. MICE は何回回せば十分?
A. 通常 10〜20 回。 trace plot で収束確認。
Q. カテゴリも MICE で補完可?
A. はい。 各列に model_class を指定で連続・二値・多値を混在可。
Q. MNAR の感度分析とは?
A. 「欠損値が観測値より δ ズレている」など複数シナリオで頑健性確認。
Q. R の mice と Python は?
A. R が伝統的に強い。 Python は scikit-learn/statsmodels で基本は揃う。
Q. Listwise と Pairwise の違い?
A. Listwise は欠損行を全削除、 Pairwise は計算ごとに利用可能ペアのみ使用。 Pairwise は共分散行列が非正定値になる落とし穴あり。

🎓 深掘り — 高度な論点

サンプル選択との関係

「欠損」の一般化が サンプル選択バイアス。 「観測される事例自体が母集団から偏る」現象。

シナリオ典型例欠損分類
追跡調査の脱落10 年後再調査で連絡不通引っ越し頻度依存 → MAR/MNAR
労働市場参加働く人の賃金しか観測不能留保賃金依存 → MNAR
医療レジストリ重症者は転院・死亡で追跡不能結果依存 → MNAR
顧客満足度極端な人だけ回答結果自体に依存 → MNAR

教育的演習

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
import numpy as np
# 学習用に分布パラメータで生成(本番では公的データを使用)
N = 200
np.random.seed(0)
income = np.random.lognormal(6.0, 0.7, N)
age    = np.random.normal(45, 12, N)

# (1) MCAR
y1 = income.copy(); y1[np.random.rand(N) < 0.3] = np.nan
# (2) MAR
prob = 1 / (1 + np.exp((age - 50)/5))
y2 = income.copy(); y2[np.random.rand(N) < prob] = np.nan
# (3) MNAR
prob3 = (income - income.min()) / (income.max() - income.min())
y3 = income.copy(); y3[np.random.rand(N) < prob3] = np.nan

print('真の平均:', income.mean())
print('MCAR後 :', np.nanmean(y1), '(不偏)')
print('MAR後  :', np.nanmean(y2), '(やや偏る)')
print('MNAR後 :', np.nanmean(y3), '(過小評価)')

補完前後で回帰係数を比較

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
from sklearn.linear_model import LinearRegression
from sklearn.impute import SimpleImputer

X = np.column_stack([age, np.ones(N)])
y_full = income; y_obs = y2  # MAR シナリオ
mask = ~np.isnan(y_obs)

print('真の係数 :', LinearRegression().fit(X, y_full).coef_)
print('Listwise:', LinearRegression().fit(X[mask], y_obs[mask]).coef_)
y_mean = SimpleImputer(strategy='mean').fit_transform(y_obs.reshape(-1,1)).ravel()
print('平均補完 :', LinearRegression().fit(X, y_mean).coef_)
# 観察: Listwise は MAR でもバイアスあり / 平均補完は係数を 0 寄りに

理論的注意:observed-data likelihood

完全データの尤度は $p(Y, M\mid\theta,\psi) = p(Y\mid\theta) p(M\mid Y,\psi)$。 観測データの尤度は $\int p(Y\mid\theta) p(M\mid Y,\psi) dY_{mis}$。 MAR では $p(M\mid Y,\psi) = p(M\mid Y_{obs},\psi)$ なので $\psi$ が $\theta$ と分離可能 → 欠損モデルを無視できる。 MNAR ではこれが成立せず、 同時推定が必要。

主要 R パッケージ早見表

パッケージ得意分野備考
mice連続・カテゴリ混在 MICE業界標準
AmeliaEM アルゴリズム + bootstrap時系列対応
miベイズ的多重代入収束診断が豊富
missForestRF による非線形補完tuning 少
VIM欠損パターン可視化診断特化

✅ 実務チェックリスト

🔄 標準ワークフロー — 「欠損メカニズム」を使う実務 5 ステップ

ステップやること使うツール例成果物
1. 目的設定分析の問いを 1 文で書く。 「欠損メカニズム」をどう使うか、 仮説と判断基準を決める。ホワイトボード、 issue tracker1 ページ計画書
2. データ取得SSDSE / e-Stat / 政府統計から、 該当指標を取得。 ライセンス・出典を確認。pandas, requests, e-Stat APIdata/raw/ の CSV
3. 前処理型変換、 欠損対処、 単位統一、 外れ値検査。 「欠損メカニズム」に必要な形に整える。pandas, scikit-learndata/processed/ の DataFrame
4. 分析・実装「欠損メカニズム」を適用。 パラメータ・前提条件を文書化。 結果を保存。pandas, sklearn, scipy, statsmodelsresults/ のテーブル・図
5. 報告図表 + 解釈 + 限界を整理。 再現性のためコードと環境(requirements.txt)を添付。Jupyter, Quarto, Markdownレポート(HTML/PDF)

推奨ディレクトリ構成

project/
├── data/
│   ├── raw/        # 取得した生データ(git にコミットして再現性確保)
│   └── processed/  # 前処理後の中間ファイル
├── notebooks/      # 探索的分析の Jupyter
├── src/            # 本番コード(モジュール化)
│   ├── preprocess.py
│   ├── analyze.py  # ← 欠損メカニズム の実装
│   └── visualize.py
├── results/        # 出力(CSV, PNG, モデルファイル)
├── docs/           # レポート、 図表説明
├── requirements.txt
└── README.md       # 「目的・データ・手順・結論」を 1 枚で

⚖️ 同種ツール・手法の比較

「欠損メカニズム」と並んで現場で使われる代替・関連手段を整理。 「どれが正解」ではなく「状況に応じて使い分ける」のが実務。

選択肢強み弱み推奨シーン
本命:欠損メカニズム標準的・実装が豊富・解釈しやすい適用条件あり仮説が明確で、 条件を満たすデータ
古典的代替案計算が軽い・教科書通り柔軟性に欠ける小規模データ、 教育用
ベイズ的代替案不確実性を確率分布で表現事前分布の選択が議論を呼ぶサンプル小、 事前知識あり
機械学習的代替案非線形・高次元に対応解釈性が低い、 過学習リスク予測重視、 大規模データ
ノンパラ・ロバスト代替案分布仮定に頼らないパワーが下がる分布が不明、 外れ値多い

⚡ パフォーマンス・スケーラビリティの目安

データ規模「欠損メカニズム」の典型計算時間必要メモリ推奨ツール
小(〜1 万行)1 秒未満〜100 MBpandas, numpy のみ
中(〜100 万行)数秒〜数分1〜4 GBpandas + 適切なベクトル化
大(〜1 億行)分〜時間16 GB+Polars / Dask / DuckDB
超大(〜100 億行)時間〜日分散環境Spark / BigQuery / Snowflake

高速化テクニック 5 つ

🧪 品質保証 — 再現性・正確性チェック

テストすべき項目

テスト種別内容ツール例
ユニットテスト個別関数が期待通りの値を返すかpytest, unittest
スキーマテストDataFrame の列・型・値域が想定通りかpandera, great_expectations
回帰テスト既知の入力に対する出力が変わっていないかpytest + 固定 seed
性能テスト計算時間・メモリが許容範囲かpytest-benchmark, memory_profiler
再現性テスト同じ入力で必ず同じ出力か(seed 固定)numpy.random.seed (※学習目的のみ)

最小限のテストコード例

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
import pytest
import pandas as pd
from src.analyze import missing_mechanism_function  # 仮の関数名

def test_basic_output():
    df = pd.read_csv('data/raw/SSDSE-B-2026.csv', encoding='utf-8', skiprows=1)
    result = missing_mechanism_function(df)
    assert result is not None
    assert len(result) > 0

def test_handles_missing():
    df = pd.DataFrame({'x': [1, 2, None, 4]})
    result = missing_mechanism_function(df)
    assert result.isnull().sum() == 0  # 仕様: NaN を除いて返す

def test_reproducible():
    df = pd.read_csv('data/raw/SSDSE-B-2026.csv', encoding='utf-8', skiprows=1)
    r1 = missing_mechanism_function(df)
    r2 = missing_mechanism_function(df)
    pd.testing.assert_frame_equal(r1, r2)

📚 関連論文・教科書(学習ロードマップ)

レベル推奨書籍/論文著者備考
入門Pythonによるデータ分析入門 (第3版)Wes McKinneypandas 公式バイブル
入門データサイエンス 100 本ノックThe Quest 創業者実装演習
中級Python Data Science HandbookJake VanderPlasNumPy/pandas/sklearn/matplotlib 一気通貫
中級R for Data Science (2e)Hadley Wickhamtidy 思想の理論
中級Statistical Rethinking (2e)Richard McElreathベイズ統計の名著
上級Elements of Statistical LearningHastie, Tibshirani, Friedman機械学習の数理
上級Causal Inference: The MixtapeScott Cunningham因果推論
論文「ggplot2: Elegant Graphics for Data Analysis」Wickham可視化哲学

公的データソース(欠損メカニズム の練習用)

📝 レポート・論文での記述テンプレート

Methods 節(コピペ可)

「本研究では、 47 都道府県の社会経済指標(SSDSE-B-2026)について、 欠損メカニズム(Missing Data Mechanism)を用いて [目的] を分析した。 適用条件として [前提条件] を確認し、 [パラメータ設定] を採用した。 計算には Python 3.11、 pandas 2.2.0、 [当該ライブラリ] を使用した。 再現性のためコードは GitHub に公開している。」

Results 節(コピペ可)

「欠損メカニズムの結果、 [指標] = [値](95% CI: [下限–上限])が得られた。 表 X に [比較対象] との対比を示す。 [予想と一致/予想と異なる] 結果であり、 [解釈] と考えられる。 ロバストネスチェックとして [代替手法] でも同様の結論を確認した。」

Discussion 節(コピペ可)

「本研究の限界として、 (1) 観察データに基づくため因果関係を厳密には主張できない、 (2) 欠損メカニズムの前提である [前提] が完全には満たされない可能性、 (3) サンプルが 47 都道府県に限定される、 が挙げられる。 今後は [追加データ・追加手法] による頑健性検証が望まれる。」