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

Convierte tus certificados en títulos universitarios en USA

Antes: $249

Currency
$209

Paga en 4 cuotas sin intereses

Paga en 4 cuotas sin intereses
Suscríbete

Termina en:

18 Días
5 Hrs
38 Min
17 Seg

Estadística descriptiva aplicada: funciones de densidad de probabilidad

14/28
Recursos

Aportes 21

Preguntas 4

Ordenar por:

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

Vamos por la mitad de este Nuevo Curso de Análisis Exploratorio de Datos, y hasta aquí realmente se nota la diferencia con el anterior, que bien que Platzi se renueva constantemente

Aca podemos ver que hay cierto grado de sesgo en cada variable, pero hay que tener en cuenta que estamos analizando las 3 especies en un solo conjunto, es normal que haya este tipo de sesgo.

Pero si analizamos cada variable dividida por especie podemos ver que la distribución empírica se adapta mejor a la distribución teórica

Estadistica Descriptiva Aplicada: Funciones de Probabilidad (PDFs)

Nos ayudan a estimar la probabilidad para valores que no contiene el dataset, fomando una distribucion continua. Tambien son utiles para ver la forma de la distribucion a detalle y hacer comparaciones con la distribucion teorica.

  • Grafica de la Densidad de probabilidad. Varia el ancho de banda de los picos de la distribucion con el parametro bw_method para obtener mucha mas informacion. Utiliza este parametro para comparar distribuciones
sns.kdeplot(
    data=preprocessed_penguins_df,
    x='flipper_length_mm',
    bw_method=0.2 #ancho de banda 
)
  • Comparando la distribución de los datos con la teórica utilizando la ECDFs
# Obtenemos los estadisticos de la variable
stats = dataFrame.nombre_variable.describe()

# generamos los valores aleatorios a partir de los estadisticos de los datos 
# utilizando el ECDFs
xs = np.linspace(stats['min'], stats['max']) #array de valores aleatorios
ys = scipy.stats.norm(stats['mean'], stats['std']).cdf(xs) #valores de probabilidad para cada valor

# grafica de la distribucion de datos aleatorios
plt.plot(xs, ys, color='black', linestyle='dashed')

# grafica de la distribucion de los datos reales
empiricaldist.Cdf.from_seq(
    dataFrame.nombre_variable,
    normalize=True
).plot()
  • Comparando la distribución de los datos con la teórica utilizando PDFs
# generar valores aleatorios a partir de los estadisticos de los datos
# utilizando el PDFs
xs = np.linspace(stats['min'], stats['max']) #array de valores aleatorios
ys = scipy.stats.norm(stats['mean'], stats['std']).pdf(xs) #valores de probabilidad para cada valor

# grafica de la distribucion de datos aleatorios
plt.plot(xs, ys, color='black', linestyle='dashed')

# empiricaldist no incluye esta funcion por lo que utilizamos seaborn
sns.kdeplot(
    data=dataFrame,
    x='nombre_variable'
)

Esta super bien el curso, solo tengo una corrección. En realidad al analizar la pdf la distribución esta sesgada a la derecha y no a la izquierda (si es izquierda o derecha depende de que lado la cola de la distribución es más pesada). Esta super bueno el curso de análisis exploratorio de datos 10/10.

Muy bueno este curso, facil de seguir y entender 💯

14. Estadística descriptiva aplicada: funciones de densidad de probabilidad

Para el que le pueda servir

La función plot_kde_for_numeric_variables genera gráficos de densidad de probabilidad kernel (KDE) por especie para las columnas numéricas en un DataFrame. Itera sobre cada especie y columna para generar los gráficos correspondientes. También se traza una distribución normal con línea punteada para representar la distribución teórica basada en las estadísticas de cada columna y especie. Los gráficos se organizan en una o varias filas, y cada gráfico tiene etiquetas de ejes y títulos correspondientes. Finalmente, los gráficos se muestran mediante plt.show().

