From 9b9bb2d490e356ff0393aec66b137cff0a64803d Mon Sep 17 00:00:00 2001 From: Benjamin Auder <benjamin.auder@somewhere> Date: Thu, 4 May 2017 20:54:11 +0200 Subject: [PATCH] update reports, last fixes, cleanup --- pkg/R/F_Neighbors.R | 22 +---- pkg/R/plot.R | 89 ++++++++++--------- reports/Experiments.gj | 196 ++++++++++++++++++++--------------------- 3 files changed, 146 insertions(+), 161 deletions(-) diff --git a/pkg/R/F_Neighbors.R b/pkg/R/F_Neighbors.R index 9d1e3fb..17fdd58 100644 --- a/pkg/R/F_Neighbors.R +++ b/pkg/R/F_Neighbors.R @@ -128,8 +128,6 @@ NeighborsForecaster = R6::R6Class("NeighborsForecaster", # limit=Inf to not censor any day (TODO: finite limit? 60?) tdays = getSimilarDaysIndices(today, data, limit=Inf, same_season=TRUE, days_in=tdays_cut, operational=opera) -# if (length(tdays) <= 1) -# return (NA) # TODO: 10 == magic number tdays = .getConstrainedNeighbs(today, data, tdays, min_neighbs=10) if (length(tdays) == 1) @@ -142,7 +140,7 @@ NeighborsForecaster = R6::R6Class("NeighborsForecaster", } return ( data$getSerie(tdays[1])[predict_from:horizon] ) } - max_neighbs = 10 #TODO: 12 = arbitrary number + max_neighbs = 10 #TODO: 10 or 12 or... ? if (length(tdays) > max_neighbs) { distances2 <- .computeDistsEndo(data, today, tdays, predict_from) @@ -226,11 +224,7 @@ NeighborsForecaster = R6::R6Class("NeighborsForecaster", .getConstrainedNeighbs = function(today, data, tdays, min_neighbs=10) { levelToday = data$getLevelHat(today) -# levelYersteday = data$getLevel(today-1) - distances = sapply(tdays, function(i) { -# sqrt((data$getLevel(i-1)-levelYersteday)^2 + (data$getLevel(i)-levelToday)^2) - abs(data$getLevel(i)-levelToday) - }) + distances = sapply( tdays, function(i) abs(data$getLevel(i) - levelToday) ) #TODO: 1, +1, +3 : magic numbers dist_thresh = 1 min_neighbs = min(min_neighbs,length(tdays)) @@ -242,14 +236,7 @@ NeighborsForecaster = R6::R6Class("NeighborsForecaster", break dist_thresh = dist_thresh + ifelse(dist_thresh>1,3,1) } - tdays = tdays[same_pollution] -# max_neighbs = 12 -# if (nb_neighbs > max_neighbs) -# { -# # Keep only max_neighbs closest neighbors -# tdays = tdays[ order(distances[same_pollution])[1:max_neighbs] ] -# } - tdays + tdays[same_pollution] } # compute similarities @@ -277,8 +264,7 @@ NeighborsForecaster = R6::R6Class("NeighborsForecaster", sapply(tdays, function(i) { delta = lastSerie - c(data$getSerie(i-1), data$getSerie(i)[if (predict_from>=2) 1:(predict_from-1) else c()]) -# sqrt(mean(delta^2)) - sqrt(sum(delta^2)) + sqrt(mean(delta^2)) }) } diff --git a/pkg/R/plot.R b/pkg/R/plot.R index 2488d81..8675c62 100644 --- a/pkg/R/plot.R +++ b/pkg/R/plot.R @@ -30,40 +30,24 @@ plotError <- function(err, cols=seq_along(err)) { if (!is.null(err$abs)) err = list(err) - par(mfrow=c(2,2), mar=c(4.7,5,1,1), cex.axis=1.5, cex.lab=1.5, lwd=2) + par(mfrow=c(2,2), mar=c(4.7,5,1,1), cex.axis=1.5, cex.lab=1.5, lty=1) L = length(err) + yrange = range( sapply(1:L, function(i) ( err[[i]]$abs$day ) ), na.rm=TRUE ) - for (i in seq_len(L)) - { - plot(err[[i]]$abs$day, type="l", xlab=ifelse(i==1,"Time (hours)",""), - ylab=ifelse(i==1,"Mean |y - y_hat|",""), ylim=yrange, col=cols[i]) - if (i < L) - par(new=TRUE) - } + matplot( sapply( seq_len(L), function(i) err[[i]]$abs$day ), type="l", + xlab="Time (hours)", ylab="Mean |y - y_hat|", ylim=yrange, col=cols, lwd=2 ) + yrange = range( sapply(1:L, function(i) ( err[[i]]$abs$indices ) ), na.rm=TRUE ) - for (i in seq_len(L)) - { - plot(err[[i]]$abs$indices, type="l", xlab=ifelse(i==1,"Time (days)",""), - ylab=ifelse(i==1,"Mean |y - y_hat|",""), ylim=yrange, col=cols[i]) - if (i < L) - par(new=TRUE) - } + matplot( sapply( seq_len(L), function(i) err[[i]]$abs$indices ), type="l", + xlab="Time (days)", ylab="Mean |y - y_hat|", ylim=yrange, col=cols, lwd=2 ) + yrange = range( sapply(1:L, function(i) ( err[[i]]$MAPE$day ) ), na.rm=TRUE ) - for (i in seq_len(L)) - { - plot(err[[i]]$MAPE$day, type="l", xlab=ifelse(i==1,"Time (hours)",""), - ylab=ifelse(i==1,"Mean MAPE",""), ylim=yrange, col=cols[i]) - if (i < L) - par(new=TRUE) - } + matplot( sapply( seq_len(L), function(i) err[[i]]$MAPE$day ), type="l", + xlab="Time (hours)", ylab="Mean MAPE", ylim=yrange, col=cols, lwd=2 ) + yrange = range( sapply(1:L, function(i) ( err[[i]]$MAPE$indices ) ), na.rm=TRUE ) - for (i in seq_len(L)) - { - plot(err[[i]]$MAPE$indices, type="l", xlab=ifelse(i==1,"Time (days)",""), - ylab=ifelse(i==1,"Mean MAPE",""), ylim=yrange, col=cols[i]) - if (i < L) - par(new=TRUE) - } + matplot( sapply( seq_len(L), function(i) err[[i]]$MAPE$indices ), type="l", + xlab="Time (days)", ylab="Mean MAPE", ylim=yrange, col=cols, lwd=2 ) } #' Plot measured / predicted @@ -77,7 +61,13 @@ plotError <- function(err, cols=seq_along(err)) plotPredReal <- function(data, pred, index) { prediction = pred$getForecast(index) - measure = data$getSerie( pred$getIndexInData(index) )[1:length(prediction)] + measure = data$getSerie( pred$getIndexInData(index) )[1:length(pred$getForecast(1))] + + # Remove the common part, where prediction == measure + dot_mark <- ifelse(prediction[1]==measure[1], which.max(prediction==measure), 0) + prediction = prediction[(dot_mark+1):length(prediction)] + measure = measure[(dot_mark+1):length(measure)] + yrange = range(measure, prediction) par(mar=c(4.7,5,1,1), cex.axis=1.5, cex.lab=1.5, lwd=3) plot(measure, type="l", ylim=yrange, xlab="Time (hours)", ylab="PM10") @@ -98,8 +88,11 @@ plotSimils <- function(pred, index) weights = pred$getParams(index)$weights if (is.null(weights)) stop("plotSimils only works on 'Neighbors' forecasts") - par(mar=c(4.7,5,1,1), cex.axis=1.5, cex.lab=1.5) - hist(pred$getParams(index)$weights, nclass=20, main="", xlab="Weight", ylab="Count") + par(mfrow=c(1,2), mar=c(4.7,5,1,1), cex.axis=1.5, cex.lab=1.5) + small_weights = weights[ weights < 1/length(weights) ] + large_weights = weights[ weights >= 1/length(weights) ] + hist(small_weights, nclass=25, main="", xlab="Weight < 1/N", ylab="Count") + hist(large_weights, nclass=25, main="", xlab="Weight >= 1/N", ylab="Count") } #' Functional boxplot @@ -137,7 +130,6 @@ plotFbox <- function(data, indices=seq_len(data$getSize())) #' @param index Index in forecast (integer or date) #' @param limit Number of neighbors to consider #' @param plot Should the result be plotted? -#' @param predict_from First prediction instant #' #' @return A list with #' \itemize{ @@ -147,18 +139,24 @@ plotFbox <- function(data, indices=seq_len(data$getSize())) #' } #' #' @export -computeFilaments <- function(data, pred, index, predict_from, limit=60, plot=TRUE) +computeFilaments <- function(data, pred, index, limit=60, plot=TRUE) { - if (is.null(pred$getParams(index)$weights) || is.na(pred$getParams(index)$weights[1])) + weights <- pred$getParams(index)$weights + if (is.null(weights) || is.na(pred$getParams(index)$weights[1])) stop("computeFilaments requires a serie without NAs") - # Compute colors for each neighbor (from darkest to lightest) - sorted_dists = sort(-log(pred$getParams(index)$weights), index.return=TRUE) - nn = min(limit, length(sorted_dists$x)) - min_dist = min(sorted_dists$x[1:nn]) - max_dist = max(sorted_dists$x[1:nn]) - color_values = floor(19.5*(sorted_dists$x[1:nn]-min_dist)/(max_dist-min_dist)) + 1 - colors = gray.colors(20,0.1,0.9)[color_values] #TODO: 20 == magic number + nn <- min(limit, length(weights)) + sorted_dists = sort(-log(weights), index.return=TRUE) + # Compute colors for each neighbor (from darkest to lightest), if weights differ + if ( any( weights != weights[1] ) ) + { + min_dist = min(sorted_dists$x[1:nn]) + max_dist = max(sorted_dists$x[1:nn]) + color_values = floor(19.5*(sorted_dists$x[1:nn]-min_dist)/(max_dist-min_dist)) + 1 + colors = gray.colors(20,0.1,0.9)[color_values] #TODO: 20 == magic number + } + else + colors <- rep(colors()[17], length(weights)) if (plot) { @@ -179,7 +177,9 @@ computeFilaments <- function(data, pred, index, predict_from, limit=60, plot=TRU } # Also plot ref curve, in red plot(ref_serie, ylim=yrange, type="l", col="#FF0000", xlab="", ylab="") - abline(v=24+predict_from-0.5, lty=2, col=colors()[56], lwd=1) + dot_mark <- 0.5 + which.max( pred$getForecast(1) == + data$getSerie( pred$getIndexInData(1) )[1:length(pred$getForecast(1))] ) + abline(v=24+dot_mark, lty=2, col=colors()[56], lwd=1) } list( @@ -194,6 +194,7 @@ computeFilaments <- function(data, pred, index, predict_from, limit=60, plot=TRU #' #' @inheritParams computeError #' @param fil Output of \code{computeFilaments} +#' @param predict_from First predicted time step #' #' @export plotFilamentsBox = function(data, fil, predict_from) @@ -213,7 +214,7 @@ plotFilamentsBox = function(data, fil, predict_from) usr <- par("usr") yr <- (usr[4] - usr[3]) / 27 par(new=TRUE) - plot(c(data$getSerie(fil$index),data$getSerie(fil$index+1)), type="l", lwd=2, lty=2, + plot(c(data$getSerie(fil$index-1),data$getSerie(fil$index)), type="l", lwd=2, lty=2, ylim=c(usr[3] + yr, usr[4] - yr), xlab="", ylab="") abline(v=24+predict_from-0.5, lty=2, col=colors()[56]) } diff --git a/reports/Experiments.gj b/reports/Experiments.gj index 36ed5c5..55147e9 100644 --- a/reports/Experiments.gj +++ b/reports/Experiments.gj @@ -10,15 +10,15 @@ prédiction = moyenne de tous les mardis passés si le jour courant est un lundi * la persistence, reproduisant le jour courant ou allant chercher le lendemain de la dernière journée "similaire" (même principe que ci-dessus ; argument "same\_day"). -Concernant l'algorithme principal à voisins, trois variantes sont étudiées dans cette +Concernant l'algorithme principal à voisins, deux variantes sont comparées dans cette partie : * avec simtype="mix" et raccordement "Neighbors" dans le cas "non local", i.e. on va chercher des voisins n'importe où du moment qu'ils correspondent au premier élément d'un couple de deux jours consécutifs sans valeurs manquantes. - * avec simtype="endo" puis simtype="none", choisissant dans les deux cas -raccordement==NULL (aucun ajustement après moyenne des courbes) dans le cas "local" : -voisins de même niveau de pollution et même saison. + * avec simtype="none" (moyenne simple) et raccordement=NULL (aucun ajustement après +moyenne des courbes) dans le cas "local" : voisins de même niveau de pollution et même +saison. Pour chaque période retenue $-$ chauffage, épandage, semaine non polluée $-$ les erreurs de prédiction sont d'abord affichées, puis quelques graphes de courbes réalisées/prévues @@ -57,47 +57,44 @@ ${"##"} ${list_titles[i]} p1 = computeForecast(data, ${list_indices[i]}, "Neighbors", "Neighbors", predict_from=P, horizon=H, simtype="mix", local=FALSE) p2 = computeForecast(data, ${list_indices[i]}, "Neighbors", NULL, predict_from=P, - horizon=H, simtype="endo", local=TRUE) -p3 = computeForecast(data, ${list_indices[i]}, "Neighbors", NULL, predict_from=P, horizon=H, simtype="none", local=TRUE) -p4 = computeForecast(data, ${list_indices[i]}, "Average", "Zero", predict_from=P, +p3 = computeForecast(data, ${list_indices[i]}, "Average", "Zero", predict_from=P, horizon=H) -p5 = computeForecast(data, ${list_indices[i]}, "Persistence", "Zero", predict_from=P, +p4 = computeForecast(data, ${list_indices[i]}, "Persistence", "Zero", predict_from=P, horizon=H, same_day=${'TRUE' if loop.index < 2 else 'FALSE'}) -----r e1 = computeError(data, p1, P, H) e2 = computeError(data, p2, P, H) e3 = computeError(data, p3, P, H) e4 = computeError(data, p4, P, H) -e5 = computeError(data, p5, P, H) options(repr.plot.width=9, repr.plot.height=7) -plotError(list(e1, e5, e4, e2, e3), cols=c(1,2,colors()[258],4,6)) +plotError(list(e1, e4, e3, e2), cols=c(1,2,colors()[258],4)) -# noir: Neighbors non-local (p1), bleu: Neighbors local endo (p2), -# mauve: Neighbors local none (p3), vert: moyenne (p4), -# rouge: persistence (p5) +# noir: Neighbors non-local (p1), bleu: Neighbors local (p2), +# vert: moyenne (p3), rouge: persistence (p4) sum_p23 = e2$abs$indices + e3$abs$indices -i_np = which.min(sum_p23) #indice de (veille de) jour "facile" -i_p = which.max(sum_p23) #indice de (veille de) jour "difficile" +i_np = which.min(sum_p23) #indice de jour "facile" +i_p = which.max(sum_p23) #indice de jour "difficile" ----- % if i == 0: -L'erreur absolue deÌpasse 20 sur 1 aÌ 2 jours suivant les modeÌles (graphe en haut aÌ -droite). Sur cet exemple le modeÌle aÌ voisins "contraint" (local=TRUE) utilisant des -pondeÌrations baseÌes sur les similariteÌs de forme (simtype="endo") obtient en moyenne les -meilleurs reÌsultats, avec un MAPE restant en geÌneÌral infeÌrieur aÌ 30% de 8h aÌ 19h (7+1 aÌ -7+12 : graphe en bas aÌ gauche). +L'erreur absolue -- en haut à gauche -- reste modérée pour les meilleurs modèles +(variantes à voisins), ne dépassant 10 que deux jours. Les deux modèles naïfs ont des +erreurs similaires sauf sur la période "difficile" (jours 4 à 6), sur laquelle on gagne +donc à chercher des jours similaires pour effectuer la prévision. +Le MAPE reste en geÌneÌral infeÌrieur aÌ 35% pour les meilleurs méthodes. % elif i == 1: -Il est difficile dans ce cas de deÌterminer une meÌthode meilleure que les autres : elles -donnent toutes de plutoÌt mauvais reÌsultats, avec une erreur absolue moyenneÌe sur la -journeÌe deÌpassant presque toujours 15 (graphe en haut aÌ droite). +Le modèle à voisins avec contrainte de localité obtient ici les meilleurs résultats, son +erreur étant clairement en dessous des autres à partir du jour 4 (graphe en haut à +droite). Le MAPE jour après jour est du même ordre que précédemment pour cette méthode +(35%, graphe en bas à droite) sauf un jour sur lequel le MAPE explose. % else: Dans ce cas plus favorable les intensiteÌ des erreurs absolues ont clairement diminueÌ : -elles restent souvent en dessous de 5. En revanche le MAPE moyen reste au-delaÌ de 20%, et -meÌme souvent plus de 30%. Comme dans le cas de l'eÌpandage on constate une croissance -globale de la courbe journalieÌre d'erreur absolue moyenne (en haut aÌ gauche) ; ceci peut -eÌtre duÌ au fait que l'on ajuste le niveau du jour aÌ preÌdire en le recollant sur la -dernieÌre valeur observeÌe. +elles sont souvent en dessous de 5. En revanche le MAPE moyen reste en général au-delaÌ de +20%. Comme dans le cas de l'eÌpandage on constate une croissance globale de la courbe +journalieÌre d'erreur absolue moyenne (en haut aÌ gauche) -- sauf pour la méthode à voisins +"locale" ; ceci peut eÌtre duÌ au fait que l'on ajuste le niveau du jour aÌ preÌdire en le +recollant sur la dernieÌre valeur observeÌe (sauf pour "Neighbors local"). % endif -----r options(repr.plot.width=9, repr.plot.height=4) @@ -109,40 +106,41 @@ plotPredReal(data, p1, i_p); title(paste("PredReal p1 day",i_p)) plotPredReal(data, p2, i_np); title(paste("PredReal p2 day",i_np)) plotPredReal(data, p2, i_p); title(paste("PredReal p2 day",i_p)) -plotPredReal(data, p3, i_np); title(paste("PredReal p3 day",i_np)) -plotPredReal(data, p3, i_p); title(paste("PredReal p3 day",i_p)) - -# Bleu : prévue ; noir : réalisée +# Bleu : prévue ; noir : réalisée (confondues jusqu'à predict_from-1) ----- % if i == 0: Le jour "facile aÌ preÌvoir", aÌ gauche, se deÌcompose en deux modes : un leÌger vers 10h (7+3), puis un beaucoup plus marqueÌ vers 19h (7+12). Ces deux modes sont retrouveÌs par -les trois variantes de l'algorithme aÌ voisins, bien que l'amplitude soit mal preÌdite. +les deux variantes de l'algorithme aÌ voisins, bien que l'amplitude soit mal preÌdite. Concernant le jour "difficile aÌ preÌvoir" (à droite) il y a deux pics en tout deÌbut et toute fin de journeÌe (aÌ 9h et 23h), qui ne sont pas du tout anticipeÌs par les méthodes ; la grande amplitude de ces pics explique alors l'intensiteÌ de l'erreur observeÌe. % elif i == 1: -Dans le cas d'un jour "facile" aÌ preÌdire $-$ aÌ gauche $-$ la forme est plus ou moins -retrouveÌe, mais le niveau moyen est trop bas (courbe en bleu). Concernant le jour -"difficile" aÌ droite, non seulement la forme n'est pas anticipeÌe mais surtout le niveau -preÌdit est treÌs infeÌrieur au niveau de pollution observeÌ. Comme on le voit ci-dessous -cela deÌcoule d'un manque de voisins au comportement similaire. +Dans le cas d'un jour "facile" aÌ preÌdire $-$ aÌ gauche $-$ la forme est plutôt bien +retrouveÌe, ainsi que le niveau moyen pour la méthode sans contrainte de localité +(dans l'autre, l'algorithme a probablement écarté trop de voisins potentiels). +Concernant le jour "difficile" aÌ droite, non seulement la forme n'est pas anticipeÌe mais +surtout le niveau preÌdit est largement supérieur au niveau de pollution observeÌ -- dans +une moindre mesure toutefois pour la variante "locale". % else: -La forme est raisonnablement retrouveÌe pour les meÌthodes "locales", l'autre version -lissant trop les preÌdictions. Le biais reste cependant important, surtout en fin de -journeÌe sur la courbes "difficile à prévoir". +L'impression visuelle est plutôt mauvaise dans ce cas, mais les écart étant minimes les +erreurs au final ne sont pas très importantes. De plus deux des quatres graphes sont +satisfaisants (en haut à droite et en bas à gauche : forme + niveau acceptables. % endif -----r par(mfrow=c(1,2)) -f_np1 = computeFilaments(data, p1, i_np, predict_from=P, plot=TRUE) - title(paste("Filaments p1 day",i_np)) -f_p1 = computeFilaments(data, p1, i_p, predict_from=P, plot=TRUE) - title(paste("Filaments p1 day",i_p)) - -f_np2 = computeFilaments(data, p2, i_np, predict_from=P, plot=TRUE) - title(paste("Filaments p2 day",i_np)) -f_p2 = computeFilaments(data, p2, i_p, predict_from=P, plot=TRUE) - title(paste("Filaments p2 day",i_p)) + +f_np1 = computeFilaments(data, p1, i_np, plot=TRUE) +title(paste("Filaments p1 day",i_np)) + +f_p1 = computeFilaments(data, p1, i_p, plot=TRUE) +title(paste("Filaments p1 day",i_p)) + +f_np2 = computeFilaments(data, p2, i_np, plot=TRUE) +title(paste("Filaments p2 day",i_np)) + +f_p2 = computeFilaments(data, p2, i_p, plot=TRUE) +title(paste("Filaments p2 day",i_p)) ----- % if i == 0: Les voisins du jour courant (peÌriode de 24h allant de 8h aÌ 7h le lendemain) sont afficheÌs @@ -153,7 +151,7 @@ peÌriode de 24h et la forme sur les 24h suivantes ; **cette observation est la difficulteÌs rencontreÌes par l'algorithme sur ce jeu de donneÌes.** % elif i == 1: Les observations sont les meÌmes qu'au paragraphe preÌceÌdent : trop de variabiliteÌ des -lendemains (et meÌme des voisins du jour courant). +voisins (et ce meÌme le jour précédent). % else: Les graphes de filaments ont encore la meÌme allure, avec une assez grande variabiliteÌ observeÌe. Cette observation est cependant trompeuse, comme l'indique plus bas le graphe @@ -161,10 +159,14 @@ de variabiliteÌ relative. % endif -----r par(mfrow=c(1,2)) -plotFilamentsBox(data, f_np1, predict_from=P); title(paste("FilBox p1 day",i_np)) -plotFilamentsBox(data, f_p1, predict_from=P); title(paste("FilBox p1 day",i_p)) -# En pointilleÌs la courbe du jour courant + lendemain (aÌ preÌdire) +plotFilamentsBox(data, f_np1, predict_from=P) +title(paste("FilBox p1 day",i_np)) + +plotFilamentsBox(data, f_p1, predict_from=P) +title(paste("FilBox p1 day",i_p)) + +# En pointilleÌs la courbe du jour courant (aÌ preÌdire) + précédent ----- % if i == 0: Sur cette boxplot fonctionnelle (voir la fonction fboxplot() du package R "rainbow") on @@ -174,82 +176,78 @@ rouge aÌ gauche) ; et, dans le cas d'une courbe aÌ preÌdire atypique (aÌ dro des voisins sont trop eÌloigneÌs de la forme aÌ preÌdire et forcent ainsi un aplatissement de la preÌdiction. % elif i == 1: -On constate la preÌsence d'un voisin au lendemain compleÌtement atypique avec un pic en -deÌbut de journeÌe (courbe en vert aÌ gauche), et d'un autre pheÌnomeÌne semblable avec la -courbe rouge sur le graphe de droite. AjouteÌ au fait que le lendemain aÌ preÌvoir est -lui-meÌme un jour "hors norme", cela montre l'impossibiliteÌ de bien preÌvoir une courbe en -utilisant l'algorithme aÌ voisins. +Concernant le jour "difficile" on constate la preÌsence de voisins au lendemains +compleÌtement atypiques avec un pic en deÌbut de journeÌe (courbes en vert et rouge à +droite). AjouteÌ au fait que le jour aÌ preÌvoir est lui-meÌme "hors norme", cela montre +l'impossibiliteÌ de bien preÌvoir une courbe en utilisant l'algorithme aÌ voisins. % else: On peut reÌappliquer les meÌmes remarques qu'auparavant sur les boxplots fonctionnels : -lendemains de voisins atypiques, courbe aÌ preÌvoir elle-meÌme leÌgeÌrement "hors norme". +voisins atypiques, courbe aÌ preÌvoir elle-meÌme leÌgeÌrement "hors norme". % endif -----r par(mfrow=c(1,2)) -plotRelVar(data, f_np1, predict_from=P); title(paste("StdDev p1 day",i_np)) -plotRelVar(data, f_p1, predict_from=P); title(paste("StdDev p1 day",i_p)) -plotRelVar(data, f_np2, predict_from=P); title(paste("StdDev p2 day",i_np)) -plotRelVar(data, f_p2, predict_from=P); title(paste("StdDev p2 day",i_p)) +plotRelVar(data, f_np1, predict_from=P) +title(paste("StdDev p1 day",i_np)) -# Variabilité globale en rouge ; sur les voisins (+ lendemains) en noir +plotRelVar(data, f_p1, predict_from=P) +title(paste("StdDev p1 day",i_p)) + +plotRelVar(data, f_np2, predict_from=P) +title(paste("StdDev p2 day",i_np)) + +plotRelVar(data, f_p2, predict_from=P) +title(paste("StdDev p2 day",i_p)) + +# Variabilité globale en rouge ; sur les voisins en noir ----- % if i == 0: Ces graphes viennent confirmer l'impression visuelle apreÌs observation des filaments. En effet, la variabiliteÌ globale en rouge (eÌcart-type heure par heure sur l'ensemble des -couples "aujourd'hui/lendemain"du passeÌ) devrait rester nettement au-dessus de la +couples "hier/aujourd'hui" du passeÌ) devrait rester nettement au-dessus de la variabiliteÌ locale, calculeÌe respectivement sur un voisinage d'une soixantaine de jours -(pour p1) et d'une dizaine de jours (pour p2). Or on constate que ce n'est pas du tout le -cas sur la peÌriode "lendemain", sauf en partie pour p2 le jour 4 $-$ mais ce n'est pas -suffisant. +(pour p1) et d'une dizaine de jours (pour p2). Or ce n'est pas du tout le cas sur la +moitié droite, sauf pour le jour "facile" avec l'algorithme "local". % elif i == 1: -Comme preÌceÌdemment les variabiliteÌs locales et globales sont confondues dans les parties -droites des graphes $-$ sauf pour la version "locale" sur le jour "facile"; mais cette -bonne proprieÌteÌ n'est pas suffisante si l'on ne trouve pas les bons poids aÌ appliquer. +Comme preÌceÌdemment les variabiliteÌs locales et globales sont trop proches dans les +parties droites des graphes pour le jour "difficile". L'allure des graphes est +raisonnable ppour l'autre jour, qui est d'ailleurs bien prédit. % else: Cette fois la situation ideÌale est observeÌe : la variabiliteÌ globale est nettement au-dessus de la variabiliteÌ locale. Bien que cela ne suffise pas aÌ obtenir de bonnes preÌdictions de forme, on constate au moins l'ameÌlioration dans la preÌdiction du niveau. % endif -----r -par(mfrow=c(1,2)) -plotSimils(p1, i_np); title(paste("Weights p1 day",i_np)) -plotSimils(p1, i_p); title(paste("Weights p1 day",i_p)) +plotSimils(p1, i_np) +title(paste("Weights p1 day",i_np)) -plotSimils(p2, i_np); title(paste("Weights p2 day",i_np)) -plotSimils(p2, i_p); title(paste("Weights p2 day",i_p)) +plotSimils(p1, i_p) +title(paste("Weights p1 day",i_p)) + +# Poids < 1/N à gauche, >= 1/N à droite ; jour facile en haut, difficile en bas ----- % if i == 0: -Les poids se concentrent preÌs de 0 dans le cas "non local" (p1), et se reÌpartissent assez -uniformeÌment dans [ 0, 0.2 ] dans le cas "local" (p2). C'est ce que l'on souhaite -observer pour eÌviter d'effectuer une simple moyenne. +Les poids se concentrent preÌs de 0 : c'est ce que l'on souhaite observer pour eÌviter +d'effectuer une simple moyenne. % elif i == 1: -En comparaison avec le pragraphe preÌceÌdent on retrouve le meÌme (bon) comportement des -poids pour la version "non locale". En revanche la feneÌtre optimiseÌe est trop grande sur -le jour "facile" pour la meÌthode "locale" (voir affichage ci-dessous) : il en reÌsulte des -poids tous semblables autour de 0.084, l'algorithme effectue donc une moyenne simple $-$ -expliquant pourquoi les courbes mauve et bleue sont treÌs proches sur le graphe d'erreurs. +En comparaison avec le paragraphe preÌceÌdent on retrouve le meÌme (bon) comportement des +poids pour la version "non locale". % else: -Concernant les poids en revanche, deux cas a priori mauvais se cumulent : - - * les poids dans le cas "non local" ne sont pas assez concentreÌs autour de 0, menant aÌ -un lissage trop fort $-$ comme observeÌ sur les graphes des courbes reÌaliseÌes/preÌvues ; - * les poids dans le cas "local" sont trop semblables (aÌ cause de la trop grande feneÌtre -optimiseÌe par validation croiseÌe, cf. ci-dessous), reÌsultant encore en une moyenne simple -$-$ mais sur moins de jours, plus proches du jour courant. +Concernant les poids en revanche, deux cas a priori mauvais se cumulent : ... % endif -----r -# Fenêtres sélectionnées dans ]0,7] : -# "non-local" 2 premières lignes, "local" ensuite +options(digits=2) + p1$getParams(i_np)$window p1$getParams(i_p)$window -p2$getParams(i_np)$window -p2$getParams(i_p)$window +# Fenêtres sélectionnées dans ]0,7] % endfor ----- ${"##"} Bilan -Nos algorithmes aÌ voisins ne sont pas adapteÌs aÌ ce jeu de donneÌes ouÌ la forme varie -consideÌrablement d'un jour aÌ l'autre. Toutefois, un espoir reste permis par exemple en -aggreÌgeant les courbes spatialement (sur plusieurs stations situeÌes dans la meÌme +Nos algorithmes aÌ voisins donnent de meilleurs résultats que les approches naïves +(persistence, moyenne sur tout le jeu de données). Les erreurs restent cependant assez +élevées, notamment en terme de MAPE. Une possible poste d'amélioration consisterait à +aggreÌger les courbes spatialement (sur plusieurs stations situeÌes dans la meÌme agglomeÌration ou dans une meÌme zone). -- 2.44.0