2 Solución reto día del Hackathon.

En este apartado está descrito cómo nuestro equipo solucionó este reto durante el Hackathon. Se han añadido comentarios para dar más claridad al desarrollo. Aparte de estas notas no hemos añadido nada sustancial al análisis que no fuese incluido durante la competición.

Para ver un análisis hecho con más tiempo y más cercano a lo que nos hubiese gustado hacer puedes pasar directamente al apartado 3 de este notebook.

2.1 Carga de las librerias necesarias.

library(tidyverse)
library(readxl)
library(VIM)
library(GGally)

2.2 Preparación datos “train”.

Los datasets originales de train estaban en formato ‘xls’ y al abrirlos daban un error de formato. No pudimos importarlos en R directamente, ya que nos daba un error con la importación también. Así que los guardamos como ‘csv’ para posteriormente importarlos en R. En este proceso también tuvimos algún problema, así que la importación de los datos nos llevó mucho más tiempo de lo esperado.

Archivos originales “train”:

‘sunlab-faro_meteo_2015.xls’
‘sunlab-faro_meteo_2016.xls’
‘sunlab-faro-pv-2015.xls’
‘sunlab-faro-pv-2016.xls’

Importamos los archivos ya convertidos a formato ‘csv’.

meteo_2015 <- read_csv("./data/hackathon_data/train/sunlab-faro_meteo_2015.csv")
meteo_2016 <- read_csv("./data/hackathon_data/train/sunlab-faro_meteo_2016.csv")
prod_2015 <- read_csv("./data/hackathon_data/train/sunlab-faro-pv-2015.csv")
prod_2016 <- read_csv("./data/hackathon_data/train/sunlab-faro-pv-2016.csv")

Unimos las parejas de archivos de datos de producción y meteorológicos.

meteo_2015_2016 <- bind_rows(meteo_2015, meteo_2016)
prod_2015_2016 <- bind_rows(prod_2015, prod_2016)

# Borramos los archivos originales

rm(meteo_2015)
rm(meteo_2016)
rm(prod_2015)
rm(prod_2016)

Echamos un vistazo a los datos de producción con las funciones ‘summary’ y ‘glimpse’.

