【问题标题】:Latin hypercube sampling with python使用 python 进行拉丁超立方体采样
【发布时间】:2014-10-01 08:30:00
【问题描述】:

我想在多个维度 (2,3,4) 中对函数定义的分布进行采样:

f(x, y, ...) = ...

分布可能是丑陋的、非标准的(如数据上的 3D 样条曲线、高斯之和等)。为此,我想对 2..4 维空间进行均匀采样,然后用一个额外的随机数接受或拒绝空间的给定点进入我的样本。

  1. 是否有现成的可用于此目的的 python 库?

  2. 是否有 python 库用于在这个 2..4 维空间中使用拉丁超立方体采样或其他统一采样方法生成点?具有独立随机数的蛮力采样通常会导致空间的密度越来越大。

  3. 如果 1) 和 2) 不存在,有没有人愿意分享他针对相同或类似问题的实现。

我将在 python 代码中使用它,但也承认指向其他解决方案的链接。

【问题讨论】:

    标签: python random sampling


    【解决方案1】:

    我想这是一个迟到的答案,但这也适用于未来的访客。我刚刚在 git 上发布了 an implementation of multi-dimensional uniform Latin Hypercube sampling。它很小,但非常易于使用。如果您的变量是独立的,您可以使用拉丁超立方抽样生成在 n 维中抽样的均匀随机变量。下面是一个示例图,比较蒙特卡洛和拉丁超立方抽样与多维均匀性 (LHS-MDU) 在二维零相关性。

    import lhsmdu
    import matplotlib.pyplot as plt
    import numpy
    
    l = lhsmdu.sample(2,10) # Latin Hypercube Sampling of two variables, and 10 samples each.
    k = lhsmdu.createRandomStandardUniformMatrix(2,10) # Monte Carlo Sampling
    
    fig = plt.figure()
    ax = fig.gca()
    ax.set_xticks(numpy.arange(0,1,0.1))
    ax.set_yticks(numpy.arange(0,1,0.1))
    plt.scatter(k[0], k[1], color="b", label="LHS-MDU")
    plt.scatter(l[0], l[1], color="r", label="MC")
    plt.grid()
    plt.show()
    

    【讨论】:

    • 这对我来说马上就失败了:ndexError: only integers, slices (:), ellipsis (...), numpy.newaxis (None) and integer or boolean arrays are valid indices .失败的行是 l = lhsmdu.sample(2, 10) (我在 python 3 上)
    • @SantiPeñate-Vera 抱歉回复晚了。这目前仅适用于 Python 2.7,如果您仍打算使用它,我不介意花一些时间使其与 Python 3 兼容。
    • 我现在不急用这个库,但是如果你把它移植到python 3,我一定会用它。
    • 我试图 pip install 'lhsmdu' 但这个名称下没有模块。
    • 早先不在点子上。我现在已经放了。你能再检查一次吗?
    【解决方案2】:

    现在 pyDOE 库提供了一个工具来生成基于拉丁超立方体的样本。

    https://pythonhosted.org/pyDOE/randomized.html

    在 n 维上生成样本:

    lhs(n, [samples, criterion, iterations])
    

    其中n为维数,samples为样本空间的总数。

    【讨论】:

    • 如何指定种子值以便每次都能得到相同的结果?
    • 不确定是否相关,但我将这些值保存在文本文件中,以便以后使用。就个人而言,我没有检查过它的结果在尝试之间会有所不同,但认为在我的硬盘驱动器中保存一份副本可能是个好主意。
    • 问题在于我事先不知道我的“n”和“p”参数。但是,我能够在不修改 pyDOE 源代码的情况下解决我的问题,方法是在我导入 pyDOE 后在我的主脚本中导入 numpy,然后执行 numpy.random.seed(seed_value)。这可确保运行之间的数字相同。
    • pyDOE2 是 pyDOE 的一个分支,仍在维护中。它的一项改进是您可以将随机种子直接传递给lhs
    【解决方案3】:

    这个 2-D 示例在二维上均匀采样,以恒定概率选择每个点(从而保持二项式分布的点数),从样本空间中随机且不替换地选择这些点,并生成一对向量然后你可以传递给你的函数 f:

    import numpy as np
    import random
    resolution = 10
    keepprob = 0.5
    min1, max1 = 0., 1.
    min2, max2 = 3., 11. 
    keepnumber = np.random.binomial(resolution * resolution, keepprob,1)
    array1,array2  = np.meshgrid(np.linspace(min1,max1,resolution),np.linspace(min2,max2,resolution))
    randominixes  = random.sample(list(range(resolution * resolution)), int(keepnumber))
    randominixes.sort()
    vec1Sampled,vec2Sampled  = array1.flatten()[randominixes],array2.flatten()[randominixes]
    

    【讨论】:

      【解决方案4】:

      这里是 Sahil M 对 Python 3 的回答的更新(从 Python 2 更新到 Python 3 以及一些小的代码更改以匹配代码和图形):

      import lhsmdu
      import matplotlib.pyplot as plt
      import numpy
      
      l = lhsmdu.sample(2,10) # Latin Hypercube Sampling of two variables, and 10 samples each.
      k = lhsmdu.createRandomStandardUniformMatrix(2,10) # Monte Carlo Sampling
      
      fig = plt.figure()
      ax = fig.gca()
      ax.set_xticks(numpy.arange(0,1,0.1))
      ax.set_yticks(numpy.arange(0,1,0.1))
      plt.scatter([k[0]], [k[1]], color="r", label="MC")
      plt.scatter([l[0]], [l[1]], color="b", label="LHS-MDU")
      plt.legend()
      plt.grid()
      plt.show()
      

      我曾经遇到过运行此脚本的 Python 内存错误。有什么建议为什么会发生这种情况或如何更改脚本以便将来不再发生?

      【讨论】:

      • 回答此问题需要更多信息。您能否将其作为新问题或作为 Github 上的问题发布?
      • 是的,我会的。对于小样本,它做得很好。只是对于更大的样本或/和更多的变量,它有时会崩溃或者需要很长时间才能生成它(这对于复杂的操作是可以接受的,但是更多的力量会很有用)
      • 如果有人在这个答案上突然出现,the algorithm 已经更新,现在运行速度提高了大约 20 倍。
      • 感谢您的更新。然而,生成 9D 1000 个样本太慢了。
      【解决方案5】:

      自 1.7 版以来,拉丁超立方体采样现在是 SciPy 的一部分。请参阅doc

      from scipy.stats.qmc import LatinHypercube
      
      engine = LatinHypercube(d=2)
      sample = engine.random(n=100)
      

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 2017-06-09
        • 1970-01-01
        • 1970-01-01
        相关资源
        最近更新 更多