我有一个理论分布,我想在2D空间中随机采样以进行以下分布:
def p(z,m):
E = { 'ft':0.55, 'alpha': 2.99, 'z0':0.191, 'km':0.089, 'kt':0.25 }
S = { 'ft':0.39, 'alpha': 2.15, 'z0':0.121, 'km':0.093, 'kt':-0.175 }
I={ 'ft':0.06, 'alpha': 1.77, 'z0':0.045, 'km':0.096, 'kt':0.0 }
Evalue=E['ft']*np.exp(-1*E['kt']*(m-20))*z**E['alpha']*np.exp(-1*(z/(E['z0']+E['km']*(m-20)))**E['alpha'])
Svalue=S['ft']*np.exp(-1*S['kt']*(m-20))*z**S['alpha']*np.exp(-1*(z/(S['z0']+S['km']*(m-20)))**S['alpha'])
Ivalue=I['ft']*np.exp(-1*I['kt']*(m-20))*z**I['alpha']*np.exp(-1*(z/(I['z0']+I['km']*(m-20)))**I['alpha'])
value=Evalue+Svalue+Ivalue
return value
更新: 我发现逆变换采样是从概率分布中采样数据的合适方法。 我如何在python中为2D数据编程这个方法,或者我可以使用任何库吗?
答案 0 :(得分:1)
看看马尔可夫链蒙特卡洛(MCMC)的方法。基本上你会跳过(z,m)点的空间。无论你身在何处,你总是接受一个增加p(z,m)的跳跃。你接受一个以一定概率降低p(z,m)的跳跃。有一个Python库PyMC来执行该过程。
答案 1 :(得分:-1)
如果你想从p(z,m)中随机抽样一个值,那么实现它的一个简单方法就是在python中使用'random'模块。我使用numpy的随机版本来展示这个想法:
import numpy as np
import matplotlib.pyplot as plt
def p(z,m):
E = { 'ft':0.55, 'alpha': 2.99, 'z0':0.191, 'km':0.089, 'kt':0.25 }
S = { 'ft':0.39, 'alpha': 2.15, 'z0':0.121, 'km':0.093, 'kt':-0.175 }
I={ 'ft':0.06, 'alpha': 1.77, 'z0':0.045, 'km':0.096, 'kt':0.0 }
Evalue=E['ft']*np.exp(-1*E['kt']*(m-20))*z**E['alpha']*np.exp(-1*(z/(E['z0']+E['km']*(m-20)))**E['alpha'])
Svalue=S['ft']*np.exp(-1*S['kt']*(m-20))*z**S['alpha']*np.exp(-1*(z/(S['z0']+S['km']*(m-20)))**S['alpha'])
Ivalue=I['ft']*np.exp(-1*I['kt']*(m-20))*z**I['alpha']*np.exp(-1*(z/(I['z0']+I['km']*(m-20)))**I['alpha'])
value=Evalue+Svalue+Ivalue
return value
# Define the number of iterations you want for each variable
num_iter_m = 50
num_iter_z = 50
# I then set rand_m to go from 20 to 30, as your function fails for <20
rand_m = (np.random.random(num_iter_m)*10)+20
# z goes from the range 0 - 1
rand_z = (np.random.random(num_iter_z))
# Note, I am sampling from a uniform distribution for m and z. You can use more complicated functions, i.e., Gaussian/Normal shapes or even user defined.
rand_p = np.zeros((len(rand_z), len(rand_m)))
# Fill a grid with the random p(z,m) values
for i in range(len(rand_z)):
for j in range(len(rand_m)):
rand_p[i][j] = p(rand_z[i], rand_m[j])
# Plot
fig = plt.figure(0)
ax1 = fig.add_subplot(211)
ax1.scatter(rand_z, rand_m)
ax1.set_xlabel("z")
ax1.set_ylabel("m")
ax2 = fig.add_subplot(212)
cf = ax2.contourf(rand_z, rand_m, rand_p)
ax2.set_xlabel("z")
ax2.set_ylabel("m")
colbar = plt.colorbar(cf)
colbar.set_label("p(z,m)")
plt.show()
以更复杂的方式使用的特定模块将是例如PyMC( https://github.com/pymc-devs/pymc)或主持人(http://dan.iel.fm/emcee/current/)。
如果你想用2D函数p(z,m)对z和m加权进行采样,这有点复杂。