posiciones - llenar una matriz con numeros aleatorios en python
Generando variables aleatorias discretas con pesos especificados usando SciPy o NumPy (5)
Estoy buscando una función simple que pueda generar una matriz de valores aleatorios específicos en función de sus probabilidades correspondientes (también especificadas). Solo necesito generar valores flotantes, pero no veo por qué no debería ser capaz de generar ningún escalar. Puedo pensar en muchas formas de construir esto a partir de las funciones existentes, pero creo que probablemente me perdí una función obvia de SciPy o NumPy.
P.ej:
>>> values = [1.1, 2.2, 3.3]
>>> probabilities = [0.2, 0.5, 0.3]
>>> print some_function(values, probabilities, size=10)
(2.2, 1.1, 3.3, 3.3, 2.2, 2.2, 1.1, 2.2, 3.3, 2.2)
Nota: Encontré scipy.stats.rv_discrete pero no entiendo cómo funciona. Específicamente, no entiendo qué significa esto (abajo) ni qué debería hacer:
numargs = generic.numargs
[ <shape(s)> ] = [''Replace with resonable value'', ]*numargs
Si rv_discrete es lo que debería estar usando, ¿podrían darme un ejemplo simple y una explicación de la declaración de "forma" anterior?
Aquí hay una función corta y relativamente simple que devuelve valores ponderados, usa NumPy''s random_sample
, accumulate
y random_sample
.
import numpy as np
from numpy.random import random_sample
def weighted_values(values, probabilities, size):
bins = np.add.accumulate(probabilities)
return values[np.digitize(random_sample(size), bins)]
values = np.array([1.1, 2.2, 3.3])
probabilities = np.array([0.2, 0.5, 0.3])
print weighted_values(values, probabilities, 10)
#Sample output:
[ 2.2 2.2 1.1 2.2 2.2 3.3 3.3 2.2 3.3 3.3]
Funciona así:
- Primero usando
accumulate
creamos contenedores. - Luego creamos un grupo de números aleatorios (entre
0
y1
) usando larandom_sample
- Usamos
digitize
para ver a qué contenedores pertenecen estos números. - Y devuelve los valores correspondientes.
Dibujar desde una distribución discreta está directamente integrado en numpy. La función se llama random.choice (difícil de encontrar sin ninguna referencia a distribuciones discretas en los documentos numpy).
elements = [1.1, 2.2, 3.3]
probabilities = [0.2, 0.5, 0.3]
np.random.choice(elements, 10, p=probabilities)
La forma más sencilla de hacer el bricolaje sería resumir las probabilidades en una distribución acumulativa. De esta manera, divide el intervalo de la unidad en subintervalos de la longitud igual a sus probabilidades originales. Ahora genere un solo número aleatorio uniforme en [0,1), y vea a qué intervalo aterriza.
También podría usar Lea , un paquete de Python puro dedicado a distribuciones de probabilidad discretas.
>>> distrib = Lea.fromValFreqs((1.1,2),(2.2,5),(3.3,3))
>>> distrib
1.1 : 2/10
2.2 : 5/10
3.3 : 3/10
>>> distrib.random(10)
(2.2, 2.2, 1.1, 2.2, 2.2, 2.2, 1.1, 3.3, 1.1, 3.3)
Et voilà!
scipy.stats.rv_discrete()
en una buena dirección: el scipy.stats.rv_discrete()
crea directamente una variable aleatoria discreta. Así es como funciona:
>>> from scipy.stats import rv_discrete
>>> values = numpy.array([1.1, 2.2, 3.3])
>>> probabilities = [0.2, 0.5, 0.3]
>>> distrib = rv_discrete(values=(range(len(values)), probabilities)) # This defines a Scipy probability distribution
>>> distrib.rvs(size=10) # 10 samples from range(len(values))
array([1, 2, 0, 2, 2, 0, 2, 1, 0, 2])
>>> values[_] # Conversion to specific discrete values (the fact that values is a NumPy array is used for the indexing)
[2.2, 3.3, 1.1, 3.3, 3.3, 1.1, 3.3, 2.2, 1.1, 3.3]
La distribución distrib
arriba devuelve índices de la lista de values
.
De manera más general, rv_discrete()
toma una secuencia de valores enteros en los primeros elementos de su argumento values=(…,…)
y devuelve estos valores, en este caso; no es necesario convertir a valores específicos (float). Aquí hay un ejemplo:
>>> values = [10, 20, 30]
>>> probabilities = [0.2, 0.5, 0.3]
>>> distrib = rv_discrete(values=(values, probabilities))
>>> distrib.rvs(size=10)
array([20, 20, 20, 20, 20, 20, 20, 30, 20, 20])
donde los valores de entrada (enteros) se devuelven directamente con la probabilidad deseada.