Acá la solución a mano para validar el ejercicio. Me sirvió mucho para entender mejor!
Incertidumbre y probabilidad
¿Qué es la probabilidad?
Probabilidad en machine learning
Fundamentos de probabilidad
Tipos de probabilidad
Ejemplos de cálculo de probabilidad
Ejemplos avanzados con probabilidad
Distribuciones de probabilidad
¿Qué es una distribución?
Distribuciones discretas
Usando la distribución binomial
Distribuciones continuas
¿Cómo estimar una distribución?
MLE (Maximum Likelihood Estimation)
¿Qué es MLE?
MLE en machine learning
Regresión logística
Aplicación de regresión logística
Inferencia bayesiana
Teorema de Bayes
Bayes en machine learning
Retos finales
No tienes acceso a esta clase
¡Continúa aprendiendo! Únete y comienza a potenciar tu carrera
Convierte tus certificados en títulos universitarios en USA
Antes: $249
Paga en 4 cuotas sin intereses
Termina en:
Francisco Camacho
Aportes 118
Preguntas 21
Acá la solución a mano para validar el ejercicio. Me sirvió mucho para entender mejor!
Esta clase desde lo teórico hasta Python es muy buena.
A mi me dio pereza calcularlo a papel pero lo hice en mi calculadora recordando los tiempos de universidad jaja :c
No es necesario usar el for loop con binomial. Pueden definir arr:
p = 0.5
n = 3
arr = binomial(n,p,100)
def my_binom(k, n, p):
dic = []
for i in range(k + 1):
formula = factorial(n)/(factorial(i)*factorial(n-i)) * p**(i) * (1-p)**(n-i)
dic.append(formula)
return sum(dic)
my_binom(2, 3, 0.5)
# Output:
0.875
binom(3, 0.5).cdf(2)
# Output:
0.875
No es necesario calcular la probabilidad k<=2, ósea k=0, k=1, k =2, solo necesitas la probabilidad de k=3 y le resta 1, 1-(k=3) y te dará exactamente lo mismo
Una pequeña corrección, tanto .pmf() como .cdf() son MÉTODOS del objeto dist, NO ATRIBUTOS. Excelente clase y Francisco de los mejores profesores que he visto en platzi hasta ahora.
Acá les dejo otra forma de hacer el código en Python, de una manera frecuentista. Por ahí les sirva:
Esto demuestra, que efectivamente al realizar la simulación muchas veces, la probabilidad teórica y la dada por la simulación, es prácticamente la misma.
Siempre he tenido letra fea, pero les dejo mi solución
#EXERCISE TO PRACTICE BINOMIAL DISTRIBUTION
import numpy as np
from numpy.random import binomial
from scipy.stats import binom
from math import factorial
import matplotlib.pyplot as plt
#function that implements binomial distribution
def my_binomial(k,n,p):
return factorial(n)/factorial(k)*factorial(n-k)*pow(p,k)*pow(1-p,n-k)
#Example with scipy library Probability density
dist= binom(3,0.5).pmf(2)
#Accumulated Probability density/ second example
dist_2=binom(3,0.5).cdf(2)
#Simulation with 100 launches of an equilibrated coin
p=0.5
n=3
def plot_graph(num_trials):
values=[0,1,2,3]
arr=[]
for _ in range(100):
arr.append(binomial(n,p))
sim= np.unique(arr,return_counts=True)[1]/len(arr)
teoric=[binom(3,0.5).pmf(k) for k in values]
plt.bar(values,sim, color= 'red')
plt.bar(values,teoric , alpha=0.5, color= 'blue')
plt.title(f'Experiments {num_trials}')
plt.savefig('barras.png')
plt.show
if __name__ == "__main__":
example= my_binomial(2,3,0.5)
print(f'Example 1 {example}')
print(f'Example 2 {dist}')
print(f'Example 3 {dist_2}')
plot_graph(2000)
El factorial de cero es igual a 1:
0! = 1
https://colab.research.google.com/drive/1AVDeTETXmUBRIR-VYajRdiibPfEtSeQB?usp=sharing
Les comparto el archivo en Colaboratory con los comentarios que se hicieron a lo largo de la clase
![](
Que lindo haber vivido en el S XXI y poder ver como una computadora puede sacar horas de cálculos humanos en segundos y poder simular escenarios que serían sumamente costosos de realizar.
import numpy as np #libreria de manejo de matrices y arreglos, util para el manejo de tablas
from numpy.random import binomial #importa un generador de numeros aleatorios basado en la distribucion Binomial
from scipy.stats import binom #permite implemenatar la funcion de distribucion binomial
from math import factorial # liberia de funciones matematicas
import matplotlib.pyplot as plt # permite desarrolar visualizaciones y graficas```
Si no existiera el atributo de dist.cdf
mi forma de hacerla seria asi
acum = 0
for n in range(3):
made = binom(3, 0.5)
k = made.pmf(n)
acum = k + acum
print(acum)
Mi solución a P(k <= 2, n = 3, p = 0.5):
def my_binomial(k_start, k_end, n, p):
return sum([factorial(n)/(factorial(k)*factorial(n-k))*pow(p,k)*pow(1-p,n-k) for k in range(k_start, k_end+1)])
print(my_binomial(0,2,3,0.5))
Esta inforgrafia me parece muy útil para resumir conceptos
No lo olvides:
Me demoré un BUEN(eufemismo) de tiempo pensando porque salía morado.
Ahora no puedo parar de reír.
Prefiero separar las graficas, los colores me confunden
def plot_hist_2(num_trials):
values = [0,1,2,3]
arr = []
for _ in range(num_trials):
arr.append(binomial(3, 0.5))
sim = np.unique(arr, return_counts=True)[1]/len(arr)
teorica = [binom(3, 0.5).pmf(k) for k in values]
fig, axes = plt.subplots(nrows = 1, ncols = 2)
axes[0].bar(values, sim, color = "red")
axes[0].set_title("simulation")
axes[1].bar(values, teorica, alpha = 0.5, color = "blue")
axes[1].set_title("Theoretical")
fig.suptitle("{} experimentos".format(num_trials))
plt.show()
Les comparto esta herramienta online que permite entender las distribuciones de probabilidad continuas y discretas, con sus definiciones y permite jugar con ella. También te permite encontrar la mejor distribución de probabilidad para un conjunto de datos phitter.io
distrib_acumulada = binom(3,0.5).cdf(2)
print(distrib_acumulada)
Otra forma de validar el ejercicio a mano es en vez de preguntarnos por P(k =< 2, n= 3), nos preguntamos 1-P(k=3, n=3), que vendría a ser exactamente lo mismo, ya que tener k = 3 es el evento opuesto a k =< 2.
Esa es mi solución, saludos!
Dejo link de un ejemplo parecido a este en otro curso con link del codigo
aqui
Si no entiendes las explicaciones no te rindas, te recomiendo que complementes con otros videos o lectura sobre el tema, y vuelvas a ver el video, vas a ver que empiezas a entender
Francamente, esta clase me parecio excelente. Es incluso aun mas impactante si posees experiencia previa con Python.
Si no estoy mal, a los generadores aleatorios que menciona Francisco, también se le conocen como Simulaciones de montecarlo.
En el enlace les dejo la clase que cuenta la historia de como se originan estas simulaciones.
Mi cálculo
El ejercicio a mano, pero dándole al teclado
Para los que no entiendan esta línea:
teorica = [binom(3, 0.5).pmf(k) for k in values]
Es igual a esto:
teorica = []
for k in values:
uno_teorica = binom(3, 0.5).pmf(k)
teorica.append(uno_teorica)
Por alguna razón para mi todo cobra mas sentido cuando lo escribimos en código que cuando hacemos las operaciones.
dist .pmf (Probability Mass Function)
dist .cdf (Cummulative Density Function)
binomial( ) viene de numpy.random
Inocentemente valide lo que el profedijo mediante codigo, solo para darme cuenta mas adelante que era mas facil de hacer jajaja
distKCero = binom(3, 0.5)
distKUno = binom(3, 0.5)
distKDos = binom(3, 0.5)
distKMenorDos = distKCero.pmf(0) + distKUno.pmf(1) + distKDos.pmf(2)
print(distKMenorDos)
print(7/8)
Esta clase me motivó de gran manera, quiero volver en un tiempo a ella y ver todo lo que he avanzado en el mundo de la data Science.
Yo lo hice en codigo, jajajaja
sum = 0
i=0
while i <= 2:
sum += dist.pmf(i)
i +=1
print(sum)
Este link me aclaro con ejemplos https://statologos.jaol.net/python-de-distribucion-binomial/
La función de densidad de probabilidad sirve para:
-Tener una teoría de la distribución de una variable numérica en una población
-Calcular la probabilidad de ocurrencia. El área debajo de la curva
-Tener distribuciones de referencia cómo la distribución normal
Les dejo el link donde lo explican detalladamente
https://conceptosclaros.com/para-que-sirve-la-funcion-densidad-probabilidad/
A medida que aumenta el número de experimentos, la probabilidad de los eventos aleatorios se acerca a la teórica. Es decir, en el límite superior de eventos aleatorios la probabilidad de los eventos reales (o simulados) es igual a la probabilidad teórica.
Que gran clase del profesor.
Quiero compartirles algo de información. Si uds planean ejecutar esta práctica desde un entorno local, les comparto las librerías que tengo instaladas en mi entorno virtual para la clase de Probabilidad:
asttokens==2.0.5
colorama==0.4.4
cycler==0.10.0
executing==0.6.0
icecream==2.1.0
kiwisolver==1.3.1
matplotlib==3.4.2
numpy==1.20.3
Pillow==8.2.0
Pygments==2.9.0
pyparsing==2.4.7
python-dateutil==2.8.1
scipy==1.6.3
six==1.16.0
Y les comparto también una vista de como luce la ejecución.
Para la impresión de las variables, estoy usando una libreria que se llama icecream, me es muy útil porque no hay necesidad de declarar print para manejo de variables y muestra tanto valores como definición de variables. Me ha resultado muy ilustrativa, tanto como se hace en collab el colocar sólo la variable para imprimir en pantalla los valores que van tomando:
Y, de igual forma, les dejo el script documentado que generé, dentro de mi GitHub, espero les sirva 😄
https://tuit.es/Wu2V4
Muy pero muy interesante la clase, muy pocos profesores hacen los temas tan interesantes. Thanks Platzi
Probabilidad Binomial con Colab
import numpy as np
from numpy.random import binomial
from scipy.stats import binom
from math import factorial
import matplotlib.pyplot as plt
def my_binomial(k, n, p):
return factorial(n)/(factorial(k)*(factorial(n-k)))*pow(p,k)*pow(1-p, n-k)
print('my binomial: {}'.format(my_binomial(2, 3, 0.5)))
0.375
Usando scipy
import numpy as np
from numpy.random import binomial
from scipy.stats import binom
from math import factorial
import matplotlib.pyplot as plt
dist = binom(3, 0.5)
dist.pmf(2)
0.375
Dejo mis apuntes por si a alguien le sirven!
Bueno acabo de aprender el uso de probabilidad binomial. No sabia que la funcionalidad de esta si que es de utilidad. Aqui comparto mi desarrollo a mano.
![](
La función binomial
recibe un tercer parámetro llamado size
el cual puede recibir un número int
, con el le decimos el número total de experimentos que queremos realizar y de esta forma evitamos utilizar un ciclo for
.
.
Código de la clase:
arr = []
for _ in range(num_trials):
arr.append(binomial(n, p))
Utilizando el parámetro sIze
:
arr = binomial(n, p, num_trials)
Este es mi ejercicio a mano.
![](
vamossssssss me sallió el ejercicio a mano
Para el ejericio a mano otra forma interesante de verlo y realizarlo es que la probabilidad de tener 2 o menos exitos para 3 lanzamientos es igual a 1 - la probabilidad de tener 3 exitos, esto facilita mucho los calculos ya que nos quedaria 1 - la combinatoria de 3 con 3 ( que daria 1) * (1/2)^3 * (1/2)^0 (que nuevamente es 1) por lo que al final tendriamos que la probabilidad es 1-(1/2)^3 = 1- (1/8) = 7/8
sumatoria = 0
for i in range(3):
sumatoria += binomial (i, 3, 0.5)
print (sumatoria)
Le hice una pequeña modificacion a la funcion
def plot_hist(num_trials):
values = [0, 1, 2, 3]
r = np.arange(4)
bar_width = 0.25
arr = []
for i in range(num_trials):
arr.append(binomial(n,p))
# distribucion simulada
sim = np.unique(arr, return_counts = True)[1]/len(arr)
# distribucion teorica
teorica = [binom(3, 0.5).pmf(k) for k in values]
print('simulada: ',sim)
print('teorica : ',teorica)
plt.bar(r - bar_width / 2, sim, color='red', width = bar_width, label='Simulada')
plt.bar(r + bar_width / 2, teorica, color='blue', width = bar_width, label='Teorica')
plt.title('{} experimentos'.format(num_trials))
plt.legend(loc='upper left')
plt.show()
<code>
aqui se llama con 3 num_trials
plot_hist(100)
plot_hist(10000)
plot_hist(1000000)
y aqui se ve el resultado:
Es importante tener encuenta que es mas eficiente predefinir el tamaño de un array cuando podamos y evitar usar np.append(porque es muhco mas eficiente predefinirlo)
una forma de hacerlo y además usar list comprehension por simplificación en vez del for normal es
arr = np.zeros((num_trials))
arr = [binomial(n,p) for i in arr]
arr = np.array(arr)
Una cosa interesante de la que em di cuenta al realizar experimentos con la función del profe es que si se ingresa un número de intentos bajo, aproximadamente menor a 10, existe la posibilidad de que la distribución teórica y simulada sean tan diferentes que las escalas no coincidan y se genere el error “ValueError: shape mismatch: objects cannot be broadcast to a single shapeel”. Aquí les dejo el código donde agregué una línea que indica que deben usarse al menos 15 intentos.
def plot_hist(num_trials):
if num_trials < 15:
raise Exception("El número de ensayos debe ser al menos 15")
values = [0,1,2,3]
arr = []
for _ in range(num_trials):
arr.append(binomial(3, 0.5))
print(arr)
distribucion_simulada = np.unique(arr, return_counts=True)[1]/len(arr)
distribucion_teorica = [binom(3, 0.5).pmf(k) for k in values]
plt.bar(values, distribucion_teorica, label = 'teoría', color = 'red')
plt.bar(values, distribucion_simulada, label = 'simulación', alpha = 0.5, color = 'blue')
plt.title('simulación con {} experimentos'.format(num_trials))
plt.show()
La expresión esta calculando la probabilidad acotada de obtener un número k de éxito en una serie de ensayos independientes, donde el numero de ensayos es 3 (n=3), la probabilidad de exito es de 1/2 (p=1/2), y la acotación es que el numero de exitos k sea menor o igual a 2. Esto se calcula sumando las probabilidades individuales de obtener 0, 1 o 2 éxitos.
En resumen, el resultado es P(k≤2,n=3,p=1/2) = 7/8
Agregue un poco más de información a la función para visualizar los labels y los array de ambas distribuciones:
def plot_hist(num_trials):
values = [0,1,2,3]
arr = []
for _ in range(num_trials):
arr.append(binomial(3, 0.5))
distribucion_simulada = np.unique(arr, return_counts=True)[1]/len(arr)
distribucion_teorica = [binom(3, 0.5).pmf(k) for k in values]
plt.bar(values, distribucion_teorica, label = 'teoríca', color = 'red')
plt.bar(values, distribucion_simulada, label = 'simulada', alpha = 0.5, color = 'blue')
plt.title('simulación con {} experimentos'.format(num_trials))
plt.legend()
plt.show()
print("")
print("distribucion simulada: {}".format(distribucion_simulada))
print("distribucion teorica: {}".format(distribucion_teorica))
print("")
El cálculo de la distribución acumulada también se puede demostrar usando la misma función de densidad de probabilidad con un ciclo for o un comprehesions list
# calculo de dist.pmf utilizando un ciclo for1
dist_cdf = 0
for k in range(3):
dist_cdf += dist.pmf(k)
print(dist_cdf)
# calculo de dist.pmf utilizando comprehesions list
print(sum([dist.pmf(k) for k in range(0,3)]))
Si no entiendo un tema recurro a una segunda opinión: https://www.youtube.com/watch?v=-XxZGvNClkg
un crack este señor para explicar la distribución binomial
Gráfico:
Los generadores aleatorios tienen como proposito simular muestras de datos que resultarian de muestreo en la vida real de procesos aleatorios como lanzar una moneda o un dado.
Los generadores aleatorios esta relacionado a la Escuela Frecuentista ya que simulan experimentos aleatorios como si fueran reales: La probabilidad de lanzar una moneda y que caiga cara es del 50% pero esto no necesariamente quiere decir que de 10 lanzamientos, 5 caigan cara. Lo que implica es que en la medida en que el numero de lanzamientos es cada vez mas grande, la fraccion de las caras que obtienes se acerca al 50% como lo indica la Filosofia de dicha escuela
Que buena clase, es la tercera vez que a veo.
Python me hubiera facilitado la vida en mi época de estudiante con cálculo y estadística 😅
import plotly.graph_objects as go
import plotly.offline as pyo
import plotly.express as px
pyo.init_notebook_mode()
def plot_hist(num_trials):
values = [0,1,2,3]
arr = []
for _ in range(num_trials):
arr.append(binomial(3, 0.5))
distribucion_simulada = np.unique(arr, return_counts=True)[1]/len(arr)
distribucion_teorica = [binom(3, 0.5).pmf(k) for k in values]
# datos_array = np.array([values, distribucion_teorica, distribucion_simulada])
# df = pd.DataFrame(datos_array)
# df1 = df.T
# df1.rename(columns={0:'values' ,1:'distribucion_teorica', 2:'distribucion_simulada'}, inplace=True)
# df1.set_index('values', inplace=True)
# return df1.head()
fig = go.Figure(go.Bar(x=values, y=distribucion_teorica, opacity = 0.5, name='Distribucion teorica'))
fig.add_trace(go.Bar(x=values, y=distribucion_simulada, name='Distribucion simulada'))
# fig1 = px.bar(x=values, y=distribucion_teorica, opacity = 0.5)
# fig1.update_traces(marker=dict(color='red'))
# fig2 = px.bar(x=values, y=distribucion_simulada, opacity = 0.5)
# fig2.update_traces(marker=dict(color='blue'))
# fig3 = go.Figure(data=fig1.data + fig2.data)
fig.update_layout(title = f'simulación con {num_trials} experimentos',
font = dict(family = 'verdana', size = 16, color = 'white'),
template = 'plotly_dark',
height = 400,
width = 850,
barmode='group',
xaxis={'categoryorder':'category ascending'})
fig.update_yaxes(ticksuffix = ' Probabilidad')
fig.update_xaxes(ticksuffix = ' Tipo experimento')
fig.show()
plot_hist(20)
plot_hist(200)
plot_hist(20000)
acá una versión de dencidad discreta
# definición de la distribución binomial (Discreta)
def my_binomial_dist(k, n, p):
acumulation = 0
for k_exitos in range(k+1):
acumulation = acumulation + factorial(n)/(factorial(k_exitos)*factorial(n-k_exitos))*pow(p,k_exitos)*pow(1-p, n-k_exitos)
return acumulation
¿Cómo estableció el valor de P en esta función? ¿A qué refiere la probabilidad equilibrada?
Le escribí estos condicionales para que el resultado tuviese un mensaje completo en cada intento.
p=0.5
n=3
cara = binomial(n, p)
if cara == 0:
print(f'En este intento de tres lanzamientos ningúno salió cara')
elif cara == 1:
print(f'En este intento de tres lanzamientos {cara} salió cara')
else:
print(f'En este intento de tres lanzamientos {cara} salieron cara')
chicxs, comparto una sugerencia
aunque ya dominéis ciertais librerías y lógicas de python, no os limitéis a ver el vídeo sin comprobar el código por vosotros mismos
las probabilidades de que entendáis mucho mejor el contenido son TODAS.
tengo una duda a la hora de graficar, porque cuando escribo y corro el codigo de la simulacion me da como resultado solo uno de los tres graficos, en cambio cuando copio y pego el codigo del profe si me salen las tres graficas
aqui mi codigo:
y el del profe
Validación de ejercicio
Validación del ejercicio a mano:
Intenté usar la misma fórmula para calcular la probabilidad de que salga 3 o 6 lanzando varias veces el dado. No me está dando el valor correcto. Alguien podría decirme porqué o compartir como se escribe en código usando la fórmula del profe?
Genial la clase!
Les comparto un video de 15min en español que encontré en youtube, sobre google colab.
Este es el resultado del ejercicio:
Aquí una forma sencilla y rápida de hacer la validación del ejercicio a mano.
prob = 0
for i in range(3):
dist_i= binom(3, 0.5)
prob += dist_i.pmf(i)
print(prob)
Realice parte del codigo antes de tiempo y esto fue lo que me salio.
Espero les guste y sea de ayuda.
#Author: Kevin Andres Rosales Marquez
import random
import numpy as np
from scipy.stats import binom
import matplotlib.pyplot as plt
class CMoneda(object):
def __init__(self, estado = -1):
self.estado = estado
def LanzarMoneda(self):
self.estado = random.randint(0, 1)
return self.estado
def CreaMonedas(n):
monedas = []
for i in range(n):
monedas.append(CMoneda())
return monedas
def LanzaMonedas(monedas):
lanzamientos = [moneda.LanzarMoneda() for moneda in monedas]
caras = [lanzamiento for lanzamiento in lanzamientos if lanzamiento == 1]
return len(caras)
def simulacion(n, k):
monedas = CreaMonedas(n)
retultados = LanzaMonedas(monedas)
experimento = [LanzaMonedas(monedas) for resultado in range(k)]
return(experimento)
def main():
n = 3
k = 100
values = [0, 1, 2, 3]
teorica = [binom(3,0.5).pmf(k) for k in values]
experimento = simulacion(n, k)
#Fragmento tomado de la clase
experimento = np.unique(experimento, return_counts=True)[1]/len(experimento)
print("Probabilidad Simulada: ", experimento)
print("Probabilidad Teorica: ", teorica)
plt.bar(values, teorica, alpha = 0.5, color = 'blue')
plt.bar(values, experimento, alpha = 0.5,color = 'red')
plt.title('{} Experimentos'.format(k))
plt.show()
if __name__ == '__main__':
main()
Este ejemplo está buenísimo para practicar:
Se tiene una muestra de 20 llantas, en el departamento de control de calidad se quiere determinar la probabilidad de que ninguna sea defectuosa, sabiendo que el 8% de las llantas de la población son defectuosas
Intenta hacerlo y después lees el resultado…
Resultado:
dist = binom.pmf(k=0, n=20, p=.08)
En este caso toma en cuenta que el evento de que una llanta salga defectuosa es un éxito, porque la probabilidad de ese éxito es de 8%
Si tomamos al evento de que una llanta salga en buen estado como éxito, entonces la probabilidad es del 92% y el ejercicio queda así
dist = binom.pmf(k=20, n=20, p=.92)
¿Cómo estableció el valor de P en esta función? ¿A qué refiere la probabilidad equilibrada?
pmf = Probability Mass Function
cdf = Cumulative Distribution Function
De la clase pasada a esta es mucha la diferencia jajaja
de hacerlo en papel o con ejemplos a hacerlo en código
Para quienes tengan Python3 en su escritorio pueden usar el código directo pero primero cree un env e instalen:
NUMPY:
pip install numpy
MATPLOTLIB:
python -m pip install -U matplotlib
SCIPY:
pip install scipy
Distribución binomial con SciPy
¿Quieres ver más aportes, preguntas y respuestas de la comunidad?