Análisis estadístico de hipótesis en Python con ANOVA, chi-cuadrado y correlación de Pearson

Abordaremos el análisis de hipótesis estadísticas con Python con ANOVA, chi-cuadrado y correlación de Pearson en el conjunto de datos de Gapminder.

Introducción

Python es un lenguaje increíblemente versátil, útil para una amplia variedad de tareas en una amplia gama de disciplinas. Una de esas disciplinas es el análisis estadístico de conjuntos de datos y, junto con SPSS, Python es una de las herramientas más comunes para las estadísticas.

La naturaleza intuitiva y fácil de usar de Python facilita la ejecución de pruebas estadísticas y la implementación de técnicas analíticas, especialmente mediante el uso de la biblioteca de estadísticos.

Presentación de la biblioteca statsmodels en Python

La biblioteca statsmodels es un módulo para Python que brinda fácil acceso a una variedad de herramientas estadísticas para realizar pruebas estadísticas y explorar datos. Hay una serie de pruebas y funciones estadísticas a las que la biblioteca da acceso, incluidas las regresiones de mínimos cuadrados ordinarios (OLS), modelos lineales generalizados, modelos logit, [Análisis de componentes principales (PCA)](/implementando-pca-en-python -con-scikit-learn/) y Modelos de media móvil integrada autorregresiva (ARIMA).

Los resultados de los modelos se prueban constantemente con otros paquetes estadísticos para garantizar que los modelos sean precisos. Cuando se combina con SciPy y pandas, es simple visualizar datos, ejecutar pruebas estadísticas y verificar relaciones de significado.

Elegir un conjunto de datos

Antes de que podamos practicar estadísticas con Python, debemos seleccionar un conjunto de datos. Haremos uso de un conjunto de datos compilado por la Fundación Gapminder.

El conjunto de datos de Gapminder rastrea muchas variables utilizadas para evaluar la salud y el bienestar general de las poblaciones en países de todo el mundo. mundo. Usaremos el conjunto de datos porque está muy bien documentado, estandarizado y completo. No tendremos que hacer mucho en la forma de preprocesamiento para poder utilizarlo.

Hay algunas cosas que querremos hacer solo para preparar el conjunto de datos para ejecutar regresiones, ANOVA y otras pruebas, pero en general, el conjunto de datos está listo para trabajar.

El punto de partida de nuestro análisis estadístico del conjunto de datos de Gapminder es el análisis exploratorio de datos. Usaremos algunas funciones de gráficos y trazados de Matplotlib y Seaborn para visualizar algunas relaciones interesantes y tener una idea de qué relaciones variables podemos querer explorar.

