バイアスーバリアンス分解:モデルの複雑さの問題
モデルの複雑さの問題として... バイアス-バリアンスのトレードオフ
損失関数:二乗損失関数 L=(t−y(x))2
最適な予測:条件付き期待値 h(x)=E[t∣x]=∫tp(t∣x)dt
二乗損失の期待値(=平均的な誤差)を計算しましょう。
E[L]=∫{y(x)−h(x)}2p(x)dx+∫∫{h(x)−t}2p(x,t)dxdt
一項目から、
{y(x;D)−h(x)}2={y(x;D)−ED[y(x;D)]+ED[y(x;D)]−h(x)}2=(y−ED)2+(ED−h)2+2(y−ED)(ED−h)
∴ ED[{y(x;D)−h(x)}2]=(ED−h)2+ED[(y−ED)2]
と表されます。これは以下の関係を表しています。
二乗損失の期待値=(バイアス)2+(バリアンス)+(ノイズ)
したがって、モデルの複雑さを制御し、**バイアスとバリアンスをバランスよく小さくする**ことで、過学習を防ぐことができます。
ベイズ線形回帰
ベイズ的に扱うことで、モデルの複雑さを回避します。
Liklihood : p(t∣w)=∏n=1NN(tn∣wTϕ(xn),β−1)
Prior : p(w)=N(w∣m0,S0)
Posterior : p(w∣t)∝p(t∣w)p(w)
したがって、今までの結論から、
p(w∣t)=N(w∣mN,SN)
となります。ただし、
{mN=SN(S0−1m0+βΦTt)SN=S0−1+βΦTΦ
となります。簡単にするため、等方的ガウス分布を用いて、
p(w)=p(w∣α)=N(w∣0,α−1I)
とすると、
{mN=βSNΦTtSN=αI+βΦTΦ
となるので、事後分布の対数は、
lnp(w∣t)=−[2βn=1∑N{tn−wTϕ}+2αwTw]+(定数)
となります。したがって、事後分布を最大化するためには、[ ]内を最小化すればよいでしょう。
予測分布:新しい x に対する t の確率分布(不確かさ) を予測する。
p(tnew∣t;α,β)=∫p(tnew∣w;β)p(w∣t;α,β)dw
=N(tnew∣mNTϕ(xnew),σN2(xnew))
ただし、σN2(xnew)=β1+ϕTSNϕ
となり、これは(ノイズ)+(wの不確かさ)を表しています。
▷ データ点の近傍で不確かさは最小となります。データ数を増やせば不確かさが減ります。
α,β=1.0 としたときのベイズ回帰の Python による実装は以下です。データ点と不確かさの関係が確認できます。
alpha=1.0
beta=1.0
N = 20
M = 10
ary_mu = np.linspace(0,1,M)
x_real = np.arange(0, 1, 0.01)
y_real = np.sin(2*np.pi*x_real)
x_train = np.linspace(0,1,N)
y_train = np.sin(2*np.pi*x_train) + np.random.normal(0,0.3,N)
def phi(mus, x):
ret = np.array([np.exp(-(x-mu)**2/(2*0.1**2)) for mu in mus])
ret[0] = 1
return ret
def pred(x_train, y_train,ax):
N = x_train.shape[0]
PHI = np.array([phi(ary_mu,x) for x in x_train]).reshape(N,M)
S = inv(alpha * np.identity(M) + beta * (PHI.T).dot(PHI))
m = beta * (S.dot(PHI.T).dot(y_train.T))
PHI_real = np.array([phi(ary_mu,x) for x in x_real]).reshape(100,M)
pred_mean = PHI_real.dot(m)
pred_std = np.sqrt(1.0/beta + np.diag(PHI_real.dot(S).dot(PHI_real.T)))
ax.plot(x_train, y_train, 'bo')
ax.plot(x_real, y_real, 'g-')
ax.plot(x_real, pred_mean, 'r-')
ax.fill_between(x_real, pred_mean+pred_std, pred_mean-pred_std, color='pink')
ax.set_xlim(0.0, 1.0)
ax.set_ylim(-2, 2)
ax.set_title("N={}".format(N))
f,axes = plt.subplots(1,4,figsize=(15,4))
r = np.arange(N)
np.random.shuffle(r)
for i,k in enumerate((1, 2, 5, N)):
indices = np.sort(r[0:k])
pred(x_train[indices], y_train[indices],axes[i])
等価カーネル(平滑化行列)
今までの結果を回帰式に代入すると、
y(x,mN)=mNTϕ=βϕSNΦTt=n=1∑NβϕSNϕ(xn)tn
∴y(x,mN)=n=1∑Nk(x,xn)tn
と表せます。このk(x,xn)を**等価カーネル**といい、2つ以上のxに対するyの事後分布同士の不確かさを決めます。
Reference
- Bishop, Christopher M. Pattern recognition and machine learning. springer, 2006.