<jupyter_start><jupyter_text>!['Logo FIUNA'](http://www.ing.una.py/images/logo-horizontal.png) PROBABILIDAD Y ESTADÍSTICA---  Distribuciones de probabilidad Distribución de Poisson  Materiales y recursos Teoría* [Distribución de Poisson](https://drive.google.com/file/d/1l1GnSW3wD3dtmPajYCSCw_sqYnuKUfVl/view?ts=5f0faec8) Actividades de laboratorio* [Vídeos de ejercicios de distribución de Poisson resueltos (en excel)](https://www.youtube.com/playlist?list=PLtwTdZpdrv8i7jpvTC64lEpFycvSq-_ed)* [Archivos distribución de Poisson](https://eaula.ing.una.py/mod/folder/view.php?id=27090)  Importar módulos necesarios* En esta sección, estaremos usando el módulo [scipy.stats](https://docs.scipy.org/doc/scipy/reference/tutorial/stats.html), el cual nos provee la clase `poisson` , para la resolución de problemas de distribución de probabilidades de Poisson.* Complementariamente usaremos el módulo matplotlib.pyplot para realizar todos los gráficos que necesitemos.<jupyter_code>from scipy.stats import poisson   # De esta manera importamos solamente la clase deseada y no todo el módulo scipy.stats
import matplotlib.pyplot as plt   # Importamos el módulo matplotlib.pyplot y le asignamos el alias de "plt" por conveniencia a la hora de trabajar con el mismo<jupyter_output><empty_output><jupyter_text>Distribución de PoissonRecordemos que la distribución de probabilidades de Poisson está dada por la fórmula:> $p(x) = \frac{e^{-\lambda }\lambda ^{x}}{x!}$donde:* $p(x)$: es la probabilidad de ocurrencia de un suceso, cuando la variable discreta toma un valor finito x.* $\lambda $ (lambda): es la media de ocurrencia en el segmento dado.* $x$: el número de éxitos por unidad.  Ejercicios de distribución de probabilidades de Poisson.1. Carlos ha notado que cada minuto que pasa, hay una probabilidad de 1/720 de que  la  página  en  Facebook  de  su  negocio  obtenga  un  “me  gusta”, independientemente de lo que suceda en cualquier otro minuto.> (a).  ¿Cuántos “me gusta” espera recibir Carlos durante un periodo de 24 horas? (b). ¿Cuál es la probabilidad de que Carlos reciba más de 2 “me gusta” en las próximas 12 horas? (c). ¿Cuál es la probabilidad de que Carlos reciba 3 o 4 “me gusta” en las próximas 12 horas?<jupyter_code># Definimos las variables que vamos a necesitar
prob_exito = 1/720
prob_fracaso = 1 - prob_exito
n = 24*60 # 24 horas expresadas en minutos
# En python "lambda" es una palabra reservada por lo que para resolver los ejercicios estaremos usando la variable L
L = n * prob_exito<jupyter_output><empty_output><jupyter_text>(a). ¿Cuántos “me gusta” espera recibir Carlos durante un periodo de 24 horas?. En un periodo de 24 horas se espera recibir L me gustas.<jupyter_code># Imprimimos el resultado
print('En un periodo de 24 horas, Carlos espera recibir:', int(L), '"me gusta"')<jupyter_output>En un periodo de 24 horas, Carlos espera recibir: 2 "me gusta"<jupyter_text>(b). ¿Cuál es la probabilidad de que Carlos reciba más de 2 “me gusta” en las próximas 12 horas?. Para este caso, debemos modificar `n` y por lo tanto `L` y aplicar el método `sf(x)` _survival function_ a un objeto del tipo `poisson`. La función `sf(x)` es lo mismo que $1-cdf(x)$ donde `cdf(x)` es la probabilidad acumulada de x.<jupyter_code># Volvemos a asignar las variables n y L
n = 12*60 # 12 horas expresadas en minutos
L = n * prob_exito # Para actualizar el valor de L, debemos volver a ejecutar esta línea de código

# Creamos un objeto del tipo poisson al que llamaremos dist_poisson, y que contiene los datos del problema
dist_poisson = poisson(L)
# Aplicamos pmf(x) a dist_poisson
prob_mas_2_megusta = dist_poisson.sf(2)

# Imprimimos la respuesta
print('La probabilidad de que Carlos reciba más de 2 "me gusta" en 12 horas es:', prob_mas_2_megusta)<jupyter_output>La probabilidad de que Carlos reciba más de 2 "me gusta" en 12 horas es: 0.08030139707139418<jupyter_text>(c). ¿Cuál es la probabilidad de que Carlos reciba 3 o 4 “me gusta” en las próximas 12 horas?. Para esto tenemos dos opciones que deberían darnos el mismo resultado.* Hallar p(3) y p(4), utilizando el método `pmf(x)`, y sumando ambos resultados* Hallar p(4) acumulado y p(2) acumulado, usando el método `cdf(x)`, y restando ambos resultados<jupyter_code># Utilicemos el primer método
prob_3MG = dist_poisson.pmf(3)
prob_4MG = dist_poisson.pmf(4)

# La probabilidad de 3 o 4 "me gusta" está dada por la suma de p(3) y p(4)
prob_3o4MG = prob_3MG + prob_4MG

# Imprimimos el resultado
print('La probabilidad de que carlos reciba 3 o 4 "me gusta" en las próximas 12 horas es:', prob_3o4MG)
# Resolvemos ahora por el segundo método
prob_4MG_acum = dist_poisson.cdf(4)
prob_2MG_acum = dist_poisson.cdf(2)

# La probabilidad de 3 o 4 "me gusta" está dada por la diferencia de p_acum(4) y p_acum(2)
prob_3o4MG = prob_4MG_acum - prob_2MG_acum

# Imprimimos el resultado
print('La probabilidad de que carlos reciba 3 o 4 "me gusta" en las próximas 12 horas es:', prob_3o4MG)<jupyter_output>La probabilidad de que carlos reciba 3 o 4 "me gusta" en las próximas 12 horas es: 0.0766415502440505<jupyter_text>De lo anterior se comprueba que ambos métodos arrojan el mismo resultado. Que era lo esperado OpcionalDe manera a ver el potencial que nos ofrece el módulo `scipy.stats` vemos los siguientes ejemplos:<jupyter_code># Por ejemplo, haciendo uso de las variables de la pregunta (a)
prob_exito = 1/720
prob_fracaso = 1 - prob_exito
n = 24*60 # 24 horas expresadas en minutos
# En python "lambda" es una palabra reservada por lo que para resolver los ejercicios estaremos usando la variable L
L = n * prob_exito

# Podemos hallar los valores que describen nuestra distribución, por medio del método stats
media, var, sesgo, curt = poisson.stats(L, moments='mvsk')
print('Media:', media)
print('Varianza:', var)
print('Sesgo:', sesgo)
print('Curtosis:', curt)
# Usando los valores de la pregunta (b) y (c):
n = 12*60 # 12 horas expresadas en minutos
L = n * prob_exito # Para actualizar el valor de L, debemos volver a ejecutar esta línea de código

# Creamos un objeto del tipo poisson al que llamaremos dist_poisson, y que contiene los datos del problema
dist_poisson = poisson(L)

# Podriamos calcular, en un solo paso, la distribución de probabilidades para obtener 0, 1, 2, 3, 4... 20 "me gusta" en un intervalo de 12 horas
# Definamos los valores de x
x = range(21) # crea un objeto iterable de 0 a 20
p = dist_poisson.pmf(x) # calcula la distribución de probabilidades para cada valor de x dado

# Imprimimos el vector p
print(p)<jupyter_output>[3.67879441e-01 3.67879441e-01 1.83939721e-01 6.13132402e-02
 1.53283100e-02 3.06566201e-03 5.10943668e-04 7.29919526e-05
 9.12399408e-06 1.01377712e-06 1.01377712e-07 9.21615563e-09
 7.68012969e-10 5.90779207e-11 4.21985148e-12 2.81323432e-13
 1.75827145e-14 1.03427732e-15 5.74598513e-17 3.02420270e-18
 1.51210135e-19]<jupyter_text>Podríamos aprovechar lo anterior para graficar la distribución de probabilidades de Poisson, comparando los resultados para diferentes intervalos de tiempo. Usemos 24 horas y 12 horas, como en las preguntas (a) y (b) de manera a entender como esto afecta a las probabilidades.<jupyter_code># Hallemos p(x) para los datos en (a). Siendo x = [0, 1, 2, 3, ... 20]
# Como anteriormente definimos x, no necesitamos volver a hacerlo, ya que los valores asignados son los mismos
n = 24*60 # 24 horas expresadas en minutos
L = n * prob_exito # Para actualizar el valor de L, debemos volver a ejecutar esta línea de código

# Otra forma de caldular la probabilidad sin definir antes un objeto del tipo Poisson
p24 = poisson.pmf(x, L) 

# Imprimimos p24(x)
print(p24)
# Finalmente podemos graficar la función haciendo uso del módulo matplotlib.plotlib, al que llamamos con el alias de plt
fig, ax = plt.subplots(1, 1, figsize= (16,8)) # Creamos un lienzo para nuestro gráfico

# El gráfico está dado por:

# Distribución de probabilidades para 24 hs.
ax.plot(x, p24, 'go', ms= 10, label= '24 horas') # Agregamos nuestro gráfico en forma de puntos verdes con el comando 'go' -> g: green (verde)- o: puntos, ms determina el tamaño del punto, que lo hacemos más grande para que sea visible
ax.vlines(x= x, ymin= 0, ymax= p24, colors='g') # Agregamos las líneas verticales desde ymin= 0 hasta ymax = p(x), de color verde
# Distribución de probabilidades para 12 hs.
ax.plot(x, p, 'bo', label= '12 horas') # Agregamos nuestro gráfico en forma de puntos azules con el comando 'bo' -> b: blue (azul)- o: puntos
ax.vlines(x= x, ymin= 0, ymax= p, colors='b') # Agregamos las líneas verticales desde ymin= 0 hasta ymax = p(x), de color azul

# Los demás complementos, opcionales:
ax.grid() # Agrega las grillas al gráfico
plt.xticks(x) # Modifica los puntos representados en el eje x, y la grilla para que coincidan exactamente a intervalos enteros
ax.set_title('Distribución de probabilidades', fontsize='x-large', fontweight= 'bold')
ax.set_xlabel('Cantidad de "Me Gusta"', fontsize='large')
ax.set_ylabel('Probabilidad de obtener "Me Gusta" en un intervalo dado.', fontsize='large')
ax.legend(loc= 'best')
plt.show()<jupyter_output><empty_output><jupyter_text>Del gráfico, resulta muy interesante observar lo siguiente:1. La probabilidad de recibir 0 o 1 "me gusta" es menor en un periodo de 24 horas que en uno de 12 horas. Si analizamos, esto nos resulta bastante intuitivo, ya que en un mayor periodo de tiempo sería menos probable que nadie o solo una persona le de "me gusta" a la página.2. Por otro lado, la probabilidad de recibir 2, 3, 4, 5, 6 y 7 "me gusta" es mayor en un perdiodo de 24 horas que en uno de 12 horas. --- 2. El  número  de  colonias  de  cianobacterias  contenidas  en  muestras  de  agua  del lago Ypacarai se estima sigue una distribución de Poisson con una media de 2 colonias por centímetro cúbico. > (a). Si   se   toman   en   forma   independiente   cuatro   muestras   de   agua   de   1 centímetro cubico cada una, calcule la probabilidad de que por lo menos una muestra contenga alguna colonia de cianobacterias.(b). La  probabilidad  de  encontrar menos  de  2  colonias  de  cianobacterias  en  2 muestras de agua de 1 centímetro cubico.<jupyter_code># Definimos las variables que vamos a necesitar
prob_exito = 2
prob_fracaso = 1 - prob_exito
cant_ensayos = 4
# En python "lambda" es una palabra reservada por lo que para resolver los ejercicios estaremos usando la variable L
L = cant_ensayos * prob_exito<jupyter_output><empty_output><jupyter_text>(a). Si se toman en forma independiente cuatro muestras de agua de 1 centímetro cubico cada una, calcule la probabilidad de que por lo menos una muestra contenga alguna colonia de cianobacterias. Para ello hallamos la probabilidad de no encontrar ninguna bacteria p(0), y hacemos 1 - p(0).<jupyter_code># Creamos un objeto del tipo poisson al que llamaremos dist_poisson, y que contiene los datos del problema
dist_poisson = poisson(L)

# Calculamos la probabilidad de hallar 0 bacterias y guardamos el resultado en la variable prob_0_bacterias
prob_0_bacterias = dist_poisson.pmf(0)

# Calculamos ahora la probabilidad de encontrar al menos una bacteria
prob_almenos_1 = 1 - prob_0_bacterias

# Imprimimos el resultado
print('La probabilidad de encontrar al menos una bacteria en las cuatro muestras tomadas es de:', prob_almenos_1)<jupyter_output>La probabilidad de encontrar al menos una bacteria en las cuatro muestras tomadas es de: 0.9996645373720975<jupyter_text>Otra forma de hallar el resultado en un único paso es usar `sf(x)` _survival function_ a un objeto del tipo `poisson`. La función `sf(x)` es lo mismo que $1-cdf(x)$ donde `cdf(x)` es la probabilidad acumulada de x.<jupyter_code># Calculamos ahora la probabilidad de encontrar al menos una bacteria, haciendo uso de sf(x)
prob_almenos_1 = dist_poisson.sf(0)

# Imprimimos el resultado
print('La probabilidad de encontrar al menos una bacteria en las cuatro muestras tomadas es de:', prob_almenos_1)<jupyter_output>La probabilidad de encontrar al menos una bacteria en las cuatro muestras tomadas es de: 0.9996645373720975<jupyter_text>Y podemos comprobar que ambos métodos nos llevan al mismo resultado, la probabilidad de encontrar al menos 1 bacteria es: $p(x>0) =0.9996645373720975$  ---(b). La probabilidad de encontrar menos de 2 colonias de cianobacterias en 2 muestras de agua de 1 centímetro cubico. Para ello podemos hacer: $p(x<2) =p(0) + p(1)$O bien, hacer uso del método cdf(x), el cual aplicado a un objeto de distribución de Poisson nos calcula la probabilidad acumulada de que ocurra x.<jupyter_code># Volvemos a definir las variables que cambian para el enunciado (b)
cant_ensayos = 2
# L para representar Lambda
L = cant_ensayos * prob_exito
# Volvemos a crear el objeto del tipo poisson
dist_poisson = poisson(L)
# Ahora, haciendo uso del método cdf(x) hallamos:
prob_1_acum = dist_poisson.cdf(1)
# Imprimimos el valor hallado
print('La probabilidad de encontrar menos de 2 colonias en 2 muestras es:', prob_1_acum)<jupyter_output>La probabilidad de encontrar menos de 2 colonias en 2 muestras es: 0.0915781944436709<jupyter_text>OpcionalSi queremos entender en qué afecta variar la cantidad de muestras tomadas en un problema de distribución de Poisson, nos puede resultar muy útil gráficar la distribución para los ejemplos dados.<jupyter_code># Hallemos primero la probabilidad de encontrar exactamente [0, 1, 2, 3, 4, 5, 6, 7, 8, 9] colonias de bacterias para el caso 1
x = range(10) # x es un objeto del tipo range, con valores de 0 a 9.
# Recordemos que L era:
L = 2*4 # Probabilidad de éxito 2 y 4 muestras
p_caso_a = poisson.pmf(x, L) # Esta es otra forma de hallar la probabilidad sin tener que definir previamente un objeto Poisson, cualquiera de los dos caminos es válido
# Hallemos ahora lo mismo, para los datos del caso (b)
L = 2*2 # Probabilidad de éxito 2 y 2 muestras
p_caso_b = poisson.pmf(x, L)
# Finalmente podemos graficar la función haciendo uso del módulo matplotlib.plotlib, al que llamamos con el alias de plt
fig, ax = plt.subplots(1, 1, figsize= (16,8)) # Creamos un lienzo para nuestro gráfico

# El gráfico está dado por:

# Distribución de probabilidades para 4 muestras.
ax.plot(x, p_caso_a, 'go', label= '4 muestras') # Agregamos nuestro gráfico en forma de puntos verdes con el comando 'go' -> g: green (verde)- o: puntos, ms determina el tamaño del punto, que lo hacemos más grande para que sea visible
ax.vlines(x= x, ymin= 0, ymax= p_caso_a, colors='g') # Agregamos las líneas verticales desde ymin= 0 hasta ymax = p_caso_a(x), de color verde
# Distribución de probabilidades para 2 muestras.
ax.plot(x, p_caso_b, 'bo', label= '2 muestras') # Agregamos nuestro gráfico en forma de puntos azules con el comando 'bo' -> b: blue (azul)- o: puntos
ax.vlines(x= x, ymin= 0, ymax= p_caso_b, colors='b') # Agregamos las líneas verticales desde ymin= 0 hasta ymax = p_caso_b(x), de color azul

# Los demás complementos, opcionales:
ax.grid() # Agrega las grillas al gráfico
plt.xticks(x) # Modifica los puntos representados en el eje x, y la grilla para que coincidan exactamente a intervalos enteros
ax.set_title('Distribución de probabilidades para diferentes tamaños de muestra', fontsize='x-large', fontweight= 'bold')
ax.set_xlabel('Cantidad de colonias de cianobacterias.', fontsize='large')
ax.set_ylabel('Probabilidad de encontrar cianobacterias.', fontsize='large')
ax.legend(loc= 'best')
plt.show()<jupyter_output><empty_output><jupyter_text>* El gráfico anterior nos muestra cómo afecta el tamaño de muestra a la distribución de Poisson, haciendo variar la media de las probabilidades.* También es interesante notar que, aparentemente, para un número mayor de muestras, la distribución de probabilidades se hace más "plana" es decir, los picos tienen valores menores a medida que aumentamos el número de muestras.  Desafío:Para comprobar esto último podemos calcular nuevas distribuciones de probabilidad y seguir agregándolas al gráfico. Te animámos a que pruebes obtener un gráfico parecido al que dejamos a continuación.<jupyter_code><jupyter_output><empty_output>
{'fraction_non_alphanumeric': 0.0754928874469678, 'fraction_numerical': 0.038807087596705765, 'mean_word_length': 4.963169642857143, 'pattern_counts': {'":': 0, '<': 47, '<?xml version=': 0, '>': 54, 'https://': 4, 'lorem ipsum': 0, 'www.': 2, 'xml': 0}, 'pii_count': 0, 'substrings_counts': 0, 'word_list_counts': {'cursed_substrings.json': 1, 'profanity_word_list.json': 0, 'sexual_word_list.json': 0, 'zh_pornsignals.json': 0}}
{'chain_length': '13', 'dir': 'jupyter-structured-clean-dedup', 'id': '322077', 'license': 'MIT', 'n_tokens_mistral': 6144, 'n_tokens_neox': 5710, 'n_words': 2215, 'path': 'notebooks/Distribuciones de Probabilidad/Distribucion_de_Poisson.ipynb', 'repo_name': 'FranCodiGo/LabDataScience', 'size': '16028'}