観測予測モデル(自己回帰・マスク予測・拡散)
観測予測では「どの条件で次を当てるか」の設計が重要です。自己回帰・マスク予測・拡散は同じ予測問題に対して異なる情報の使い方をします。
次を当てるにも、見てよい情報の範囲が違う
観測予測モデルと一口に言っても、自己回帰のように過去だけを使うもの、マスク予測のように前後から穴埋めするもの、拡散のようにノイズを削りながら戻すものでは、条件づけのしかたがまるで違います。
この違いは、そのまま向いているタスクの違いになります。逐次予測をしたいのか、欠損を埋めたいのか、ノイズに強くしたいのかで、同じ『予測』でも設計を変える必要があります。
三つの予測は、何を入力にしてよいかで分かれる
自己回帰は過去だけ、マスク予測は周辺文脈、拡散はノイズを帯びた全体から少しずつ元へ戻します。ここでは 1 次元系列でその差を単純化し、情報の流れの違いがどう誤差に現れるかを見ます。
この notebook の見どころ
三つの MSE をただ比べるのではなく、どの条件でその予測が成り立っているかを意識しながら読みます。とくに mask_idx の穴埋めと反復デノイズは、使える情報の範囲が大きく違います。
数値は同じ系列から計算していますが、タスク設定まで完全に同一ではありません。だから『どれが一番強いか』ではなく、『何を入力にしてよい設計か』として比較してください。
反復計算が増える意味
拡散型は一回で答えを出す代わりに、少しずつ戻る方向を積み上げます。計算は重くなりますが、ノイズに対して粘り強い復元がしやすく、その性格がここでも少し見えます。
読み方の軸
逐次予測、欠損補完、ノイズ除去を同じ問題だと思わないことが重要です。入力条件の違いがそのままモデルの役割の違いになります。
過去だけを見て次を当てる
まずは自己回帰の流儀で、順番に次の値を予測する形を確認します。
import numpy as np
np.random.seed(1)
T = 80
t = np.arange(T)
series = np.sin(t / 6.0) + 0.1 * np.random.randn(T)
周辺情報やデノイズで埋める
続いて、穴埋め型と拡散型の復元を並べ、使える文脈の違いがどこに効くかを見ます。
# 1) 自己回帰: x_t = a*x_{t-1} + b
x = series[:-1]
y = series[1:]
a = np.dot(x, y) / np.dot(x, x)
b = y.mean() - a * x.mean()
ar_pred = a * x + b
ar_mse = np.mean((ar_pred - y) ** 2)
# 2) マスク予測: 中央点を前後平均で補完
mask_idx = np.arange(1, T - 1, 5)
masked = series.copy()
masked[mask_idx] = np.nan
filled = masked.copy()
for i in mask_idx:
filled[i] = 0.5 * (masked[i - 1] + masked[i + 1])
mask_mse = np.mean((filled[mask_idx] - series[mask_idx]) ** 2)
# 3) 拡散風予測: ノイズ付加 -> 逐次平滑で復元
noisy = series + 0.35 * np.random.randn(T)
den = noisy.copy()
for _ in range(20):
den[1:-1] = 0.25 * den[:-2] + 0.5 * den[1:-1] + 0.25 * den[2:]
diff_mse = np.mean((den - series) ** 2)
print('AR MSE =', round(ar_mse, 6))
print('Mask-fill MSE =', round(mask_mse, 6))
print('Diffusion-like =', round(diff_mse, 6))
この notebook の要点は、三方式を順位づけすることではありません。何を条件として観測を予測するのか、その違いがモデル選択そのものを決めると見ることです。