Análisis y preprocesamiento de datos exploratorios {#análisis y preprocesamiento de datos exploratorios}

Comenzaremos visualizando algunas relaciones posibles. Usando Seaborn y Pandas, podemos hacer algunas regresiones que analizan la fuerza de las correlaciones entre las variables en nuestro conjunto de datos para tener una idea de qué relaciones de variables vale la pena estudiar.

Importaremos esas dos y cualquier otra biblioteca que usaremos aquí:

1
2
3
4
5
6
7
8
9
import statsmodels.formula.api as smf
import statsmodels.stats.multicomp as multi
import scipy
from scipy.stats import pearsonr
import pandas as pd
from seaborn import regplot
import matplotlib.pyplot as plt
import numpy as np
import seaborn as sns

No hay mucho preprocesamiento que tengamos que hacer, pero necesitamos hacer algunas cosas. Primero, verificaremos si falta algún dato faltante o nulo y convertiremos las entradas no numéricas en numéricas. También haremos una copia del marco de datos transformado con el que trabajaremos:

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
# Check for missing data
def check_missing_values(df, cols):

    for col in cols:
       print("Column {} is missing:".format(col))
       print((df[col].values == ' ').sum())
       print()

# Convert to numeric
def convert_numeric(dataframe, cols):

    for col in cols:
        dataframe[col] = pd.to_numeric(dataframe[col], errors='coerce')

df = pd.read_csv("gapminder.csv")

print("Null values:")
print(df.isnull().values.any())

cols = ['lifeexpectancy', 'breastcancerper100th', 'suicideper100th']
norm_cols = ['internetuserate', 'employrate']

df2 = df.copy()

check_missing_values(df, cols)
check_missing_values(df, norm_cols)

convert_numeric(df2, cols)
convert_numeric(df2, norm_cols)

Aquí están las salidas:

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
Null values:
Column lifeexpectancy is missing:
22

Column breastcancerper100th is missing:
40

Column suicideper100th is missing:
22

Column internetuserate is missing:
21

Column employrate is missing:
35

Hay un puñado de valores faltantes, pero nuestra conversión numérica debería convertirlos en valores NaN, lo que permite llevar a cabo un análisis exploratorio de datos en el conjunto de datos.

En concreto, podríamos intentar analizar la relación entre la tasa de uso de Internet y la esperanza de vida, o entre la tasa de uso de Internet y la tasa de empleo. Intentemos hacer gráficos individuales de algunas de estas relaciones usando Seaborn y Matplotlib:

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
sns.lmplot(x="internetuserate", y="breastcancerper100th", data=df2, fit_reg=False)
plt.title("Internet Use Rate and Breast Cancer Per 100k")
plt.show()

sns.lmplot(x="internetuserate", y="lifeexpectancy", data=df2, fit_reg=False)
plt.title("Internet Use Rate and Life Expectancy")
plt.show()

sns.lmplot(x="internetuserate", y="employrate", data=df2, fit_reg=False)
plt.title("Internet Use Rate and Employment Rate")
plt.show()

Estos son los resultados de las gráficas:

scatter plot of internet use and breast cancer

scatter plot of internet use and life expectancy

scatter plot of internet use and employment rate

Parece que hay algunas relaciones interesantes que podríamos investigar más a fondo. Curiosamente, parece haber una relación positiva bastante fuerte entre la tasa de uso de Internet y el cáncer de mama, aunque es probable que esto sea solo un artefacto de mejores pruebas en países que tienen más acceso a la tecnología.

También parece haber una relación bastante fuerte, aunque menos lineal, entre la esperanza de vida y la tasa de uso de Internet.

Finalmente, parece que existe una relación parabólica no lineal entre la tasa de uso de Internet y la tasa de empleo.

Selección de una hipótesis adecuada {#selección de una hipótesis adecuada}

Queremos elegir una relación que merezca una mayor exploración. Hay muchas relaciones potenciales aquí sobre las que podríamos formular una hipótesis y explorar la relación con pruebas estadísticas. Cuando formulamos una hipótesis y realizamos una prueba de correlación entre las dos variables, si la prueba de correlación es significativa, debemos realizar pruebas estadísticas para ver qué tan fuerte es la correlación y si podemos decir de manera confiable que la correlación entre las dos variables es más que casualidad.

El tipo de prueba estadística que utilicemos dependerá de la naturaleza de nuestras variables explicativas y de respuesta, también conocidas como variables independientes y dependientes ). Veremos cómo ejecutar tres tipos diferentes de pruebas estadísticas:

  • ANOVA
  • Pruebas de chi-cuadrado
  • Regresiones.

Iremos con lo que visualizamos arriba y elegiremos explorar la relación entre las tasas de uso de Internet y la esperanza de vida.

La hipótesis nula es que no existe una relación significativa entre la tasa de uso de Internet y la esperanza de vida, mientras que nuestra hipótesis es que existe una relación entre las dos variables.

Vamos a realizar varios tipos de pruebas de hipótesis en el conjunto de datos. El tipo de prueba de hipótesis que usamos depende de la naturaleza de nuestras variables explicativas y de respuesta. Diferentes combinaciones de variables explicativas y de respuesta requieren diferentes pruebas estadísticas. Por ejemplo, si una variable es categórica y una variable es de naturaleza cuantitativa, se requiere un Análisis de varianza.

Análisis de varianza (ANOVA)

Un Análisis de varianza (ANOVA) es una prueba estadística que se emplea para comparar dos o más medias entre sí, las cuales se determinan a través del análisis de varianza. Las pruebas ANOVA de una vía se utilizan para analizar las diferencias entre grupos y determinar si las diferencias son estadísticamente significativas.

Los ANOVA de una vía comparan dos o más medias de grupos independientes, aunque en la práctica se usan con mayor frecuencia cuando hay al menos tres grupos independientes.

Para realizar un ANOVA en el conjunto de datos de Gapminder, necesitaremos transformar algunas de las características, ya que estos valores en el conjunto de datos son continuos, pero los análisis de ANOVA son apropiados para situaciones en las que una variable es categórica y otra cuantitativa.

Podemos transformar los datos de continuos a cuantitativos seleccionando una categoría y agrupando la variable en cuestión, dividiéndola en percentiles. La variable independiente se convertirá en una variable categórica, mientras que la variable dependiente permanecerá continua. Podemos usar la función qcut() en Pandas para dividir el marco de datos en contenedores:

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
def bin(dataframe, cols):
    # Create new columns that store the binned data
    for col in cols:
        new_col_name = "{}_bins".format(col)
        dataframe[new_col_name] = pd.qcut(dataframe[col], 10, labels=["1=10%", "2=20%", "3=30%", "4=40%", "5=50%", "6=60%", "7=70%", "8=80", "9=90%", "10=100%"])

df3 = df2.copy()

# This creates new columns filled with the binned column data
bin(df3, cols)
bin(df3, norm_cols)

Después de que las variables se hayan transformado y estén listas para ser analizadas, podemos usar la biblioteca statsmodel para realizar un ANOVA en las características seleccionadas. Imprimiremos los resultados del ANOVA y comprobaremos si la relación entre las dos variables es estadísticamente significativa:

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
anova_df = df3[['lifeexpectancy', 'internetuserate_bins', 'employrate_bins']].dropna()

relate_df = df3[['lifeexpectancy', 'internetuserate_bins']]

anova = smf.ols(formula='lifeexpectancy ~ C(internetuserate_bins)', data=anova_df).fit()

print(anova.summary())

# We may also want to check the mean and standard deviation for the groups
mean = relate_df.groupby("internetuserate_bins").mean()
sd = relate_df.groupby("internetuserate_bins").std()
print(mean)
print(sd)

Aquí está la salida del modelo:

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
                            OLS Regression Results                            
==============================================================================
Dep. Variable:         lifeexpectancy   R-squared:                       0.689
Model:                            OLS   Adj. R-squared:                  0.671
Method:                 Least Squares   F-statistic:                     38.65
Date:                Mon, 11 May 2020   Prob (F-statistic):           1.71e-35
Time:                        17:49:24   Log-Likelihood:                -521.54
No. Observations:                 167   AIC:                             1063.
Df Residuals:                     157   BIC:                             1094.
Df Model:                           9                                         
Covariance Type:            nonrobust                                         
======================================================================================================
                                         coef    std err          t      P>|t|      [0.025      0.975]
------------------------------------------------------------------------------------------------------
Intercept                             56.6603      1.268     44.700      0.000      54.157      59.164
C(internetuserate_bins)[T.2=20%]       1.6785      1.870      0.898      0.371      -2.015       5.372
C(internetuserate_bins)[T.3=30%]       5.5273      1.901      2.907      0.004       1.772       9.283
C(internetuserate_bins)[T.4=40%]      11.5693      1.842      6.282      0.000       7.932      15.207
C(internetuserate_bins)[T.5=50%]      14.6991      1.870      7.860      0.000      11.005      18.393
C(internetuserate_bins)[T.6=60%]      16.7287      1.870      8.946      0.000      13.035      20.422
C(internetuserate_bins)[T.7=70%]      17.8802      1.975      9.052      0.000      13.978      21.782
C(internetuserate_bins)[T.8=80]       19.8302      1.901     10.430      0.000      16.075      23.586
C(internetuserate_bins)[T.9=90%]      23.0723      1.901     12.135      0.000      19.317      26.828
C(internetuserate_bins)[T.10=100%]    23.3042      1.901     12.257      0.000      19.549      27.060
==============================================================================
Omnibus:                       10.625   Durbin-Watson:                   1.920
Prob(Omnibus):                  0.005   Jarque-Bera (JB):               11.911
Skew:                          -0.484   Prob(JB):                      0.00259
Kurtosis:                       3.879   Cond. No.                         10.0
==============================================================================

Warnings:
[1] Standard Errors assume that the covariance matrix of the errors is correctly specified.

Podemos ver que el modelo da un valor P muy pequeño (Prob F-statistic) de 1.71e-35. Esto es mucho menor que el umbral de significación habitual de 0,05, por lo que concluimos que existe una relación significativa entre la esperanza de vida y la tasa de uso de Internet.

Dado que el valor P de la correlación parece ser significativo, y dado que tenemos 10 categorías diferentes, querremos ejecutar una prueba post-hoc para verificar que la diferencia entre las medias sigue siendo significativa incluso después de verificar el tipo. 1 errores. Podemos realizar pruebas post-hoc con la ayuda del módulo multicomp, utilizando una prueba de Tukey Honestly Significant Difference (Tukey HSD):

1
2
3
multi_comparison = multi.MultiComparison(anova_df["lifeexpectancy"], anova_df["internetuserate_bins"])
results = multi_comparison.tukeyhsd()
print(results)

Aquí están los resultados de la prueba:

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
  Multiple Comparison of Means - Tukey HSD, FWER=0.05  
=======================================================
 group1 group2 meandiff p-adj   lower    upper   reject
-------------------------------------------------------
10=100%  1=10% -23.3042  0.001 -29.4069 -17.2015   True
10=100%  2=20% -21.6257  0.001 -27.9633 -15.2882   True
10=100%  3=30% -17.7769  0.001 -24.2097  -11.344   True
10=100%  4=40% -11.7349  0.001 -17.9865  -5.4833   True
10=100%  5=50%  -8.6051  0.001 -14.9426  -2.2676   True
10=100%  6=60%  -6.5755 0.0352  -12.913   -0.238   True
10=100%  7=70%  -5.4241 0.2199 -12.0827   1.2346  False
10=100%   8=80  -3.4741 0.7474  -9.9069   2.9588  False
10=100%  9=90%  -0.2319    0.9  -6.6647    6.201  False
  1=10%  2=20%   1.6785    0.9  -4.3237   7.6807  False
  1=10%  3=30%   5.5273 0.1127  -0.5754  11.6301  False
  1=10%  4=40%  11.5693  0.001   5.6579  17.4807   True
  1=10%  5=50%  14.6991  0.001   8.6969  20.7013   True
  1=10%  6=60%  16.7287  0.001  10.7265  22.7309   True
  1=10%  7=70%  17.8801  0.001  11.5399  24.2204   True
  1=10%   8=80  19.8301  0.001  13.7274  25.9329   True
  1=10%  9=90%  23.0723  0.001  16.9696  29.1751   True
  2=20%  3=30%   3.8489 0.6171  -2.4887  10.1864  False
  2=20%  4=40%   9.8908  0.001   3.7374  16.0443   True
  2=20%  5=50%  13.0206  0.001   6.7799  19.2614   True
  2=20%  6=60%  15.0502  0.001   8.8095   21.291   True
  2=20%  7=70%  16.2017  0.001   9.6351  22.7683   True
  2=20%   8=80  18.1517  0.001  11.8141  24.4892   True
  2=20%  9=90%  21.3939  0.001  15.0563  27.7314   True
  3=30%  4=40%    6.042 0.0678  -0.2096  12.2936  False
  3=30%  5=50%   9.1718  0.001   2.8342  15.5093   True
  3=30%  6=60%  11.2014  0.001   4.8638  17.5389   True
  3=30%  7=70%  12.3528  0.001   5.6942  19.0114   True
  3=30%   8=80  14.3028  0.001     7.87  20.7357   True
  3=30%  9=90%   17.545  0.001  11.1122  23.9778   True
  4=40%  5=50%   3.1298 0.8083  -3.0237   9.2833  False
  4=40%  6=60%   5.1594 0.1862  -0.9941  11.3129  False
  4=40%  7=70%   6.3108 0.0638  -0.1729  12.7945  False
  4=40%   8=80   8.2608 0.0015   2.0092  14.5124   True
  4=40%  9=90%   11.503  0.001   5.2514  17.7546   True
  5=50%  6=60%   2.0296    0.9  -4.2112   8.2704  False
  5=50%  7=70%    3.181 0.8552  -3.3856   9.7476  False
  5=50%   8=80    5.131 0.2273  -1.2065  11.4686  False
  5=50%  9=90%   8.3732 0.0015   2.0357  14.7108   True
  6=60%  7=70%   1.1514    0.9  -5.4152    7.718  False
  6=60%   8=80   3.1014 0.8456  -3.2361    9.439  False
  6=60%  9=90%   6.3436 0.0496   0.0061  12.6812   True
  7=70%   8=80     1.95    0.9  -4.7086   8.6086  False
  7=70%  9=90%   5.1922 0.2754  -1.4664  11.8508  False
   8=80  9=90%   3.2422 0.8173  -3.1907    9.675  False
-------------------------------------------------------

Ahora tenemos una mejor idea de qué grupos en nuestra comparación tienen diferencias estadísticamente significativas.

Si la columna rechazar tiene la etiqueta Falso, sabemos que se recomienda rechazar la hipótesis nula y suponer que existe una diferencia significativa entre los dos grupos que se comparan.

La prueba de independencia de chi-cuadrado

ANOVA es apropiado para instancias donde una variable es continua y la otra es categórica. Ahora veremos cómo llevar a cabo una Prueba de independencia Chi-Cuadrado.

La prueba de independencia Chi-Cuadrado se utiliza cuando las variables explicativas y de respuesta son categóricas. Es probable que también desee utilizar la prueba de chi-cuadrado cuando la variable explicativa es cuantitativa y la variable de respuesta es categórica, lo que puede hacer dividiendo la variable explicativa en categorías.

La prueba de independencia Chi-Cuadrado es una prueba estadística utilizada para analizar qué tan significativa es una relación entre dos variables categóricas. Cuando se ejecuta una prueba de chi-cuadrado, cada categoría en una variable tiene su frecuencia comparada con las categorías de la segunda variable. Esto significa que los datos se pueden mostrar como una tabla de frecuencia, donde las filas representan las variables independientes y las columnas representan las variables dependientes.

Al igual que convertimos nuestra variable independiente en una variable categórica (al agruparla), para la prueba ANOVA, necesitamos hacer que ambas variables sean categóricas para llevar a cabo la prueba Chi-Cuadrado. Nuestra hipótesis para este problema es la misma que la hipótesis del problema anterior, que existe una relación significativa entre la esperanza de vida y la tasa de uso de Internet.

Mantendremos las cosas simples por ahora y dividiremos nuestra variable de tasa de uso de Internet en dos categorías, aunque fácilmente podríamos hacer más. Escribiremos una función para manejar eso.

Realizaremos una comparación post-hoc para protegernos contra los errores de tipo 1 (falsos positivos) utilizando un enfoque llamado Ajuste de Bonferroni. Para hacer esto, puede realizar comparaciones para los diferentes pares posibles de su variable de respuesta, y luego verifique su significado ajustado.

No realizaremos comparaciones para todos los diferentes pares posibles aquí, solo mostraremos cómo se puede hacer. Haremos algunas comparaciones diferentes utilizando un esquema de grabación y mapearemos los registros en nuevas columnas de características.

Luego, podemos verificar los conteos observados y crear tablas de esas comparaciones:

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
def half_bin(dataframe, cols):

    for col in cols:
        new_col_name = "{}_bins_2".format(col)
        dataframe[new_col_name] = pd.qcut(dataframe[col], 2, labels=["1=50%", "2=100%"])

half_bin(df3, ['internetuserate'])

# Recoding scheme
recode_2 = {"3=30%": "3=30%", "7=70%": "7=70%"}
recode_3 = {"2=20%": "2=20%", "8=80": "8=80"}
recode_4 = {"6=60%": "6=60%", "9=90%": "9=90%"}
recode_5 = {"4=40%": "4=40%", "7=70%": "7=70%"}

# Create the new features
df3['Comp_3v7'] = df3['lifeexpectancy_bins'].map(recode_2)
df3['Comp_2v8'] = df3['lifeexpectancy_bins'].map(recode_3)
df3['Comp_6v9'] = df3['lifeexpectancy_bins'].map(recode_4)
df3['Comp_4v7'] = df3['lifeexpectancy_bins'].map(recode_5)

Ejecutar una prueba de Chi-Cuadrado y una comparación post-hoc implica primero construir una tabla de comparación de tabulaciones cruzadas. La tabla de comparación de tabulaciones cruzadas muestra el porcentaje de ocurrencia de la variable de respuesta para los diferentes niveles de la variable explicativa.

Solo para tener una idea de cómo funciona esto, imprimamos los resultados de todas las comparaciones de intervalos de esperanza de vida:

1
2
3
# Get table of observed counts
count_table = pd.crosstab(df3['internetuserate_bins_2'], df3['lifeexpectancy_bins'])
print(count_table)
1
2
3
4
lifeexpectancy_bins     1=10%  2=20%  3=30%  4=40%  ...  7=70%  8=80  9=90%  10=100%
internetuserate_bins_2                              ...                             
1=50%                      18     19     16     14  ...      4     4      1        0
2=100%                      0      0      1      4  ...     15    11     16       19

Podemos ver que una comparación de tabulaciones cruzadas verifica la frecuencia de las categorías de una variable en la segunda variable. Arriba vemos la distribución de la esperanza de vida en situaciones en las que caen en uno de los dos contenedores que creamos.

Ahora necesitamos calcular las tabulaciones cruzadas para los diferentes pares que creamos anteriormente, ya que esto es lo que ejecutamos a través de la prueba Chi-Square:

1
2
3
4
count_table_3 = pd.crosstab(df3['internetuserate_bins_2'], df3['Comp_3v7'])
count_table_4 = pd.crosstab(df3['internetuserate_bins_2'], df3['Comp_2v8'])
count_table_5 = pd.crosstab(df3['internetuserate_bins_2'], df3['Comp_6v9'])
count_table_6 = pd.crosstab(df3['internetuserate_bins_2'], df3['Comp_4v7'])

Una vez que hemos transformado las variables para que se pueda realizar la prueba de Chi-Cuadrado, podemos utilizar la función chi2_contingency en statsmodel para realizar la prueba.

Queremos imprimir los porcentajes de la columna, así como los resultados de la prueba Chi-Square, y crearemos una función para hacerlo. Luego usaremos nuestra función para hacer la prueba Chi-Square para las cuatro tablas de comparación que creamos:

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
def chi_sq_test(table):

    print("Results for:")
    print(str(table))

    # Get column percentages
    col_sum = table.sum(axis=0)
    col_percents = table/col_sum
    print(col_percents)

    chi_square = scipy.stats.chi2_contingency(table)
    print("Chi-square value, p-value, expected_counts")
    print(chi_square)

    print()

print("Initial Chi-square:")
chi_sq_test(count_table)
print(" ")

chi_sq_test(count_table_3)
chi_sq_test(count_table_4)
chi_sq_test(count_table_5)
chi_sq_test(count_table_6)

Aquí están los resultados:

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
Initial Chi-square:
Results for:
lifeexpectancy_bins     1=10%  2=20%  3=30%  4=40%  ...  7=70%  8=80  9=90%  10=100%
internetuserate_bins_2                              ...                             
1=50%                      18     19     16     14  ...      4     4      1        0
2=100%                      0      0      1      4  ...     15    11     16       19

[2 rows x 10 columns]
lifeexpectancy_bins     1=10%  2=20%     3=30%  ...      8=80     9=90%  10=100%
internetuserate_bins_2                          ...                             
1=50%                     1.0    1.0  0.941176  ...  0.266667  0.058824      0.0
2=100%                    0.0    0.0  0.058824  ...  0.733333  0.941176      1.0

[2 rows x 10 columns]
Chi-square value, p-value, expected_counts
(102.04563740451277, 6.064860600653971e-18, 9, array([[9.45251397, 9.97765363, 8.9273743 , 9.45251397, 9.45251397,
        9.97765363, 9.97765363, 7.87709497, 8.9273743 , 9.97765363],
       [8.54748603, 9.02234637, 8.0726257 , 8.54748603, 8.54748603,
        9.02234637, 9.02234637, 7.12290503, 8.0726257 , 9.02234637]]))
-----
 
Results for:
Comp_3v7                3=30%  7=70%
internetuserate_bins_2              
1=50%                      16      4
2=100%                      1     15
Comp_3v7                   3=30%     7=70%
internetuserate_bins_2                    
1=50%                   0.941176  0.210526
2=100%                  0.058824  0.789474
Chi-square value, p-value, expected_counts
(16.55247678018576, 4.7322137795376575e-05, 1, array([[ 9.44444444, 10.55555556],
       [ 7.55555556,  8.44444444]]))
-----
Results for:
Comp_2v8                2=20%  8=80
internetuserate_bins_2             
1=50%                      19     4
2=100%                      0    11
Comp_2v8                2=20%      8=80
internetuserate_bins_2                 
1=50%                     1.0  0.266667
2=100%                    0.0  0.733333
Chi-square value, p-value, expected_counts
(17.382650301643437, 3.0560286589975315e-05, 1, array([[12.85294118, 10.14705882],
       [ 6.14705882,  4.85294118]]))
-----
Results for:
Comp_6v9                6=60%  9=90%
internetuserate_bins_2              
1=50%                       6      1
2=100%                     13     16
Comp_6v9                   6=60%     9=90%
internetuserate_bins_2                    
1=50%                   0.315789  0.058824
2=100%                  0.684211  0.941176
Chi-square value, p-value, expected_counts
(2.319693757720874, 0.12774517376836148, 1, array([[ 3.69444444,  3.30555556],
       [15.30555556, 13.69444444]]))
-----
Results for:
Comp_4v7                4=40%  7=70%
internetuserate_bins_2              
1=50%                      14      4
2=100%                      4     15
Comp_4v7                   4=40%     7=70%
internetuserate_bins_2                    
1=50%                   0.777778  0.210526
2=100%                  0.222222  0.789474
Chi-square value, p-value, expected_counts
(9.743247922437677, 0.0017998260000241526, 1, array([[8.75675676, 9.24324324],
       [9.24324324, 9.75675676]]))
-----

Si solo observamos los resultados de la tabla de conteo completa, parece que hay un valor P de 6.064860600653971e-18.

Sin embargo, para determinar cómo los diferentes grupos divergen entre sí, debemos realizar la prueba Chi-Square para los diferentes pares en nuestro marco de datos. Verificaremos si hay una diferencia estadísticamente significativa para cada uno de los diferentes pares que seleccionamos. Tenga en cuenta que el valor P que indica un resultado significativo cambia según la cantidad de comparaciones que realice y, aunque no lo cubriremos en este tutorial, deberá tenerlo en cuenta.

La comparación de 6 frente a 9 nos da un valor P de ‘0,127’, que está por encima del umbral de ‘0,05’, lo que indica que la diferencia para esa categoría puede no ser significativa. Ver las diferencias de las comparaciones nos ayuda a comprender por qué necesitamos comparar diferentes niveles entre sí.

Correlación de Pearson

Hemos cubierto la prueba que debe usar cuando tiene una variable explicativa categórica y una variable de respuesta cuantitativa (ANOVA), así como la prueba que usa cuando tiene dos variables categóricas (Chi-Squared).

Ahora veremos el tipo de prueba apropiado para usar cuando tiene una variable explicativa cuantitativa y una variable de respuesta cuantitativa: la correlación de Pearson.

La configuración de Pearson se utiliza para analizar la fuerza de una relación entre dos siempre variables, ambas de naturaleza cuantitativa. El valor, o fuerza de la correlación de Pearson, estará entre +1 y -1.

Una correlación de 1 indica una asociación perfecta entre las variables, y la correlación es positiva o negativa. Los coeficientes de correlación cercanos a 0 indican correlaciones muy débiles, casi inexistentes. Si bien existen otras formas de medir las correlaciones entre dos variables, como Correlación de Spearman o Correlación de rango de Kendall, la correlación de Pearson es probablemente la prueba de correlación más utilizada.

Como el conjunto de datos de Gapminder tiene sus características representadas con variables cuantitativas, no necesitamos hacer ninguna transformación categórica de los datos antes de ejecutar una Correlación de Pearson en él. Tenga en cuenta que se supone que ambas variables se distribuyen normalmente y que no hay muchos valores atípicos significativos en el conjunto de datos. Necesitaremos acceso a SciPy para realizar la correlación de Pearson.

Graficaremos la relación entre la esperanza de vida y las tasas de uso de Internet, así como la tasa de uso de Internet y la tasa de empleo, solo para ver cómo se vería otro gráfico de correlación. Después de crear una función gráfica, usaremos la función personr() de SciPy para realizar la correlación y verificar los resultados:

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
df_clean = df2.dropna()
df_clean['incomeperperson'] = df_clean['incomeperperson'].replace('', np.nan)

def plt_regression(x, y, data, label_1, label_2):

    reg_plot = regplot(x=x, y=y, fit_reg=True, data=data)
    plt.xlabel(label_1)
    plt.ylabel(label_2)
    plt.show()

plt_regression('lifeexpectancy', 'internetuserate', df_clean, 'Life Expectancy', 'Internet Use Rate')
plt_regression('employrate', 'internetuserate', df_clean, 'Employment Rate', 'Internet Use Rate')

print('Assoc. - life expectancy and internet use rate')
print(pearsonr(df_clean['lifeexpectancy'], df_clean['internetuserate']))

print('Assoc. - between employment rate and internet use rate')
print(pearsonr(df_clean['employrate'], df_clean['internetuserate']))

Aquí están las salidas:

correlation between internet use rate and life expectancy

correlation between internet use rate and employment rate

1
2
3
4
Assoc. - life expectancy and internet use rate
(0.77081050888289, 5.983388253650836e-33)
Assoc. - between employment rate and internet use rate
(-0.1950109538173115, 0.013175901971555317)

El primer valor es la dirección y la fuerza de la correlación, mientras que el segundo es el valor P. Los números sugieren una correlación bastante fuerte entre la esperanza de vida y la tasa de uso de Internet que no se debe al azar. Mientras tanto, existe una correlación más débil, aunque significativa, entre la tasa de empleo y la tasa de uso de Internet.

Tenga en cuenta que también es posible ejecutar una Correlación de Pearson en datos categóricos, aunque los resultados se verán algo diferentes. Si quisiéramos, podríamos agrupar los niveles de ingresos y ejecutar la Correlación de Pearson sobre ellos. Puede usarlo para verificar la presencia de variables moderadoras que podrían tener un efecto en su asociación de interés.

Moderadores e interacción estadística

Veamos cómo dar cuenta de la interacción estadística entre múltiples variables, también conocida como moderación.

La moderación es cuando una tercera (o más) variable impacta la fuerza de la asociación entre la variable independiente y la variable dependiente.

Hay diferentes formas de probar la moderación/interacción estadística entre una tercera variable y las variables independientes/dependientes. Por ejemplo, si realizó una prueba ANOVA, podría probar la moderación haciendo una prueba ANOVA de dos vías para probar la posible moderación.

Sin embargo, una forma confiable de probar la moderación, sin importar qué tipo de prueba estadística haya realizado (ANOVA, Chi-Square, Pearson Correlation) es verificar si existe una asociación entre las variables explicativas y de respuesta para cada subgrupo/nivel del tercer grupo. variable.

Para ser más concretos, si estuviera realizando pruebas de ANOVA, podría ejecutar un ANOVA para cada categoría en la tercera variable (la variable que sospecha que podría tener un efecto moderador en la relación que está estudiando).

Si estuviera utilizando una prueba de Chi-Cuadrado, podría simplemente realizar una prueba de Chi-Cuadrado en nuevos marcos de datos que contienen todos los puntos de datos encontrados dentro de las categorías de su variable moderadora.

Si su prueba estadística es una correlación de Pearson, necesitará crear categorías o contenedores para la variable moderadora y luego ejecutar la correlación de Pearson para los tres contenedores.

Echemos un vistazo rápido a cómo llevar a cabo Correlaciones de Pearson para variables moderadoras. Crearemos categorías/niveles artificiales a partir de nuestras características continuas. El proceso de prueba de moderación para los otros dos tipos de prueba (Chi-Square y ANOVA) es muy similar, pero tendrá variables categóricas preexistentes con las que trabajar.

Querremos elegir una variable adecuada para que actúe como nuestra variable moderadora. Probemos el nivel de ingresos por persona y dividámoslo en tres grupos diferentes:

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
def income_groups(row):
    if row['incomeperperson'] <= 744.23:
        return 1
    elif row['incomeperperson'] <= 942.32:
        return 2
    else:
        return 3


# Apply function and set the new features in the dataframe
df_clean['income_group'] = df_clean.apply(lambda row: income_groups(row), axis=1)

# Create a few subframes to try test for moderation
subframe_1 = df_clean[(df_clean['income_group'] == 1)]
subframe_2 = df_clean[(df_clean['income_group'] == 2)]
subframe_3 = df_clean[(df_clean['income_group'] == 3)]

print('Assoc. - life expectancy and internet use rate for low income countries')

print(pearsonr(subframe_1['lifeexpectancy'], subframe_1['internetuserate']))

print('Assoc. - life expectancy and internet use rate for medium income countries')

print(pearsonr(subframe_2['lifeexpectancy'], subframe_2['internetuserate']))

print('Assoc. - life expectancy and internet use rate for high income countries')

print(pearsonr(subframe_3['lifeexpectancy'], subframe_3['internetuserate']))

Aquí están las salidas:

1
2
3
4
5
6
7
8
Assoc. - life expectancy and internet use rate for low income countries
(0.38386370068495235, 0.010101223355274047)

Assoc. - life expectancy and internet use rate for medium income countries
(0.9966009508278395, 0.05250454954743393)

Assoc. - life expectancy and internet use rate for high income countries
(0.7019997488251704, 6.526819886007788e-18)

Una vez más, el primer valor es la dirección y la fuerza de la correlación, mientras que el segundo es el valor P.

Yendo más lejos: proyecto de extremo a extremo portátil

¿Tu naturaleza inquisitiva te hace querer ir más allá? Recomendamos consultar nuestro Proyecto guiado: ["Predicción práctica del precio de la vivienda: aprendizaje automático en Python"](https://wikihtp.com/courses/hands-on-house- precio-predicción-aprendizaje-máquina-en-python/#cta){target="_blank"}.

[](https://wikihtp.com/ cursos/predicción-de-precio-de-la-casa-práctica-aprendizaje-de-máquina-en-python/#cta)

En este proyecto guiado, aprenderá a crear potentes modelos tradicionales de aprendizaje automático, así como modelos de aprendizaje profundo, utilizar Ensemble Learning y capacitar a los meta-aprendices para predecir los precios de la vivienda a partir de una bolsa de modelos Scikit-Learn y Keras.

Con Keras, la API de aprendizaje profundo creada sobre Tensorflow, experimentaremos con arquitecturas, crearemos un conjunto de modelos apilados y entrenaremos una red neuronal meta-aprendizaje (modelo de nivel 1) para averiguar el precio de un casa.

El aprendizaje profundo es sorprendente, pero antes de recurrir a él, se recomienda intentar resolver el problema con técnicas más simples, como los algoritmos de aprendizaje superficial. Nuestro rendimiento de referencia se basará en un algoritmo de Regresión de bosque aleatorio. Además, exploraremos la creación de conjuntos de modelos a través de Scikit-Learn a través de técnicas como embalaje y votación.

Este es un proyecto integral y, como todos los proyectos de aprendizaje automático, comenzaremos con Análisis exploratorio de datos, seguido de Preprocesamiento de datos y, finalmente, Creación de modelos de aprendizaje superficial y Profundo para ajustarse a los datos que hemos explorado y limpiado previamente.

Conclusión

statsmodels es una biblioteca extremadamente útil que permite a los usuarios de Python analizar datos y ejecutar pruebas estadísticas en conjuntos de datos. Puede realizar ANOVA, Pruebas de Chi-Cuadrado, Correlaciones de Pearson y prueba de moderación.

Una vez que se familiarice con la forma de realizar estas pruebas, podrá probar las relaciones significativas entre las variables dependientes e independientes, adaptándose a la naturaleza categórica o continua de las variables.