26

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

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

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

4

5 回答 5

42

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

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 的向量,这将导致您的计算机简单地挂在十几个维度左右,因为他们中的任何一个获得资格的可能性变得非常小。

于 2011-12-10T00:56:34.377 回答
13

使用您描述的算法,您将无法获得均匀分布的角度集合。角度将偏向 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
于 2011-06-08T17:59:00.420 回答
2

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

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

f_X(x) = 1/(4*cos²(x))如果 0 < x < 45⁰<br> 并且
f_X(x) = 1/(4*sin²(x))如果 x > 45⁰</p>

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

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

于 2018-01-21T15:25:43.990 回答
1

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

于 2012-06-07T13:20:01.997 回答
-3
#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);
于 2012-04-23T15:05:30.630 回答