summary(prod_2015_2016)
##     Datetime                   A_Vertical - Voltage DC [V]
##  Min.   :2015-01-01 07:40:00   Min.   :10.20              
##  1st Qu.:2015-05-28 18:54:30   1st Qu.:26.65              
##  Median :2015-10-08 17:39:00   Median :27.95              
##  Mean   :2015-12-04 18:29:34   Mean   :26.28              
##  3rd Qu.:2016-07-19 14:47:30   3rd Qu.:29.10              
##  Max.   :2016-12-29 17:31:00   Max.   :35.05              
##                                NA's   :13979              
##  A_Vertical - Current DC [A] A_Vertical - Power DC [W]
##  Min.   :0.000               Min.   :  0.00           
##  1st Qu.:0.710               1st Qu.: 15.90           
##  Median :1.822               Median : 50.94           
##  Mean   :2.252               Mean   : 63.56           
##  3rd Qu.:3.460               3rd Qu.:100.67           
##  Max.   :8.105               Max.   :245.18           
##  NA's   :13979               NA's   :13979            
##  A_Optimal - Voltage DC [V] A_Optimal - Current DC [A]
##  Min.   :10.10              Min.   : 0.000            
##  1st Qu.:27.05              1st Qu.: 1.097            
##  Median :27.90              Median : 3.482            
##  Mean   :27.53              Mean   : 3.574            
##  3rd Qu.:28.95              3rd Qu.: 5.860            
##  Max.   :35.30              Max.   :10.238            
##  NA's   :8342               NA's   :8342              
##  A_Optimal - Power DC [W] A_Horizontal - Voltage DC [V]
##  Min.   :  0.00           Min.   :10.10                
##  1st Qu.: 30.74           1st Qu.:26.90                
##  Median : 99.79           Median :27.70                
##  Mean   :100.48           Mean   :26.53                
##  3rd Qu.:165.06           3rd Qu.:28.90                
##  Max.   :307.64           Max.   :35.35                
##  NA's   :8342             NA's   :9039                 
##  A_Horizontal - Current DC [A] A_Horizontal - Power DC [W]
##  Min.   : 0.000                Min.   :  0.00             
##  1st Qu.: 1.095                1st Qu.: 27.55             
##  Median : 2.930                Median : 83.44             
##  Mean   : 3.163                Mean   : 87.10             
##  3rd Qu.: 5.055                3rd Qu.:140.21             
##  Max.   :10.238                Max.   :304.63             
##  NA's   :9039                  NA's   :9039               
##  A_Vertical - Temperature [ºC] A_Optimal - Temperature [ºC]
##  Min.   : 1.80                 Min.   : 2.0                
##  1st Qu.:22.60                 1st Qu.:21.5                
##  Median :30.20                 Median :29.0                
##  Mean   :29.21                 Mean   :28.8                
##  3rd Qu.:35.80                 3rd Qu.:36.0                
##  Max.   :52.80                 Max.   :58.6                
##                                                            
##  A_Horizontal - Temperature [ºC] B_Vertical - Voltage DC [V]
##  Min.   : 1.40                   Min.   :10.30              
##  1st Qu.:20.70                   1st Qu.:26.45              
##  Median :28.30                   Median :27.00              
##  Mean   :28.59                   Mean   :25.48              
##  3rd Qu.:36.30                   3rd Qu.:27.60              
##  Max.   :64.80                   Max.   :34.65              
##                                  NA's   :11201              
##  B_Vertical - Current DC [A] B_Vertical - Power DC [W]
##  Min.   :0.000               Min.   :  0.00           
##  1st Qu.:0.678               1st Qu.: 14.95           
##  Median :1.847               Median : 49.89           
##  Mean   :2.382               Mean   : 64.48           
##  3rd Qu.:3.695               3rd Qu.:102.69           
##  Max.   :9.078               Max.   :255.99           
##  NA's   :11201               NA's   :11201            
##  B_Optimal - Voltage DC [V] B_Optimal - Current DC [A]
##  Min.   :10.35              Min.   : 0.000            
##  1st Qu.:26.70              1st Qu.: 1.083            
##  Median :27.35              Median : 3.438            
##  Mean   :26.31              Mean   : 3.654            
##  3rd Qu.:28.00              3rd Qu.: 6.250            
##  Max.   :35.15              Max.   :10.238            
##  NA's   :6730               NA's   :6730              
##  B_Optimal - Power DC [W] B_Horizontal - Voltage DC [V]
##  Min.   :  0.00           Min.   :10.65                
##  1st Qu.: 27.08           1st Qu.:26.70                
##  Median : 96.81           Median :27.35                
##  Mean   : 99.69           Mean   :26.26                
##  3rd Qu.:170.25           3rd Qu.:28.35                
##  Max.   :302.01           Max.   :35.10                
##  NA's   :6730             NA's   :11902                
##  B_Horizontal - Current DC [A] B_Horizontal - Power DC [W]
##  Min.   : 0.000                Min.   :  0.00             
##  1st Qu.: 1.077                1st Qu.: 25.83             
##  Median : 2.857                Median : 81.42             
##  Mean   : 3.120                Mean   : 85.54             
##  3rd Qu.: 4.980                3rd Qu.:139.04             
##  Max.   :10.238                Max.   :300.98             
##  NA's   :11902                 NA's   :11902              
##  B_Vertical - Temperature [ºC] B_Optimal - Temperature [ºC]
##  Min.   : 3.20                 Min.   : 2.30               
##  1st Qu.:23.50                 1st Qu.:22.50               
##  Median :30.50                 Median :30.90               
##  Mean   :29.53                 Mean   :30.67               
##  3rd Qu.:35.70                 3rd Qu.:38.70               
##  Max.   :51.10                 Max.   :62.00               
##                                                            
##  B_Horizontal - Temperature [ºC]
##  Min.   : 1.60                  
##  1st Qu.:21.10                  
##  Median :28.30                  
##  Mean   :28.59                  
##  3rd Qu.:36.10                  
##  Max.   :62.10                  
## 
glimpse(prod_2015_2016)
## Observations: 420,507
## Variables: 25
## $ Datetime                          <dttm> 2015-01-09 12:52:00, 2015-0...
## $ `A_Vertical - Voltage DC [V]`     <dbl> 29.35, 29.10, 29.10, 29.35, ...
## $ `A_Vertical - Current DC [A]`     <dbl> 6.4125, 6.3975, 6.3325, 6.41...
## $ `A_Vertical - Power DC [W]`       <dbl> 188.206875, 186.167250, 184....
## $ `A_Optimal - Voltage DC [V]`      <dbl> 28.75, 28.45, 28.45, 28.75, ...
## $ `A_Optimal - Current DC [A]`      <dbl> 7.1700, 7.1925, 7.0925, 7.21...
## $ `A_Optimal - Power DC [W]`        <dbl> 206.13750, 204.62662, 201.78...
## $ `A_Horizontal - Voltage DC [V]`   <dbl> 29.25, 29.50, 29.45, 29.50, ...
## $ `A_Horizontal - Current DC [A]`   <dbl> 4.3225, 4.2525, 4.1825, 4.30...
## $ `A_Horizontal - Power DC [W]`     <dbl> 126.43313, 125.44875, 123.17...
## $ `A_Vertical - Temperature [ºC]`   <dbl> 32.6, 32.4, 33.2, 32.2, 32.8...
## $ `A_Optimal - Temperature [ºC]`    <dbl> 28.8, 28.6, 29.4, 28.2, 27.8...
## $ `A_Horizontal - Temperature [ºC]` <dbl> 26.5, 26.1, 26.8, 26.4, 26.1...
## $ `B_Vertical - Voltage DC [V]`     <dbl> 27.55, 27.60, 27.40, 27.40, ...
## $ `B_Vertical - Current DC [A]`     <dbl> 7.0925, 7.0475, 7.0100, 7.14...
## $ `B_Vertical - Power DC [W]`       <dbl> 195.39837, 194.51100, 192.07...
## $ `B_Optimal - Voltage DC [V]`      <dbl> 27.85, 28.05, 27.85, 28.05, ...
## $ `B_Optimal - Current DC [A]`      <dbl> 7.2225, 7.1125, 7.0450, 7.17...
## $ `B_Optimal - Power DC [W]`        <dbl> 201.14663, 199.50563, 196.20...
## $ `B_Horizontal - Voltage DC [V]`   <dbl> 29.05, 29.05, 28.75, 28.95, ...
## $ `B_Horizontal - Current DC [A]`   <dbl> 4.1775, 4.1275, 4.1125, 4.19...
## $ `B_Horizontal - Power DC [W]`     <dbl> 121.356375, 119.903875, 118....
## $ `B_Vertical - Temperature [ºC]`   <dbl> 31.2, 31.5, 31.9, 31.7, 32.2...
## $ `B_Optimal - Temperature [ºC]`    <dbl> 30.2, 30.0, 30.9, 29.9, 30.7...
## $ `B_Horizontal - Temperature [ºC]` <dbl> 25.3, 24.9, 25.7, 25.1, 25.6...

