多维空间中的随机单位向量
Posted
技术标签:
【中文标题】多维空间中的随机单位向量【英文标题】:random unit vector in multi-dimensional space 【发布时间】:2011-09-11 02:28:36 【问题描述】:我正在研究一种数据挖掘算法,我想从特征空间中的特定点选择一个随机方向。
如果我从 [-1,1] 中为 n 个维度中的每一个选择一个随机数,然后将向量标准化为长度为 1,我会在所有可能的方向上得到均匀分布吗?
我只是在理论上说,因为计算机生成的随机数实际上并不是随机的。
【问题讨论】:
【参考方案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 快速解释为什么会这样:一个点在给定使用您描述的算法,您不会得到均匀分布的角度集合。角度将偏向 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,为什么它比公认的答案更好,或者什么?以上是关于多维空间中的随机单位向量的主要内容,如果未能解决你的问题,请参考以下文章