観測予測モデル(自己回帰・マスク予測・拡散)

観測予測では「どの条件で次を当てるか」の設計が重要です。自己回帰・マスク予測・拡散は同じ予測問題に対して異なる情報の使い方をします。

次を当てるにも、見てよい情報の範囲が違う

観測予測モデルと一口に言っても、自己回帰のように過去だけを使うもの、マスク予測のように前後から穴埋めするもの、拡散のようにノイズを削りながら戻すものでは、条件づけのしかたがまるで違います。

この違いは、そのまま向いているタスクの違いになります。逐次予測をしたいのか、欠損を埋めたいのか、ノイズに強くしたいのかで、同じ『予測』でも設計を変える必要があります。

三つの予測は、何を入力にしてよいかで分かれる

自己回帰は過去だけ、マスク予測は周辺文脈、拡散はノイズを帯びた全体から少しずつ元へ戻します。ここでは 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 の要点は、三方式を順位づけすることではありません。何を条件として観測を予測するのか、その違いがモデル選択そのものを決めると見ることです。