Capítulo II de mis pruebas con el Notebook alternativo de Sofia2 y con Anaconda, Jupyter y Python para la analítica de datos. Esta vez vamos a jugar con mis datos históricos de localización que tiene Google gracias al teléfono Android y al servicio de localización del móvil.
Me descargo de google (https://takeout.google.com/settings/takeout) el fichero HistorialdeUbicaciones.json / locationhistory.json con todo el histórico de mis localizaciones.
# Importo las librerías necesarias
import matplotlib
import matplotlib.pyplot as plt
import numpy as np
import pandas as pd
import json
import datetime
import seaborn as sns
%matplotlib inline
matplotlib.rcParams['figure.figsize'] = (12.0, 6.0)
# Cargo el fichero json con mis localizaciones
with open('Downloads/PythonRecursos/takeout-20160821T103444Z/HistorialdeUbicaciones.json', 'r') as fl:
raw = json.loads(fl.read())
data = pd.DataFrame(raw['locations'])
del raw
# Reviso la cantidad de datos que hay en el fichero
data.shape
data.sample()
# Conversión a las unidades habituales
data['latitudeE7'] = data['latitudeE7']/float(1e7)
data['longitudeE7'] = data['longitudeE7']/float(1e7)
data['timestampMs'] = data['timestampMs'].map(lambda x: float(x)/1000) #to seconds
data['datetime'] = data.timestampMs.map(datetime.datetime.fromtimestamp)
# Renombrado de columnas
data.rename(columns={'latitudeE7':'latitude', 'longitudeE7':'longitude', 'timestampMs':'timestamp'}, inplace=True)
data.reset_index(drop=True, inplace=True)
longitudeE7 –> La longitud
timestampMs –> La fecha de la medida
activitys –> Campo interesante pero que no va a ser motivo de esta guerra
accuracy –> Exactitud o precisión de la localización medida. Campo que voy a estudiar.Me centro en extraer información sobre campo accuracy, el campo activitys que contiene bastante información lo dejaremos para otro día.
# Mostramos la distribución de la propiedad accuracy (exactitud)
data.accuracy.hist(bins=30)

# Se crean nuevas columnas con el año, la fecha y la hora
data['year'] = data['datetime'].dt.year
data['date'] = data['datetime'].dt.date
data['hour'] = data['datetime'].dt.hour
# Muestro los histogramas de la columna accuaracy divididos por años
data.accuracy.hist(by=data['year'])
Se aprecia que la precisión de la localización ha ido mejorando con los años lo cual demuestra que esta tecnología va mejorando.
# Se crea una nueva columna que indique si la precisión es mayor o menor de 2000 metros
data['value_accuracy'] = np.where(data['accuracy']>=2000, '1', '0')
# Se crean nuevos dataframes para los registros con poca precisión
data_2000 = data[data.accuracy >= 2000]
# Selecciono los datos del año 2016 para poder visualizar mejor los puntos
data_2000_201601_06 = data[(data.accuracy >= 2000) & (data.datetime >= '2016-01-01') & (data.datetime < '2016-06-01')]
data_l2000_201601_06 = data[(data.accuracy < 2000) & (data.datetime >= '2016-01-01') & (data.datetime < '2016-06-01')]
data_201601_06 = data[(data.datetime >= '2016-01-01') & (data.datetime < '2016-06-01')]
# Gráfico con todos los puntos
sns.jointplot(x="longitude", y="latitude", data=data)
# Gráfico con lo datos de este año de enero a mayo con buena precisión ya que el error en la posición es de más de 2000 metros
sns.jointplot(x="longitude", y="latitude", data=data_l2000_201601_06, xlim=(-7,-3), ylim=(37,42))
# Gráfico con lo datos de este año de enero a mayo con una exactitud en la medida de más de 2000 metros
sns.jointplot(x="longitude", y="latitude", data=data_2000_201601_06, xlim=(-7,-3), ylim=(37,42))
# Se mezclan los puntos de las dos gráficas para ver las discrepancias
g = sns.FacetGrid(data_201601_06, hue="value_accuracy", size=6, xlim=(-7,-3), ylim=(37,42), palette='husl')
g.map(plt.scatter, "longitude", "latitude", s=40, alpha=.4, linewidth=.5, edgecolor="white")
g.add_legend()
Se ven diferencias claramente 3 zonas: una en la parte superior derecha con los puntos con buena y mala precisión superpuestos y las otras dos zonas donde la supersposición de los puntos bien localizados y los malos no es tan clara.
Amplio la zona donde los puntos están menos superpuestos.
# Amplio la zona donde los puntos están menos superpuestos, parte superior izquierda
g = sns.FacetGrid(data_201601_06, hue="value_accuracy", size=6, xlim=(-6,-5.6), ylim=(40,40.6))
g.map(plt.scatter, "longitude", "latitude", s=40, alpha=.4, linewidth=.5, edgecolor="white")
g.add_legend()
Si localizo la zona google maps http://maps.google.com/maps?q=40.1,-5.93 se que la posición está lejos de una población.Amplio la zona con los puntos de ubicación más superpuestos.
# Amplio la zona donde los puntos bien y mal localizados están superpuestos, parte superior derecha
g = sns.FacetGrid(data_201601_06, hue="value_accuracy", size=6, xlim=(-3.7,-3.5), ylim=(40.2,40.6), palette='RdBu')
g.map(plt.scatter, "longitude", "latitude", s=40, alpha=.4, linewidth=.5, edgecolor="white")
g.add_legend()
Se ve que la mayor parte de los puntos siguen superpuestos
Creo dos dataframe nuevos con los datos con buena y mala precisión.
Muestro una distribución para la latitud de los puntos con una mala precisión.
# Divido los datos entre buena y mala precisión
data_201601_06_cuadrante = data_201601_06[(data_201601_06.longitude >= -3.7) & (data_201601_06.longitude <= -3.5)
& (data_201601_06.latitude >= 40.2) & (data_201601_06.latitude <= 40.6)
& (data_201601_06.accuracy >= 2000)]
data_201601_06_cuadrante_total = data_201601_06[(data_201601_06.longitude >= -3.7) & (data_201601_06.longitude <= -3.5)
& (data_201601_06.latitude >= 40.2) & (data_201601_06.latitude <= 40.6)]
# Histograma de la latitud
data_201601_06_cuadrante.latitude.hist()
data_201601_06_cuadrante.groupby(['latitude','longitude']).count().head(3)
http://maps.google.com/maps?q=40.332033,-3.524198
El punto está localizado en el H2Ocio de Rivas.
Todos pertenecen al mismo día 2016-02-13 21:46:55.12 y a la misma franja horaria así que da la impresión de que se debe a un error temporal en la ubicación de las celdas de telefonía en esa zona, no hay ninguna wifi cerca y el GPS no funciona por ser una zona interior.
Filtramos para quedarnos con el resto de los datos con una mala localización que son sólo 62.
# Se seleccionan el resto de los datos con una mala localización
data_201601_06_cuadrante_rest = data_201601_06_cuadrante[(data_201601_06_cuadrante.latitude != 40.3320326)]
data_201601_06_cuadrante_rest.shape
# data_201601_06_cuadrante_rest
# data_201601_06_cuadrante_rest.activitys.tolist()
data_201601_06_cuadrante_rest
data_201601_06_cuadrante_rest.activitys.tolist()
http://maps.google.com/maps?q=x,y
# Las horas más frecuentes con errores de localización
sns.countplot(data_201601_06_cuadrante_rest.hour)










Deja un comentario