Por si se les presenta una serie de advertencias de numpy como me paso, le dejo un código que tal vez no es el mejor pero me ayudo a eliminar la gran cantidad de advertencias.
number_samples =1000sample_size =35np.random.seed(42)# definimos el DataFrame en blanco con su tamaño definido
samples_df = pd.DataFrame(np.random.randint(1, sample_size, size =(sample_size, number_samples)))# Le asignamos nombres a las columnas.col_names=[]for i inrange(1, number_samples +1): col_names.append(f"sample_{i}")samples_df.columns= col_names
for i inrange(1, number_samples +1): sex_numeric_sample = sex_numeric.sample(sample_size, replace=True).to_numpy() sample_name = f"sample_{i}" samples_df[sample_name]= sex_numeric_sample
male_population_mean = samples_df.mean().mean()print(f"El porcentaje estimado de pingüinos machos en la población es: {male_population_mean * 100:.4f}%")
Excelente, muchas gracias!!
GRACIAS
Demostracion Computacional del T. de los grande numeros
Tomamos como ejemplo el lanzamiento de una dado
#calculo de la probabilidad para cada cara del dadodice = empiricaldist.Pmf.from_seq([1,2,3,4,5,6])dice.bar()
Valores de probabilidad para cada cara del dado en diferentes tamaños de muestras
for sample_size in(1e2,1e3,1e4):#100 1000 10000 sample_size =int(sample_size) values = dice.sample(sample_size)# obtener valores segun tamaño de la muestra sample_pmf = empiricaldist.Pmf.from_seq(values)#calculo de la probabilidad para cada valor#graficas para cada tamaño de muestra plt.figure(figsize=(5,5)) sample_pmf.bar() plt.axhline(y=1/6, color='red', linestyle='dashed') plt.ylim([0,0.50]) plt.title(f'Sample size: {sample_size}')
Fijamos el numero de muestras a tomar y el tamaño de cada muestra, luego calculamos la media de los machos de cada muestra y a todas ellas le sacamos la media observando asi que se aproxima a la proporcion de machos dada por los datos
number_sample =1000#cantidad de muestras a tomarsample_size =35#tamaño de la muestrasample_df = pd.DataFrame()#dataframe donde se almacena las media de cada muestranp.random.seed(42)for i inrange(1, number_sample +1): sex_numeric_sample = sex_numeric.sample(sample_size, replace=True).to_numpy() sample_name =f'sample {i}' sample_df[sample_name]= sex_numeric_sample
male_population_mean = sample_df.mean().mean()print(f'El porcentaje de pinguinos machos en la poblacion es de: {male_population_mean*100:.4f}%')
La distribucion binomial se convierte en este caso en una distribucion Normal como se evidencia en la grafica que sigue
Otra manera de verlo es ir incrementando la cantidad de muestras y observar el efecto en la proporcion de machos
sample_size_experiment = pd.DataFrame([[i, sample_df.iloc[:,0:i].mean().mean().mean()]for i inrange(1, number_sample +1)], columns=['sample_size','estimated_mean'])#grafica del efectosns.scatterplot( data=sample_size_experiment, x='sample_size', y='estimated_mean')plt.axhline( y=sex_numeric.mean(), color='red', linestyle='dashed')plt.ylim([sex_numeric.mean()-0.20, sex_numeric.mean()+0.20])
Gracias por el aporte.
Muchas gracias por el aporte
Teorema de los grandes números
La probabilidad experimental tiende a la probabilidad teorica a medida que aumenta el numero de repeticiones del experimento. Es muy util cuando no se conoce la probabilidad teorica de un evento y tenemos la capacidad de aumentar la muestra. Mediante este teorema, al incrementar la muestra la probabilidad experimental al final se convertira en la probabilidad teorica.
Teorema del Limite Central
La media de las muestras tiende aproximadamente a una distribución normal
La suma de n variables aleatorias independientes con medias y varianzas finitas converge en distribucion a una variable aleatoria normal
El método 'replace' también puede recibir un diccionario 😉
Muchas gracias David. Tu respuesta me ayudo a resolver el error que me salía ejecutando el código que puso el profesor Jesús:
'sex_numeric = processed_penguins_df.sex.replace([‘Male’, ‘Female’], [1, 0])'
Cuando lo ejecutaba no me transformaba la columna ‘sex’ en valores numéricos porque el código tiene un error de sintaxis que descubrí con el tuyo: escribe 'Male' y 'Famale' con mayúscula inicial, cuando debería ser minúscula. Con el código que proporcionaste también se puede llegar a la respuesta: 50.1829% que coincide con el valor que debería dar. De nuevo gracias. 👍
Al ejecutar el bucle for, da este Warning (traducido al español) como resultado en jupiter lab, y estoy seguro que no es por falta de buen hardware:
DataFrame está muy fragmentado.Esto suele ser el resultado de llamar a `frame.insert` muchas veces, lo que tiene un rendimiento deficiente.Considere unir todas las columnas a la vez usando pd.concat(axis=1) en su lugar.Para obtener un marco desfragmentado, use `newframe = frame.copy()`
Se soluciona con:
from warnings import simplefilter
simplefilter(action="ignore", category=pd.errors.PerformanceWarning)
Detallito en el codigo.
Gracias por la solución Alfonso. Quería preguntarte por qué se generó ese warning??
En Python, las expresiones como 1e3 o 1e2se utilizan para representar números en notación científica. En particular, 1e3 significa "1 multiplicado por 10 elevado a la potencia de 3", que es igual a 1000. De manera similar, 1e2 significa "1 multiplicado por 10 elevado a la potencia de 2", que es igual a 100.
Gracias por la información!
Gracias crack!
Muy buena clase, sin embargo me queda la duda, el parámetro 42, adentro de la función np.random.seed(), a que hace referencia??
Esa función de numpy sirve para poner una semilla del código, realmente puede ser cualquier número. El objetivo es que si por ejemplo genero valores randómicos, siempre obtener los mismos valores, y que no pase que cada vez que se ejecuta el código se generen nuevos números. A continuación te muestro un ejemplo:
Tenia la misma duda! Gracias
Por si les aparece el error de DataFrame is highly fragmented correr este codigo antes:
from warnings import simplefilter
simplefilter(action="ignore", category=pd.errors.PerformanceWarning)
Muchas gracias, ya me estaba comenzando a enojar con migo mismo jajaja, ve parce como es que sabes resover ese error?, es que tambien quiero ser capaz de resolve futuros errores similares a ese.
Buenas 👋 Al ejecutar el código me salía un festival de warnings :/ por si a alguien le sirve, pude resolverlo usando map en vez de replace + cambiando un poco el código.
Versión de pandas: 2.2.1
sex_numeric = df_penguins['sex'].map({'male':0,'female':1}).astype(int)number_samples =1000sample_size =35 # número de muestras
np.random.seed(42)# lista auxiliar: almacenar las muestras
samples_list =[]for i inrange(1, number_samples +1): sex_numeric_sample = sex_numeric.sample(sample_size, replace=True).to_numpy() samples_list.append(pd.Series(sex_numeric_sample, name=f'sample_{i}')) # almacenar cada muestra en una serie
# Concatenar todas las muestras en un nuevo df
samples_df = pd.concat(samples_list, axis=1)male_proportion_mean = samples_df.mean().mean()print(f'Estimated percentage for male penguins (in total population): {male_proportion_mean * 100:.2f}%')
Correlaciones entre variables Correlación Person:
*Correlación positiva Alta: En orden de correlación>5
1ro: body_mass con Flipper_length_mm
El peso de los pingüinos presenta una alta correlación con la longitud de sus alas (0,87)
2do: flipper_length_mm con bill_length_mm
La longitud de las alas de los pingüinos presenta una correlación positiva media o alta con respecto a el largo de sus picos (0,65)
3ro: body_mass con bill_length_mm
El peso de los pingüinos presenta una correlación positiva media con respecto al largo de sus picos (0,59)
Correlación positiva baja: <=5
body_mass con numeric_sex (0,42)
body_mass con year (0,022)
bill_length_mm con numeric_sex(0,34)
bill_length_mm con year (0,033)
Flipper_length_mm con numeric_sex (0,26)
Flipper_length_mm con year (0,15)
Estas variables no guardan relación entre ellas
****Correlación negativa: ****
La única variable con una correlación negativa media o alta mayor a 5, es bill_depth_mm con Flipper_length_mm.
Gran aporte amigo.
Hola, por qué en 13:55 se aplicó mean() 3 veces? Note al escribir que con 2 veces se obtiene el mismo resultado como sospechaba.
Les comparto la forma de eliminar el warning del Teorema del límite central
number_samples =1000sample_size =35np.random.seed(42)samples_list =[]for i inrange(1, number_samples +1): sex_numeric_sample = sex_numeric.sample(sample_size, replace=True).to_numpy() samples_list.append(sex_numeric_sample)samples_df = pd.DataFrame(np.column_stack(samples_list), columns=[f"sample_{i}"for i inrange(1, number_samples +1)])male_population_mean = samples_df.mean().mean()print(f"Estimated percentage of male penguins in population is: {male_population_mean * 100:.4f}%")
A qué se debe aplicar 2 veces el método del promedio?
male_population_mean = sample_df.mean().mean()
La primera vez que lo aplicas calcula el promedio por cada sample. Ya aplicándolo por segunda vez calcula el promedio para todo el set de datos.
El reto del profesor
sample_means_binomial= pd.DataFrame(samples_df.mean(), columns=['sample_mean'])#Distribucion de los datos
sns.kdeplot( data=sample_means_binomial, label='Distribucion real', fill=True, alpha=0.1, color ='red', linewidth=0.4,)# Distribucion teorica
plt.plot( xs, ys, color='#891652', linestyle='dashed', label='Disribucion teorica', alpha=0.9)# Linea vertical en la media poblacional
xs=np.linspace(sample_means_binomial.min(), sample_means_binomial.max())ys=scipy.stats.norm(sample_means_binomial.mean(), sample_means_binomial.std()).pdf(xs)plt.axvline( x=sex_numeric.mean(), color='#FEC7B4', label='Media poblacional')plt.legend()plt.show()
El teorema del límite central es uno de los conceptos fundamentales de la estadística. El teorema establece que, si tomamos suficientes muestras aleatorias de una población, la distribución de las medias muestrales se aproxima a una distribución normal independientemente de la distribución de la población original, siempre que el tamaño de muestra sea suficientemente grande.
En otras palabras, el teorema del límite central nos dice que, a medida que aumenta el tamaño de la muestra, la distribución de las medias muestrales se acerca cada vez más a una distribución normal. Esto es importante porque muchas de las técnicas estadísticas que utilizamos asumen que las variables tienen una distribución normal, y el teorema del límite central nos permite utilizar estas técnicas incluso cuando la población original no es normal.
import seaborn as sns
# Cargamos los datos de pingüinos
penguins = sns.load_dataset('penguins')# Seleccionamos la columna del largo del pico para la especie Adeliaadelia_bill_length = penguins[penguins['species']=='Adelie']['bill_length_mm']
import numpy as np
# Generamos100 muestras aleatorias de tamaño 30n_samples =100sample_size =30samples = np.random.choice(adelia_bill_length, size=(n_samples, sample_size))means = samples.mean(axis=1)
import matplotlib.pyplotas plt
# Graficamos la distribución de las medias muestrales
plt.hist(means, bins=20)plt.title('Distribución de las medias muestrales de Adelia (n=30)')plt.xlabel('Largo del pico (mm)')plt.ylabel('Frecuencia')plt.show()
¿Por que el profesor no deja el codigo ya hecho en la seccion de recursos?. A veces lo que pasa la comunidad esta mal tipeado. Seria bueno que el profe sea el que pase la documentacion correcta.
Por si se les presenta un montón de warnings.
number_samples =1000sample_size=35samples =[]np.random.seed(42)for i inrange(1, number_samples +1): sex_numeric_sample = sex_numeric.sample(sample_size, replace=True).to_numpy() samples.append(pd.Series(sex_numeric_sample, name=f"sample_{i}"))samples_df = pd.concat(samples, axis=1)male_population_mean = samples_df.mean(numeric_only=True).mean()print(f"Estimated percentage of male penguins in population is: {male_population_mean * 100:.4f}%")
Estimad@, si sentiste que esto no te quedó claro, yo te lo voy a dejar clarisimo.
La ley de los grandes numeros consiste en que, entre mas numeros tengas, la probabilidad de tener eventos tienden a equilibrarse.
y el teorema de limite central es que, segun la ley anterior, la distribucion de los numeros, tienden a ser central.
y esto tiene todo el sentido del mundo.
porque:
imaginate tu tienes 3 frutas.
si las metes en una caja.
cual es la probabilidad de sacar Manzana, Pera y coco(respectivamente)
obviamente Manzana es la mayor probabilidad.
entonces, la ley de los numeros grandes establece que:
entre mas unidades(muestras) tengas, esta probabilidad tiende a equipararse(equilibrarse) osea que, ya sacar una manzana no es una gran probabilidad.
ahora.
el teorema de limite central acompaña a esta teoria(complementa), diciendo que:
entonces, cuando se aplica la ley anterior, la distribucion de los numeros tienden a ser centrales.
es decir, van a ser limites centrales, limite central es que busca una distribucion normal.
(**SI NO LO ENTIENDES AQUI, TE RECOMIENDO QUE COPIES Y PEGUES ESTA INFORMACION EN CHAT-GPT **y le hagas preguntas sobre esto.)
el codigo tiene mayusculas: sex_numeric = processed_penguins_df.sex.replace(['Male', 'Female'], [1, 0])
Un error muy sutil, pero que genera que tu código no se ejecute de la manera correcta. Gracias por la observación.
15. Bonus: Teorema del límite central
Ley de los grandes números
“La probabilidad experimental tiende a la probabilidad teórica a medida que aumenta el número de repeticiones del experimento”
Teorema del Límite Central
“La media de las muestras tiende aproximadamente a una distribución normal.”
“La suma de n variables aleatorias independientes con medias y varianzas finitas converge en una distribución a una variable aleatoria con distribución normal.”