Histórico de localizaciones de Google y la propiedad accuracy

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.

In [1]:
# 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
In [2]:
matplotlib.rcParams['figure.figsize'] = (12.0, 6.0)
In [3]:
# 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 
In [4]:
# Reviso la cantidad de datos que hay en el fichero
data.shape
Out[4]:
(1072894, 8)
Mi primera sorpresa es ver que google ya tiene más de un millón de puntos míos geolocalizados.

 

In [5]:
data.sample()
Out[5]:
accuracy activitys altitude heading latitudeE7 longitudeE7 timestampMs velocity
811552 671 [{u’activities’: [{u’confidence’: 100, u’type’… NaN NaN 405141787 -36754236 1393356876515 NaN

 

In [6]:
# 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)
Reviso un registro para ver que campos almacena y me encuentro que con datos tenemos estas propiedades:
latitudeE7 –> La latitud
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.
Reviso la distribución de valores (histograma) del campo accuracy

 

In [7]:
# Mostramos la distribución de la propiedad accuracy (exactitud)
data.accuracy.hist(bins=30)
Out[7]:
LocationHistory_Google_histogram
Otra sorpresa es ver la poca exactitud que tienen los puntos geolocalizados, si tenemos en cuenta que la localización la realiza en base a tres servicios: GPS, ID de las celdas de telefonía y la Wifi, que el GPS es muy preciso y que lo suelo tener activado está claro que Google/Android por defecto no está utilizando el GPS para generar el histórico de localizaciones. Malas noticias para los que piensan que desactivando el GPS Google no les localiza su posición.

 

In [8]:
# 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 propiedad accuracy divididos por año.

 

In [9]:
# Muestro los histogramas de la columna accuaracy divididos por años
data.accuracy.hist(by=data['year'])
Out[9]:
LocationHistory_Google_hist_byyear
Google tiene datos míos de ubicación desde el año 2012, ya no me acordaba que llevaba tanto tiempo con un móvil Android.
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.
Voy a centrarme en los datos geolocalizados con un error mayor de 2000 metros.

 

In [10]:
# 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')
In [11]:
# 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')]
In [12]:
# Gráfico con todos los puntos 
sns.jointplot(x="longitude", y="latitude", data=data)
Out[12]:
LocationHistory_Google_plotall
En mi caso el gráfico con todos los puntos nos aporta poco e indica que he realizado un viaje corto a un sitio lejano.
Hago zoom en una zona y selecciono los datos de este año y con mejor precisión (<2000 metros).

 

In [13]:
# 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))
Out[13]:
LocationHistory_Google_plot_1
Con el mismo zoom muestro los datos de menor exactitud (> 2000 m)

 

In [14]:
# 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))
Out[14]:
LocationHistory_Google_plot_2
Lo que se aprecia en los dos gráficos es que los histogramas que se muestran en los laterales no son parecidos cuando sería lo esperable si los errores en la precisión fuesen aleatorios.
Muestro en una única gráfica todos los puntos para ver las diferencias.

 

In [15]:
# 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()
Out[15]:
LocationHistory_Google_plot_union

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.

In [16]:
# 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()
Out[16]:
LocationHistory_Google_plot_zoom1
Se aprecia claramente que la baja exactitud en la localización depende de la posición donde me encontaba no hay wifi, hay mala cobertura y no ha debido funcionar el GPS.
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.


In [17]:
# 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()
Out[17]:
LocationHistory_Google_plot_zoom2

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.

In [18]:
# 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)]
In [19]:
# Histograma de la latitud
data_201601_06_cuadrante.latitude.hist()
Out[19]:
LocationHistory_Google_hist_latitud
Se observa que muchos de los puntos tienen la misma latitud ????

 

In [20]:
data_201601_06_cuadrante.groupby(['latitude','longitude']).count().head(3)
Out[20]:
accuracy activitys altitude heading timestamp velocity datetime year date hour value_accuracy
latitude longitude
40.332033 -3.524198 34 24 0 0 34 0 34 34 34 34 34
40.334555 -3.528936 1 1 0 0 1 0 1 1 1 1 1
40.364131 -3.652332 1 1 0 0 1 0 1 1 1 1 1


Justo este punto 40.332033 -3.524198 está repetido 34 veces parece mucha casualidad.
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.

In [21]:
# 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)]
In [22]:
data_201601_06_cuadrante_rest.shape
Out[22]:
(62, 13)
In [23]:
# data_201601_06_cuadrante_rest
# data_201601_06_cuadrante_rest.activitys.tolist()
Revisamos fechas, localizaciones y el campo activitys para ver si encuentramos alguna relación para los errores en la preción en la localización.
data_201601_06_cuadrante_rest
data_201601_06_cuadrante_rest.activitys.tolist()
http://maps.google.com/maps?q=x,y


Gráfico por la hora del día


In [24]:
# Las horas más frecuentes con errores de localización
sns.countplot(data_201601_06_cuadrante_rest.hour)
Out[24]:
LocationHistory_Google_plot_hour
No encuentro ningún patrón claro para estos errores en la geolocalización, son siempre en trayectos en coche, en días distintos y en localizaciones diferentes. Si que se aprecia que las horas más frecuentes con errores de localización coinciden con las horas de mis desplazamientos diarios en coche, para estos pocos puntos la precisión en la ubicación no habrá funcionado todo lo bien que se espera porque no habrá una wifi cerca geoposicionada, el sistema de localización por potencia de la señal y celdas de telefonía no habrá funcionado correctamente y además no tendría activado el GPS o se perdió la señal de este. Hemos identificado por los datos que para Google el sistema de localización por GPS es el menos prioritario de los tres que utiliza y que nos geolocaliza aunque lo tengamos desactivado (existe la opción en el móvil de desactivar el servicio de localización). Sea como sea estas imprecisiones en nuestra localización van a menos con el paso de los años.


Anuncios

Responder

Introduce tus datos o haz clic en un icono para iniciar sesión:

Logo de WordPress.com

Estás comentando usando tu cuenta de WordPress.com. Cerrar sesión / Cambiar )

Imagen de Twitter

Estás comentando usando tu cuenta de Twitter. Cerrar sesión / Cambiar )

Foto de Facebook

Estás comentando usando tu cuenta de Facebook. Cerrar sesión / Cambiar )

Google+ photo

Estás comentando usando tu cuenta de Google+. Cerrar sesión / Cambiar )

Conectando a %s

A %d blogueros les gusta esto: