Tras los capítulos anteriores de un café con IoT, Capítulo 0: Una receta de hacktivismo interno y Capítulo 1: Los flujos de NiFi, hoy hablaremos sobre el Capítulo 2: Los datos en bruto.
Declaración de la máquina de café
Presentadora: Y así es como una vez más un cocodrilo de las alcantarillas… Disculpen, me comunican que vamos a conectar en directo con nuestro reportero Cafeole, que se encuentra en el centro de la noticia.
Cafeole: Muchas gracias por darme paso Hillary. Me encuentro junto a la máquina de café de Future Space, quien está dispuesta a hacernos una confesión altamente secreta sobre su contaminación con IOT.
Máquina de café: ¡Souvenirs, novedades, artículos de coña!
# Leer fichero -----------------------------------------------------------------
# Ruta
fichero.ruta = "./data/coffee.csv"
# Lectura de las líneas
conexion = file(fichero.ruta, open = "r")
lineas = readLines(
con = conexion)
close(conexion)
Una vista exterior
Tal y como se ha contado en anteriores artículos, los datos resultantes de la monitorización del consumo eléctrico de la máquina de café de FutureSpace se vuelcan a un fichero de formato csv. Aunque ya se manejan datos en las fases anteriores (en el enchufe inteligente o en el flujo de NiFi), este fichero es nuestra fuente de datos primigenia, el primer lugar en el que podemos considerar que los datos se encuentran almacenados y disponibles, permitiendo así que tanto humanos como máquinas podamos acceder a ellos.
En lo que concierne a este artículo, dejaremos de lado lo que ocurre en un proyecto de análisis de datos antes de tener los datos, y vamos a considerar que nuestro análisis comienza en este punto. Así pues, empecemos por averiguar algunas cosas sobre el fichero que tenemos entre manos.
# Datos del fichero ------------------------------------------------------------
# Tamaño del fichero
fichero.tamanio <- round(
x = file.size(fichero.ruta) / 2^20,
digits = 2)
# Número de líneas
fichero.numLineas <- as.numeric(length(lineas))
Visto desde fuera, el archivo nos da algo de información, como el formato de los datos que contiene (csv o comma separated values) o su tamaño en disco (204,97 MB). Se trata de información que, si bien no va a llegar muy lejos en el proceso de análisis, resulta muy útil de cara a cargar los datos en nuestra herramienta de análisis.
Una vista interior
A continuación, es interesante ojear cómo es el contenido del fichero para ver qué aspecto tienen los datos en bruto (raw data). En este caso, al ser un csv, el formato se orienta a datos tabulares, por lo que es importante averiguar cosas como el número de registros que tiene (5.358.606 líneas) o si tiene cabecera, es decir, si al principio del fichero aparece una línea con los nombres de las columnas de la tabla. Una operación que también es frecuente en este punto es la revisión de las primeras y últimas líneas del fichero. Esto nos ayuda a obtener información sobre los registros, pero también nos permite detectar contenido que no sean datos, como anotaciones o títulos, ya que son las zonas en las que más frecuentemente se insertan.
# Líneas de ejemplo ------------------------------------------------------------
# Primeras líneas
lineas.inicio <- lineas[1:10]
lineas.inicio <- paste(
"Primeras líneas: ",
paste(lineas.inicio, collapse = "\n"),
sep = "\n")
cat(lineas.inicio)
# Últimas líneas
lineas.final <- lineas[(fichero.numLineas - 10):fichero.numLineas]
lineas.final <- paste(
"Últimas líneas: ",
paste(lineas.final, collapse = "\n"),
sep = "\n")
cat(lineas.final)
Primeras líneas:
Thu Jun 14 13:03:01 CEST 2018,32.274447
Thu Jun 14 13:03:03 CEST 2018,32.299572
Thu Jun 14 13:03:05 CEST 2018,32.321334
Thu Jun 14 13:03:07 CEST 2018,32.377058
Thu Jun 14 13:03:09 CEST 2018,32.279788
Thu Jun 14 13:03:11 CEST 2018,32.304122
Thu Jun 14 13:03:13 CEST 2018,32.202237
Thu Jun 14 13:03:15 CEST 2018,32.254729
Thu Jun 14 13:03:17 CEST 2018,32.300891
Thu Jun 14 13:03:19 CEST 2018,32.360703
Últimas líneas:
Mon Oct 22 11:54:49 CEST 2018,32.333468
Mon Oct 22 11:54:51 CEST 2018,32.277744
Mon Oct 22 11:54:53 CEST 2018,32.158976
Mon Oct 22 11:54:55 CEST 2018,32.255982
Mon Oct 22 11:54:57 CEST 2018,32.198016
Mon Oct 22 11:54:59 CEST 2018,32.191817
Mon Oct 22 11:55:01 CEST 2018,32.277678
Mon Oct 22 11:55:03 CEST 2018,32.216085
Mon Oct 22 11:55:06 CEST 2018,32.199533
Mon Oct 22 11:55:08 CEST 2018,32.206721
Mon Oct 22 11:55:10 CEST 2018,32.213579
Sólo con ver estos registros, ya hay algunas cosas de las que podemos tomar nota de cara a nuestro proceso analítico, por ejemplo:
- El fichero carece de cabecera.
- La información se presenta en 2 columnas.
- La primera columna hace referencia al momento en el que se consulta al enchufe inteligente sobre el consumo eléctrico que está registrando. En ella se presenta una fecha y hora con precisión de segundos, en formato inglés, pero referido a la hora de Europa central en verano (Central European Summer Time).
- La segunda, muestra el consumo medido en vatios, tal y como nos especifica el fabricante del enchufe inteligente.
- El registro de información se inició el día 14 de junio de 2018 sobre las 13 horas, y finalizó el 22 de octubre del mismo año en torno a las 12 del medio día.
# Duración y observaciones -----------------------------------------------------
# Fechas de inicio y fin
fechaInicio <- mdy_hms("Jun 14 2018 13:03:01")
fechaFin <- mdy_hms("Oct 22 2018 11:55:10")
# Duración de la monitorización
observacionesTeoricas.segundos <- as.integer(
difftime(fechaFin, fechaInicio, units = "secs"))
observacionesTeoricas.numero <- observacionesTeoricas.segundos / 2
observacionesTeoricas.duracion <- seconds_to_period(
observacionesTeoricas.segundos)
observacionesReales.numero <- fichero.numLineas
observacionesReales.segundos <- observacionesReales.numero * 2
# Diferencia entre monitorización teórica y real
observacionesAusentes.segundos <-
observacionesTeoricas.segundos - observacionesReales.segundos
observacionesAusentes.duracion <- seconds_to_period(
observacionesAusentes.segundos)
Si a esto le añadimos algunas cuentas rápidas, podemos daros cuenta de que entre el momento inicial y el final del registro, han transcurrido 11.227.929 segundos (equivalentes a un periodo de 129d 22H 52M 9S), o que, si tenemos en cuenta que la extracción de datos estaba preparada para realizar una medición cada 2 segundos, deberíamos de tener 5.613.965 observaciones, aunque el fichero únicamente tiene 5.358.606. Casualmente, si se presta atención a los registros, es posible percatarse de que se producen saltos de más de 2 segundos entre un registro y el siguiente (posiblemente debidos a retrasos en las repuestas del enchufe inteligente). Por ejemplo, entre las últimas líneas, que se corresponden al día 22 de octubre, es posible observar un salto de 3 segundos entre dos registros, donde se pasa de las 11:55:03 a las 11:55:06.
Si quisiéramos profundizar un poco más en el estudio del contenido del fichero, podríamos simular una carga de los datos en la herramienta de análisis. Esto nos permite detectar con facilidad algunos registros peculiares, especialmente cuando no obedecen al formato anteriormente observado. De esta forma, se detectan 31.025 registros con formato incorrecto, cuyo contenido es un código de error devuelto por la API del enchufe inteligente. Veamos una línea de ejemplo:
# Carga de datos inicial -------------------------------------------------------
# Tabla base
electricidad <- read.csv(
file = fichero.ruta,
header = F,
col.names = c("momento", "consumo"),
sep = ",",
colClasses = rep("character", 2),
stringsAsFactors = F
)
# Observaciones erróneas
observacionesErroneas <- which(is.na(as.numeric(electricidad$consumo)))
observacionesErroneas.numero <- length(observacionesErroneas)
lineas.erroneas <- lineas[observacionesErroneas[1]]
{«error_code»:-20002,»msg»:»Request timeout»}
Conclusión
Llegados a este punto, ya tenemos una idea del tipo de cosas que podemos aprender sobre los datos a partir del propio fichero. Además, hemos tomado nota de las características y particularidades del fichero y de los datos en sí, lo que nos permitirá saber cómo cargarlos en nuestra herramienta analítica. Pero poco más podemos sacar de aquí. Para entender los datos, necesitamos hacer algo más que leerlos. Y ese algo tiene por nombre estadística.
¿Y no podemos ver todos los datos de alguna forma? Lo veremos en los siguientes capítulos de Café con IOT.
*Nota al margen. Para los curiosos: El dato objetivo
Pongamos otro ejemplo (uno que me toca en lo personal). Un cliente puede decirle a un arquitecto ‘quiero una casa con dos habitaciones, un salón, una cocina y un baño’. Y, como no podría ser de otra forma, el arquitecto apunta ‘espacio reticular con movilidad dinamizada por atractores de flujo, en el que la luz conviva con los volúmenes fragmentados y la rizomática organicidad del color unifique los paramentos verticales’. Un dato subjetivo y otro objetivo.
En medicina se suele distinguir entre datos objetivos y datos subjetivos. Por ejemplo, cuando un paciente dice ‘me duele el pecho’ o ‘tengo escalofríos’, estamos ante datos subjetivos. En cambio, cuando el médico apunta en el informe ‘sudoración’ o ‘taquicardias’, tenemos datos objetivos. Es raro que se reconozca esta dualidad de los datos fuera de las ciencias de la salud, pero podríamos decir que siempre que hay un humano que ejerce de sujeto y otro que sea un profesional del área de interés que se esté tratando, podemos tener datos objetivos y subjetivos.
Al aparecer la fotografía, la pintura se volvió claramente subjetiva. Una imagen fotográfica era considerada una representación fiel de la realidad, así que los pintores tuvieron que pintar otras cosas. Pero no tardamos en darnos cuenta de que el fotógrafo tiene su propia mirada. Simplemente el hecho de elegir qué es lo que se fotografía y qué no, ya es un elemento de subjetividad. A eso se le añaden capas y capas de decisiones técnicas (distancia focal, tiempo de exposición, grano de la película…), narrativas (título, pie de foto o tweet que acompaña a la imagen, etc. Y no digamos nada de lo que ocurre cuando le dejas una máquina fotográfica a un mago como Méliès.
Así pues no parece casualidad que a las opiniones de uno se le llamen ‘punto de vista’.
A los datos les pasa lo mismo que a la fotografía. Parecen objetivos, incluso algo así como ciertos, pero elegimos qué medimos, con qué precisión o con qué unidad. Construimos la historia de lo que queremos contar desde el mismo momento en el que recopilamos los datos, y creamos un mundo en el que si no te miden no existes.