Y aquí directamente ya decidimos quedarnos directamente con las variables target a predecir ‘A_Optimal - Power DC [W]’ y ‘B_Optimal - Power DC [W]’) más la variable ‘Datetime’ que nos servirá para cruzar esta tabla con la tabla de datos meteorológicos.

prod_2015_2016_final <- prod_2015_2016 %>%
                        select(Datetime, 
                               'A_Optimal - Power DC [W]',
                               'B_Optimal - Power DC [W]')

Vemos los principales estadísticos de las variables de la tabla de datos meteorológicos.

summary(meteo_2015_2016)
##     Datetime                   Ambient Temperature [ºC]
##  Min.   :2015-01-01 00:00:00   Min.   :-1.500e+09      
##  1st Qu.:2015-05-26 11:06:30   1st Qu.: 1.400e+01      
##  Median :2015-10-18 23:12:00   Median : 1.800e+01      
##  Mean   :2015-11-27 03:00:27   Mean   :-5.358e+03      
##  3rd Qu.:2016-05-17 18:32:30   3rd Qu.: 2.300e+01      
##  Max.   :2016-12-31 23:00:00   Max.   : 3.800e+01      
##                                                        
##  Global Radiation [W/m2] Diffuse Radiation [W/m2] Ultraviolet [W/m2]
##  Min.   :   0.7285       Min.   :  1.6            Min.   : 0.4954   
##  1st Qu.:   1.5693       1st Qu.:  1.7            1st Qu.: 0.5106   
##  Median :  13.0063       Median : 16.5            Median : 1.5008   
##  Mean   : 237.1203       Mean   : 68.2            Mean   :14.5440   
##  3rd Qu.: 452.7272       3rd Qu.:103.7            3rd Qu.:26.0017   
##  Max.   :1421.3282       Max.   :720.4            Max.   :84.2660   
##                          NA's   :399744                             
##  Wind Velocity [m/s]  Wind Direction [º] Precipitation [mm]
##  Min.   :-1.500e+09   Min.   :  0.0      Min.   :0         
##  1st Qu.: 1.000e+00   1st Qu.:123.6      1st Qu.:0         
##  Median : 2.000e+00   Median :235.8      Median :0         
##  Mean   :-5.375e+03   Mean   :212.8      Mean   :0         
##  3rd Qu.: 3.000e+00   3rd Qu.:296.7      3rd Qu.:0         
##  Max.   : 1.200e+01   Max.   :360.0      Max.   :2         
##                                          NA's   :776160    
##  Atmospheric pressure [hPa] Direct Radiation [W/m2]
##  Min.   : 999.1             Min.   :  1.6          
##  1st Qu.:1014.3             1st Qu.:  1.7          
##  Median :1020.4             Median :  8.6          
##  Mean   :1019.9             Mean   : 63.9          
##  3rd Qu.:1025.7             3rd Qu.: 91.9          
##  Max.   :1033.8             Max.   :790.1          
##  NA's   :776160             NA's   :437159

