关于random:使用python进行拉丁超立方体采样

Latin hypercube sampling with python

我想对一个函数定义的分布进行多维(2、3、4)采样:

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

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

  • 是否有为此目的准备使用python lib?

  • 是否有python lib可以通过拉丁超立方体采样或其他统一采样方法在2..4维空间中生成点?具有独立随机数的Bruteforce采样通常会导致空间密度越来越小。

  • 如果1)和2)不存在,那么是否有人善良地分享相同或相似问题的实现。

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


    我想这是一个较晚的答案,但这也适用于将来的访客。我刚刚在git上实现了多维统一的Latin Hypercube采样的实现。它很小,但是非常易于使用。如果变量是独立的,则可以使用Latin Hypercube Sampling生成在n个维度上采样的统一随机变量。下面是一个示例图,该图在零相关性的两个维度中比较了具有多维均匀性(LHS-MDU)的蒙特卡洛和拉丁超立方体采样。

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    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()

    MCS versus LHS


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

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

    生成n个维度上的样本:

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

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


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

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    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]

    这是Sahil M对Python 3的回答的更新(从Python 2更新到Python 3,并对代码进行了一些较小的更改以使代码和图形匹配):

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    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()

    code visual output

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