def plot_kde_for_numeric_variables(dataframe):  # Funcion para graficar la funcion de densidad de probabilidad por especie
    numeric_columns = dataframe.select_dtypes(include=np.number).columns  # Obtiene las columnas numéricas del DataFrame
    num_plots = len(numeric_columns)  # Cantidad de gráficos a generar según las columnas numéricas
    species = dataframe['species'].unique()  # Especies únicas presentes en la columna "species"
    num_species = len(species)  # Cantidad de especies presentes

    fig, axes = plt.subplots(num_species, num_plots, figsize=(15, 5*num_species))  # Crea una figura y subfiguras para los gráficos

    for i, specie in enumerate(species):  # Itera sobre cada especie
        specie_data = dataframe[dataframe['species'] == specie]  # Filtra los datos para la especie actual

        for j, column in enumerate(numeric_columns):  # Itera sobre cada columna numérica
            ax = axes[i, j] if num_species > 1 else axes[j]  # Obtiene los ejes correspondientes a la subfigura actual
            stats = {
                'min': specie_data[column].min(),  # Mínimo de la columna actual y especie actual
                'max': specie_data[column].max(),  # Máximo de la columna actual y especie actual
                'mean': specie_data[column].mean(),  # Media de la columna actual y especie actual
                'std': specie_data[column].std()  # Desviación estándar de la columna actual y especie actual
            }

            xs = np.linspace(stats['min'], stats['max'], num=100)  # Valores para el eje x (espaciados uniformemente)
            ys = scipy.stats.norm(stats['mean'], stats['std']).pdf(xs)  # Valores de densidad de probabilidad para el eje y
            ax.plot(xs, ys, color='gray', linestyle='dashed')  # Traza la distribución normal en los ejes

            sns.kdeplot(data=specie_data, x=column, ax=ax)  # Traza el gráfico de densidad de probabilidad kernel (KDE)

            ax.set_xlabel(column)  # Etiqueta del eje x
            ax.set_ylabel('Density')  # Etiqueta del eje y

            ax.set_title('KDE Plot for ' + column + ' (' + specie + ')')  # Título de la subfigura

    plt.tight_layout()  # Ajusta los espacios entre subfiguras
    plt.show()  # Muestra los gráficos

En 9:40, el profe menciona que la gráfica está sesgada a la izquierda, cuando el término correcto es que es asimétrico hacia la derecha, pues su lado derecho se extiende mucho más lejos que el izquierdo.

bw_method es el ancho de banda utilizado para el KDE, que controla la suavidad del gráfico. Un valor bajo indica una curva más suave, mientras que un valor alto indica una curva más irregular. En este caso, se utiliza un valor de 0.1.

  • mi aporte de la grafica de dispersión normal para las otras 3 variables
medida=df_penguis.select_dtypes('float64').columns
fig,ax=plt.subplots(1,4,figsize=(15,3))
for i ,value in enumerate(medida) :
    stats=df_penguis[value].describe()
    xs=np.linspace(stats['min'],stats['max'])
    ys=scipy.stats.norm(stats['mean'],stats['std']).pdf(xs)
    ax[i].plot(xs,ys,color='purple',linestyle='dashed')
    #value real
    sns.kdeplot(
        ax=ax[i],
        data=df_penguis,
        x=value,
        color='black'
    )
fig.tight_layout()

El bill_length_mm tampoco sigue una distribución normal:

stats = process_penguins_df.bill_length_mm.describe()

xs = np.linspace(stats['min'], stats['max'])
ys = scipy.stats.norm(stats['mean'], stats['std']).pdf(xs)

plt.plot(xs, ys, color='black', linestyle='dashed')
sns.kdeplot(
    data=process_penguins_df,
    x='bill_length_mm'
)

