fix mistake in report
[talweg.git] / reports / report_2017-01-13.rnw
1 \documentclass[a4paper,12pt]{article}
2 \usepackage[utf8]{inputenc}
3 \usepackage[T1]{fontenc}
4
5 \renewcommand*\familydefault{\sfdefault}
6
7 \marginparwidth 0pt
8 \oddsidemargin 0pt
9 \evensidemargin 0pt
10 \marginparsep 0pt
11 \topmargin 0pt
12 \textwidth 16cm
13 \textheight 23cm
14 \parindent 5mm
15
16 \begin{document}
17
18 \section{Package R "ppmfun"}
19
20 Le package $-$ Predict PM10 with FUNctional methods $-$ contient le code permettant de (re)lancer
21 les expériences numériques décrites dans ce document. La fonction principale \emph{predictPM10}
22 se divise en trois parties, décrites successivement au cours des trois paragraphes suivants.\\
23
24 <<setup, out.width='7cm', out.height='7cm'>>=
25 #Chargement de la librairie (après compilation, "R CMD INSTALL ppmfun/")
26 library(ppmfun)
27
28 #Exemple d'appel principal (détaillé ci-après)
29 p_mix = predictPM10("GMT", "7h", 400, 30, "Neighbors", NULL, 0, "direct",
30 simtype="mix")
31
32 #Allure des courbes prédites
33 yrange = range(p_mix$forecasts[401:430], na.rm=TRUE)
34 plot(0,xaxt='n',yaxt='n',bty='n',pch='',ylab='Prédictions PM10',
35 xlab='Temps',ylim=yrange,main="Courbes PM10 prédites")
36 for (i in 401:430)
37 {
38 if (!any(is.na(p_mix$forecasts[[i]])))
39 {
40 par(new=TRUE)
41 plot(p_mix$forecasts[[i]], type="l", ylim=yrange, xlab="", ylab="")
42 }
43 }
44 @
45
46 L'appel à \emph{predictPM10()} ci-dessus se traduit par :
47 \begin{enumerate}
48 \item charger les données découpées selon le temps universel, en segments de $24h$ de $7h15$ à
49 $7h$ le lendemain ;
50 \item commencer la prédiction au jour $400$, terminer au jour $400+30-1 = 429$ ;
51 \item utiliser la méthode "Neighbors" qui place plus de poids sur les voisins de la courbe de
52 PM10 du jour courant, en tenant compte de tout l'historique ;
53 \item raccorder continûment la prévision centrée aux mesures sur le dernier bloc de $24h$.
54 \end{enumerate}
55
56 \subsection{Acquisition des données}
57
58 Compte-tenu de la nature hétérogène des données utilisées $-$ fonctionnelles pour les PM10,
59 vectorielles pour les variables exogènes $-$, celles-ci sont organisées sous forme d'une liste
60 \emph{data}, la $i^{eme}$ cellule correspondant aux données disponibles au $i^{eme}$ jour à
61 l'heure $H$ de prédiction choisie (0h15, 7h15 ou 13h15) : c'est-à-dire les valeurs des PM10 de
62 $H-24h$ à $H-15m$, ainsi que les variables météo mesurées du dernier jour complet avant l'heure
63 $H$, et les variables météo prédites pour la période de $0h15$ à $0h$ du jour courant.\\
64
65 Exemple :\\
66 <<data>>=
67 #Le premier argument indique la zone horaire souhaitée ; "GMT" ou "local"
68 #pour l'heure française, ou tout autre fuseau horaire.
69 data = getData("GMT", "7h")
70 @
71
72 \subsection{Prédiction}
73
74 Deux types de prévisions du prochain bloc de $24h$ sont à distinguer :
75 \begin{itemize}
76 \item prévision de la forme (centrée) ;
77 \item prévision du niveau.
78 \end{itemize}
79
80 \noindent Si l'on choisit de raccorder la prévision de la forme au dernier PM10 mesuré, alors le niveau n'a
81 pas à être prédit (d'où l'argument \texttt{NULL} dans l'appel principal). Dans le cas contraire il faut
82 préciser une méthode ; seule la persistance est actuellement implémentée. la méthode de prévision
83 de forme "Neighbors" est détaillée ci-après (voir aussi le fichier S\_Neighbors.R).\\
84
85 \begin{enumerate}
86 \item \textbf{Préparation des données} : calcul des niveaux sur 24h, fenêtrage si demandé
87 (paramètre "memory").
88 \item \textbf{Optimisation des paramètres d'échelle} : via la fonction \emph{optim()}
89 minimisant la somme des 45 dernières erreurs jounalières L2.
90 \item \textbf{Prédiction finale} : une fois le (ou les, si "simtype" vaut "mix") paramètre
91 d'échelle $h$ déterminé, les similarités sont évaluées sur les variables exogènes et/ou
92 endogènes, sous la forme $s(i,j) = \mbox{exp}\left(-\frac{\mbox{dist}^2(i,j)}{h^2}\right)$.
93 La formule indiquée plus haut dans le rapport est alors appliquée.
94 \end{enumerate}
95
96 Exemple :\\
97 <<forecasts>>=
98 forecasts = as.list(rep(NA, length(data)))
99 for (i in 400:429)
100 {
101 #forecast with data up to index i
102 forecasts[[i+1]] = getForecasts(data[1:i], "Neighbors", NULL, 0,
103 "direct", simtype="mix")
104 }
105 @
106
107 \subsection{Calcul des erreurs}
108
109 Pour chacun des instants à prévoir jusqu'à minuit du jour courant, on calcule l'erreur moyenne
110 sur tous les instants similaires du passé (sur la plage prédite, dans l'exemple 401 à 430). Deux
111 types d'erreurs sont considérées :
112 \begin{itemize}
113 \item l'erreur "L1" égale à la valeur absolue entre la mesure et la prédiction ;
114 \item l'erreur "MAPE" égale à l'erreur L1 normalisée par la mesure.
115 \end{itemize}
116
117 Code :\\
118 <<errors, out.width='7cm', out.height='7cm', fig.show='hold'>>=
119 e = getErrors(data, forecasts)
120 #Erreurs absolues, point par point, moyennées sur les 30 jours
121 plot(e$L1, type="l", xlab="Temps", ylab="Erreur absolue")
122 #Erreurs relatives, point par point, moyennées sur les 30 jours
123 plot(e$MAPE, type="l", xlab="Temps", ylab="Erreur relative")
124 @
125
126 \subsection{Autres expériences numériques}
127
128 <<others1, out.width='7cm', out.height='7cm', fig.show='hold'>>=
129 p_endo = predictPM10("GMT", "7h", 400, 30, "Neighbors", NULL, 0,
130 "direct", simtype="endo")
131 p_exo = predictPM10("GMT", "7h", 400, 30, "Neighbors", NULL, 0,
132 "direct", simtype="exo")
133 yrange_L1 = range(p_mix$errors$L1, p_endo$errors$L1, p_exo$errors$L1)
134 plot(p_mix$errors$L1, type="l", main="Erreur L1", xlab="Temps",
135 ylab="Erreur absolue", ylim=yrange_L1) ; par(new=TRUE)
136 plot(p_endo$errors$L1, type="l", col=2, xlab="", ylab="",
137 ylim=yrange_L1) ; par(new=TRUE)
138 plot(p_exo$errors$L1, type="l", col=3, xlab="", ylab="",
139 ylim=yrange_L1)
140 yrange_MAPE =
141 range(p_mix$errors$MAPE, p_endo$errors$MAPE, p_exo$errors$MAPE)
142 plot(p_mix$errors$MAPE, type="l", main="Erreur MAPE", xlab="Temps",
143 ylab="Erreur relative", ylim=yrange_MAPE) ; par(new=TRUE)
144 plot(p_endo$errors$MAPE, type="l", col=2, xlab="", ylab="",
145 ylim=yrange_MAPE) ; par(new=TRUE)
146 plot(p_exo$errors$MAPE, type="l", col=3, xlab="", ylab="",
147 ylim=yrange_MAPE)
148
149 #Ne tenir compte que des similarités sur les variables exogènes semble
150 #conduire à l'erreur la plus faible.
151 @
152
153 <<others2, out.width='7cm', out.height='7cm', fig.show='hold'>>=
154 p_exo_h = predictPM10("GMT", "7h", 400, 30, "Neighbors", NULL, 0,
155 "direct", simtype="exo", h_window=0.25)
156 plot(p_exo_h$errors$L1, type="l", main="Erreur L1", xlab="Temps",
157 ylab="Erreur absolue")
158 plot(p_exo_h$errors$MAPE, type="l", main="Erreur MAPE", xlab="Temps",
159 ylab="Erreur relative")
160
161 #Diminuer la fenêtre n'améliore pas les performances moyennes
162 #(car les données individuelles sont très variables).
163 @
164
165 <<others3, out.width='7cm', out.height='7cm', fig.show='hold'>>=
166 p_exo_s = predictPM10("GMT", "7h", 400, 30, "Neighbors", "Persistence",
167 0, "separate", simtype="exo")
168 plot(p_exo_s$errors$L1, type="l", main="Erreur L1", xlab="Temps",
169 ylab="Erreur absolue")
170 plot(p_exo_s$errors$MAPE, type="l", main="Erreur MAPE", xlab="Temps",
171 ylab="Erreur relative")
172
173 #Prédire séparément forme et niveau mène à une erreur plus grande ;
174 #d'autres méthodes de prévision du niveau doivent tout de même être testées.
175 @
176
177 \subsection{Suite du travail}
178
179 Le type de jour n'est pas pris en compte dans la recherche de voisins ; cela diminuerait
180 nettement le nombre de similarités retenues, mais pourrait significativement améliorer les
181 prévisions.\\
182
183 \noindent Il serait intéressant également de disposer de plusieurs méthodes de prédiction, pour
184 par exemple les agréger à l'aide de méthodes similaires à celles du précédent contrat.
185
186 \end{document}