Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/python/338.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Python 离散浮动网格中的PyMC离散Metropolis_Python_Pymc - Fatal编程技术网

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或值t_h或值几天前我设法解决了我的问题。令我惊讶的是,我在Facebook群组中的一些天文学朋友也对这个问题感兴趣,所以我认为发布我的解决方案可能会很有用,以防其他人也有同样的问题。请注意,这个解决方案可能不是解决这个问题的最佳方法,事实上,我相信还有更优雅的方法。但现在,这是我能想到的最好的了。希望这对你们中的一些人有所帮助

我解决这个问题的方法非常简单,我总结如下

1> 定义斜率,y_截取连续形式的随机变量(
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()