probabilidad - Ajustar una distribución gamma con(python) Scipy
numeros aleatorios en python (4)
Estaba insatisfecho con la función ss.gamma.rvs, ya que puede generar números negativos, algo que se supone que no tiene la distribución gamma. Así que ajusté la muestra a través del valor esperado = mean (data) y varianza = var (data) (ver wikipedia para más detalles) y escribí una función que puede producir muestras aleatorias de una distribución gamma sin scipy (que encontré difícil de instalar correctamente, en otros comentarios):
import random
import numpy
data = [6176, 11046, 670, 6146, 7945, 6864, 767, 7623, 7212, 9040, 3213, 6302, 10044, 10195, 9386, 7230, 4602, 6282, 8619, 7903, 6318, 13294, 6990, 5515, 9157]
# Fit gamma distribution through mean and average
mean_of_distribution = numpy.mean(data)
variance_of_distribution = numpy.var(data)
def gamma_random_sample(mean, variance, size):
"""Yields a list of random numbers following a gamma distribution defined by mean and variance"""
g_alpha = mean*mean/variance
g_beta = mean/variance
for i in range(size):
yield random.gammavariate(g_alpha,1/g_beta)
# force integer values to get integer sample
grs = [int(i) for i in gamma_random_sample(mean_of_distribution,variance_of_distribution,len(data))]
print("Original data: ", sorted(data))
print("Random sample: ", sorted(grs))
# Original data: [670, 767, 3213, 4602, 5515, 6146, 6176, 6282, 6302, 6318, 6864, 6990, 7212, 7230, 7623, 7903, 7945, 8619, 9040, 9157, 9386, 10044, 10195, 11046, 13294]
# Random sample: [1646, 2237, 3178, 3227, 3649, 4049, 4171, 5071, 5118, 5139, 5456, 6139, 6468, 6726, 6944, 7050, 7135, 7588, 7597, 7971, 10269, 10563, 12283, 12339, 13066]
¿Alguien puede ayudarme a adaptar una distribución gamma en Python? Bueno, tengo algunos datos: coordenadas X e Y, y quiero encontrar los parámetros gamma que se ajusten a esta distribución ... En el documento Scipy , resulta que realmente existe un método de ajuste, pero no sé cómo para usarlo: s ... Primero, ¿en qué formato debe estar el argumento "data", y cómo puedo proporcionar el segundo argumento (los parámetros) ya que eso es lo que estoy buscando?
1): la variable "datos" podría estar en el formato de una lista o tupla de python, o una numpy.ndarray, que podría obtenerse mediante el uso de:
data=numpy.array(data)
donde los 2da datos en la línea antedicha deben ser una lista o una tupla, conteniendo sus datos.
2: la variable "parámetro" es una primera conjetura que podría proporcionar opcionalmente a la función de ajuste como punto de partida para el proceso de adaptación, por lo que podría omitirse.
3: una nota sobre la respuesta de @mondano. El uso de momentos (media y varianzas) para calcular los parámetros de gamma es razonablemente bueno para parámetros de forma grandes (alfa> 10), pero podría dar resultados pobres para valores pequeños de alfa (ver Métodos estadísticos en las pruebas atmosféricas de Wilks, y THOM, HCS, 1958: Una nota sobre la distribución gamma. Mon. Wea. Rev., 86, 117-122.
El uso de Estimadores de máxima verosimilitud, como el implementado en el módulo scipy, se considera una mejor opción en tales casos.
Si desea un ejemplo largo que incluya una discusión sobre cómo estimar o corregir el soporte de la distribución, puede encontrarlo en https://github.com/scipy/scipy/issues/1359 y en el mensaje de la lista de correo vinculada.
El soporte preliminar para corregir parámetros, como la ubicación, durante el ajuste se ha agregado a la versión troncal de scipy.
Genera algunos datos gamma:
import scipy.stats as stats
alpha = 5
loc = 100.5
beta = 22
data = stats.gamma.rvs(alpha, loc=loc, scale=beta, size=10000)
print(data)
# [ 202.36035683 297.23906376 249.53831795 ..., 271.85204096 180.75026301
# 364.60240242]
Aquí ajustamos los datos a la distribución gamma:
fit_alpha, fit_loc, fit_beta=stats.gamma.fit(data)
print(fit_alpha, fit_loc, fit_beta)
# (5.0833692504230008, 100.08697963283467, 21.739518937816108)
print(alpha, loc, beta)
# (5, 100.5, 22)