Análisis descriptivo

Autor: Roberto P. Muñoz
Cargo: Data Scientist en MetricArts
Github: https://github.com/rpmunoz

En este tutorial revisaremos los conceptos de tablas de frencuencias, medidas de localización y medidas de dispersión.


In [1]:
import numpy as np
import pandas as pd

np.set_printoptions(precision=2)
%precision 2


Out[1]:
'%.2f'

Lectura de datos

Para este tutorial usaremos la base de datos de vuelos áreos publicada por el sitio web Openflights. En particular, usaremos la tabla de las rutas de vuelos comerciales (rutas.csv).

Más información en https://github.com/jpatokal/openflights


In [2]:
rutas_file='data/rutas.csv'
rutas=pd.read_csv(rutas_file)
rutas=rutas.sample(frac=1)

rutas.head()


Out[2]:
Linea_aerea Linea_aerea_Id Aeropuerto_origen Aeropuerto_origen_Id Aeropuerto_destino Aeropuerto_destino_Id Vuelo_operado Numero_paradas Modelo_avion Pais_origen Pais_destino Distancia_km
41260 MU 1758 JIC 11473 NAY 6341 Y 0 737 Unknown China 0.000000
10972 AM 321 TRC 1845 MEX 1824 NaN 0 EMJ Mexico Mexico 813.915407
55173 UA 5209 BHX 469 BRU 302 Y 0 DH4 United Kingdom Belgium 462.626170
36094 KL 3090 BSL 1423 CDG 1382 Y 0 AT7 France France 400.489936
25043 FL 1316 OKC 3863 ATL 3682 NaN 0 717 United States United States 1220.878210

In [3]:
print("Número de rutas aéreas: ", len(rutas))
print("Número de países: ", len(rutas['Pais_origen'].unique()))


Número de rutas aéreas:  66765
Número de países:  225

Construcción de tabla de frencuencias

Una de los primeros pasos del análisis descriptivo consiste en la organización de los datos mediante el uso de tablas o estructuras similares. La organización de los datos es fundamental para facilitar el entendimiento y posterior análisis de los datos.

Es común analizar conjuntos de datos con un gran número de registros y cuyo entendimiento se dificulta debido al volumen de los datos. En nuestro caso, la tabla de rutas aéreas contiene más de 66 mil registros.

La tabla de frecuencias o distribución de frecuencias es una manera de organizar los datos en forma de tabla, asignando a cada categoría o rango de valores su frecuencia correspondiente. Se pueden usar tanto variables cuantitativas como cualitativas.

La primera columna contiene el valor único o el rango de valores de la variable en estudio. En nuestro caso, usaremos la variable País de origen para construir la tabla de frencuencias.

La segunda columna contiene la frecuencia absoluta, la cual es el número de veces que aparece un determinado valor en un conjunto de datos. La suma de las frecuencias absolutas es igual al número total de registros.

La tercera columna contiene la frecuencia relativa, la cual es el cuociente entre la frecuencia absoluta de un determinado valor y el número total de datos. La suma de las frecuencias relativas es igual a 1.


In [4]:
rutas_pais=pd.value_counts(rutas['Pais_origen']).reset_index()
rutas_pais.columns=['País', 'Frecuencia absoluta']
rutas_pais['Frencuencia relativa']=rutas_pais['Frecuencia absoluta']/rutas_pais['Frecuencia absoluta'].sum()
rutas_pais


Out[4]:
País Frecuencia absoluta Frencuencia relativa
0 United States 13046 0.195402
1 China 8121 0.121636
2 United Kingdom 2661 0.039856
3 Spain 2528 0.037864
4 Germany 2352 0.035228
5 France 1926 0.028847
6 Russia 1808 0.027080
7 Italy 1776 0.026601
8 Canada 1521 0.022781
9 Brazil 1387 0.020774
10 India 1382 0.020699
11 Japan 1285 0.019247
12 Australia 1112 0.016655
13 Mexico 1058 0.015847
14 Turkey 970 0.014529
15 Indonesia 833 0.012477
16 Greece 787 0.011788
17 United Arab Emirates 740 0.011084
18 Norway 646 0.009676
19 Unknown 608 0.009107
20 Thailand 604 0.009047
21 South Korea 589 0.008822
22 Netherlands 570 0.008537
23 Malaysia 563 0.008433
24 Saudi Arabia 542 0.008118
25 Portugal 530 0.007938
26 Sweden 454 0.006800
27 Switzerland 429 0.006426
28 Iran 419 0.006276
29 Taiwan 414 0.006201
... ... ... ...
195 Micronesia 9 0.000135
196 Eritrea 8 0.000120
197 Western Sahara 7 0.000105
198 Guinea-Bissau 7 0.000105
199 French Guiana 7 0.000105
200 Marshall Islands 7 0.000105
201 Kiribati 7 0.000105
202 Gibraltar 6 0.000090
203 Anguilla 6 0.000090
204 North Korea 5 0.000075
205 Bhutan 5 0.000075
206 Tonga 5 0.000075
207 Samoa 5 0.000075
208 Wallis and Futuna 4 0.000060
209 Saint Vincent and the Grenadines 4 0.000060
210 Faroe Islands 4 0.000060
211 East Timor 4 0.000060
212 Sao Tome and Principe 3 0.000045
213 Saint Pierre and Miquelon 3 0.000045
214 Nauru 3 0.000045
215 Norfolk Island 3 0.000045
216 Central African Republic 3 0.000045
217 Christmas Island 2 0.000030
218 American Samoa 1 0.000015
219 Swaziland 1 0.000015
220 Lesotho 1 0.000015
221 Tuvalu 1 0.000015
222 Falkland Islands 1 0.000015
223 Cocos (Keeling) Islands 1 0.000015
224 Niue 1 0.000015

