rte-antares-rpackage / antaDraft

2 stars 0 forks source link

Build
Status AppVeyor Build
Status version Project Status: WIP - Initial development is in progress, but there
has not yet been a stable, usable release suitable for the
public. codecov

antaDraft

Le package contient un ensemble de fonctions pour vérifier et corriger des données entsoe.

L’objectif du package est de permettre la création d’un jeu de données complet pour deux années de données et pour plusieurs pays.

Les données peuvent être manquantes ou imparfaites. Il s’agit de permettre :

La procédure est pour l’instant implémentée pour les données de consommation.

Utilisation

On va charger l’ensemble des données archivées sur archive.org à l’URL suivante : https://archive.org/details/RTE_load

Le zip à charger est le suivant: https://archive.org/download/RTE_load/load.zip.

load_dir <- file.path(tempdir(), "load_files" )
load_zip <- file.path(tempdir(), "load.zip" )

local_zip <- "/Users/davidgohel/Documents/consulting/RTE/load_20180115.zip"
if( file.exists(local_zip))
  file.copy(local_zip, load_zip, overwrite = TRUE )
#> [1] TRUE

if( !file.exists(load_zip) )
  download.file(url = "https://archive.org/download/RTE_load/load.zip", 
                destfile = load_zip )

if( dir.exists(load_dir) )
  unlink(load_dir, recursive = TRUE, force = TRUE)

utils::unzip(load_zip, exdir = load_dir )

Les données sont disponibles dans le répertoire /var/folders/51/6jygptvs3bb4njv0t6x7br900000gn/T//RtmpKjomya/load_files. Celui ci contient les fichiers suivants :

csv_files <- list.files(load_dir, full.names = TRUE, pattern = "\\.csv$")
csv_infos <- file.info(csv_files)[, c(1, 3) ]
row.names(csv_infos) <- NULL
csv_infos$file <- basename(csv_files)

kable(csv_infos)
size mode file
4818387 644 2014_12_ActualTotalLoad.csv
11754929 644 2015_1_ActualTotalLoad.csv
11875895 644 2015_10_ActualTotalLoad.csv
11310965 644 2015_11_ActualTotalLoad.csv
11781789 644 2015_12_ActualTotalLoad.csv
10726713 644 2015_2_ActualTotalLoad.csv
11787017 644 2015_3_ActualTotalLoad.csv
11697487 644 2015_4_ActualTotalLoad.csv
12126637 644 2015_5_ActualTotalLoad.csv
11542277 644 2015_6_ActualTotalLoad.csv
11876256 644 2015_7_ActualTotalLoad.csv
11475976 644 2015_8_ActualTotalLoad.csv
11391554 644 2015_9_ActualTotalLoad.csv
11419260 644 2016_1_ActualTotalLoad.csv
11875625 644 2016_10_ActualTotalLoad.csv
11451870 644 2016_11_ActualTotalLoad.csv
11912513 644 2016_12_ActualTotalLoad.csv
10715373 644 2016_2_ActualTotalLoad.csv
11896459 644 2016_3_ActualTotalLoad.csv
11049881 644 2016_4_ActualTotalLoad.csv
11394632 644 2016_5_ActualTotalLoad.csv
11051677 644 2016_6_ActualTotalLoad.csv
11618280 644 2016_7_ActualTotalLoad.csv
11567961 644 2016_8_ActualTotalLoad.csv
11135435 644 2016_9_ActualTotalLoad.csv
11781347 644 2017_1_ActualTotalLoad.csv
12206677 644 2017_10_ActualTotalLoad.csv
11575500 644 2017_11_ActualTotalLoad.csv
11797364 644 2017_12_ActualTotalLoad.csv
10570762 644 2017_2_ActualTotalLoad.csv
11948418 644 2017_3_ActualTotalLoad.csv
11574925 644 2017_4_ActualTotalLoad.csv
11943294 644 2017_5_ActualTotalLoad.csv
11596317 644 2017_6_ActualTotalLoad.csv
11715569 644 2017_7_ActualTotalLoad.csv
11458478 644 2017_8_ActualTotalLoad.csv
11212775 644 2017_9_ActualTotalLoad.csv
3153704 644 2018_1_ActualTotalLoad.csv

Les données brutes

Avant de dégager une série de consommation par pays

library(antaDraft)
load_data <- anta_load(data_dir = load_dir )

Validation des données brutes

L’opération va ajouter autant de colonnes qu’il y a de tests exprimés dans le fichier config/load/raw_validate.yml.

Ce fichier décrit les règles de validation de chaque ligne de donnée.

rules:

- expr: observed==TRUE
  name: IS_OBS
- expr: is.finite(TotalLoadValue)
  name: IS_FINITE
- expr: sign(TotalLoadValue)>0.001
  name: IS_POS
load_data <- augment_validation(load_data)
head(load_data)
#>     DateTime MapCode AreaTypeCode     country AreaName TotalLoadValue
#> 1 2014-12-01      AT          CTA     AUSTRIA     <NA>             NA
#> 2 2014-12-01      AT          CTY     AUSTRIA     <NA>             NA
#> 3 2014-12-01      BE          BZN     BELGIUM  Elia BZ        9100.34
#> 4 2014-12-01      BE          CTA     BELGIUM  Elia CA        9100.34
#> 5 2014-12-01      BE          CTY     BELGIUM  Belgium        9100.34
#> 6 2014-12-01      CH          BZN SWITZERLAND     <NA>             NA
#>   observed IS_OBS IS_FINITE IS_POS
#> 1    FALSE  FALSE      TRUE   TRUE
#> 2    FALSE  FALSE      TRUE   TRUE
#> 3     TRUE   TRUE      TRUE   TRUE
#> 4     TRUE   TRUE      TRUE   TRUE
#> 5     TRUE   TRUE      TRUE   TRUE
#> 6    FALSE  FALSE      TRUE   TRUE

Les données agrégées

On va produire les données agrégées avec la fonction aggregate_with_rules. Les règles sont exprimées dans le fichier config/global/atc_per_country.yml.

FRANCE:
  CTY:
    - FR
  CTA:
    - FR
  BZN:
    - FR

BELGIUM:
  CTY:
    - BE
  CTA:
    - BE
  BZN:
    - BE

SWITZERLAND:
  CTY:
    - CH
  CTA:
    - CH
  BZN:
    - CH

SPAIN:
  CTY:
    - ES
  CTA:
    - ES
  BZN:
    - ES

NETHERLANDS:
  CTY:
    - NL
  CTA:
    - NL
  BZN:
    - NL

PORTUGAL:
  CTY:
    - PT
  CTA:
    - PT
  BZN:
    - PT

ITALY:
  CTY:
    - IT
  CTA:
    - IT
  BZN:
    - IT_CNOR
    - IT_CSUD
    - IT_North
    - IT_SARD
    - IT_SICI
    - IT_SUD

GERMANY:
  CTY:
    - DE
  CTA:
    - DE_TenneT_GER
    - DE_TransnetBW
    - DE_Amprion
    - DE_50HzT
  BZN:
    - DE_AT_LU
    - "!CTY|AUSTRIA"
    - "!CTY|LUXEMBOURG"

AUSTRIA:
  CTY:
    - AT
  CTA:
    - AT
  BZN:
    - DE_AT_LU
    - "!CTY|GERMANY"
    - "!CTY|LUXEMBOURG"

UK:
  CTY:
    - GB
    - "!CTA|NORTH_IRELAND"
  CTA:
    - GB
  BZN:
    - GB

IRELAND:
  CTY:
    - IE
  CTA:
    - IE
  BZN:
    - IE_SEM
    - "!CTA|NORTH_IRELAND"

NORTH_IRELAND:
  CTY:
    - NIE
  CTA:
    - NIE
  BZN:
    - IE_SEM
    - "!CTY|IRELAND"

LUXEMBOURG:
  CTY:
    - LU
  CTA:
    - LU
  BZN:
    - DE_AT_LU
    - "!CTY|GERMANY"
    - "!CTY|AUSTRIA"

La fonction prend des données de load comme argument, c’est à dire obtenue avec la fonction anta_load().

aggregated_db <- agg_data(load_data)

Ces données peuvent être représentées graphiquement avec la fonction plot (voire ?plot_agg).

plot_agg(aggregated_db, subset = aggregated_db$country %in% "SWITZERLAND")

Validation des données agrégées

Comme pour les données brutes, l’opération va ajouter autant de colonnes qu’il y a de tests exprimés dans le fichier agg_validate.yml.

rules:

- expr: is.finite(CTY)
  name: CTY_NA
- expr: is.finite(CTA)
  name: CTA_NA
- expr: is.finite(BZN)
  name: BZN_NA

- expr: CTY > 0.001
  name: CTY_IS_POS
- expr: CTA > 0.001
  name: CTA_IS_POS
- expr: BZN > 0.001
  name: BZN_IS_POS

- expr: abs(CTY-CTA) < 1
  name: CTY_CTA_EQUAL
- expr: abs(CTY-BZN) < 1
  name: CTY_BZN_EQUAL
- expr: abs(CTA-BZN) < 1
  name: CTA_BZN_EQUAL

- expr: abs(1 - (CTY / CTA) ) < .05
  name: CTY_CTA_DIFF_LT_05
- expr: abs(1 - (CTY / BZN) ) < .05
  name: CTY_BZN_DIFF_LT_05
- expr: abs(1 - (CTA / BZN) ) < .05
  name: CTA_BZN_DIFF_LT_05

- expr: abs(1 - (CTY / CTA) ) < .1
  name: CTY_CTA_DIFF_LT_10
- expr: abs(1 - (CTY / BZN) ) < .1
  name: CTY_BZN_DIFF_LT_10
- expr: abs(1 - (CTA / BZN) ) < .1
  name: CTA_BZN_DIFF_LT_10

- expr: (is.na(data.table::shift(CTY)) | sign(CTY) < 1 | (abs(CTY - data.table::shift(CTY)) / CTY) < .3 ) & ( is.na(data.table::shift(CTY)) | sign(CTY) < 1 | (abs(data.table::shift(CTY) - CTY) / data.table::shift(CTY)) < .3 )
  name: CTY_LAG_LT_30
- expr: ( is.na(data.table::shift(CTA)) | sign(CTA) < 1 | (abs(CTA - data.table::shift(CTA)) / CTA) < .3 ) & ( is.na(data.table::shift(CTA)) | sign(CTA) < 1 | (abs(data.table::shift(CTA) - CTA) / data.table::shift(CTA)) < .3 )
  name: CTA_LAG_LT_30
- expr: ( is.na(data.table::shift(BZN)) | sign(BZN) < 1 | (abs(BZN - data.table::shift(BZN)) / BZN)  < .3 ) & (is.na(data.table::shift(BZN)) | sign(BZN) < 1 | (abs(data.table::shift(BZN) - BZN) / data.table::shift(BZN)) < .3 )
  name: BZN_LAG_LT_30

aggregated_db <- augment_validation(aggregated_db)

Ces données peuvent être représentées graphiquement avec la fonction plot (voire ?plot.controled).

plot(aggregated_db, subset = aggregated_db$country %in% "SWITZERLAND")

Correction mécanique des données agrégées

aggregated_db <- data_correct_with_rules(aggregated_db)

Qualification résumée des lignes agrégées

aggregated_db <- augment_process_summary(aggregated_db)

library(dplyr)
library(tidyr)
aggregated_db %>% 
  group_by_at(c( "country", "summary") ) %>% 
  tally() %>% 
  spread(summary, n) %>% 
  kable()
country corrected invalid original
AUSTRIA 13989 13044 218
BELGIUM 9 22724 4518
FRANCE 1 26985 265
GERMANY 14012 1211 12028
IRELAND 9 27242 NA
ITALY 24 25440 1787
LUXEMBOURG 13854 13351 46
NETHERLANDS 28 27223 NA
NORTH_IRELAND 21310 5941 NA
PORTUGAL 1047 24418 1786
SPAIN 767 26484 NA
SWITZERLAND 49 27165 37
UK 1 27162 88

Correction des données par modèles de prévisions

Il faut dans un premier temps enrichir la base de données avec des variables potentiellement explicatives. On utilise la fonction as_learning_db.

