从任意多元函数中有效采样

2024-04-20

我想从 Python 中的任意函数中采样。

In 快速任意分布随机抽样 https://stackoverflow.com/questions/21100716/fast-arbitrary-distribution-random-sampling据说可以使用逆变换采样以不同概率选择列表元素的 Pythonic 方法 https://stackoverflow.com/questions/4113307/pythonic-way-to-select-list-elements-with-different-probability有人提到应该使用逆累积分布函数。据我了解,这些方法仅适用于单变量情况。我的函数是多变量的,而且太复杂,因此中的任何建议https://stackoverflow.com/a/48676209/4533188 https://stackoverflow.com/a/48676209/4533188会适用。

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

import scipy.optimize
scipy.optimize.rosen([1.1,1.2])

(here [1.1,1.2]是来自 scipy 的输入向量,请参阅https://docs.scipy.org/doc/scipy-0.15.1/reference/ generated/scipy.optimize.rosen.html https://docs.scipy.org/doc/scipy-0.15.1/reference/generated/scipy.optimize.rosen.html.

这就是我的想法:我在感兴趣的区域上绘制了一个网格,并计算每个点的函数值。然后,我按值对结果数据框进行排序并进行累积和。这样我们就得到了具有不同大小的“槽”——具有大函数值的点比具有小函数值的点具有更大的槽。现在我们生成随机值并查看随机值落入哪个槽。数据框的行是我们的最终样本。

这是代码:

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

运行 MH 并绘制样本

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()

查看这个仓库 https://github.com/abdulfatir/sampling-methods-numpy/我的详细信息。

本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

从任意多元函数中有效采样 的相关文章

  • from __future__ importabsolute_import 实际上做了什么?

    I have answered https stackoverflow com a 22679558 2588818一个关于Python中绝对导入的问题 我认为我通过阅读理解了这个问题Python 2 5 变更日志 https docs p
  • Python:我可以修改元组吗?

    我有一个 2 D 元组 实际上我以为 它是一个列表 但错误说它是一个元组 但无论如何 该元组的形式为 浮点数 val prod id 现在我有一个字典 其中包含 key gt prod id 和 value prod name 现在 我想将
  • 将 python scikit learn 模型导出到 pmml

    我想将 python scikit learn 模型导出到 PMML 中 什么 python 包最适合 我读到Augustus https github com opendatagroup augustus 但我找不到任何使用 scikit
  • 在 Windows 上使用 Python 打开设备句柄

    我正在尝试使用 Giveio sys 驱动程序 该驱动程序需要先打开一个 文件 然后才能访问受保护的内存 我正在查看 WinAVR AVRdude 中的 C 示例 它使用以下语法 define DRIVERNAME giveio HANDL
  • 不要在异常堆栈中显示 Python raise-line

    当我在 Python 库中引发自己的异常时 异常堆栈将引发行本身显示为堆栈的最后一项 这显然不是一个错误 在概念上是正确的 但是当您在外部使用代码 例如作为模块 时 它会将重点放在对调试无用的东西上 有没有办法避免这种情况并强制 Pytho
  • 如何在 for 循环中跳过一些迭代

    在 python 中 我通常简单地循环遍历范围 for i in range 100 do something 但现在我想跳过循环中的几个步骤 更具体地说 我想要类似的东西continue 10 这样它就会跳过整个循环并将计数器增加 10
  • 使用 Python 连接从 FTP 检索文件

    我构建了这个简单的工具来暴力破解并连接到 ftp 服务器 import socket import ftplib from ftplib import FTP port 21 ip 192 168 1 108 file1 passwords
  • 在 python 中返回 self [关闭]

    Closed 这个问题需要多问focused help closed questions 目前不接受答案 我有一个代表对象的类 我有很多方法可以修改这个对象状态 没有明显的返回或显然没有任何返回 在 C 中 我会将所有这些方法声明为void
  • AWS Lambda - 在区域之间自动复制 EC2 快照?

    我想创建一个 Lambda 函数 python 它将自动将已创建的快照复制到另一个区域 我已联系 AWS Support 他们只向我发送了用于 RDS 数据库的 GitHub 脚本 没有 EC2 快照复制脚本 任何帮助都会很棒 谢谢 是的
  • 使用自定义元素类在 Python 中解析 xml

    我想使用 Python 的 xml etree ElementTree 模块解析 xml 文档 但是 我希望生成的树对象中的所有元素都具有我定义的一些类方法 这建议创建我自己的 Python 元素类的子类 但我无法告诉解析器在解析时使用我自
  • 为什么我在 Python 中收到“连接被拒绝”错误? (插座)

    我是套接字新手 请原谅我完全缺乏理解 我有一个服务器脚本 server py usr bin python import socket import the socket module s socket socket Create a so
  • 在 AWS Elastic Beanstalk 中部署 Flask 应用程序

    当我部署 Flask 应用程序时 它显示成功 但是当我检索日志时 我看到错误 找不到 Flask 我的需求文件中有烧瓶 任何帮助 Sat Jan 11 06 51 50 503908 2020 error pid 3393 remote 1
  • 如何将当前日期分配给 odoo v8 中的日期字段?

    我想将当前日期分配给以下代码中的日期字段 start date calendar obj create cr uid name rec res act ion user id rec res asgnd to id start date l
  • 在用户提交的正则表达式中查找捕获组

    我有一个 python 应用程序 需要处理用户提交的正则表达式 出于性能考虑 我想禁止捕获组和反向引用 我的想法是使用另一个正则表达式来验证用户提交的正则表达式不包含任何命名或未命名的组捕获 如下所示 def validate user r
  • 有没有更快的方法将数字转换为名称?

    以下代码定义了映射到数字的名称序列 它的设计目的是获取一个号码并检索一个特定的名称 该类通过确保名称存在于其缓存中来进行操作 然后通过索引到其缓存中来返回名称 问题在这 如何在不存储缓存的情况下根据数字计算出名称 该名称可以被认为是一个以
  • 为什么删除 DataFrame 的列或部分会增加内存使用量,以及如何确保对未使用的 DataFrame 切片进行垃圾回收

    处理大型 DataFrame 时 您需要小心内存使用情况 例如 您可能想要分块下载大数据 处理这些块 然后从内存中删除所有不必要的部分 我找不到任何有关处理垃圾收集的最佳程序的资源pandas 但我尝试了以下方法并得到了令人惊讶的结果 im
  • numpy.polyfit 没有关键字“cov”

    我试图使用 polyfit 来找到一组数据的最佳拟合直线 但我还需要知道参数的不确定性 所以我也想要协方差矩阵 在线文档建议我写 polyfit x y 2 cov True 但这给出了错误 类型错误 polyfit 得到了意外的关键字参数
  • python字符串包含双引号字符

    我的输入字符串由字符组成 包括双引号和单引号 和 B SS JU PQ AD DDSFD ABD E J 但是 当我从文本文件打开上述输入并打印它时 第三行中的双引号 被打印为 xe2 x80 x9d 我的目标是进行简单的字符计数 B 2
  • 如何在Python中检查元组是否包含元素?

    我试图找到可用的方法 但找不到 没有contains 我应该使用index 我只想知道该项目是否存在 不需要它的索引 You use in if element in thetuple whatever you want to do
  • 在大型文本文件中查找重复记录

    我在一台 Linux 机器 Redhat 上 并且有一个 11GB 的文本文件 文本文件中的每一行包含单个记录的数据 并且该行的前 n 个字符包含该记录的唯一标识符 该文件包含略多于 2700 万条记录 我需要验证文件中不存在具有相同唯一标

随机推荐