Python 离散浮动网格中的PyMC离散Metropolis
目前,我正在尝试解决天体物理学中的一个问题,可以简化为: 我想将一个线性模型(比如说Python 离散浮动网格中的PyMC离散Metropolis,python,pymc,Python,Pymc,目前,我正在尝试解决天体物理学中的一个问题,可以简化为: 我想将一个线性模型(比如说y=a+b*x)拟合到观测数据中,并希望使用PyMC来描述离散网格参数空间中a和b的后验特征,如下图所示: 我知道PyMC有DiscreteMetropolis类在离散空间中查找后验值,但这是在整数空间中,而不是在自定义离散空间中。所以我想定义一个潜在的强制PyMC在网格中搜索,但效果不好…有人能帮忙吗?还是有人解决了类似的问题?任何想法都将不胜感激:) 这是我的代码草案,注释掉潜在类是我强制PyMC在网格中搜
y=a+b*x
)拟合到观测数据中,并希望使用PyMC
来描述离散网格参数空间中a和b的后验特征,如下图所示:
我知道PyMC
有DiscreteMetropolis
类在离散空间中查找后验值,但这是在整数空间中,而不是在自定义离散空间中。所以我想定义一个潜在的强制PyMC在网格中搜索,但效果不好…有人能帮忙吗?还是有人解决了类似的问题?任何想法都将不胜感激:)
这是我的代码草案,注释掉潜在类是我强制PyMC在网格中搜索的想法:
import sys
import matplotlib.pyplot as plt
import numpy as np
from scipy import stats
import pymc
#------------------------------------------------------------
# Generate the data
size = 200
slope_true = 12.3
y_intercept_true = 22.4
x = np.linspace(0, 1, size)
# y = a + b*x
y_true = y_intercept_true + slope_true * x
# add noise
y = y_true + np.random.normal(scale=.03, size=size)
# Define searching parameter space
# Note: this is discrete but not in the form of integer
slope_search_space = np.linspace(1,30,51)
y_intercept_search_space = np.linspace(1,30,51)
#------------------------------------------------------------
#Start initializing PyMC
@pymc.stochastic(dtype=int)
def slope(value = 5, t_l=1, t_h=30):
"""The switchpoint for the rate of disaster occurrence."""
def logp(value, t_l, t_h):
if value > t_h or value < t_l:
return -np.inf
else:
return -np.log(t_h - t_l + 1)
#@pymc.potential
#def slope_prior(val=slope,t_l=-30, t_h=30):
# if val not in slope_search_space:
# return -np.inf
# return -np.log(t_h - t_l + 1)
#---
@pymc.stochastic(dtype=int)
def y_intercept(value=4, t_l=1, t_h=30):
"""The switchpoint for the rate of disaster occurrence."""
def logp(value, t_l, t_h):
if value > t_h or value < t_l:
return -np.inf
else:
return -np.log(t_h - t_l + 1)
#@pymc.potential
#def y_intercept_prior(val=y_intercept,t_l=-30, t_h=30):
# if val not in y_intercept_search_space:
# return -np.inf
# return -np.log(t_h - t_l + 1)
# Define observed data
@pymc.deterministic
def mu(x=x, slope=slope, y_intercept=y_intercept):
# Linear age-price model
return y_intercept + slope*x
# Sampling distribution of prices
p = pymc.Poisson('p', mu, value=y, observed=True)
model = dict(slope=slope, y_intercept=y_intercept, mu=mu, p=p)
#-----------------------------------------------------------
# perform the MCMC
M = pymc.MCMC(model)
trace = M.sample(iter=10000,burn=5000)
#Plot
pymc.Matplot.plot(M)
plt.figure()
pymc.Matplot.summary_plot([M.slope,M.y_intercept])
plt.show()
导入系统
将matplotlib.pyplot作为plt导入
将numpy作为np导入
从scipy导入统计信息
导入pymc
#------------------------------------------------------------
#生成数据
尺寸=200
斜率_真=12.3
y_截距_真=22.4
x=np.linspace(0,1,大小)
#y=a+b*x
y_真=y_截距_真+斜率_真*x
#增加噪音
y=y_真+np.random.normal(比例=0.03,大小=size)
#定义搜索参数空间
#注意:这是离散的,但不是整数形式
斜率搜索空间=np.linspace(1,30,51)
y_截距_搜索空间=np.linspace(1,30,51)
#------------------------------------------------------------
#开始初始化PyMC
@pymc.randomic(dtype=int)
def斜率(值=5,t_l=1,t_h=30):
“”“灾难发生率的切换点。”“”
def logp(值、t_l、t_h):
如果值>t_h或值PyMC
然后使用Metropolis
进行采样)
2> 定义一个函数find_nearest
,将连续随机变量斜率、y_截距映射到网格,例如Grid_slope=np。数组([1,2,3,4,…51])
,slope=4.678
,然后find_nearest(Grid_slope,slope)
将返回5,因为网格_slope中的斜率值最接近5。与y_截距变量类似
3> 当计算似然度时,这就是我的窍门,我将查找最近的
函数应用于似然函数中的模型,即将模型(斜率,y_截距)
更改为模型(查找最近的(网格斜率,斜率),查找最近的(网格y_截距,y_截距))
,它将仅在网格参数空间中计算似然
4> PyMC
为斜率和y_截距返回的跟踪可能不是严格意义上的网格值,您可以使用find_nearest
函数将跟踪映射到网格值,然后从中进行任何统计推断。就我而言,我只是直接使用跟踪来获得统计数据,结果很好:)
加上一个用于排列“=”符号。
import sys
import matplotlib.pyplot as plt
import numpy as np
from scipy import stats
import pymc
#------------------------------------------------------------
# Generate the data
size = 200
slope_true = 12.3
y_intercept_true = 22.4
x = np.linspace(0, 1, size)
# y = a + b*x
y_true = y_intercept_true + slope_true * x
# add noise
y = y_true + np.random.normal(scale=.03, size=size)
# Define searching parameter space
# Note: this is discrete but not in the form of integer
slope_search_space = np.linspace(1,30,51)
y_intercept_search_space = np.linspace(1,30,51)
#------------------------------------------------------------
#Start initializing PyMC
from pymc import Normal, Gamma, deterministic, MCMC, Matplot, Uniform
# Constant priors for parameters
slope = Uniform('slope', 1, 30)
y_intercept = Uniform('y_intp', 1, 30)
# Precision of normal distribution of y value
tau = Uniform('tau',0,10000 )
@deterministic
def mu(x=x,slope=slope, y_intercept=y_intercept):
def find_nearest(array,value):
"""
This function maps 'value' to the nearest point in 'array'
"""
idx = (np.abs(array-value)).argmin()
return array[idx]
# Linear model
iso = find_nearest(y_intercept_search_space,y_intercept) + find_nearest(slope_search_space,slope)*x
return iso
# Sampling distribution of y
p = Normal('p', mu, tau, value=y, observed=True)
model = dict(slope=slope, y_intercept=y_intercept,tau=tau, mu=mu, p=p)
#-----------------------------------------------------------
# perform the MCMC
M = pymc.MCMC(model)
trace = M.sample(40000,20000)
#Plot
pymc.Matplot.plot(M)
M.slope.summary()
M.y_intercept.summary()
plt.figure()
pymc.Matplot.summary_plot([M.slope,M.y_intercept])
plt.show()