dat <- as_learning_db(aggregated_db )
head(dat)
#>   country            DateTime BZN CTA CTY rule_0003_BZN rule_0002_CTY
#> 1 AUSTRIA 2014-12-01 00:00:00   0   0   0         FALSE         FALSE
#> 2 AUSTRIA 2014-12-01 01:00:00   0   0   0         FALSE         FALSE
#> 3 AUSTRIA 2014-12-01 02:00:00   0   0   0         FALSE         FALSE
#> 4 AUSTRIA 2014-12-01 03:00:00   0   0   0         FALSE         FALSE
#> 5 AUSTRIA 2014-12-01 04:00:00   0   0   0         FALSE         FALSE
#> 6 AUSTRIA 2014-12-01 05:00:00   0   0   0         FALSE         FALSE
#>   rule_0001_CTA CTY_NA CTA_NA BZN_NA CTY_IS_POS CTA_IS_POS BZN_IS_POS
#> 1         FALSE   TRUE   TRUE   TRUE      FALSE      FALSE      FALSE
#> 2         FALSE   TRUE   TRUE   TRUE      FALSE      FALSE      FALSE
#> 3         FALSE   TRUE   TRUE   TRUE      FALSE      FALSE      FALSE
#> 4         FALSE   TRUE   TRUE   TRUE      FALSE      FALSE      FALSE
#> 5         FALSE   TRUE   TRUE   TRUE      FALSE      FALSE      FALSE
#> 6         FALSE   TRUE   TRUE   TRUE      FALSE      FALSE      FALSE
#>   CTY_CTA_EQUAL CTY_BZN_EQUAL CTA_BZN_EQUAL CTY_CTA_DIFF_LT_05
#> 1          TRUE          TRUE          TRUE               TRUE
#> 2          TRUE          TRUE          TRUE               TRUE
#> 3          TRUE          TRUE          TRUE               TRUE
#> 4          TRUE          TRUE          TRUE               TRUE
#> 5          TRUE          TRUE          TRUE               TRUE
#> 6          TRUE          TRUE          TRUE               TRUE
#>   CTY_BZN_DIFF_LT_05 CTA_BZN_DIFF_LT_05 CTY_CTA_DIFF_LT_10
#> 1               TRUE               TRUE               TRUE
#> 2               TRUE               TRUE               TRUE
#> 3               TRUE               TRUE               TRUE
#> 4               TRUE               TRUE               TRUE
#> 5               TRUE               TRUE               TRUE
#> 6               TRUE               TRUE               TRUE
#>   CTY_BZN_DIFF_LT_10 CTA_BZN_DIFF_LT_10 CTY_LAG_LT_30 CTA_LAG_LT_30
#> 1               TRUE               TRUE          TRUE          TRUE
#> 2               TRUE               TRUE          TRUE          TRUE
#> 3               TRUE               TRUE          TRUE          TRUE
#> 4               TRUE               TRUE          TRUE          TRUE
#> 5               TRUE               TRUE          TRUE          TRUE
#> 6               TRUE               TRUE          TRUE          TRUE
#>   BZN_LAG_LT_30 summary is_off likely_off year.iso week.iso hour.iso
#> 1          TRUE invalid  FALSE      FALSE     2014       49        0
#> 2          TRUE invalid  FALSE      FALSE     2014       49        1
#> 3          TRUE invalid  FALSE      FALSE     2014       49        2
#> 4          TRUE invalid  FALSE      FALSE     2014       49        3
#> 5          TRUE invalid  FALSE      FALSE     2014       49        4
#> 6          TRUE invalid  FALSE      FALSE     2014       49        5
#>   day.iso light_time HOUR_SHIFT_CTY_PLUS_1 HOUR_SHIFT_CTY_MINUS_1
#> 1       2        524                    NA                     NA
#> 2       2        524                    NA                     NA
#> 3       2        524                    NA                     NA
#> 4       2        524                    NA                     NA
#> 5       2        524                    NA                     NA
#> 6       2        524                    NA                     NA
#>   DAILY_MIN_CTY_PLUS_1 DAILY_AVG_CTY_PLUS_1 DAILY_MAX_CTY_PLUS_1
#> 1                   NA                   NA                   NA
#> 2                   NA                   NA                   NA
#> 3                   NA                   NA                   NA
#> 4                   NA                   NA                   NA
#> 5                   NA                   NA                   NA
#> 6                   NA                   NA                   NA
#>   DAILY_MIN_CTY_MINUS_1 DAILY_AVG_CTY_MINUS_1 DAILY_MAX_CTY_MINUS_1
#> 1                  6306              7581.317                8661.2
#> 2                  6306              7581.317                8661.2
#> 3                  6306              7581.317                8661.2
#> 4                  6306              7581.317                8661.2
#> 5                  6306              7581.317                8661.2
#> 6                  6306              7581.317                8661.2

On peut alors créer deux modèles, un dépandant des mesures suivantes et un dépendant des mesures précédentes.

On utilisera pour cela la fonction define_model_rf. Celle-ci sauvegarde les modèles dans un répertoire local à la machine.

repertoire_model <- tempfile()
dir.create(repertoire_model, showWarnings = FALSE, recursive = TRUE)

Création du modèle backward:

x_vars <- c(
  "year.iso", "week.iso", "hour.iso", "day.iso", "light_time",
  "is_off", "likely_off",
  "DAILY_MIN_CTY_MINUS_1", "DAILY_AVG_CTY_MINUS_1", "DAILY_MAX_CTY_MINUS_1",
  "HOUR_SHIFT_CTY_MINUS_1")

dat <- define_model_rf( 
  data = dat, x_vars = x_vars, y_var = "CTY",
  save_model_dir = repertoire_model, id = "BACKWARD" )

Création du modèle forward:

x_vars <- c(
  "year.iso", "week.iso", "hour.iso", "day.iso", "light_time",
  "is_off", "likely_off",
  "DAILY_MIN_CTY_PLUS_1", "DAILY_AVG_CTY_PLUS_1", "DAILY_MAX_CTY_PLUS_1",
  "HOUR_SHIFT_CTY_PLUS_1")

dat <- define_model_rf( 
  data = dat, x_vars = x_vars, y_var = "CTY",
  save_model_dir = repertoire_model, id = "FORWARD" )

Maintenant qu’on a deux modèles, on peut les utiliser en boucle pour remplacer les valeurs invalides par des valeurs prévues par les modèles.

for(i in 1:12 ){
  dat <- impute_with_model(dat, id = "FORWARD")
  dat <- impute_with_model(dat, id = "BACKWARD")
  dat <- update_learning_db(dat)
}
library(dplyr)
library(tidyr)
dat %>% 
  group_by_at(c( "country", "summary") ) %>% 
  tally() %>% 
  spread(summary, n) %>% 
  kable()