'update'
[talweg.git] / reports / Experiments.gj
... / ...
CommitLineData
1-----
2# Résultats numériques
3
4% if P == 8:
5Cette partie montre les résultats obtenus avec des variantes de l'algorithme décrit à la
6section 4, en utilisant le package présenté au chapitre précédent. Cet algorithme est
7systématiquement comparé à deux approches naïves :
8
9 * la moyenne des lendemains des jours "similaires" dans tout le passé, c'est-à-dire
10prédiction = moyenne de tous les mardis passés si le jour courant est un lundi.
11 * la persistence, reproduisant le jour courant ou allant chercher le lendemain de la
12dernière journée "similaire" (même principe que ci-dessus ; argument "same\_day").
13
14Concernant l'algorithme principal à voisins, deux variantes sont comparées dans cette
15partie :
16
17 * avec simtype="mix" et raccordement "Neighbors" dans le cas "non local", i.e. on va
18chercher des voisins n'importe où du moment qu'ils correspondent au premier élément d'un
19couple de deux jours consécutifs sans valeurs manquantes.
20 * avec simtype="none" (moyenne simple) et raccordement=NULL (aucun ajustement après
21moyenne des courbes) dans le cas "local" : voisins de même niveau de pollution et même
22saison.
23
24Pour chaque période retenue $-$ chauffage, épandage, semaine non polluée $-$ les erreurs
25de prédiction sont d'abord affichées, puis quelques graphes de courbes réalisées/prévues
26(sur le jour "en moyenne le plus facile" à gauche, et "en moyenne le plus difficile" à
27droite). Ensuite plusieurs types de graphes apportant des précisions sur la nature et la
28difficulté du problème viennent compléter ces premières courbes. Concernant les graphes
29de filaments, la moitié droite du graphe correspond aux jours similaires au jour courant,
30tandis que la moitié gauche affiche les jours précédents : ce sont donc les voisinages
31tels qu'utilisés dans l'algorithme.
32% endif
33<%
34list_titles = ['Pollution par chauffage','Pollution par épandage','Semaine non polluée']
35list_indices = ['indices_ch', 'indices_ep', 'indices_np']
36%>
37-----r
38library(talweg)
39
40P = ${P} #première heure de prévision
41H = ${H} #dernière heure de prévision
42
43ts_data = read.csv(system.file("extdata","pm10_mesures_H_loc_report.csv",
44 package="talweg"))
45exo_data = read.csv(system.file("extdata","meteo_extra_noNAs.csv",
46 package="talweg"))
47data = getData(ts_data, exo_data)
48
49indices_ch = seq(as.Date("2015-01-19"),as.Date("2015-01-25"),"days")
50indices_ep = seq(as.Date("2015-03-16"),as.Date("2015-03-22"),"days")
51indices_np = seq(as.Date("2015-04-27"),as.Date("2015-05-03"),"days")
52% for i in range(3):
53-----
54##<h2 style="color:blue;font-size:2em">${list_titles[i]}</h2>
55${"##"} ${list_titles[i]}
56-----r
57p1 = computeForecast(data, ${list_indices[i]}, "Neighbors", "Neighbors",
58 predict_from=P, horizon=H, simtype="mix", local=FALSE)
59p2 = computeForecast(data, ${list_indices[i]}, "Neighbors", NULL,
60 predict_from=P, horizon=H, simtype="none", local=TRUE)
61p3 = computeForecast(data, ${list_indices[i]}, "Average", "Zero",
62 predict_from=P, horizon=H)
63p4 = computeForecast(data, ${list_indices[i]}, "Persistence", "Zero",
64 predict_from=P, horizon=H, same_day=${'TRUE' if loop.index < 2 else 'FALSE'})
65-----r
66e1 = computeError(data, p1, P, H)
67e2 = computeError(data, p2, P, H)
68e3 = computeError(data, p3, P, H)
69e4 = computeError(data, p4, P, H)
70options(repr.plot.width=9, repr.plot.height=7)
71plotError(list(e1, e4, e3, e2), cols=c(1,2,colors()[258],4))
72
73# noir: Neighbors non-local (p1), bleu: Neighbors local (p2),
74# vert: moyenne (p3), rouge: persistence (p4)
75
76sum_p23 = e2$abs$indices + e3$abs$indices
77i_np = which.min(sum_p23) #indice de jour "facile"
78i_p = which.max(sum_p23) #indice de jour "difficile"
79% if P == 8:
80-----
81% if i == 0:
82L'erreur absolue $-$ en haut à droite $-$ reste modérée pour les meilleurs modèles
83(variantes à voisins), ne dépassant 10 que deux jours. Les deux modèles naïfs ont des
84erreurs similaires sauf sur la période "difficile" (jours 4 à 6), sur laquelle on gagne
85donc à chercher des jours semblables pour effectuer la prévision.
86Le MAPE reste en général inférieur à 35% pour les meilleurs méthodes.
87% elif i == 1:
88Le modèle à voisins avec contrainte de localité obtient ici les meilleurs résultats, son
89erreur étant clairement en dessous des autres à partir du jour 4 (graphe en haut à
90droite). Le MAPE jour après jour est du même ordre que précédemment pour cette méthode
91(35%, graphe en bas à droite) sauf un jour sur lequel le MAPE explose.
92% else:
93Dans ce cas plus favorable les intensité des erreurs absolues ont clairement diminué :
94elles sont souvent en dessous de 5. En revanche le MAPE moyen reste en général au-delà de
9520%. Comme dans le cas de l'épandage on constate une croissance globale de la courbe
96journalière d'erreur absolue moyenne (en haut à gauche) $-$ sauf pour la méthode à
97voisins "locale" ; ceci peut être dû au fait que l'on ajuste le niveau du jour à prédire
98en le recollant sur la dernière valeur observée (sauf pour "Neighbors local").
99% endif
100% endif
101-----r
102options(repr.plot.width=9, repr.plot.height=4)
103par(mfrow=c(1,2))
104
105plotPredReal(data, p1, i_np); title(paste("PredReal p1 day",i_np))
106plotPredReal(data, p1, i_p); title(paste("PredReal p1 day",i_p))
107
108plotPredReal(data, p2, i_np); title(paste("PredReal p2 day",i_np))
109plotPredReal(data, p2, i_p); title(paste("PredReal p2 day",i_p))
110
111# Bleu : prévue ; noir : réalisée (confondues jusqu'à predict_from-1)
112% if P == 8:
113-----
114% if i == 0:
115La courbe du jour "facile à prévoir", à gauche, se décompose en deux modes : un léger
116vers 10h (7+3), puis un beaucoup plus marqué vers 19h (7+12). Ces deux modes sont
117retrouvés par les trois variantes de l'algorithme à voisins, bien que l'amplitude soit
118mal prédite. Concernant le jour "difficile à prévoir" (à droite) il y a deux pics en tout
119début et toute fin de journée (à 9h et 23h), qui ne sont pas du tout anticipés par les
120méthodes ; la grande amplitude de ces pics explique alors l'intensité de l'erreur
121observée.
122% elif i == 1:
123Dans le cas d'un jour "facile" à prédire $-$ à gauche $-$ la forme est plutôt bien
124retrouvée, ainsi que le niveau moyen pour la méthode sans contrainte de localité
125(dans l'autre, l'algorithme a probablement écarté trop de voisins potentiels).
126Concernant le jour "difficile" à droite, non seulement la forme n'est pas anticipée mais
127surtout le niveau prédit est largement supérieur au niveau de pollution observé $-$ dans
128une moindre mesure toutefois pour la variante "locale".
129% else:
130L'impression visuelle est plutôt mauvaise dans ce cas, mais les écart étant minimes les
131erreurs au final ne sont pas très importantes. De plus deux des quatres graphes sont
132satisfaisants (en haut à droite et en bas à gauche : forme + niveau acceptables.
133% endif
134% endif
135-----r
136par(mfrow=c(1,2))
137
138f_np1 = computeFilaments(data, p1, i_np, plot=TRUE)
139title(paste("Filaments p1 day",i_np))
140
141f_p1 = computeFilaments(data, p1, i_p, plot=TRUE)
142title(paste("Filaments p1 day",i_p))
143
144f_np2 = computeFilaments(data, p2, i_np, plot=TRUE)
145title(paste("Filaments p2 day",i_np))
146
147f_p2 = computeFilaments(data, p2, i_p, plot=TRUE)
148title(paste("Filaments p2 day",i_p))
149% if P == 8:
150-----
151% if i == 0:
152Les voisins du jour courant (période de 24h allant de 8h à 7h le lendemain) sont affichés
153avec un trait d'autant plus sombre qu'ils sont proches. On constate dans le cas non
154contraint (en haut) une grande variabilité des lendemains, très nette sur le graphe en
155haut à droite. Ceci indique une faible corrélation entre la forme d'une courbe sur une
156période de 24h et la forme sur les 24h suivantes ; **cette observation est la source des
157difficultés rencontrées par l'algorithme sur ce jeu de données.**
158% elif i == 1:
159Les observations sont les mêmes qu'au paragraphe précédent : trop de variabilité des
160voisins (et ce même le jour précédent).
161% else:
162Les graphes de filaments ont encore la même allure, avec une assez grande variabilité
163observée. Cette observation est cependant trompeuse, comme l'indique plus bas le graphe
164de variabilité relative.
165% endif
166% endif
167-----r
168par(mfrow=c(1,2))
169
170plotFilamentsBox(data, f_np1, predict_from=P)
171title(paste("FilBox p1 day",i_np))
172
173plotFilamentsBox(data, f_p1, predict_from=P)
174title(paste("FilBox p1 day",i_p))
175
176# En pointillés la courbe du jour courant (à prédire) + précédent
177% if P == 8:
178-----
179% if i == 0:
180Sur cette boxplot fonctionnelle (voir la fonction fboxplot() du package R "rainbow") on
181constate essentiellement deux choses : le lendemain d'un voisin "normal" peut se révéler
182être une courbe atypique, fort éloignée de ce que l'on souhaite prédire (courbes bleue et
183rouge à gauche) ; et, dans le cas d'une courbe à prédire atypique (à droite) la plupart
184des voisins sont trop éloignés de la forme à prédire et forcent ainsi un aplatissement de
185la prédiction.
186% elif i == 1:
187Concernant le jour "difficile" on constate la présence de voisins au lendemains
188complètement atypiques avec un pic en début de journée (courbes en vert et rouge à
189droite). Ajouté au fait que le jour à prévoir est lui-même "hors norme", cela montre
190l'impossibilité de bien prévoir une courbe en utilisant l'algorithme à voisins.
191% else:
192On peut réappliquer les mêmes remarques qu'auparavant sur les boxplots fonctionnels :
193voisins atypiques, courbe à prévoir elle-même légèrement "hors norme".
194% endif
195% endif
196-----r
197par(mfrow=c(1,2))
198
199plotRelVar(data, f_np1, predict_from=P)
200title(paste("StdDev p1 day",i_np))
201
202plotRelVar(data, f_p1, predict_from=P)
203title(paste("StdDev p1 day",i_p))
204
205plotRelVar(data, f_np2, predict_from=P)
206title(paste("StdDev p2 day",i_np))
207
208plotRelVar(data, f_p2, predict_from=P)
209title(paste("StdDev p2 day",i_p))
210
211# Variabilité globale en rouge ; sur les voisins en noir
212% if P == 8:
213-----
214% if i == 0:
215Ces graphes viennent confirmer l'impression visuelle après observation des filaments. En
216effet, la variabilité globale en rouge (écart-type heure par heure sur l'ensemble des
217couples "hier/aujourd'hui" du passé) devrait rester nettement au-dessus de la
218variabilité locale, calculée respectivement sur un voisinage d'une soixantaine de jours
219(pour p1) et d'une dizaine de jours (pour p2). Or ce n'est pas du tout le cas sur la
220moitié droite, sauf pour le jour "facile" avec l'algorithme "local".
221% elif i == 1:
222Comme précédemment les variabilités locales et globales sont trop proches dans les
223parties droites des graphes pour le jour "difficile". L'allure des graphes est
224raisonnable ppour l'autre jour, qui est d'ailleurs bien prédit.
225% else:
226Cette fois la situation idéale est observée : la variabilité globale est nettement
227au-dessus de la variabilité locale. Bien que cela ne suffise pas à obtenir de bonnes
228prédictions de forme, on constate au moins l'amélioration dans la prédiction du niveau.
229% endif
230% endif
231-----r
232plotSimils(p1, i_np)
233title(paste("Weights p1 day",i_np))
234
235plotSimils(p1, i_p)
236title(paste("Weights p1 day",i_p))
237
238# Poids < 1/N à gauche, >= 1/N à droite ; jour facile en haut, difficile en bas
239% if P == 8:
240-----
241% if i == 0:
242Les poids se concentrent près de 0 : c'est ce que l'on souhaite observer pour éviter
243d'effectuer une simple moyenne.
244% elif i == 1:
245On retrouve le même (bon) comportement des poids : concentration vers 0, quelques poids
246non négligeables (presque trop peu pour le jour "difficile").
247% else:
248Les poids sont répartis comme souhaité : concentrés vers 0 avec quelques valeurs non
249négligeables.
250% endif
251% endif
252-----r
253options(digits=2)
254
255print(p1$getParams(i_np)$window)
256print(p1$getParams(i_p)$window)
257
258# Fenêtres sélectionnées dans ]0,7]
259% endfor
260% if P == 8:
261-----
262${"##"} Bilan
263
264Nos algorithmes à voisins donnent de meilleurs résultats que les approches naïves
265(persistence, moyenne sur tout le jeu de données). Les erreurs restent cependant assez
266élevées, notamment en terme de MAPE. Une possible poste d'amélioration consisterait à
267aggréger les courbes spatialement (sur plusieurs stations situées dans la même
268agglomération ou dans une même zone).
269% endif