Aunque si agrupamos por especie de entonces sucede esto:
(para probar con diferentes especies solamente cambiar la variable ++specie ++, colocar la especie de interes: Adelie, Gentoo o Chinstrap.

Quizá el Gentoo es el que sigue una distribución mas normal.

specie='Adelie'
df_by_specie = process_penguins_df[process_penguins_df['species']==specie]
stats = df_by_specie.bill_length_mm.describe()

xs = np.linspace(stats['min'], stats['max'])
ys = scipy.stats.norm(stats['mean'], stats['std']).pdf(xs)

plt.plot(xs, ys, color='black', linestyle='dashed')
sns.kdeplot(
    data=df_by_specie,
    x='bill_length_mm'
)
plt.title(f"{specie}'s bill_length_mm")



# Filtros
adelie_df = dfnn.query("species == 'Adelie'")
gentoo_df = dfnn.query("species == 'Gentoo'")
chinstrap_df = dfnn.query("species == 'Chinstrap'")

species = [adelie_df, gentoo_df, chinstrap_df]
numeric_columns = dfnn.select_dtypes(include=np.number).columns

fig, ax = plt.subplots(3, 4, figsize=(30, 20))

for i, species_df in enumerate(species):
    for j, numeric_column in enumerate(numeric_columns):
        # Calcula estadísticas descriptivas
        stats = species_df[numeric_column].describe()

        # Genera datos para la distribución normal
        xs = np.linspace(stats['min'], stats['max'], 1000)
        ys = scipy.stats.norm(stats['mean'], stats['std']).cdf(xs)

        # Grafica la distribución normal
        ax[i][j].plot(xs, ys, color='black', linestyle='--', label='Distribución Normal')

        # Grafica la distribución empírica
        empiricaldist.Cdf.from_seq(
            dfnn[numeric_column],
            normalize=True
        ).plot(ax=ax[i][j], label='Distribución Empírica')

        ax[i][j].set_title(f'{numeric_column} - {species_df["species"].iloc[0]}')
        ax[i][j].legend()

plt.tight_layout()
plt.show()

graficando la dist. acumulada (CDF) TEORICA

xs = np.linspace(stats[‘min’], stats[‘max’])
ys = scipy.stats.norm(stats[‘mean’], stats[‘std’]).cdf(xs)
plt.plot(xs,ys,color=‘black’,linestyle=‘dashed’)

graficamos nuestros datos body_mass_g

empiricaldist.Cdf.from_seq(
processed_penguins_df.body_mass_g,
normalize=True).plot()

xs = np.linspace(stats['min'], stats['max'])
ys = scipy.stats.norm(stats['mean'], stats['std']).cdf(xs)

fig1 = px.ecdf(processed_penguins_df, x="body_mass_g")

fig2 = px.line(x=xs, y=ys)

fig2.update_traces(line_color='red', line={"dash": "dash"})

fig3 = go.Figure(data=fig1.data + fig2.data)

fig3.show()
xs = np.linspace(stats['min'], stats['max'])
ys = scipy.stats.norm(stats['mean'], stats['std']).pdf(xs)

hist_data = [processed_penguins_df.body_mass_g]

group_labels = ['All body mass']

fig1 = ff.create_distplot(hist_data, group_labels, show_hist=False, histnorm='probability density', bin_size=1, show_rug=False)

fig2 = px.line(x=xs, y=ys)

fig2.update_traces(line_color='red', line={"dash": "dash"})

fig3 = go.Figure(data=fig1.data + fig2.data)

fig3.show()
![](https://static.platzi.com/media/user_upload/image-6e0095d5-2c22-45fe-a8d5-04ac99d790fc.jpg) \------------------------- ```js # # Variables o atributos mi_index = ( proces_penguins_df .columns .slice_indexer( 'bill_length_mm', 'body_mass_g' ) ) species = proces_penguins_df['species'].value_counts().reset_index()['index'] variables = proces_penguins_df.columns[mi_index] # Definiendo el grid y el grafico rows = len(species) cols = len(variables) fig, ax = plt.subplots(ncols=cols, nrows=rows, figsize=(20, 10),layout='constrained') fig.suptitle('Distr. Aleatoria Ideal Vs Real') # Filas for i, specie in enumerate(species): proces_for_specie = proces_penguins_df.loc[proces_penguins_df['species'] == specie] # Columnas for j, variable in enumerate(variables): # Obtengo los estadisticos stats = proces_penguins_df.describe()[variable] # Comparando nuestros datos con una distribucion normal xs = np.linspace(stats['min'], stats['max']) ys = scipy.stats.norm(stats['mean'], stats['std']).pdf(xs) # Asi lucen nuestros datos si siguen una distribucion normal ax[i][j].plot(xs, ys, color=f'#{i*2}{j}{3}', linestyle='dashed') sns.kdeplot( ax=ax[i][j], data=proces_for_specie, x=variable, color=penguin_color[specie] ).plot() # Parametros en 'comun' ax[i][j].grid(True) ax[i][j].set_xlabel('') # La specie como y_label pero solo en la columna 0 if j != 0: ax[i][j].set_ylabel('') else: ax[i][j].set_ylabel(specie) # Solo titulos en la fila de arriba if (i == 0): ax[i][j].set_title(variable) # Solo tick label en la fila de abajo if (i != rows - 1): ax[i][j].set_xticklabels([]) # ```

Para pruebas de bondad de ajuste con python se puede usar Phitter Library

import phitter

data: list[int | float] = [...]

phitter_cont = phitter.PHITTER(
    data=data,
    fit_type="continuous",
    num_bins=15,
    confidence_level=0.95,
    minimum_sse=1e-2,
    distributions_to_fit=["beta", "normal", "fatigue_life", "triangular"],
)
phitter_cont.fit(n_workers=6)
Estas son unas gráficas de las variables, discriminadas por especie de pingüinos. ```js #Canva de grafico fig,ax = plt.subplots(2,2, figsize=(15,10)) #Titulos de los graficos ax[0,0].set_title('Masa corporal') ax[0,1].set_title('Longitud de pico') ax[0,0].set_title('Profundidad de pico') ax[0,0].set_title('Longitud de aleta') #Funcion de graficos def chart(column,axes): stats = penguisn_df[column].describe() xs = np.linspace(stats["min"], stats["max"]) ys = scipy.stats.norm(stats["mean"], stats["std"]).pdf(xs) ax[axes].plot(xs,ys,"r--") sns.kdeplot(data=penguisn_df, x=column,ax=ax[axes], hue="species"); #Columnas a graficar chart("body_mass_g",(0,0)) chart("bill_length_mm",(0,1)) chart("bill_depth_mm",(1,0)) chart("flipper_length_mm",(1,1)) ``` ![](https://static.platzi.com/media/user_upload/descarga-b3781364-0419-4a6a-9ee4-9444219a0b4f.jpg)
Después de un gran esfuerzo aquí esta mi aporte: ```python fig, ax = plt.subplots(3, 4, figsize= (16,8.5)) fig.subplots_adjust(hspace=0.4, wspace=0.4) fig.suptitle('Función de Probabilidad de Densidad', fontsize=20) Species = pre_penguins.species.unique() Columns= pre_penguins.select_dtypes(include=float).keys() for x, x_val in enumerate(Species): for y, y_val in enumerate(Columns): variable = pre_penguins.loc[pre_penguins.species == x_val,y_val] xs = np.linspace(variable.min(), variable.max()) ys = scipy.stats.norm(variable.mean(),variable.std()).pdf(xs) ax[x,y].plot(xs, ys, 'g--', label=f'{x_val}') ax[x,y].legend(frameon=False, loc='upper right', fontsize = 'x-small') sns.kdeplot(ax=ax[x][y], data=variable, x=variable, color='red') ``` ![](https://static.platzi.com/media/user_upload/descarga-31e44a0c-ee99-4c94-b0b4-474954060912.jpg)

A mi cerebro se le hace imposible entender esto de manera teórica, tendría que verlo en un ejemplo real, para qué o porqué sirve, ojalá mas adelante se me resuelva esa duda

Deberia explicar mejor que significa cada para metro que usan

Con avisos o sin avisos, DeepNote funciona deplorablemente en Bogotá, Colombia

¿No más Deepnote, por favor @Platzi

La profesora explica muy bien