Introducción al análisis exploratorio de datos

1

¿Qué es y para qué sirve el análisis exploratorio de datos?

2

¿Cómo hacer un análisis exploratorio de datos?

3

Tipos de análisis de datos

4

Tipos de datos y análisis de variables

5

Herramientas de software para el análisis exploratorio de datos

6

Conociendo nuestros datos: palmerpenguins

7

Recolección de datos, limpieza y validación

8

Ejercicio de validación de datos

Quiz: Introducción al análisis exploratorio de datos

Análisis univariado

9

Explorando una variable categórica: conteos y proporciones

10

Estadística descriptiva aplicada: medidas de tendencia central

11

Estadística descriptiva aplicada: medidas de dispersión

12

Ejercicio de obtención de medidas de dispersión

13

Estadística descriptiva aplicada: distribuciones

14

Estadística descriptiva aplicada: funciones de densidad de probabilidad

15

Bonus: Teorema del límite central

Quiz: Análisis univariado

Análisis bivariado

16

Estableciendo relaciones: gráficos de puntos

17

Estableciendo relaciones: gráficos de violín y boxplots

18

Estableciendo relaciones: matrices de correlación

19

Limitantes de los coeficientes de correlación lineal

20

Estableciendo relaciones: análisis de regresión simple

21

Limitaciones del análisis de regresión simple

Quiz: Análisis bivariado

Análisis multivariado

22

Análisis de regresión múltiple

23

Visualización del análisis de regresión múltiple

24

Análisis de regresión logística

25

Paradoja de Simpson

26

¿Qué hacer cuando tengo muchas variables?

Quiz: Análisis multivariado

Conclusiones

27

Diversidad de gráficas al explorar datos

28

Continúa aprendiendo sobre EDA

No tienes acceso a esta clase

¡Continúa aprendiendo! Únete y comienza a potenciar tu carrera

Bonus: Teorema del límite central

15/28
Recursos

Aportes 23

Preguntas 9

Ordenar por:

¿Quieres ver más aportes, preguntas y respuestas de la comunidad?

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 = 1000
sample_size = 35

np.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 in range(1, number_samples + 1):    
    col_names.append(f"sample_{i}")
samples_df.columns = col_names


for i in range(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}%")

Demostracion Computacional del T. de los grande numeros

Tomamos como ejemplo el lanzamiento de una dado

#calculo de la probabilidad para cada cara del dado
dice = 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}')

Demostracion del T. del Limite Central

Analizamos una variable binaria

preprocessed_penguins_df.sex.value_counts(normalize=True)

La variable sex sigue una distribucion binomial. Como es categorica, debemos convertirla en una variable numerica

sex_numeric = preprocessed_penguins_df.sex.replace(['male', 'female'], [1, 0])

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 tomar
sample_size = 35 #tamaño de la muestra

sample_df = pd.DataFrame() #dataframe donde se almacena las media de cada muestra

np.random.seed(42)

for i in range(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

sample_means_binomial = pd.DataFrame(sample_df.mean(), columns=['sample_mean'])
sns.kdeplot(data=sample_means_binomial)
plt.axvline(x=sex_numeric.mean(), color='red', linestyle='dashed')

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 in range(1, number_sample + 1)],
    columns=['sample_size', 'estimated_mean']
)

#grafica  del efecto
sns.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])

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

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)

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.

El método ‘replace’ también puede recibir un diccionario 😉

sex_numeric = df_limpio.sex.replace({'male':1,'female':0})

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.

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)
  • 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 Adelia
adelia_bill_length = penguins[penguins['species']=='Adelie']['bill_length_mm']

import numpy as np

# Generamos 100 muestras aleatorias de tamaño 30
n_samples = 100
sample_size = 30
samples = np.random.choice(adelia_bill_length, size=(n_samples, sample_size))
means = samples.mean(axis=1)

import matplotlib.pyplot as 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()

Les comparto la forma de eliminar el warning del Teorema del límite central

number_samples = 1000
sample_size = 35

np.random.seed(42)

