Quiero generar una matriz de rango 5 de 100x600 en número con todas las entradas muestreadas de np.random.uniform(0, 20), para que todas las entradas se distribuyan uniformemente entre [0, 20). ¿Cuál será la mejor manera de hacerlo en python?
Veo que hay una forma inspirada en SVD de hacerlo aquí ( https://math.stackexchange.com/questions/3567510/how-to-generate-a-rank-r-matrix-with-entries-uniform ), pero No estoy seguro de cómo codificarlo. Estoy buscando un ejemplo práctico de esta forma inspirada en SVD para obtener entradas distribuidas uniformemente.
De hecho, logré codificar una matriz de 100x100 de rango 5 apilando verticalmente cinco matrices de rango 1 de 20x100 y luego mezclando los índices verticales. Sin embargo, la matriz de 100x100 resultante no tiene entradas distribuidas uniformemente [0, 20).
Aquí está mi código (mi mejor intento):
import numpy as np def randomMatrix(m, n, p, q): # creates an mxn matrix with lower bound p and upper bound q, randomly. count = np.random.uniform(p, q, size=(m, n)) return count Qs = [] my_rank = 5 for i in range(my_rank): L = randomMatrix(20, 1, 0, np.sqrt(20)) # L is tall R = randomMatrix(1, 100, 0, np.sqrt(20)) # R is long Q = np.outer(L, R) Qs.append(Q) Q = np.vstack(Qs) #shuffle (preserves rank 5 [confirmed]) np.random.shuffle(Q)No es una solución perfecta, debo admitir. Pero es simple y se acerca bastante.
Creo 5 vectores que abarcarán el espacio de la matriz y crearán combinaciones lineales aleatorias para llenar el resto de la matriz. Mi pensamiento inicial fue que una solución trivial sería copiar esos vectores 20 veces.
Para mejorar eso, creé combinaciones lineales de ellos con pesos extraídos de una distribución uniforme, pero luego la distribución de las entradas en la matriz se vuelve normal porque la media ponderada básicamente hace que el teorma del límite central tenga efecto.
Un punto medio entre el enfoque trivial y el segundo enfoque que no funciona es usar conjuntos de pesos que favorecen a uno de los vectores sobre los demás. Y puede generar este tipo de vectores de peso al pasar cualquier vector a través de la función softmax con un parámetro de temperatura apropiadamente alto.
La distribución es casi uniforme, pero los vectores todavía están muy cerca de los vectores base. Puede jugar con el parámetro de temperatura para encontrar un punto dulce que se adapte a su propósito.
from scipy.stats import ortho_group from scipy.special import softmax import numpy as np from matplotlib import pyplot as plt N = 100 R = 5 low = 0 high = 20 sm_temperature = 100 p = np.random.uniform(low, high, (1, R, N)) weights = np.random.uniform(0, 1, (NR, R, 1)) weights = softmax(weights*sm_temperature, axis = 1) p_lc = (weights*p).sum(1) rand_mat = np.concatenate([p[0], p_lc]) plt.hist(rand_mat.flatten())