| 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 | |
| 29 | Note : sur la base de nos dernières expériences, on considère que |
| 30 | \begin{itemize} |
| 31 | \item on ne touche pas à la fenêtre obtenue par optim() ;} |
| 32 | \item on oublie la méthode consistant à prédire forme et niveau de manière complètement |
| 33 | déconnectée : il faut relier les deux. |
| 34 | \end{itemize} |
| 35 | |
| 36 | \subsection{Acquisition des données} |
| 37 | |
| 38 | Compte-tenu de la nature hétérogène des données utilisées $-$ fonctionnelles pour les PM10, |
| 39 | vectorielles pour les variables exogènes $-$, celles-ci sont organisées sous forme d'une liste |
| 40 | \emph{data}, la $i^{eme}$ cellule correspondant aux données disponibles au $i^{eme}$ jour à |
| 41 | l'heure $H$ de prédiction choisie (1h00, 8h00 ou 14h00) : c'est-à-dire les valeurs des PM10 de |
| 42 | $H-24h$ à $H-1H$, ainsi que les variables météo prédites pour la période de $1h00$ à $0h$ du |
| 43 | jour courant (sauf si on prédit à 0h : on prend alors les valeurs mesurées de la veille).\\ |
| 44 | |
| 45 | Exemple :\\ |
| 46 | <<data>>= |
| 47 | #Le premier argument indique la zone horaire souhaitée ; "GMT" ou "local" |
| 48 | #pour l'heure française, ou tout autre fuseau horaire. |
| 49 | data = getData("local", "7h") |
| 50 | @ |
| 51 | |
| 52 | \subsection{Prédiction} |
| 53 | |
| 54 | Deux types de prévisions du prochain bloc de $24h$ sont à distinguer : |
| 55 | \begin{itemize} |
| 56 | \item prévision de la forme (centrée) ; |
| 57 | \item prévision du saut d'une fin de série au début de la suivante. |
| 58 | \end{itemize} |
| 59 | |
| 60 | \noindent Il faut ainsi préciser à la fois une méthode de prévision de forme ("Persistence" et |
| 61 | "Neighbors" implémentées), et une méthode de prédiction de saut ("Zero", "Persistence" ou |
| 62 | "Neighbors"). On détaille surtout la méthode à voisins ci-après.\\ |
| 63 | |
| 64 | \begin{enumerate} |
| 65 | \item \textbf{Préparation des données} : calcul des niveaux sur 24h, fenêtrage si demandé |
| 66 | (paramètre "memory"). |
| 67 | \item \textbf{Optimisation des paramètres d'échelle} : via la fonction \emph{optim()} |
| 68 | minimisant la somme des 45 dernières erreurs jounalières L2. |
| 69 | \item \textbf{Prédiction finale} : une fois le (ou les, si "simtype" vaut "mix") paramètre |
| 70 | d'échelle $h$ déterminé, les similarités sont évaluées sur les variables exogènes et/ou |
| 71 | endogènes, sous la forme $s(i,j) = \mbox{exp}\left(-\frac{\mbox{dist}^2(i,j)}{h^2}\right)$. |
| 72 | La formule indiquée plus haut dans le rapport est alors appliquée. |
| 73 | \end{enumerate} |
| 74 | |
| 75 | \subsection{Calcul des erreurs} |
| 76 | |
| 77 | Pour chacun des instants à prévoir jusqu'à minuit du jour courant, on calcule l'erreur moyenne |
| 78 | sur tous les instants similaires du passé (sur la plage prédite). Trois |
| 79 | types d'erreurs sont considérées : |
| 80 | \begin{itemize} |
| 81 | \item l'erreur "abs" égale à la valeur absolue moyenne entre la mesure et la prédiction ; |
| 82 | \item l'erreur "MAPE" égale à l'erreur absolue normalisée par la mesure. |
| 83 | \item l'erreur "RMSE" égale à la racine carrée de l'erreur quadratique moyenne. |
| 84 | \end{itemize} |
| 85 | |
| 86 | \subsection{Expériences numériques} |
| 87 | |
| 88 | %, fig.show='hold'>>= |
| 89 | <<xp1, out.width='18cm', out.height='6cm'>>= |
| 90 | p_endo = predictPM10(data, 2200, 2230, 0,0, "Neighbors", "Neighbors", simtype="endo") |
| 91 | p_exo = predictPM10(data, 2200, 2230, 0,0, "Neighbors", "Neighbors", simtype="exo") |
| 92 | p_mix = predictPM10(data, 2200, 2230, 0,0, "Neighbors", "Neighbors", simtype="mix") |
| 93 | p = c(p_endo, p_exo, p_mix) |
| 94 | yrange_MAPE = range(p_mix$errors$MAPE, p_endo$errors$MAPE, p_exo$errors$MAPE) |
| 95 | yrange_abs = range(p_mix$errors$abs, p_endo$errors$abs, p_exo$errors$abs) |
| 96 | yrange_RMSE = range(p_mix$errors$RMSE, p_endo$errors$RMSE, p_exo$errors$RMSE) |
| 97 | ranges = c(yrange_MAPE,yrange_abs,yrange_RMSE) |
| 98 | par(mfrow=c(1,3)) |
| 99 | titles = paste("Erreur",c("MAPE","abs","RMSE")) |
| 100 | for (i in 1:3) #error type (MAPE,abs,RMSE) |
| 101 | { |
| 102 | for (j in 1:3) #model (mix,endo,exo) |
| 103 | { |
| 104 | plot(p[j]$errors[[i]], type="l", col=j, main=titles[i], xlab="Temps", |
| 105 | ylab="Erreur", ylim=ranges[i]) |
| 106 | par(new=TRUE) |
| 107 | } |
| 108 | } |
| 109 | |
| 110 | #Ne tenir compte que des similarités sur les variables exogènes semble |
| 111 | #conduire à l'erreur la plus faible. |
| 112 | @ |
| 113 | |
| 114 | <<xp2, out.width='18cm', out.height='6cm'>>= |
| 115 | p_nn = predictPM10(data, 2200, 2230, 0, 0, "Neighbors", "Neighbors", sameSeaon=TRUE) |
| 116 | p_np = predictPM10(data, 2200, 2230, 0, 0, "Neighbors", "Persistence", sameSeaon=TRUE) |
| 117 | p_nz = predictPM10(data, 2200, 2230, 0, 0, "Neighbors", "Zero", sameSeaon=TRUE) |
| 118 | p_pp = predictPM10(data, 2200, 2230, 0, 0, "Persistence", "Persistence") |
| 119 | p_pz = predictPM10(data, 2200, 2230, 0, 0, "Persistence", "Zero") |
| 120 | p = c(p_nn, p_np, p_nz, p_pp, p_pz) |
| 121 | yrange_MAPE = range(p_nn$errors$MAPE, p_nz$errors$MAPE, p_np$errors$MAPE, p_pp$errors$MAPE, p_pz$errors$MAPE) |
| 122 | yrange_abs = range(p_nn$errors$abs, p_nz$errors$abs, p_np$errors$abs, p_pp$errors$abs, p_pz$errors$abs) |
| 123 | yrange_RMSE = range(p_nn$errors$RMSE, p_nz$errors$RMSE, p_np$errors$RMSE, p_pp$errors$RMSE, p_pz$errors$RMSE) |
| 124 | ranges = c(yrange_MAPE,yrange_abs,yrange_RMSE) |
| 125 | par(mfrow=c(1,3)) |
| 126 | for (i in 1:3) #error type (MAPE,abs,RMSE) |
| 127 | { |
| 128 | for (j in 1:5) #model (nn,np,nz,pp,pz) |
| 129 | { |
| 130 | plot(p[j]$errors[[i]], type="l", col=j, main=titles[i], xlab="Temps", |
| 131 | ylab="Erreur", ylim=ranges[i]) |
| 132 | if (j<5) |
| 133 | par(new=TRUE) |
| 134 | } |
| 135 | } |
| 136 | |
| 137 | #Meilleurs results: nn et nz (np moins bon) |
| 138 | @ |
| 139 | |
| 140 | %%TODO: analyse sur les trois périodes indiquées par Michel ; simtype=="exo" par defaut |
| 141 | 16/03/2015 |
| 142 | p_nn_epandage = predictPM10(data, 2200, 2200, 0, 0, "Neighbors", "Neighbors", sameSeaon=FALSE) |
| 143 | 19/01/2015 |
| 144 | p_nn_chauffage = predictPM10(data, 2200, 2200, 0, 0, "Neighbors", "Neighbors", sameSeaon=FALSE) |
| 145 | 23/02/2015 |
| 146 | p_nn_nonpollue = predictPM10(data, 2200, 2200, 0, 0, "Neighbors", "Neighbors", sameSeaon=FALSE) |
| 147 | |
| 148 | \subsection{Suite du travail} |
| 149 | |
| 150 | Le type de jour n'est pas pris en compte dans la recherche de voisins ; cela diminuerait |
| 151 | nettement le nombre de similarités retenues, mais pourrait significativement améliorer les |
| 152 | prévisions. \textcolor{blue}{OK : on le prend désormais en compte}\\ |
| 153 | |
| 154 | \noindent Il serait intéressant également de disposer de plusieurs méthodes de prédiction, pour |
| 155 | par exemple les agréger à l'aide de méthodes similaires à celles du précédent contrat. |
| 156 | \textcolor{blue}{OK : on commence à en avoir quelques-unes} |
| 157 | |
| 158 | \end{document} |