Y decidimos quedarnos únicamente con 4 variables más la variable ‘Datetime’, que nos servirá de referencia para el cruce con la tabla anterior.

meteo_2015_2016_final <- meteo_2015_2016 %>%
                        select(Datetime, 
                               'Ambient Temperature [ºC]',
                               'Diffuse Radiation [W/m2]',
                               'Ultraviolet [W/m2]',
                               'Global Radiation [W/m2]')

Cruzamos las tablas por Datetime y comprobamos que no se duplican registros, ya que la tabla final tiene el mismo número de registros que la tabla de producción: 420.507.

tabla_final <- prod_2015_2016_final %>%
  left_join(meteo_2015_2016_final, by = 'Datetime')

Inspeccionamos las variables.

summary(tabla_final) 
##     Datetime                   A_Optimal - Power DC [W]
##  Min.   :2015-01-01 07:40:00   Min.   :  0.00          
##  1st Qu.:2015-05-28 18:54:45   1st Qu.: 30.74          
##  Median :2015-10-08 17:38:30   Median : 99.79          
##  Mean   :2015-12-04 18:28:55   Mean   :100.48          
##  3rd Qu.:2016-07-19 14:47:15   3rd Qu.:165.06          
##  Max.   :2016-12-29 17:31:00   Max.   :307.64          
##                                NA's   :8342            
##  B_Optimal - Power DC [W] Ambient Temperature [ºC]
##  Min.   :  0.00           Min.   :-1.500e+09      
##  1st Qu.: 27.08           1st Qu.: 1.700e+01      
##  Median : 96.81           Median : 2.100e+01      
##  Mean   : 99.69           Mean   :-4.093e+03      
##  3rd Qu.:170.25           3rd Qu.: 2.600e+01      
##  Max.   :302.01           Max.   : 3.800e+01      
##  NA's   :6730             NA's   :55918           
##  Diffuse Radiation [W/m2] Ultraviolet [W/m2] Global Radiation [W/m2]
##  Min.   :  1.61           Min.   : 0.56      Min.   :   1.34        
##  1st Qu.: 60.12           1st Qu.: 9.75      1st Qu.: 155.74        
##  Median : 99.84           Median :24.27      Median : 426.75        
##  Mean   :127.92           Mean   :27.30      Mean   : 452.57        
##  3rd Qu.:159.23           3rd Qu.:43.45      3rd Qu.: 727.82        
##  Max.   :720.35           Max.   :84.27      Max.   :1421.33        
##  NA's   :194998           NA's   :55918      NA's   :55918

