La media aritmética se calcula como el sumatorio de todos los valores dividido por el número de valores.
$\displaystyle \overline{X}= \frac{1}{N} \sum_{i=1}^{N}x_{i}$
import pandas as pd df = pd.DataFrame({"A":[12, 4, 5, 44, 1], "B":[5, 2, 54, 3, 2], "C":[20, 16, 7, 3, 8], "D":[14, 3, 17, 2, 6]}) # axis = 0 calculará la media de cada columna (A, B, C y D) media_columnas = df.mean(axis = 0) print(media_columnas) # axis = 1 calculará la media de cada fila ({a1, b1, c1, d1}, {a2, b2, c2, d2}...) media_filas = df.mean(axis = 1) print(media_filas)
A 13.2 B 13.2 C 10.8 D 8.4 dtype: float64 0 12.75 1 6.25 2 20.75 3 13.00 4 4.25 dtype: float64
Si queremos hacer la media de la primera fila, podemos usar la función iloc() de pandas
# Media de la primera fila df = pd.DataFrame({"A":[12, 4, 5, 44, 1], "B":[5, 2, 54, 3, 2], "C":[20, 16, 7, 3, 8], "D":[14, 3, 17, 2, 6]}) print(df) media = df.iloc[0].mean(axis = 0) print("Media de la primera fila:", media)
A B C D 0 12 5 20 14 1 4 2 16 3 2 5 54 7 17 3 44 3 3 2 4 1 2 8 6 Media de la primera columna: 12.75
De igual forma, si queremos calcular la media de la primera columna:
media = df['A'].mean(axis = 0) print("Media de la columna A:", media)
Media de la columna A: 13.2
La mediana es el valor que se encuentra en el lugar central de todos los datos de un estudio cuando éstos están ordenados de menor a mayor.
Para hallar la mediana en estadística, se ordenan los números de una muestra según su valor y se determina el que queda en el medio. Si la cantidad de términos es impar, la mediana es el valor central. Si la cantidad de términos es par, suma los dos términos del medio y divide entre 2.
mediana = df.median(axis=0) print(mediana)
A 5.0 B 3.0 C 8.0 D 6.0
mediana = df.median(axis=1) print(mediana)
0 13.0 1 3.5 2 12.0 3 3.0 4 4.0
La moda es el valor más repetido de una muestra.
Si en un grupo hay dos o varios valores con la misma frecuencia y esa frecuencia es la máxima, la distribución es bimodal o multimodal, es decir, tiene varias modas.
Si dos valores adyacentes tienen la frecuencia máxima, la moda es el promedio de los dos.
moda = df.iloc[3].mode() print(moda)
0 3 Name: 3, dtype: int64
moda = df.iloc[0].mode() print(moda)
0 5 1 12 2 14 3 20
La varianza nos indica la dispersión de los datos con respecto a su media. Se calcula como la suma de los residuos al cuadrado divididos entre el total de observaciones.
$\displaystyle \sigma²= \frac{1}{N} \sum_{i=1}^{N}(x_{i} - \overline{x})²$
$\displaystyle S²= \frac{1}{N - 1} \sum_{i=1}^{N}(x_{i} - \overline{x})²$
varianza = df.var(axis = 0) print(varianza)
A 312.7 B 521.7 C 48.7 D 45.3 dtype: float64
También se le conoce como desviación estándar. Se calcula como la raíz cuadrada de la varianza. En este caso las unidades son las mismas que las de la muestra, con lo que se hace más sencillo estimar la dispersión de los datos.
$\displaystyle \sigma = \sqrt{\sigma²} = \sqrt{\frac{1}{N} \sum_{i=1}^{N}(x_{i} - \overline{x})²}$
desviacion = df.std(axis = 0) print(desviacion)
A 17.683325 B 22.840753 C 6.978539 D 6.730527 dtype: float64
Los Cuantiles son medidas de localización. Su función es informar del valor de la variable que ocupará la posición (en tanto por cien) que nos interese respecto de todo el conjunto de variables.
Podemos decir que los Cuantiles son unas medidas de posición que dividen a la distribución en un cierto número de partes de manera que en cada una de ellas hay el mismo de valores de la variable.
Los más importantes son los cuartiles, deciles y percentiles.
dividen a la distribución en cuatro partes iguales (tres divisiones): Q1,Q2,Q3, correspondientes a 25%, 50%,75%.
import pandas as pd df = pd.DataFrame(np.random.randn(100, 4), columns=list('ABCD')) # Cálculo de los cuartiles (q entre 0 y 1) cuartiles = df.quantile([0.25, 0.5, 0.75], axis=0) print(cuartiles)
A B C D 0.25 -0.571941 -0.609179 -0.803048 -0.603423 0.50 -0.147255 -0.111867 -0.177584 0.088470 0.75 0.576290 0.688897 0.502677 0.949290
# Cálculo del tercer cuartil cuartil_3 = df.quantile(0.75, axis=0) print(cuartil_3)
A 0.576290 B 0.688897 C 0.502677 D 0.949290
Dividen la sucesión de datos ordenados en diez partes porcentualmente iguales.
Los percentiles son, tal vez, las medidas más utilizadas para propósitos de ubicación. Los percentiles son ciertos números que dividen la sucesión de datos ordenados en cien partes porcentualmente iguales.
Por ejemplo, el percentil 25 es aquel que deja a la izquierda el 25% de los datos y a la derecha el 75%.
Una variable aleatoria es aquella que toma diversos valores o conjuntos de valores con distintas probabilidades.
Existen 2 características importantes de una variable aleatoria, sus valores y las probabilidades asociadas a esos valores.
Una tabla, gráfico o expresión matemática que dé las probabilidades con que una variable aleatoria toma diferentes valores, se llama distribución de la variable aleatoria.
Son aquellas en las que la variable puede pude tomar un número determinado de valores. Existen diversos tipos, entre los que destacan:
Bernouilli
Es aquel modelo que sigue un experimento que se realiza una sola vez y que puede tener dos soluciones: acierto o fracaso:
Al haber únicamente dos soluciones se trata de sucesos complementarios:
Verificándose que: p + q = 1
Ejemplo: lanzamiento de una moneda.
Binomial
La distribución binomial parte de la distribución de Bernouilli. Se aplica cuando se realizan un número “n” de veces el experimento de Bernouiili, siendo cada ensayo independiente del anterior.
La variable puede tomar valores entre:
Ejemplo: lanzar repetidamente una moneda.
Poisson
La distribución de Poisson parte de la distribución binomial. Cuando en una distribución binomial se realiza el experimento un número “n” muy elevado de veces y la probabilidad de éxito “p” en cada ensayo es reducida, entonces se aplica el modelo de distribución de Poisson.
Se tiene que cumplir que:
Ejemplo: cantidad de erratas por página en un libro.
Son aquellas en las que la variable puede pude tomar un número infinito de valores. Algunos tipos de distribuciones continuas son:
Uniforme
Puede tomar cualquier valor dentro de un intervalo, todos ellos con la misma probabilidad.
Normal
La distribución es simétrica con respecto a un valor central, alrededor del cual toma valores con gran probabilidad, sin existir apenas valores extremos.
Es el modelo de distribución más utilizado en la práctica. La importancia de la distribución normal se debe principalmente a que hay muchas variables asociadas a fenómenos naturales que siguen el modelo de la normal.
Esta distribución de caracteriza porque los valores se distribuyen formando una campana de Gauss, en torno a un valor central que coincide con el valor medio de la distribución. Un 50% de los valores están a la derecha de este valor central y otro 50% a la izquierda.
Algunas propiedades de la distribución normal:
Las puntuaciones directas nos ofrecen muy poca información. Por ejemplos, conociendo una puntuación directa no sabemos si se trata de un valor alto o bajo porque esto depende del promedio del grupo.
Existen otras puntuaciones que resuelven ese problema, como la puntuación típica o tipificada
Una puntuación típica indica el número de desviaciones típicas que se aparta de la media una determinada puntuación.
Para calcular la puntuación típica usamos la fórmula:
$ \displaystyle z_{x} = \frac{X - \overline{X}}{S_{x}} $
Si transformamos las puntuaciones directas en puntuaciones típicas, obtenemos la llamada distribución normal estándar o tipificada, que tiene de media cero y varianza 1 y que simbolizamos con N(0, 1)
En Python podemos utilizar la librería scipy.stats para calcular las puntuaciones típicas:
import numpy as np datos = np.array([479, 477, 492, 493, 454, 495, 474, 475, 478, 493, 473, 483, 487, 488, 494, 475, 465, 516, 524, 490]) mu = np.mean(datos) sigma = np.std(datos, ddof = 1) print("Media:", mu) print("Desviación:", sigma)
Media: 485.25 Desviación: 15.986425162420904
# Calcular z-scores import scipy.stats as st zscores = st.zscore(datos) print(zscores)
[-0.40111311 -0.5294693 0.43320216 0.49738026 -2.00556555 0.62573645 -0.7220036 -0.6578255 -0.46529121 0.49738026 -0.78618169 -0.14440072 0.11231167 0.17648977 0.56155835 -0.6578255 -1.29960647 1.9734765 2.48690128 0.30484596]
Primero calculamos la puntuación típica correspondiente a la nota dada (5.5):
$ \displaystyle z_{x} = \frac{X - \overline{X}}{S_{x}} = \frac{5.5 - 6}{2} = -0.25$
Cálculo en Python:
nota = 5.5 z = np.divide(np.subtract(nota, mu), sigma) print(z)
-0.25
Después tenemos que encontrar a qué probabilidad corresponde ese z-score. Lo podemos hacer manualmente utilizando la tabla de distribución normal: tabla_normal
En esa tabla buscaríamos la probabilidad de que un estadístico sea menor que una determinada puntuación típica (en este caso -0.25). Buscaríamos en la primera columna el valor -0.2 y en la primera fila el valor -0.05: 0.40129.
También podemos usar la función norm.cdf de la librería scipy.stats en Python:
import scipy.stats as st probabilidad = st.norm.cdf(z) print(probabilidad)
0.4012936743170763
¿Qué significa ese valor? Que el 40.13 % de los datos (las notas) están por debajo de la puntuación típica calculada (-0.25). O lo que es lo mismo. el 40.13% de los alumos tienen una nota menor o igual que 5.5.
Haciendo una simple regla de 3:
$ \displaystyle x = \frac{500 * 40.13}{100} = 200.65 \cong$ 201 alumnos
En otros muchos casos, conocemos el número de casos (o su proporción) y necesitamos saber cuál es el valor que nos deja por debajo (o por arriba) esos casos.
Por ejemplo, queremos saber que nota deja por debajo el 75 % de los alumnos (en realidad estamos calculando el percenti 75 de la distribución típica).
En este caso, sería hacer el procedimiento inverso al anterior: Deberíamos buscar en el interior de la tabla el valor más cercano a la proporción (0.75) y ver a qué puntuación típica corresponde (0.67). A partir de esa puntuación típica calculamos la nota ($ P_{75} $) de la siguiente manera:
$ \displaystyle z = \frac{P_{75} - \overline{X}}{S_{x}} \implies 0.67 = \frac{P_{75} - 6}{2} \implies P_{75} = (0.67 * 2) + 6 = 7.34 $
Igual que antes, en Python podemos utilizar la librería scipy.stats. En este caso usamos el método norm.ppf:
proporcion = 0.75 z = st.norm.ppf(proporcion) print(z)
0.6744897501960817
valor = np.add(np.multiply(z, sigma), mu) print(valor)
7.348979500392163
Supongamos que hacemos un test de inteligencia todos los alumnos de la Comunidad Valenciana. Representamos la función de distribución y calculamos la media y desviación típica:
Al haber utilizado toda la población estadística (el total de alumnos de la Comunidad Valenciana), lo que calculamos es la media y desviación típica poblacional.
Seleccionamos al azar 2 muestras y calculamos la media y desviación típica:
# Distribución en la muestra n = 2 datos_muestra = np.random.choice(datos_poblacion, n, replace = False) mu = np.mean(datos_muestra) # Utilizamos ddof = 1 para restar 1 a N en la fórmula de la desviación estándar # al calcularla sobre una muestra sigma = np.std(datos_muestra, ddof = 1) print(datos_muestra) print("Media:", mu) print("s:", sigma)
[95 93] Media: 94.0 s: 1.0
Si seleccionamos 5 muestras:
# Distribución en la muestra n = 5 datos_muestra = np.random.choice(datos_poblacion, n, replace = False) mu = np.mean(datos_muestra) # Utilizamos ddof = 1 para restar 1 a N en la fórmula de la desviación estándar # al calcularla sobre una muestra sigma = np.std(datos_muestra, ddof = 1) print(datos_muestra) print("Media:", mu) print("s:", sigma)
[ 73 89 86 102 110] Media: 92.0 s: 12.884098726725126
Con 25:
# Distribución en la muestra n = 25 datos_muestra = np.random.choice(datos_poblacion, n, replace = False) mu = np.mean(datos_muestra) # Utilizamos ddof = 1 para restar 1 a N en la fórmula de la desviación estándar # al calcularla sobre una muestra sigma = np.std(datos_muestra, ddof = 1) print(datos_muestra) print("Media:", mu) print("s:", sigma)
[112 102 102 105 101 104 74 81 132 109 88 114 126 109 84 99 94 87 126 101 88 113 110 106 99] Media: 102.64 s: 13.925171453163511
Como vemos, a mayor tamaño de la muestra, mayor probabilidad de que la media y la desviación típica coincidan con la de la población ($\mu$ = 100 y $\sigma$ = 15).
Supongamos ahora que seleccionamos 1000 grupos con n sujetos por grupo. Hacemos la media de cada grupo y mostramos la función de distribución de los grupos, calculando la media y desviación típica de todos los grupos.
Vamos a crear una función en Python para simularlo:
def simula(ngrupos, n): grupos = np.zeros(ngrupos) for i in range(ngrupos): muestra = np.random.choice(datos_poblacion, n, replace = False) mu_muestra = np.rint(np.mean(muestra)).astype(int) grupos[i] = mu_muestra mu = np.mean(grupos) sigma = np.std(grupos, ddof = 1) print("Media:", mu) print("Desviación:", sigma) ax = sns.histplot(grupos) ax.set(xlabel='CI', ylabel='Count', title="Función de distribución", xlim = (80, 120))
Probamos con 9 sujetos por grupo:
simula(1000, 9)
Media: 99.678 Desviación: 5.073688599037194
Con 25:
simula(1000, 25)
Media: 99.728 Desviación: 3.0538526487045834
Con 100:
simula(1000, 100)
Media: 99.475 Desviación: 1.5004582633315726
Vemos que la media de todos los grupos sigue siendo 100, pero la desviación típica cambia. Con 9 muestras por grupo es más o menos 5, con 25 3 y con 100 1.5.
En resumen, la media de las medias, o lo que es lo mismo, la media de la distribución muestral siempre es 100.
La desviación típica de las medias está en función del tamaño de la muestra:
$\displaystyle desviación \quad típica \quad muestral = \frac{desviación \quad típica \quad población}{\sqrt{tamaño \quad muestra}}$
En muchos estudios estadísticos, el objetivo, más que estimar el valor de un parámetro desconocido en la población, es comprobar la veracidad de una hipótesis formulada sobre la población objeto de estudio.
En general nunca se sabrá con absoluta certeza si una hipótesis estadística es cierta o falsa, ya que para ello habría que estudiar a todos los individuos de la población.
La metodología que se encarga de contrastar la veracidad de las hipótesis estadísticas se conoce como contraste de hipótesis.
La idea es tomar una decisión entre dos hipótesis excluyentes:
Supongamos que un estudio afirma que los españoles dedican 5 horas a la semana de media a hacer deporte, con una varianza = 4. Sospechamos que el tiempo es menor, con lo que tomamos 20 muestras aleatorias con el siguiente resultado:
7 6 4 3 1 9 8 7 3 1 10 9 4 3 2 1 5 5 6 4
Nuestras hipótesis serán:
Para comprobarlo, primero tendremos que elegir un nivel de significancia ($\alpha$), que marcará los límites entre la región de aceptación y la de rechazo.
Por ejemplo, supongamos que seleccionamos un nivel de significancia del 5%. Si calculamos la puntuación típica correspondiente, la región de rechazo será aquella que quede a la izquierda del valor, y la de aceptación la región que quede a la derecha.
import scipy.stats as st alpha = 0.05 z_alpha = st.norm.ppf(alpha) print("z-alfa:", z_alpha)
z-alfa: -1.6448536269514729
El siguiente paso será calcular la media de muestral y pasarla a puntuación típica.
$ \displaystyle Z = \frac{\overline{Y} - \overline{X}}{\frac{\sigma}{\sqrt{n}}} $
$ \displaystyle Z = \frac{4.9 - 5}{\frac{2}{\sqrt{20}}} = -0.22 $
import numpy as np # Media muestral Me = np.mean(datos) print("Media muestral", Me) z = np.divide(np.subtract(mu_muestral, mu), np.divide(sigma, np.sqrt(n))) print("Z:",z) print("Media:", mu)
Media muestral 4.9 Z: -0.2236067977499782
Por último, tenemos que calcular a qué probabilidad corresponde el valor de z:
pvalue = st.norm.cdf(z) print("pvalue:", pvalue)
pvalue: 0.411531636879061
Como el pvalue calculado es mayor que el nivel de significancia ($ \alpha = 0.05 $), no podemos rechazar la hipótesis nula, con lo que podemos afirmar, con un 5% de significancia que los españoles dedican 5 horas o más de media a hacer deporte.
Hace referencia a la variación conjunta de dos variables.
$\displaystyle S_{xy}= \frac{1}{N} \sum_{i=1}^{N}(X_{i} - \overline{X})(Y_{i} - \overline{Y})$
El signo, positivo o negativo, nos indica si la relación lineal entre ambas variables es directa o inversa.
En Python, podemos usar la función cov() de NumPy para calcular la matriz de covarianza.
# Usamos .T para hacer la transpuesta, ya que la covarianza se calcula entre vectores cov = np.cov(X.T, y.T) print("Varianza X =", np.var(X.T, ddof=1)) print("Varianza Y =",np.var(y.T, ddof=1)) print("Matriz covarianza:") print(cov) # Podríamos utilizar también cov[1][0], ya que Cov(X, y) = Cov(y, X) print("Cov(X, y) =", cov[0][1])
Varianza X = 0.3702913930365388 Varianza Y = 0.5232132889238625 Matriz covarianza: [[ 0.37029139 -0.40284492] [-0.40284492 0.52321329]] Cov(X, y) = -0.4028449167452653
El valor de la covarianza depende de las unidades en que están medidas las variables, lo que tiene una difícil interpretación.
Para evitar este inconveniente es necesario disponer de un índice cuyos valores estén acotados y su interpretación sea más sencilla: el coeficiente de correlación.
Existen diferentes tipos, entre los que destacan el de Pearson, Rho de Spearman y Tau de Kendall. Todos ellos comparten que:
Las principales diferencias entre los tres coeficientes son:
Además del valor obtenido para el coeficiente de correlación, es necesario calcular su significancia estadística. Por muy cercano que sea el valor del coeficiente de correlación a +1 o −1 , si no es significativo, no se dispone de evidencias suficiente para afirmar que existe una correlación real, ya que el valor observado podría deberse a simple aleatoriedad.
La correlación lineal, además del valor del coeficiente de correlación y de sus significancia, también tiene un tamaño de efecto asociado conocido como coeficiente de determinación R2 .
R2 se interpreta como la cantidad de varianza de Y explicada por X.
El coeficiente de correlación de Pearson es la covarianza entre dos variables, X e Y, calculada a partir de sus puntuaciones típicas:
$ \displaystyle r_{xy} = Cov(z_{x},z_{y}) $
De la expresión se deduce que, el coeficiente de correlación calculado con puntuaciones típicas es:
$\displaystyle r_{xy} = \frac{1}{n} \sum_{i=1}^{n}(z_{x}z_{y}) = \frac{1}{n} \sum_{i=1}^{n}(\frac{X - \overline{X}}{S_{X}})(\frac{X - \overline{Y}}{S_{Y}}) = \frac{\frac{1}{n} \sum_{i=1}^{n}(X - \overline{X})(Y - \overline{Y})}{S_{x}S_{y}} $
Llegando a una nueva expresión del coeficiente de correlación:
$ \displaystyle r_{xy} = \frac{S_{xy}}{S_{x}S_{y}} $
Se ve pues, que el coeficiente de correlación de Pearson se puede obtener como la covarianza entre puntuaciones típicas y también como el cociente entre la covarianza en puntuaciones directas y el producto de las respectivas desviaciones típicas de X e Y.
El coeficiente de Spearman es el equivalente al coeficiente de Pearson pero en lugar de utilizar directamente el valor de cada variable, los datos son ordenados y reemplazados por su respectivo orden (primero, segundo, tercero…). Se emplea como alternativa no paramétrica al coeficiente de Pearson cuando los valores son ordinales, o bien, cuando los valores son continuos pero no satisfacen la condición de normalidad.
Al trabajar con el orden de las observaciones en lugar de su valor real, tiene la característica de ser menos sensible que Pearson a valores extremos.
La correlación de Kendall es un método no paramétrico que, al igual que la correlación de Spearman, utiliza la ordenación de las observaciones ranking.
Es otra alternativa al coeficiente de correlación de Pearson cuando no se cumple la condición de normalidad. Suele utilizarse en lugar del coeficiente de Spearman cuando el número de observaciones es pequeño o los valores se acumulan en una región por lo que el número de ligaduras al generar el ranking es alto.
Para calcular el coeficiente de correlación, podemos utilizar varias librerías en Python. Vamos a crear dos variables con alta correlación para usar varias de esas librerías.
import numpy as np import matplotlib.pyplot as plt X = 2 * np.random.rand(100, 1) print(X.shape) y = 4 + 3 * X + np.random.rand(100, 1) fig, ax = plt.subplots(figsize=(9,6)) plt.scatter(X, y, s = 5) plt.axis([0 ,2, 0, 15]) plt.show()
Pandas permite calcular la correlación de dos variables. El cálculo se hace por pares, eliminando automáticamente aquellos con valores NA/null. Una limitación de Pandas es que no calcula la significancia estadística.
import pandas as pd # Pasamos los datos a Dataframe numpy_data = np.concatenate((X, y), axis = 1) df = pd.DataFrame(numpy_data, columns=['X', 'Y']) print('Correlación Pearson: ', df['X'].corr(df['Y'], method='pearson')) print('Correlación spearman: ', df['X'].corr(df['Y'], method='spearman')) print('Correlación kendall: ', df['X'].corr(df['Y'], method='kendall'))
Correlación Pearson: -0.8956835482791378 Correlación spearman: -0.8846684668466845 Correlación kendall: -0.6981818181818182
También podemos sacar la matriz de correlación:
# Matriz de correlación corr = df.corr() print(corr)
X Y X 1.000000 -0.895684 Y -0.895684 1.000000
La implementación de Scypy.stats sí permite calcular la significancia estadística además del coeficiente de correlación. La función stats.pearsonr(), devuelve un error si alguna de las observaciones contienen valores NA/null. Las funciones stats.spearmanr() y stats.kendalltau() sí permiten excluirlos de forma automática si se indica nan_policy='omit'.
import scipy.stats as stats r, p = stats.pearsonr(df['X'], df['Y']) print(f"Correlación Pearson: r={r}, p-value={p}") r, p = stats.spearmanr(df['X'], df['Y']) print(f"Correlación Spearman: r={r}, p-value={p}") r, p = stats.kendalltau(df['X'], df['Y']) print(f"Correlación Pearson: r={r}, p-value={p}")
Correlación Pearson: r=-0.895683548279138, p-value=2.8961037967935237e-36 Correlación Spearman: r=-0.8846684668466845, p-value=3.0144560755504517e-34 Correlación Pearson: r=-0.6981818181818182, p-value=7.62741751146521e-25
La librería Pingouin tiene una de las implementaciones más completas. Con la función corr() se obtiene, además del coeficiente de correlación, su significancia, intervalo de confianza y poder estadístico entre otros.
import pingouin as pg print(pg.corr(df['X'], df['Y'], method='pearson')) print(pg.corr(df['X'], df['Y'], method='spearman')) print(pg.corr(df['X'], df['Y'], method='kendall'))
n r CI95% p-val BF10 power pearson 100 -0.895684 [-0.93, -0.85] 2.896104e-36 7.928e+32 1.0 n r CI95% p-val power spearman 100 -0.884668 [-0.92, -0.83] 3.014456e-34 1.0 n r CI95% p-val power kendall 100 -0.698182 [-0.79, -0.58] 7.627418e-25 1.0
Ejercicio 1
Dado el array (12,34,45,23,12,65,79,48,23,3):
Ejercicio 2
Ejercicio 3