setwd("C:/Users/Ideapad/Desktop/Valdom/Projet personnel Machine Learning/ML Time Series Exchange Rate/TimeSeriesExchangeRate")Projet Machine Learning : Prediction du Taux de Change EUR/CFA
Objectif du projet:
Ce projet vise à faire une étude approndie de l’évolution du taux de change entre l’Euro et le Franc CFA aucours des vingt dernières années et par la suite prédire son évolution pour les années à venir.
IL s’agit en fait de l’étude d’une série chronologique du taux de change entre l’Euro et le Franc CFA
Définition de l’environnement de travail
Importation des librairies neccessaires à l’analyse et à la modélisation de la serie chronologique
library(tidyverse) # Manipulation des donnéesWarning: le package 'ggplot2' a été compilé avec la version R 4.3.3
── Attaching core tidyverse packages ──────────────────────── tidyverse 2.0.0 ──
✔ dplyr 1.1.4 ✔ readr 2.1.5
✔ forcats 1.0.0 ✔ stringr 1.5.1
✔ ggplot2 3.5.1 ✔ tibble 3.2.1
✔ lubridate 1.9.3 ✔ tidyr 1.3.1
✔ purrr 1.0.2
── Conflicts ────────────────────────────────────────── tidyverse_conflicts() ──
✖ dplyr::filter() masks stats::filter()
✖ dplyr::lag() masks stats::lag()
ℹ Use the conflicted package (<http://conflicted.r-lib.org/>) to force all conflicts to become errors
library(timetk) # Visualisation de la série chronologiqueWarning: le package 'timetk' a été compilé avec la version R 4.3.3
library(modeltime) # Modelisation de la série chronologiqueWarning: le package 'modeltime' a été compilé avec la version R 4.3.3
library(tidymodels) # Modelisation de la série chronologiqueWarning: le package 'tidymodels' a été compilé avec la version R 4.3.3
── Attaching packages ────────────────────────────────────── tidymodels 1.2.0 ──
✔ broom 1.0.5 ✔ rsample 1.2.1
✔ dials 1.2.1 ✔ tune 1.2.1
✔ infer 1.0.7 ✔ workflows 1.1.4
✔ modeldata 1.3.0 ✔ workflowsets 1.1.0
✔ parsnip 1.2.1 ✔ yardstick 1.3.1
✔ recipes 1.0.10
Warning: le package 'broom' a été compilé avec la version R 4.3.3
Warning: le package 'dials' a été compilé avec la version R 4.3.3
Warning: le package 'infer' a été compilé avec la version R 4.3.3
Warning: le package 'modeldata' a été compilé avec la version R 4.3.3
Warning: le package 'parsnip' a été compilé avec la version R 4.3.3
Warning: le package 'rsample' a été compilé avec la version R 4.3.3
Warning: le package 'tune' a été compilé avec la version R 4.3.3
Warning: le package 'workflows' a été compilé avec la version R 4.3.3
Warning: le package 'workflowsets' a été compilé avec la version R 4.3.3
Warning: le package 'yardstick' a été compilé avec la version R 4.3.3
── Conflicts ───────────────────────────────────────── tidymodels_conflicts() ──
✖ scales::discard() masks purrr::discard()
✖ dplyr::filter() masks stats::filter()
✖ recipes::fixed() masks stringr::fixed()
✖ dplyr::lag() masks stats::lag()
✖ yardstick::spec() masks readr::spec()
✖ recipes::step() masks stats::step()
• Dig deeper into tidy modeling with R at https://www.tmwr.org
Etape 1 : Importation des données de la série chronologique
Data=utils::read.csv("EUR_XOF - Données Historiques Mensuelles.csv",header=T, sep = ",")
Data=Data%>% dplyr:: select(Date,Dernier)%>%
dplyr:: rename(Taux_de_change=Dernier)%>%
dplyr:: mutate(Date=lubridate::dmy(Date), Taux_de_change=as.double(Taux_de_change))
Data Date Taux_de_change
1 2024-12-01 648.870
2 2024-11-01 652.210
3 2024-10-01 653.520
4 2024-09-01 648.830
5 2024-08-01 669.000
6 2024-07-01 651.670
7 2024-06-01 652.690
8 2024-05-01 653.170
9 2024-04-01 648.900
10 2024-03-01 653.930
11 2024-02-01 650.610
12 2024-01-01 651.930
13 2023-12-01 650.300
14 2023-11-01 647.110
15 2023-10-01 648.570
16 2023-09-01 652.170
17 2023-08-01 648.560
18 2023-07-01 650.410
19 2023-06-01 681.890
20 2023-05-01 652.800
21 2023-04-01 653.210
22 2023-03-01 650.880
23 2023-02-01 651.480
24 2023-01-01 653.080
25 2022-12-01 658.170
26 2022-11-01 654.990
27 2022-10-01 648.570
28 2022-09-01 661.680
29 2022-08-01 656.720
30 2022-07-01 650.890
31 2022-06-01 654.080
32 2022-05-01 651.470
33 2022-04-01 650.910
34 2022-03-01 646.750
35 2022-02-01 654.350
36 2022-01-01 656.290
37 2021-12-01 655.370
38 2021-11-01 653.240
39 2021-10-01 645.970
40 2021-09-01 645.640
41 2021-08-01 652.340
42 2021-07-01 655.220
43 2021-06-01 649.650
44 2021-05-01 653.120
45 2021-04-01 646.870
46 2021-03-01 659.450
47 2021-02-01 648.370
48 2021-01-01 655.340
49 2020-12-01 647.900
50 2020-11-01 651.870
51 2020-10-01 645.830
52 2020-09-01 651.520
53 2020-08-01 654.390
54 2020-07-01 652.740
55 2020-06-01 652.900
56 2020-05-01 650.890
57 2020-04-01 657.520
58 2020-03-01 649.610
59 2020-02-01 653.780
60 2020-01-01 656.100
61 2019-12-01 652.140
62 2019-11-01 652.360
63 2019-10-01 653.500
64 2019-09-01 649.500
65 2019-08-01 663.720
66 2019-07-01 656.260
67 2019-06-01 650.800
68 2019-05-01 657.300
69 2019-04-01 654.110
70 2019-03-01 650.810
71 2019-02-01 650.830
72 2019-01-01 648.130
73 2018-12-01 652.840
74 2018-11-01 648.010
75 2018-10-01 649.990
76 2018-09-01 651.190
77 2018-08-01 646.990
78 2018-07-01 660.800
79 2018-06-01 677.630
80 2018-05-01 682.035
81 2018-04-01 675.430
82 2018-03-01 651.780
83 2018-02-01 643.490
84 2018-01-01 657.070
85 2017-12-01 688.100
86 2017-11-01 667.945
87 2017-10-01 660.080
88 2017-09-01 656.860
89 2017-08-01 661.685
90 2017-07-01 665.470
91 2017-06-01 661.880
92 2017-05-01 657.360
93 2017-04-01 667.320
94 2017-03-01 653.280
95 2017-02-01 657.820
96 2017-01-01 661.680
97 2016-12-01 657.210
98 2016-11-01 655.640
99 2016-10-01 665.780
100 2016-09-01 665.785
101 2016-08-01 655.960
102 2016-07-01 666.015
103 2016-06-01 665.865
104 2016-05-01 665.105
105 2016-04-01 656.020
106 2016-03-01 655.950
107 2016-02-01 660.245
108 2016-01-01 667.235
109 2015-12-01 666.725
110 2015-11-01 666.770
111 2015-10-01 666.715
112 2015-09-01 656.020
113 2015-08-01 655.370
114 2015-07-01 657.515
115 2015-06-01 655.660
116 2015-05-01 656.200
117 2015-04-01 657.250
118 2015-03-01 650.240
119 2015-02-01 654.790
120 2015-01-01 655.780
121 2014-12-01 651.120
122 2014-11-01 656.490
123 2014-10-01 655.010
124 2014-09-01 652.340
125 2014-08-01 655.850
126 2014-07-01 655.810
127 2014-06-01 655.870
128 2014-05-01 656.190
129 2014-04-01 655.860
130 2014-03-01 655.960
131 2014-02-01 656.150
132 2014-01-01 655.760
133 2013-12-01 653.950
134 2013-11-01 655.670
135 2013-10-01 655.860
136 2013-09-01 655.850
137 2013-08-01 655.030
138 2013-07-01 655.760
139 2013-06-01 655.810
140 2013-05-01 655.560
141 2013-04-01 655.760
142 2013-03-01 655.810
143 2013-02-01 655.650
144 2013-01-01 655.910
145 2012-12-01 655.510
146 2012-11-01 655.000
147 2012-10-01 655.960
148 2012-09-01 654.850
149 2012-08-01 654.710
150 2012-07-01 655.530
151 2012-06-01 655.180
152 2012-05-01 654.880
153 2012-04-01 655.910
154 2012-03-01 654.290
155 2012-02-01 654.830
156 2012-01-01 655.800
157 2011-12-01 655.850
158 2011-11-01 655.860
159 2011-10-01 655.870
160 2011-09-01 654.930
161 2011-08-01 655.860
162 2011-07-01 654.860
163 2011-06-01 655.730
164 2011-05-01 655.860
165 2011-04-01 655.600
166 2011-03-01 655.640
167 2011-02-01 655.710
168 2011-01-01 655.860
169 2010-12-01 655.320
170 2010-11-01 655.850
171 2010-10-01 655.820
172 2010-09-01 655.960
173 2010-08-01 655.880
174 2010-07-01 655.780
175 2010-06-01 655.680
176 2010-05-01 655.885
177 2010-04-01 655.735
178 2010-03-01 655.660
179 2010-02-01 655.515
180 2010-01-01 655.535
181 2009-12-01 655.490
182 2009-11-01 655.585
183 2009-10-01 655.930
184 2009-09-01 655.955
185 2009-08-01 655.935
186 2009-07-01 655.400
187 2009-06-01 655.605
188 2009-05-01 655.345
189 2009-04-01 655.515
190 2009-03-01 655.590
191 2009-02-01 655.645
192 2009-01-01 655.525
193 2008-12-01 654.380
194 2008-11-01 656.010
195 2008-10-01 658.935
196 2008-09-01 655.905
197 2008-08-01 655.925
198 2008-07-01 655.935
199 2008-06-01 656.060
200 2008-05-01 655.670
201 2008-04-01 655.475
202 2008-03-01 655.350
203 2008-02-01 655.655
204 2008-01-01 655.710
205 2007-12-01 655.400
206 2007-11-01 655.795
207 2007-10-01 657.340
208 2007-09-01 656.040
209 2007-08-01 655.930
210 2007-07-01 655.305
211 2007-06-01 655.710
212 2007-05-01 655.765
213 2007-04-01 655.565
214 2007-03-01 655.935
215 2007-02-01 655.775
216 2007-01-01 655.820
217 2006-12-01 656.075
218 2006-11-01 655.815
219 2006-10-01 655.700
220 2006-09-01 655.905
221 2006-08-01 655.320
222 2006-07-01 655.365
223 2006-06-01 655.655
224 2006-05-01 655.935
225 2006-04-01 656.126
226 2006-03-01 655.308
227 2006-02-01 655.742
228 2006-01-01 654.829
229 2005-12-01 656.359
230 2005-11-01 655.968
231 2005-10-01 655.828
232 2005-09-01 656.321
233 2005-08-01 656.369
234 2005-07-01 655.738
235 2005-06-01 656.500
236 2005-05-01 655.557
237 2005-04-01 654.528
238 2005-03-01 655.527
239 2005-02-01 654.978
240 2005-01-01 655.064
241 2004-12-01 657.262
242 2004-11-01 656.650
243 2004-10-01 655.960
244 2004-09-01 655.925
245 2004-08-01 656.065
246 2004-07-01 655.667
247 2004-06-01 656.986
248 2004-05-01 654.474
249 2004-04-01 655.823
250 2004-03-01 656.833
251 2004-02-01 656.413
252 2004-01-01 656.105
str(Data)'data.frame': 252 obs. of 2 variables:
$ Date : Date, format: "2024-12-01" "2024-11-01" ...
$ Taux_de_change: num 649 652 654 649 669 ...
Etape 2 : Visualiser l’allure de la série chronologique
Data %>%
plot_time_series(Date, Taux_de_change,.title="Serie chronologique taux de change",.x_lab = "Années",.y_lab="Valeurs Taux de Change",.plotly_slider = TRUE,.line_size = 1, .interactive = FALSE)Etape 3 : Machine Learning avec Tydimodel et ModelTime
Fractionner les données (Entrainement et Test)
# Split Data 80/20
splits <- rsample::initial_time_split(Data, prop = 0.8)
Train=training(splits)
Test=testing(splits)
splits <Training/Testing/Total>
<201/51/252>
Créer et entrainer plusieurs modèles sur des données d’entrainement
Model 1: Auto ARIMA (Modeltime)
# Model 1: auto_arima ----
model_fit_arima_no_boost <- arima_reg() %>%
set_engine(engine = "auto_arima") %>%
fit(Taux_de_change ~Date , data = Train)frequency = 12 observations per 1 year
model_fit_arima_no_boostparsnip model object
Series: outcome
ARIMA(4,1,2)(2,0,0)[12]
Coefficients:
ar1 ar2 ar3 ar4 ma1 ma2 sar1 sar2
-0.0171 -0.1504 -0.1945 -0.1224 -0.6151 -0.1262 -0.0449 0.0709
s.e. 0.4472 0.1420 0.1020 0.1086 0.4453 0.3818 0.0732 0.0783
sigma^2 = 28.87: log likelihood = -616.72
AIC=1251.45 AICc=1252.39 BIC=1281.13
#> frequency = 12 observations per 1 yearModel 2: Boosted Auto ARIMA (Modeltime)
# Model 2: arima_boost ----
model_fit_arima_boosted <- arima_boost(
min_n = 2,
learn_rate = 0.015
) %>%
set_engine(engine = "auto_arima_xgboost") %>%
fit(Taux_de_change ~Date, data = Train)frequency = 12 observations per 1 year
model_fit_arima_boostedparsnip model object
ARIMA(3,1,1)
---
Model 1: Auto ARIMA
Series: outcome
ARIMA(3,1,1)
Coefficients:
ar1 ar2 ar3 ma1
0.2262 -0.1434 -0.1413 -0.8376
s.e. 0.0904 0.0757 0.0811 0.0642
sigma^2 = 28.58: log likelihood = -617.71
AIC=1245.41 AICc=1245.72 BIC=1261.91
---
Model 2: XGBoost Errors
NULL
#> frequency = 12 observations per 1 yearModel 3: Exponential Smoothing (Modeltime)
# Model 3: ets ----
model_fit_ets <- exp_smoothing() %>%
set_engine(engine = "ets") %>%
fit(Taux_de_change ~Date, data = Train)frequency = 12 observations per 1 year
model_fit_etsparsnip model object
ETS(A,N,N)
Call:
forecast::ets(y = outcome, model = model_ets, damped = damping_ets,
alpha = alpha, beta = beta, gamma = gamma)
Smoothing parameters:
alpha = 0.1429
Initial states:
l = 652.8142
sigma: 5.5777
AIC AICc BIC
1760.903 1761.025 1770.813
#> frequency = 12 observations per 1 year####Model 4: Prophet (Modeltime)
# Model 4: prophet ----
model_fit_prophet <- prophet_reg() %>%
set_engine(engine = "prophet") %>%
fit(Taux_de_change ~Date, data = Train)Disabling weekly seasonality. Run prophet with weekly.seasonality=TRUE to override this.
Disabling daily seasonality. Run prophet with daily.seasonality=TRUE to override this.
model_fit_prophetparsnip model object
PROPHET Model
- growth: 'linear'
- n.changepoints: 25
- changepoint.range: 0.8
- yearly.seasonality: 'auto'
- weekly.seasonality: 'auto'
- daily.seasonality: 'auto'
- seasonality.mode: 'additive'
- changepoint.prior.scale: 0.05
- seasonality.prior.scale: 10
- holidays.prior.scale: 10
- logistic_cap: NULL
- logistic_floor: NULL
- extra_regressors: 0
#> Disabling weekly seasonality. Run prophet with weekly.seasonality=TRUE to override this.
#> Disabling daily seasonality. Run prophet with daily.seasonality=TRUE to override this.Mettre les modèles entrainés dans une table de modèle
models_tbl <- modeltime_table(
model_fit_arima_no_boost,
model_fit_arima_boosted,
model_fit_ets,
model_fit_prophet
)
models_tbl# Modeltime Table
# A tibble: 4 × 3
.model_id .model .model_desc
<int> <list> <chr>
1 1 <fit[+]> ARIMA(4,1,2)(2,0,0)[12]
2 2 <fit[+]> ARIMA(3,1,1)
3 3 <fit[+]> ETS(A,N,N)
4 4 <fit[+]> PROPHET
Calibrer la table de modèles entraînés au jeu de données de test
calibration_tbl <- models_tbl %>%
modeltime_calibrate(new_data = Test)
calibration_tbl# Modeltime Table
# A tibble: 4 × 5
.model_id .model .model_desc .type .calibration_data
<int> <list> <chr> <chr> <list>
1 1 <fit[+]> ARIMA(4,1,2)(2,0,0)[12] Test <tibble [51 × 4]>
2 2 <fit[+]> ARIMA(3,1,1) Test <tibble [51 × 4]>
3 3 <fit[+]> ETS(A,N,N) Test <tibble [51 × 4]>
4 4 <fit[+]> PROPHET Test <tibble [51 × 4]>
Prevoir le taux de change du jeu de données Test et evaluer la precision de prevision (Visualisation)
calibration_tbl %>%
modeltime_forecast(
new_data = Test,
actual_data = Data
) %>%
plot_modeltime_forecast( .title = "Calibrage des modèles sur les données test",
.x_lab = "Années",
.y_lab = " Valeurs Taux de Change",.plotly_slider = TRUE,
.legend_max_width = 25, # For mobile screens
.interactive = FALSE
)Warning in max(ids, na.rm = TRUE): aucun argument pour max ; -Inf est renvoyé
Metrique de precision des modèles entraînés
calibration_tbl %>%
modeltime_accuracy( metric_set = metric_set(mae, rmse, rsq)) Warning: There was 1 warning in `dplyr::mutate()`.
ℹ In argument: `.nested.col = purrr::map(...)`.
Caused by warning:
! A correlation computation is required, but `estimate` is constant and has 0
standard deviation, resulting in a divide by 0 error. `NA` will be returned.
# A tibble: 4 × 6
.model_id .model_desc .type mae rmse rsq
<int> <chr> <chr> <dbl> <dbl> <dbl>
1 1 ARIMA(4,1,2)(2,0,0)[12] Test 0.438 0.598 0.0604
2 2 ARIMA(3,1,1) Test 0.424 0.582 0.00153
3 3 ETS(A,N,N) Test 0.419 0.579 NA
4 4 PROPHET Test 1.23 1.56 0.0434
Re-entraîner les modèles sur le jeu de données complet et prevoir le taux de change sur quelques années
refit_tbl <- calibration_tbl %>%
modeltime_refit(data = Data)frequency = 12 observations per 1 year
frequency = 12 observations per 1 year
frequency = 12 observations per 1 year
Disabling weekly seasonality. Run prophet with weekly.seasonality=TRUE to override this.
Disabling daily seasonality. Run prophet with daily.seasonality=TRUE to override this.
refit_tbl %>%
modeltime_forecast(h="25 years ",actual_data = Data) %>%
plot_modeltime_forecast( .title = "Prevision du Taux de Change sur quelques années ",
.x_lab = "Années",
.y_lab = " Valeurs Taux de Change",.plotly_slider = TRUE,
.legend_max_width = 25, # For mobile screens
.interactive = FALSE
)Warning in max(ids, na.rm = TRUE): aucun argument pour max ; -Inf est renvoyé