|
| 1 | +--- |
| 2 | +title: "Filtrage de séries spatio-temporelles" |
| 3 | +author: "Guyliann Engels & Philippe Grosjean" |
| 4 | +description: "**SDD III Module 5** Filtrage de séries avec moyennes et médianes mobiles ou par différence." |
| 5 | +tutorial: |
| 6 | + id: "C05La_ts_filter" |
| 7 | +version: 2.0.0/6 |
| 8 | +output: |
| 9 | + learnr::tutorial: |
| 10 | + progressive: true |
| 11 | +allow_skip: true |
| 12 | +runtime: shiny_prerendered |
| 13 | +--- |
| 14 | + |
| 15 | +```{r setup, include=FALSE} |
| 16 | +BioDataScience3::learnr_setup() |
| 17 | +SciViews::R("ts", lang = "fr") |
| 18 | +# dataset |
| 19 | +hr <- read(system.file("extdata", "heart_rate.rds", |
| 20 | + package = "BioDataScience3")) |
| 21 | +
|
| 22 | +hr_ts <- ts(hr$heart_rate, frequency = 60) |
| 23 | +hr_decomp <- tsd(hr_ts, method = "median", order = 30, times = 20) |
| 24 | +hr_filtered <- extract(hr_decomp, components = "filtered") |
| 25 | +``` |
| 26 | + |
| 27 | +```{r, echo=FALSE} |
| 28 | +BioDataScience3::learnr_banner() |
| 29 | +``` |
| 30 | + |
| 31 | +```{r, context="server"} |
| 32 | +BioDataScience3::learnr_server(input, output, session) |
| 33 | +``` |
| 34 | + |
| 35 | +------------------------------------------------------------------------ |
| 36 | + |
| 37 | +## Objectifs |
| 38 | + |
| 39 | +La décomposition d'une série est un élément central dans l'analyse d'une série spatio-temporelle. Vous avez découvert que l'on ne peut pas étudier les cycles d'une série si une tendance générale est présente. Il faut dans ce cas décomposer la série afin d'étudier chaque composante séparément. Nous aborderons dans ce tutoriel un exemple pratique de filtrage d'une série. |
| 40 | + |
| 41 | +## Variation de la fréquence cardiaque |
| 42 | + |
| 43 | +Un sportif travaille avec un médecin du sport afin d'optimiser ces performances. Le médecin n'est pas un expert dans le traitement des données collectées. Le sportif a couru sous les 36 minutes lors d'un effort maximal sur 10km, ce qui est une performance correcte pour un sportif amateur. En collaboration avec son médecin et vous, il souhaite comprendre les informations collectées par les différents capteurs qu'il a employées. Nous disposons de la distance parcourue, la puissance, la vitesse instantanée et la fréquence cardiaque. |
| 44 | + |
| 45 | +```{r} |
| 46 | +a <- chart(data = hr, speed ~ time/60) + |
| 47 | + geom_line() + |
| 48 | + labs(y = "Vitesse [m/s]", x = "Temps [min]") |
| 49 | +
|
| 50 | +b <- chart(data = hr, power ~ time/60) + |
| 51 | + geom_line() + |
| 52 | + labs(y = "Puissance [W]", x = "Temps [min]") |
| 53 | +
|
| 54 | +combine_charts(list(a,b)) |
| 55 | +``` |
| 56 | + |
| 57 | +La même tendance à la baisse s'observe sur les deux graphiques. La vitesse du coureur au cours du temps (A) et la puissance (B) qu'il développe baissent légèrement au cours du temps. En tant que biologiste doué dans l'analyse de données biologiques, on fait appel à vous afin de traiter le signal suivant : |
| 58 | + |
| 59 | +```{r} |
| 60 | +chart(data = hr, heart_rate ~ time/60) + |
| 61 | + geom_line() + |
| 62 | + labs(y = "Fréquence cardiaque [bpm]", x = "Temps [min]") |
| 63 | +``` |
| 64 | + |
| 65 | +À première vue, le médecin avance les observations suivantes. Il note une montée rapide de la fréquence cardiaque puis un plateau, suivi d'une montée progressive de la fréquence cardiaque et d'un nouveau plateau. Cependant, le médecin aurait besoin d'un signal "lissé" afin d'étudier l'évolution de la fréquence cardiaque au cours du temps plus facilement. C'est à présent à vous de jouer ! |
| 66 | + |
| 67 | +## Création de l'objet ts |
| 68 | + |
| 69 | +Les observations sont réalisées sur la même personne au cours du temps, nous sommes face à une série temporelle. Appliquez l'ensemble de vos connaissances. La fréquence cardiaque est mesurée chaque seconde. |
| 70 | + |
| 71 | +```{r, echo=TRUE} |
| 72 | +head(hr[,c("time", "heart_rate")]) |
| 73 | +``` |
| 74 | + |
| 75 | +Réalisez un objet `ts` dont le pas de temps est la minute et nommez-le `hr_ts`. Réalisez ensuite un graphique de `hr_ts`. Enfin, étudiez l'autocorrélation. Le tableau de données initial est `hr`. |
| 76 | + |
| 77 | +```{r ts_h2, exercise = TRUE} |
| 78 | +___ <- ts(___$___, frequency = ___) |
| 79 | +# graphique |
| 80 | +___(___) |
| 81 | +# autocorrélation |
| 82 | +___(___) |
| 83 | +``` |
| 84 | + |
| 85 | +```{r ts_h2-hint-1} |
| 86 | +hr_ts <- ts(hr$___, frequency = ___) |
| 87 | +# graphique |
| 88 | +___(hr_ts) |
| 89 | +# autocorrélation |
| 90 | +___(hr_ts) |
| 91 | +``` |
| 92 | + |
| 93 | +```{r ts_h2-solution} |
| 94 | +hr_ts <- ts(hr$heart_rate, frequency = 60) |
| 95 | +plot(hr_ts) |
| 96 | +# autocorrélation |
| 97 | +acf(hr_ts) |
| 98 | +``` |
| 99 | + |
| 100 | +```{r ts_h2-check} |
| 101 | +grade_code("On compte 60 secondes par minute. Il semble donc cohérent d'avoir une fréquence de 60. L'étude de l'autocorrélation de la série indique une forte corrélation. Nous pouvons donc employer tous les outils présent dans notre boite à outils dédiée à l'anayse des séries spatio-temporelles.") |
| 102 | +``` |
| 103 | + |
| 104 | +## Décomposition de la série |
| 105 | + |
| 106 | +Tentez de filtrer la tendance de cette série à l'aide des médianes mobiles avec fenêtre de 30 observations et reproduisez la décomposition 20 fois. Nommez cet objet `hr_decomp` |
| 107 | + |
| 108 | +```{r, decmed_h2, exercise = TRUE} |
| 109 | +___ <- tsd(___, method = "___", order = ___, times = ___) |
| 110 | +plot(___) |
| 111 | +``` |
| 112 | + |
| 113 | +```{r, decmed_h2-hint-1} |
| 114 | +hr_decomp <- tsd(hr_ts, method = "___", order = 30, times = ___) |
| 115 | +plot(hr_decomp) |
| 116 | +``` |
| 117 | + |
| 118 | +```{r, decmed_h2-solution} |
| 119 | +hr_decomp <- tsd(hr_ts, method = "median", order = 30, times = 20) |
| 120 | +plot(hr_decomp) |
| 121 | +``` |
| 122 | + |
| 123 | +```{r, decmed_h2-check} |
| 124 | +grade_code("Bien joué, vous avez réussi à filtrer la tendance de la série et placer le reste dans les rédidus.") |
| 125 | +``` |
| 126 | + |
| 127 | +Extrayez la composante filtrée à l'aide de la fonction `extract()` de l'objet `hr_decomp` puis réalisez un graphique de cette nouvelle série. |
| 128 | + |
| 129 | +```{r extract_h2, exercise = TRUE} |
| 130 | +hr_filtered <- extract(___, ___ = ___) |
| 131 | +plot(hr_filtered) |
| 132 | +``` |
| 133 | + |
| 134 | +```{r extract_h2-hint-1} |
| 135 | +hr_filtered <- extract(___, components = ___) |
| 136 | +plot(hr_filtered) |
| 137 | +``` |
| 138 | + |
| 139 | +```{r extract_h2-solution} |
| 140 | +hr_filtered <- extract(hr_decomp, components = "filtered") |
| 141 | +plot(hr_filtered) |
| 142 | +``` |
| 143 | + |
| 144 | +```{r extract_h2-check} |
| 145 | +grade_code("Vous avez correctement converti votre objet `tsd` en objet `ts`.") |
| 146 | +``` |
| 147 | + |
| 148 | +## Analyse de la série filtrée |
| 149 | + |
| 150 | +L'utilisation des médianes mobiles est une approche intéressante afin de faire ressortir les plateaux observés par le médecin. Débutez par réaliser un test de tendance par bootstrap sur votre objet `hr_filtered`. Réalisez 99 ré-échantillonnages. Affichez les graphiques associés à ce test. |
| 151 | + |
| 152 | +```{r trend_h2, exercise = TRUE} |
| 153 | +___(trend.test(___, R = ___)) |
| 154 | +``` |
| 155 | + |
| 156 | +```{r trend_h2-hint-1} |
| 157 | +plot(trend.test(___, R = ___)) |
| 158 | +``` |
| 159 | + |
| 160 | +```{r trend_h2-solution} |
| 161 | +plot(trend.test(hr_filtered, R = 99)) |
| 162 | +``` |
| 163 | + |
| 164 | +```{r trend_h2-check} |
| 165 | +grade_code("Un test de tendance avec bootstrap est bien plus intéressant qu'un test sans. Cependant, cette opération prend du temps. Nous avons donc décidé de faire seulement 99 rééchantillonage.") |
| 166 | +``` |
| 167 | + |
| 168 | +```{r qu_tren} |
| 169 | +question("Y a t'il un tendance générale dans cette série ? ", |
| 170 | + answer("Une tendance générale est présente dans cette série. On l'observe grâce à l'histogramme de la distribution de t.", correct = TRUE), |
| 171 | + answer("Il n'y a pas de tendance générale dans cette série. On l'observe grâce à l'histogramme de la distribution de t."), |
| 172 | + answer("Une tendance générale est présente dans cette série. On l'observe grâce au graphique quantile-quantile l'histogramme de la distribution de t*."), |
| 173 | + answer("Il n'y a pas de tendance générale dans cette série. On l'observe grâce au graphique quantile-quantile l'histogramme de la distribution de t*."), |
| 174 | + allow_retry = TRUE, |
| 175 | + random_answer_order = TRUE |
| 176 | + ) |
| 177 | +``` |
| 178 | + |
| 179 | +Calculez des statistiques glissantes afin de délimiter la période de 0 à 5, 5 à 15, 15 à 25 et de 25 à 36. Réalisez un graphique des statistiques glissantes en y ajoutant les médianes pour chaque période. Ajoutez la légende en position c(1,182). Renommez l'axe Y en "Fréquence cardiaque [bpm]", l'axe X en "Temps [min]" et le titre par "Statistiques glissantes". |
| 180 | + |
| 181 | +```{r sl_h2, exercise = TRUE} |
| 182 | +sl <- stat.slide(___(___), ___, xcut = c(___, ___, ___, ___, ___)) |
| 183 | +# Graphique de l'objet `sl` |
| 184 | +plot(__, stat = ___, leg = ___, lpos = c(___, ___), |
| 185 | + xlab = ___, ylab = ____, |
| 186 | + main = ___) |
| 187 | +``` |
| 188 | + |
| 189 | +```{r sl_h2-hint-1} |
| 190 | +sl <- stat.slide(___(___), ___, xcut = c(0, 5, 15, 25, 36)) |
| 191 | +# Graphique de l'objet `sl` |
| 192 | +plot(sl, stat = ___, leg = TRUE, lpos = c(1, 182), |
| 193 | + xlab = ___, ylab = ____, |
| 194 | + main = ___) |
| 195 | +``` |
| 196 | + |
| 197 | +```{r sl_h2-solution} |
| 198 | +sl <- stat.slide(time(hr_filtered), hr_filtered, xcut = c(0, 5, 15, 25, 36)) |
| 199 | +# Graphique de l'objet `sl` |
| 200 | +plot(sl, stat = "median", leg = TRUE, lpos = c(1, 182), |
| 201 | + xlab = "Temps [min]", ylab = "Fréquence cardiaque [bpm]", |
| 202 | + main = "Statistiques glissantes") |
| 203 | +``` |
| 204 | + |
| 205 | +```{r sl_h2-check} |
| 206 | +grade_code("Ce graphique est très explicite et va permettre au médécin d'expliquer au sportif l'évolutio de la fréquence cardiaque au cours du temps.") |
| 207 | +``` |
| 208 | + |
| 209 | +Grâce à votre analyse, le médecin peut confirmer ses premières observations. Les cinq premières minutes, la fréquence cardiaque augmente rapidement pour atteindre un plateau entre la minute 5 et la minute 15 d'une valeur médiane de 174 bpm. Une seconde augmentation plus progressive est observable entre la minute 15 et la minute 25. Enfin un nouveau plateau est observé entre la minute 25 et la fin de la course. |
| 210 | + |
| 211 | +Le médecin émet l'hypothèse suivante. Le sportif atteint le premier plateau puis on observe une probable dérive cardiaque. La dérive cardiaque est liée à l'augmentation de la température corporelle. Le corps tente de dissiper la chaleur en dilatant les vaisseaux sanguins. Afin de maintenir le débit cardiaque constant, la fréquence cardiaque va augmenter. Le dernier plateau est probablement lié à la diminution de la vitesse qui va arrêter l'augmentation de la vitesse cardiaque. |
| 212 | + |
| 213 | +## Conclusion |
| 214 | + |
| 215 | +Vous venez d'appliquer vos connaissances sur le filtrage d'une série afin d'étudier une série temporelle de la variation cardiaque d'un sportif sur un effort de 10km. |
| 216 | + |
| 217 | +```{r comm_noscore, echo=FALSE} |
| 218 | +question_text( |
| 219 | + "Laissez-nous vos impressions sur ce learnr", |
| 220 | + answer("", TRUE, message = "Pas de commentaires... C'est bien aussi."), |
| 221 | + incorrect = "Vos commentaires sont enregistrés.", |
| 222 | + placeholder = "Entrez vos commentaires ici...", |
| 223 | + allow_retry = TRUE |
| 224 | +) |
| 225 | +``` |
0 commit comments