Aquí vemos que la variable Ambient Temperature [ºC] tiene como dato mínimo un posible error. Así que filtramos esta variable para corregirlo.

tabla_final <- tabla_final %>% 
                filter(`Ambient Temperature [ºC]` > -100)

Comprobamos que hemos resuelto el problema.

summary(tabla_final$`Ambient Temperature [ºC]`)
##    Min. 1st Qu.  Median    Mean 3rd Qu.    Max. 
##   3.167  16.900  21.483  21.432  26.100  38.300

Y exportamos el archivo final en formato csv para cargarlo en la herramienta de modelización BigML.

write_csv(tabla_final, "meteo_prod_2015_2016.csv")

2.3 Preparación datos “test”.

Importaciones

test_prod_2017 <- read_csv("./data/hackathon_data/test/test-sunlab-pv-2017.csv")
test_meteo_2017 <- read_csv("./data/hackathon_data/test/test-sunlab-meteo-2017.csv")

Cruzamos las tablas por Datetime

tabla_final_test <- test_prod_2017 %>%
              left_join(test_meteo_2017, by = "Datetime") %>%
                        select(`A_Optimal - Power DC [W]`, 
                               `Global Radiation [W/m2]`,
                               `Ultraviolet [W/m2]`)

Exportamos el archivo final en formato csv para cargarlo en la herramienta de modelización BigML.

write_csv(tabla_final_test, "test_meteo_prod_2017.csv")

2.4 Modelo base panel A

Una vez creadas y exportadas la tablas para crear los modelos en BigML y mientras se ejecutan los modelos en esa plataforma creamos un modelo base (o de partida) en R para el tipo de panel A.

Creamos un modelo con una regresión lineal para predecir los valores de Power DC [W] en función de dos únicas variables Global Radiation [W/m2] y Ultraviolet [W/m2]

# Eliminamos los registros del panel tipo B y eliminamos también los registros con NAs
tabla_final_A <- tabla_final %>% 
               select(-`B_Optimal - Power DC [W]`) %>%
                na.omit()

# Y creamos el modelo
modelo_A_1=lm(`A_Optimal - Power DC [W]` ~ `Global Radiation [W/m2]` + `Ultraviolet [W/m2]` , data =  tabla_final_A)

Inspeccionamos el modelo creado.

modelo_A_1
## 
## Call:
## lm(formula = `A_Optimal - Power DC [W]` ~ `Global Radiation [W/m2]` + 
##     `Ultraviolet [W/m2]`, data = tabla_final_A)
## 
## Coefficients:
##               (Intercept)  `Global Radiation [W/m2]`  
##                    4.8996                     0.2692  
##      `Ultraviolet [W/m2]`  
##                   -0.9980

Obtenemos el resumen del mismo.

summary(modelo_A_1)
## 
## Call:
## lm(formula = `A_Optimal - Power DC [W]` ~ `Global Radiation [W/m2]` + 
##     `Ultraviolet [W/m2]`, data = tabla_final_A)
## 
## Residuals:
##      Min       1Q   Median       3Q      Max 
## -217.181  -18.974   -5.129   13.335  228.712 
## 
## Coefficients:
##                            Estimate Std. Error t value Pr(>|t|)    
## (Intercept)                4.899640   0.115664   42.36   <2e-16 ***
## `Global Radiation [W/m2]`  0.269219   0.001342  200.54   <2e-16 ***
## `Ultraviolet [W/m2]`      -0.997964   0.022165  -45.02   <2e-16 ***
## ---
## Signif. codes:  0 '***' 0.001 '**' 0.01 '*' 0.05 '.' 0.1 ' ' 1
## 
## Residual standard error: 30.48 on 221113 degrees of freedom
## Multiple R-squared:  0.8266, Adjusted R-squared:  0.8266 
## F-statistic: 5.269e+05 on 2 and 221113 DF,  p-value: < 2.2e-16