samples_list = []
for i in range(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 in range(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}%")
El reto del profesor ![](https://static.platzi.com/media/user_upload/image-78c2e6e3-6b84-4679-80c0-c5f7e91da5ab.jpg) ```js 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 codigo tiene mayusculas: sex_numeric = processed_penguins_df.sex.replace([‘Male’, ‘Female’], [1, 0])

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.”

Este muestreo es un muestreo aleatorio con reemplazo, ya que cada vez que saco 35 pingüinos de la muestra de los 333 pingüinos debo volver a meter los pingüinos que saque por decirlo así de la bolsa y hacer el ejercicio 999 veces mas.

In the Python string formatting syntax, .4f is used to specify that the float value should be formatted with four decimal places after the decimal point.

In the context of the given code, {male_population_mean * 100:.4f} means that the float value of male_population_mean * 100 will be formatted to display up to four decimal places after the decimal point.

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* ```js sex_numeric = df_penguins['sex'].map({'male': 0, 'female': 1}).astype(int) number_samples = 1000 sample_size = 35 # número de muestras np.random.seed(42) # lista auxiliar: almacenar las muestras samples_list = [] for i in range(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}%') ```
Yo use la funcion distplot (que esta deprecada y sera removida de versiones siguientes) y nos entrega la comparacion de la funcion de densidad normal vs el histograma: `sns.histplot(data=df_samples.mean())` `plt.axvline(x=sex_numeric.mean(), color='red')` `plt.ylabel('Valor real de la proporcion de Males')` `plt.title('Distribucion de las medias de las 1000 samples de 35 valores cada sample')` `plt.show()` ![](https://static.platzi.com/media/user_upload/image-640142bd-07b2-4572-8a54-6161173704eb.jpg)
number_samples = 10000
sample_size = 50

samples_list = []

np.random.seed(42)
for i in range(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 in range(1, number_samples + 1)])

# Plot kernel density of sample means
sample_means_binomial = pd.DataFrame(samples_df.mean(), columns=['sample_mean'])

# Set a wider figure size
plt.figure(figsize=(12, 6))

sns.kdeplot(data=sample_means_binomial['sample_mean'], label='Sample Means')

# Calculate statistics for the sample means
sample_means_stats = {
    'mean': sample_means_binomial['sample_mean'].mean(),
    'std' : sample_means_binomial['sample_mean'].std(),
    'min' : sample_means_binomial['sample_mean'].min(),
    'max' : sample_means_binomial['sample_mean'].max()
}

# Generate x values for the theoretical normal distribution
xs = np.linspace(sample_means_stats['min'], sample_means_stats['max'], 50)

# Calculate the PDF for the theoretical normal distribution
ys = scipy.stats.norm(sample_means_stats['mean'], sample_means_stats['std']).pdf(xs)

# Plot the theoretical normal distribution
plt.plot(xs, ys, color='black', linestyle='dashed', label='Theoretical Normal Distribution')

# Highlight the mean of sample means
plt.axvline(x=sample_means_stats['mean'], color='red', linestyle='dashed', label='Mean of Sample Means')

plt.title('Kernel Density Plot and Theoretical Normal Distribution of Sample Means')
plt.legend()
plt.show()

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.

  1. Manzana.
  2. Pera.
  3. Coco.
    se distribuyen asi.
    1 = 40 unidades.
    2 = 15 unidades.
    3 = 2 unidades.

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.)

Qué curioso que la grafica final se asemeje demasiado a las resultantes al calcular la funcion de transferencia en teoria de control clásico mediante la transformada de LaPlace

¿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.

Este video me ayudo a entender mejor el concepto: https://www.youtube.com/watch?v=o2afi9BKRIM&ab_channel=Estadísticaútil

Aquí aplique el Teorema del límite central a la variable body_mass_g y estos fueron los resultados(el codigo esta en mi deepnote):
Esto también funciona para estimar (o inferir) otros estadísticos (standard deviation, median, mode, etc).
Estimado de la media = 4198.408571428571
Media real del conjunto = 4207.057057057057