Commit | Line | Data |
---|---|---|
3d69ff21 BA |
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} |