我正在研究一个数据挖掘算法,在其中我想从特征空间的一个特定点选择一个随机方向。
如果我为每个 n 个维度选取 [-1,1] 中的一个随机数,然后将向量标准化到长度为 1,这样做是否能够获得所有可能方向上的均匀分布?
我这里仅在理论上讨论,因为计算机生成的随机数实际上并不是真正的随机。
我正在研究一个数据挖掘算法,在其中我想从特征空间的一个特定点选择一个随机方向。
如果我为每个 n 个维度选取 [-1,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的高斯分布中选择)。然后,使用勾股定理计算出所得向量的大小(将每个值平方、相加并对结果取平方根)。最后,将每个值除以向量大小以获得归一化的随机向量。使用您描述的算法将无法获得角度的均匀分布集合。 角度将偏向于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
在开发机器学习算法时,我也曾经有过同样的问题。
在绘制2D样本并绘制角度分布后,我得出了与Jim Lewis相同的结论。
此外,如果您尝试从[-1,1]中随机抽取x轴和y轴的值,并推导出2D方向的密度分布,则会发现:
f_X(x) = 1/(4*cos²(x))
,如果 0 < x < 45⁰
且
f_X(x) = 1/(4*sin²(x))
,如果 x > 45⁰
其中x是角度,f_X是概率密度分布。
关于这个问题,我在这里写了一篇文章: https://aerodatablog.wordpress.com/2018/01/14/random-hyperplanes/
#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);
numpy
,这将是vec = numpy.random.randn(dims); return vec / numpy.linalg.norm(vec)
。 - stav