Y obtenemos un modelo base significativo (p-value mucho menor que 0,05) y con un R cuadrado ajustado de 0,83. Bastante bien para empezar.

Extraemos del modelo los valores predecidos y seleccionamos también de la tabla los valores reales para posteriormente obtener los errores y el MAE (Mean Absolute Error).

fitted_values <- modelo_A_1$fitted.values
real_values <- tabla_final_A$`A_Optimal - Power DC [W]`

Obtenemos el MAE para tenerlo como referencia de comparación con los modelos que estamos desarrollando en BigML.

real_values_df <- as.data.frame(real_values)
fitted_values_df <- as.data.frame(fitted_values)


real_vs_fitted <- bind_cols(real_values_df, fitted_values_df)

errors <- real_vs_fitted %>% 
          mutate(abs_error = abs(fitted_values - real_values))

MAE <- mean(errors$abs_error)
MAE
## [1] 22.53593

El MAE que tendremos como referencia a mejorar es 22,54.

Para hacer la predicción para los 7 primeros días de 2017 seleccionamos de la tabla de test los campos utilizados en el modelo.

tabla_final_test_A <- tabla_final_test %>%
                        select(`A_Optimal - Power DC [W]`, 
                               `Global Radiation [W/m2]`,
                               `Ultraviolet [W/m2]`)

Hacemos la prediccion para los paneles A con nuestro modelo.

prediccion_test <- predict(modelo_A_1, tabla_final_test_A)

Y exportamos nuestras predicciones para enviarlas también, junto a las obtenidas con BigML, al jurado del Hackathon.

prediccion_test <- as.data.frame(prediccion_test)
write_csv(prediccion_test, "predicciones_panel_A.csv")

El modelo base para los datos del tipo de panel B no nos dio tiempo a hacerlo.

2.5 Modelización en BigML

Aquí se ven las fuente de datos creadas para este reto. “meteo_prod_2015_2016.csv” es la fuente a partir de los datos procesados en R para el entrenamiento del modelo. Y “test_meteo_prod_2017.csv” es la fuente, también procesada en R, con los datos para hacer la predicción.

Detalle de la fuente con las columnas que dejamos despues de procesar en R.

Aquí se ven los datasets que creamos a partir de las dos fuentes. Se puede ver que creamos un dataset a partir de los datos originales de la fuente “meteo_prod_2015_2016” y sobre él fuimos iterando. Primero lo dividimos en dos datasets, uno para los paneles de tipo A (“meteo_prod_2015_2016_CONDATOS_A”) y otro para los paneles de tipo B (“meteo_prod_2015_2016_CONDATOS_B”). Y luego eliminamos un valor de temperatura que era erroneo y nos descuadraba el resultado. También está el dataset “test_meteo_prod_2017” que creamos a partir de los datos de test para hacer luego la predicción con el modelo.

Detalle de uno de los datasets con los campos que eliminamos para que no influyesen en la predicción.

Detalle de uno de los datasets con los campos que eliminamos para que no influyesen en la predicción.

Regresiones lineales creadas a partir de los datasets, una para cada modelo de panel solar.

Detalle de la grafica de predicción de una de las regresiones en función de la radiación.

Detalle de regresiones para uno de los paneles.

Predicciones batch para cada modelo creadas con el dataset de prueba.

Detalle de una de las predicciones.

Con las prisas y la falta de experiencia con la herramienta BigML no nos dio tiempo tampoco a comprobar la bondad del ajuste y calidad de los modelos generados. Nos dio el tiempo justo para simplemente enviar las predicciones de los primeros modelos que obtuvimos.