225 rows × 3 columns

Medidas de localización y dispersión

Si bien la tabla de frecuencias ofrece toda la información disponible, el analista puede encontrar difícil la interpretación de toda esta información. Supongamos que queremos estudiar la columna Distancia_km de la tabla rutas, la cual contiene la distancia en kilómetros de cada vuelo aéreo que existe en el mundo. Sin duda la cantidad de datos es grande y difícil de interpretar.

En el análisis descriptivo es conveniente sinterizar la información en unas pocas medidas de resumen. Estas medidas son llamadas medidas de localización y medidas de dispersión.

Usaremos la columna Distancia_km para sintetizar la información asociada al largo de los vuelos.

Las medidas de localización más empleadas son el promedio, la mediana, los percentiles y los cuartiles.

Partamos calculando el valor promedio usando la función mean() de la librería numpy de Python.


In [5]:
np.mean(rutas['Distancia_km'])


Out[5]:
1824.65

El valor promedio de la distancia reocrrida por los vuelos aéreos es 1.824,65 kilómetros.

Calculemos la mediana usando la función median()


In [6]:
np.median(rutas['Distancia_km'])


Out[6]:
1180.01

Vemos que el valor de la mediana es 1.180,01 kilómetros, muy diferente al valor promedio. Esto suele ocurrir cuando el conjunto de datos contiene un número importante de valores atípicos o la distribución de datos tiene un alto grado de asimetría.

Calculemos los percentiles usando la función percentile(). Calculemos los percentiles 10, 50 y 90.


In [7]:
np.percentile(rutas['Distancia_km'],10)


Out[7]:
309.21

In [8]:
np.percentile(rutas['Distancia_km'],50)


Out[8]:
1180.01

In [9]:
np.percentile(rutas['Distancia_km'],90)


Out[9]:
3927.46

Una vez ordenados los datos de menor a mayor, el percentil 10 es el valor de la variable por debajo del cual se encuentra el 10% de los datos. Para el percentil 50 corresponde al valor que encierra al 50% de los datos, y cuyo valor coincide con la mediana.

Calculemos los cuartiles usando la función percentile() y los valores 25, 50 y 75 que corresponden a los tres cuartiles.


In [10]:
np.percentile(rutas['Distancia_km'],25)


Out[10]:
610.76

In [11]:
np.percentile(rutas['Distancia_km'],50)


Out[11]:
1180.01

In [12]:
np.percentile(rutas['Distancia_km'],75)


Out[12]:
2139.02

Las medidas de dispersón más empleadas son el rango estadísitico, la desviación, la varianza y la desviación típica.

Partamos calculando el rango estadístico usando la función ptp()


In [13]:
np.ptp(rutas['Distancia_km'])


Out[13]:
16072.16

Vemos que la diferencia entre el vuelo más largo de la tabla y el vuelo más corto corresponde a 16.072.16 kms

Calculemos la desviación para los primeros 5 valores de la tabla. Usaremos el valor de cada registro y el promedio calculado usando la función mean()


In [14]:
rutas['Distancia_km'][0:5].values - np.mean(rutas['Distancia_km'])


Out[14]:
array([-1824.65, -1010.73, -1362.02, -1424.16,  -603.77])

Vemos que el primer registro está por debajo del promedio y por ello su desviación es negativa.

Calulemos la varianza usando la función var()


In [15]:
np.var(rutas['Distancia_km'])


Out[15]:
4050466.74

Vemos que la varianza del conjunto de datos es bastante alta, pues su valor es 4.050.466,74 $km^2$. Es importante notar que las unidades de varianza son cuadráticas y por ello decimos $km^2$.

Calulemos la desviación típica o desviación estándar usando la función std()


In [16]:
np.std(rutas['Distancia_km'])


Out[16]:
2012.58

Vemos que la desviación típica es 2.012,58 km. La desviación estándar tiene las mismas unidades físicas que el conjunto de datos.


In [ ]: