【问题标题】:random unit vector in multi-dimensional space多维空间中的随机单位向量
【发布时间】:2011-09-11 02:28:36
【问题描述】:

我正在研究一种数据挖掘算法,我想从特征空间中的特定点选择一个随机方向。

如果我从 [-1,1] 中为 n 个维度中的每一个选择一个随机数,然后将向量标准化为长度为 1,我会在所有可能的方向上得到均匀分布吗?

我只是在理论上说,因为计算机生成的随机数实际上并不是随机的。

【问题讨论】:

    标签: random distribution data-mining computational-geometry uniform


    【解决方案1】:

    一个简单的技巧是从高斯分布中选择每个维度,然后进行归一化:

    from random import gauss
    
    def make_rand_vector(dims):
        vec = [gauss(0, 1) for i in range(dims)]
        mag = sum(x**2 for x in vec) ** .5
        return [x/mag for x in vec]
    

    例如,如果您想要一个 7 维随机向量,请选择 7 个随机值(来自均值为 0 和标准差为 1 的高斯分布)。然后,使用毕达哥拉斯公式计算结果向量的大小(对每个值求平方,将平方相加,然后取结果的平方根)。最后,将每个值除以幅度,得到归一化的随机向量。

    如果您的维度数量很大,那么这具有始终立即工作的强大优势,同时生成随机向量,直到您找到一个大小恰好小于 1 的向量,这将导致您的计算机简单地挂在十几个维度上左右,因为他们中的任何一个合格的可能性变得非常小。

    【讨论】:

    • 不错!感谢您的额外建议。
    • 顺便说一下,这就是 boost boost.org/doc/libs/1_47_0/boost/random/uniform_on_sphere.hpp 的实现方式。 ;)
    • 这里有一个关于为什么这个方法是正确的参考mathworld.wolfram.com/HyperspherePointPicking.html
    • 快速解释为什么会这样:一个点在给定 处的概率 P 是 P(x)*P(y)。高斯分布大致有e^(-x^2)的形式,所以e^(-x^2)*e^(-y^2)就是e^(-(x^2+y^2))。这只是点到原点的距离的函数,因此得到的分布是径向对称的。这很容易推广到更高的维度。
    • 附加说明:Box–Muller 变换可用于从独立的均匀分布变量对生成独立的正态分布变量对(没有“浪费”)。
    【解决方案2】:

    使用您描述的算法,您不会得到均匀分布的角度集合。角度将偏向 n 维超立方体的角。

    这可以通过消除与原点距离大于 1 的任何点来解决。然后您处理的是球形而不是立方(n 维)体积,然后您的一组角度应该均匀分布在样本空间中。

    伪代码:

    设 n 为维数,K 为所需的向量数:

    vec_count=0
    while vec_count < K
       generate n uniformly distributed values a[0..n-1] over [-1, 1]
       r_squared = sum over i=0,n-1 of a[i]^2
       if 0 < r_squared <= 1.0
          b[i] = a[i]/sqrt(r_squared)  ; normalize to length of 1
          add vector b[0..n-1] to output list
          vec_count = vec_count + 1
       else
          reject this sample
    end while
    

    【讨论】:

    • 这就是我所担心的。我只是无法按照您描述的方式在脑海中将其正式化。直觉上我知道我希望我可能的随机向量来描述一个圆。我只是没有看到如何在代码中实现它。
    • @Matt:我稍微扩展了我的答案,希望对您有所帮助。
    • 如果可以使用封闭式表达式解决这个问题,为什么还要使用运行时间不确定的算法和分支?
    • 在高维中,这是极其低效的。例如,在六个维度中,只有 8% 的样本会被接受。在十个维度上,这一比例下降到 0.25%。
    【解决方案3】:

    我在开发 ML 算法时也遇到了完全相同的问题。
    在为二维情况绘制样本并绘制角度的结果分布后,我得出了与 Jim Lewis 相同的结论。

    此外,如果您在 x 轴和 y 轴从 [-1,1] 随机绘制时尝试导出 2d 方向的密度分布,您将看到:

    f_X(x) = 1/(4*cos²(x)) 如果 0 和
    f_X(x) = 1/(4*sin²(x)) 如果 x > 45⁰

    其中x是角度,f_X是概率密度分布。

    我在这里写过这个: https://aerodatablog.wordpress.com/2018/01/14/random-hyperplanes/

    【讨论】:

      【解决方案4】:

      从正态分布中采样的算法有一个 boost 实现:random::uniform_on_sphere

      【讨论】:

        【解决方案5】:
        #define SCL1 (M_SQRT2/2)
        #define SCL2 (M_SQRT2*2)
        
        // unitrand in [-1,1].
        double u = SCL1 * unitrand();
        double v = SCL1 * unitrand();
        double w = SCL2 * sqrt(1.0 - u*u - v*v);
        
        double x = w * u;
        double y = w * v;
        double z = 1.0 - 2.0 * (u*u + v*v);
        

        【讨论】:

        • 对于像我这样的非机械人员来说,不再难以阅读代码。任何关于它的作用的cmets,为什么它比公认的答案更好,或者什么?
        猜你喜欢
        • 2020-05-18
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 2015-11-02
        • 2016-11-15
        相关资源
        最近更新 更多