Python 任意多元函数的有效抽样

Python 任意多元函数的有效抽样,python,distribution,sampling,Python,Distribution,Sampling,我想从Python中的任意函数中进行示例 其中指出可以使用逆变换采样,并提到应使用逆累积分布函数。据我所知,这些方法只适用于单变量情况。不过,我的函数是多元的,太复杂了,中的任何建议都不适用 基本原理:我的函数是基于Rosenbrock的香蕉函数,我们可以用这个值得到函数的值 import scipy.optimize scipy.optimize.rosen([1.1,1.2]) (此处[1.1,1.2]是输入向量)来自scipy,请参阅 下面是我的想法:我在我感兴趣的区域上做一个网格,然后

我想从Python中的任意函数中进行示例

其中指出可以使用逆变换采样,并提到应使用逆累积分布函数。据我所知,这些方法只适用于单变量情况。不过,我的函数是多元的,太复杂了,中的任何建议都不适用

基本原理:我的函数是基于Rosenbrock的香蕉函数,我们可以用这个值得到函数的值

import scipy.optimize
scipy.optimize.rosen([1.1,1.2])
(此处
[1.1,1.2]
是输入向量)来自scipy,请参阅

下面是我的想法:我在我感兴趣的区域上做一个网格,然后计算每个点的函数值。然后,我按值对结果数据帧进行排序,并进行累计和。通过这种方式,我们得到了大小不同的“槽”——具有大函数值的点比具有小函数值的点具有更大的槽。现在,我们生成随机值,并查看随机值落在哪个插槽中。数据框的行是我们的最终示例

代码如下:

import scipy.optimize
from itertools import product
from dfply import *

nb_of_samples = 50
nb_of_grid_points = 30

rosen_data = pd.DataFrame(array([item for item in product(*[linspace(fm[0], fm[1], nb_of_grid_points) for fm in zip([-2,-2], [2,2])])]), columns=['x','y'])
rosen_data['z'] = [np.exp(-scipy.optimize.rosen(row)**2/500) for index, row in rosen_data.iterrows()]
rosen_data = rosen_data >> \
    arrange(X.z) >> \
    mutate(z_upperbound=cumsum(X.z)) >> \
    mutate(z_upperbound=X.z_upperbound/np.max(X.z_upperbound))
value = np.random.sample(1)[0]

def get_rosen_sample(value):
    return (rosen_data >> mask(X.z_upperbound >= value) >> select(X.x, X.y)).iloc[0,]

values = pd.DataFrame([get_rosen_sample(s) for s in np.random.sample(nb_of_samples)])
这很有效,但我认为效率不高。对我的问题有什么更有效的解决办法


我读到马尔可夫链蒙特卡罗可能会有所帮助,但现在我对如何在Python中实现这一点有些不知所措。

我也遇到过类似的情况,因此,我实现了Metropolis Hastings的基本版本(这是一种MCMC方法),以从二元分布中进行采样。下面是一个例子

比如说,我们想从以下丹尼斯店取样:

def density1(z):
    z = np.reshape(z, [z.shape[0], 2])
    z1, z2 = z[:, 0], z[:, 1]
    norm = np.sqrt(z1 ** 2 + z2 ** 2)
    exp1 = np.exp(-0.5 * ((z1 - 2) / 0.8) ** 2)
    exp2 = np.exp(-0.5 * ((z1 + 2) / 0.8) ** 2)
    u = 0.5 * ((norm - 4) / 0.4) ** 2 - np.log(exp1 + exp2)
    return np.exp(-u)
看起来像这样

以下函数实现MH,建议使用多元正态分布

def metropolis_hastings(target_density, size=500000):
    burnin_size = 10000
    size += burnin_size
    x0 = np.array([[0, 0]])
    xt = x0
    samples = []
    for i in range(size):
        xt_candidate = np.array([np.random.multivariate_normal(xt[0], np.eye(2))])
        accept_prob = (target_density(xt_candidate))/(target_density(xt))
        if np.random.uniform(0, 1) < accept_prob:
            xt = xt_candidate
        samples.append(xt)
    samples = np.array(samples[burnin_size:])
    samples = np.reshape(samples, [samples.shape[0], 2])
    return samples


查看我的详细信息。

这有效吗?诚然,我只是读了你的帖子,还没有理解。你能详细介绍一下大都会黑斯廷斯吗?
samples = metropolis_hastings(density1)
plt.hexbin(samples[:,0], samples[:,1], cmap='rainbow')
plt.gca().set_aspect('equal', adjustable='box')
plt.xlim([-3, 3])
plt.ylim([-3, 3])
plt.show()