Intrinsic CARモデルについては下記サイトを参考にしました。 http://glau.ca/?p=340
In [1]:
import pymc
import numpy
import pandas
import scipy
In [29]:
import os
import urllib
import pandas
import pandas.rpy.common as com
def fetch_rdata():
src = "http://hosho.ees.hokudai.ac.jp/~kubo/stat/iwanamibook/fig/spatial/Y.RData"
if (not os.path.exists('data')):
os.makedirs('data')
urllib.urlretrieve(src, 'data/Y.RData')
ret = pandas.DataFrame({'Y':com.load_data('Y'), 'm':com.load_data('m')})
return ret
In [30]:
def draw_figure_11_2():
df = fetch_rdata()
xx = range(len(df))
y1 = df['Y'].values
y2 = df['m'].values
plot(xx, y1, 'ow')
plot(xx, y2, 'k--')
xlabel(u"位置$j$")
ylabel(u"個体数$y_j$")
ylim(0, 25)
return
In [31]:
figure(figsize(8,7))
draw_figure_11_2()
plt.show()
In [62]:
N = 50
# 観測ベクトル
Y = fetch_rdata()['Y'].values
# 隣接ベクトル(muの計算に用いる)
a1 = np.arange(N)
a2 = map(list, zip(a1-1, a1+1))
a2[0] = [1]
a2[-1] = [49]
A = np.asarray(a2)
# 重みベクトル(muの計算に用いる)
W = np.asarray(map(lambda x: [x**(-1)]*x, map(len, A)))
# n_jベクトル(sigmaの計算に用いる)
Wplus = array([len(w) for w in W])
In [63]:
Y
Out[63]:
In [64]:
A
Out[64]:
In [65]:
W
Out[65]:
In [66]:
Wplus
Out[66]:
In [81]:
### hyper priors
beta = pymc.Normal('beta', mu=0, tau=1.0e-4)
s = pymc.Uniform('s', lower=0, upper=1.0e+4)
tau = pymc.Lambda('tau', lambda s=s: s**(-2))
### Intrinsic CAR
@pymc.stochastic
def R(tau=tau, value=np.zeros(N)):
# Calculate mu based on average of neighbors
mu = np.array([sum(W[i]*value[A[i]])/Wplus[i] for i in xrange(N)])
# Scale precision to the number of neighbors
taux = tau*Wplus
return pymc.normal_like(value, mu, taux)
@pymc.deterministic
def M(beta=beta, R=R):
return [np.exp(beta + R[i]) for i in xrange(N)]
obsvd = pymc.Poisson("obsvd", mu=M, value=Y, observed=True)
model = pymc.Model([s, beta, obsvd])
In [82]:
# グラフィカルモデルの描画
# require pydot and graphviz
import pydot
import scipy.misc
pymc.graph.graph(model, format='png', path='',name='model',prog='dot')
figure(figsize=(8, 8))
imshow(imread('model.png'))
Out[82]:
In [83]:
mcmc = pymc.MCMC(model)
mcmc.sample(iter=10000, burn=1000, thin=10)
In [84]:
# サンプリング過程の可視化
pymc.Matplot.plot(mcmc.trace("beta"), common_scale=False)
In [85]:
# サンプリング過程の可視化
pymc.Matplot.plot(mcmc.trace("s"), common_scale=False)
In [86]:
def draw_figure_11_4(burnin=0):
b = np.mean(mcmc.trace('beta')[burnin:, None].flatten())
R = np.mean(mcmc.trace("R")[burnin:, None], axis=0).flatten()
xx = np.arange(N)
yy = np.exp(b + R)
draw_figure_11_2()
plot(xx, yy, 'k-')
return
In [87]:
figure(figsize(8,7))
draw_figure_11_4(burnin = 700) #betaやsの振る舞いが安定してきたあたりをburninに設定.
plt.show()
$\beta$=2.27 に固定する
In [88]:
### hyper priors
beta = 2.27
s = pymc.Uniform('s', lower=0, upper=1.0e+4)
tau = pymc.Lambda('tau', lambda s=s: s**(-2))
### Intrinsic CAR
@pymc.stochastic
def R(tau=tau, value=np.zeros(N)):
# Calculate mu based on average of neighbors
mu = np.array([sum(W[i]*value[A[i]])/Wplus[i] for i in xrange(N)])
# Scale precision to the number of neighbors
taux = tau*Wplus
return pymc.normal_like(value, mu, taux)
@pymc.deterministic
def M(beta=beta, R=R):
return [np.exp(beta + R[i]) for i in xrange(N)]
obsvd = pymc.Poisson("obsvd", mu=M, value=Y, observed=True)
model = pymc.Model([s, beta, obsvd])
mcmc = pymc.MCMC(model)
mcmc.sample(iter=10000, burn=1000, thin=3)
In [89]:
# サンプリング過程の可視化
pymc.Matplot.plot(mcmc.trace("s"), common_scale=False)
In [90]:
def draw_figure_11_5(burnin=0):
s = mcmc.trace('s')[burnin:, None].flatten()
S = [min(s), median(s), percentile(s, 95)]
L = list(s)
I = [L.index(_s) for _s in S]
R = [mcmc.trace('R')[burnin:, None][i].flatten() for i in I]
figure(figsize(8, 21))
beta = 2.27
xx = np.arange(N)
P = [311, 312, 313]
for i in xrange(3):
subplot(P[i])
draw_figure_11_2()
plot(xx, np.exp(beta+R[i]), 'k-')
title("s={0}".format(S[i]))
In [91]:
draw_figure_11_5(burnin=0)
car.normalの実装を確認しなきゃかけなそうなので、ここは時間があったらやります。