vectors vecteezy source icon freevectors flaticon easy random distribution data-mining computational-geometry uniform

random - vecteezy - freevectors co



vector de unidades aleatorias en el espacio multidimensional (5)

Hay una implementación de impulso del algoritmo que toma muestras de distribuciones normales: boost.org/doc/libs/1_47_0/boost/random/uniform_on_sphere.hpp

Estoy trabajando en un algoritmo de minería de datos en el que quiero elegir una dirección aleatoria de un punto particular en el espacio de características.

Si selecciono un número aleatorio para cada una de las n dimensiones de [-1,1] y luego normalizo el vector a una longitud de 1, ¿obtendré una distribución uniforme en todas las direcciones posibles?

Solo estoy hablando teóricamente aquí, ya que los números aleatorios generados por computadora no son realmente aleatorios.


No obtendrá un conjunto de ángulos distribuidos uniformemente con el algoritmo que describió. Los ángulos se desviarán hacia las esquinas de su hipercubo n-dimensional.

Esto se puede arreglar eliminando cualquier punto con una distancia mayor que 1 desde el origen. Entonces, se trata de un volumen esférico en lugar de cúbico (n-dimensional), y su conjunto de ángulos debe distribuirse uniformemente sobre el espacio de la muestra.

Pseudocódigo

Sea n el número de dimensiones, K el número deseado de vectores:

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


Tuve la misma pregunta al desarrollar un algoritmo ML.
Llegué a la misma conclusión que Jim Lewis después de extraer muestras para el caso 2-d y trazar la distribución resultante del ángulo.

Además, si intenta derivar la distribución de densidad para la dirección en 2d cuando dibuja al azar de [-1,1] para los ejes x e y, verá que:

f_X(x) = 1/(4*cos²(x)) si 0 <x <45⁰
y
f_X(x) = 1/(4*sin²(x)) si x> 45⁰

donde x es el ángulo, y f_X es la distribución de densidad de probabilidad.

He escrito sobre esto aquí: https://aerodatablog.wordpress.com/2018/01/14/random-hyperplanes/


Un truco simple es seleccionar cada dimensión de una distribución gaussiana y luego normalizar:

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]

Por ejemplo, si desea un vector aleatorio de 7 dimensiones, seleccione 7 valores aleatorios (de una distribución gaussiana con media 0 y desviación estándar 1). Luego, calcule la magnitud del vector resultante usando la fórmula de Pitágoras (cuadrar cada valor, agregar los cuadrados y tomar la raíz cuadrada del resultado). Finalmente, divida cada valor por la magnitud para obtener un vector aleatorio normalizado.

Si su número de dimensiones es grande, entonces tiene el fuerte beneficio de trabajar siempre de inmediato, mientras que genera vectores aleatorios hasta que encuentre uno que tenga una magnitud menor que uno hará que su computadora simplemente se cuelgue en más de una docena de dimensiones. porque la probabilidad de que alguno de ellos califique se hace cada vez más pequeño.


#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);