library(dplyr) # manipulate data
library(ggplot2) # visualization
library(MLmetrics) # evaluation metricsBeberapa hal yang harus diperhatikan ketika melakukan analisis data time series, yaitu:
dateprophetKolom yang akan masuk ke dalam pemodelan prophet harus
bertipe date dengan format YYYY-MM-DD untuk sebuah tanggal.
Oleh sebab itu, wajib kita lakukan konversi tipe data terlebih
dahulu.
#> Rows: 235,636
#> Columns: 9
#> $ X <int> 1385158, 1385159, 1385160, 1385161, 1385162, 1385163, 1…
#> $ date <chr> "03.01.2013", "02.01.2013", "11.01.2013", "26.01.2013",…
#> $ date_block_num <int> 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0…
#> $ shop_id <int> 31, 31, 31, 31, 31, 31, 31, 31, 31, 31, 31, 31, 31, 31,…
#> $ shop_name <chr> "Moscow shopping center \"Semenovsky\"", "Moscow shoppi…
#> $ item_id <int> 4906, 4906, 4890, 4901, 4901, 4901, 4901, 4901, 4901, 4…
#> $ item_price <dbl> 1794.00, 1789.00, 799.00, 1499.00, 1499.00, 1499.00, 16…
#> $ item_cnt_day <int> 2, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 2, 1, 2, 1, 1…
#> $ total_revenue <dbl> 3588.0, 1789.0, 799.0, 1499.0, 1499.0, 1499.0, 1699.0, …
📌 Untuk melakukan konversi ini dengan efisien, kita dapat
memanfaatkan library lubridate di R. Library ini
menyediakan berbagai fungsi yang memudahkan manipulasi dan konversi tipe
data tanggal. Salah satu fungsi yang sangat berguna adalah
dmy(), yang dapat digunakan untuk mengubah string tanggal
menjadi objek date dengan format yang tepat.
📅 Ingat kembali cheatsheet berikut: Cheatsheet Lubridate
# mengubah tipe data ke date
transaction <- transaction %>%
mutate(date = dmy(date))
glimpse(transaction)#> Rows: 235,636
#> Columns: 9
#> $ X <int> 1385158, 1385159, 1385160, 1385161, 1385162, 1385163, 1…
#> $ date <date> 2013-01-03, 2013-01-02, 2013-01-11, 2013-01-26, 2013-0…
#> $ date_block_num <int> 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0…
#> $ shop_id <int> 31, 31, 31, 31, 31, 31, 31, 31, 31, 31, 31, 31, 31, 31,…
#> $ shop_name <chr> "Moscow shopping center \"Semenovsky\"", "Moscow shoppi…
#> $ item_id <int> 4906, 4906, 4890, 4901, 4901, 4901, 4901, 4901, 4901, 4…
#> $ item_price <dbl> 1794.00, 1789.00, 799.00, 1499.00, 1499.00, 1499.00, 16…
#> $ item_cnt_day <int> 2, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 2, 1, 2, 1, 1…
#> $ total_revenue <dbl> 3588.0, 1789.0, 799.0, 1499.0, 1499.0, 1499.0, 1699.0, …
Salah satu syarat dalam membuat model Time Series adalah data tanggal harus terurut dengan baik dari data paling lampau sampai dengan data paling baru.
📌 Untuk mengurutkan data dengan dplyr kita dapat menggunakan fungsi
arrange(), dimana secara default akan mengurutkan secara
ascending
Hal yang penting dari sebuah data time series adalah memiliki interval waktu tiap baris yang tetap, seperti interval harian, mingguan ataupun bulanan. Data kita memiliki banyak transaksi yang terjadi dalam sehari. Oleh karena itu, data kita masih dalam interval tidak tetap.
daily_transaction <- transaction %>%
group_by(date) %>%
summarise(item_cnt_day = sum(item_cnt_day),
total_revenue = sum (total_revenue))
daily_transactionSebagai catatan, ketika melakukan agregasi data, kita hanya dapat mengubah ke bentuk data dari periode yang lebih singkat ke periode lebih panjang, sebagai contoh:
prophetUntuk menggunakan prophet, kita perlu mempersiapkan data
time series ke dalam format yang spesifik sesuai kebutuhan library ini.
prophet membutuhkan dataframe dengan 2 kolom berikut:
ds: kolom dengan informasi waktu, harus bertipe data
datey: nilai yang ingin di-forecastMerubah nama kolom dengan fungsi
rename(new_colname = old_colname)
— Checkpoint —
Persiapan data di prophet (berurutan):
ds dan target = y
-> formating dari prophetData dari 2 Januari 2013 hingga 31 Oktober 2015, kita ingin coba
ambil data item_cnt_day satu tahun terakhir (data ini akan
digunakan sebagai prediktor future)
#> ds item_cnt_day y
#> Min. :2013-01-02 Min. : 102.0 Min. : 84199
#> 1st Qu.:2013-09-16 1st Qu.: 221.5 1st Qu.: 150015
#> Median :2014-06-02 Median : 275.0 Median : 193096
#> Mean :2014-06-01 Mean : 301.4 Mean : 228145
#> 3rd Qu.:2015-02-15 3rd Qu.: 358.5 3rd Qu.: 256967
#> Max. :2015-10-31 Max. :1080.0 Max. :2177573
Pertama, nilai item_cnt_day disimpan untuk nanti digunakan ketika ingin melakukan pembuatan dataframe future
#> [1] 568 423 431 415 435 312 354 262 254 315 488 313 228 246
#> [15] 274 242 365 497 327 240 256 283 286 407 461 347 299 281
#> [29] 268 296 362 465 364 265 325 297 398 459 566 415 282 378
#> [43] 321 381 454 454 414 396 446 377 496 749 614 395 241 265
#> [57] 313 268 378 453 374 323 447 416 803 619 421 379 293 416
#> [71] 383 338 439 542 443 291 302 355 340 433 529 370 295 308
#> [85] 342 261 449 535 393 212 286 277 262 388 513 374 254 320
#> [99] 247 277 366 483 296 227 195 208 234 399 395 310 225 262
#> [113] 215 293 392 468 397 309 537 375 224 264 314 247 298 273
#> [127] 382 212 202 217 256 195 170 240 233 416 386 329 246 329
#> [141] 322 329 440 438 401 272 310 251 411 441 406 380 291 336
#> [155] 265 367 421 378 330 270 383 377 275 463 283 263 253 283
#> [169] 259 290 401 353 271 325 308 399 351 416 422 253 348 303
#> [183] 328 321 456 352 282 220 332 272 363 412 388 332 289 337
#> [197] 324 241 323 361 249 277 268 228 276 346 293 266 201 284
#> [211] 228 303 442 351 285 275 317 341 279 336 302 221 243 230
#> [225] 249 284 345 356 255 268 256 283 313 378 401 355 338 310
#> [239] 325 375 423 443 478 319 440 352 309 414 482 455 223 248
#> [253] 321 264 356 432 394 254 785 312 316 457 488 329 185 280
#> [267] 317 376 467 536 352 263 291 307 226 391 462 374 330 313
#> [281] 339 361 498 502 348 237 302 263 312 400 472 367 207 213
#> [295] 240 275 472 507 367 265 414 316 383 425 480 460 330 460
#> [309] 307 287 483 524 413 312 263 245 256 429 561 467 270 341
#> [323] 335 412 461 508 358 266 324 325 296 575 537 376 325 348
#> [337] 330 300 482 575 392 233 345 304 363 455 642 415 340 395
#> [351] 453 406 526 705 550 459 485 646 691 861 1028 962 1035 891
#> [365] 557 520 434 380 440 408 362 304 270 488 344 210 276 226
#> [379] 239 292 402 303 217 284 223 264 404 388 307 242 230 323
#> [393] 283 397 442 352 286 222 336 285 316 428 365 254 312 245
#> [407] 237 490 417 387 289 311 327 378 556 673 480 200 226 241
#> [421] 245 428 516 274 236 286 272 346 562 421 346 278 194 166
#> [435] 198 417 417 367 266 236 283 229 455 389 356 193 182 225
#> [449] 265 297 410 315 246 208 250 280 394 405 300 202 253 247
#> [463] 269 360 450 300 310 437 256 322 348 387 236 162 223 213
#> [477] 240 335 367 274 189 257 423 212 194 249 224 168 213 244
#> [491] 327 149 173 262 158 143 200 179 324 321 232 161 195 268
#> [505] 243 325 291 202 250 481 312 310 418 398 218 215 218 234
#> [519] 233 372 320 228 236 324 325 335 287 218 173 207 281 220
#> [533] 220 267 399 219 167 205 260 241 313 335 204 227 217 202
#> [547] 234 267 235 212 184 237 237 239 290 289 180 238 198 192
#> [561] 254 223 210 207 176 260 252 210 252 206 263 188 210 277
#> [575] 217 295 226 228 222 229 243 237 307 291 241 239 235 222
#> [589] 232 278 322 265 207 246 262 232 321 342 246 204 270 234
#> [603] 294 311 402 365 253 235 207 266 374 483 252 225 284 268
#> [617] 315 341 295 327 240 233 225 259 327 291 282 197 232 229
#> [631] 357 372 448 284 221 261 266 330 357 386 279 221 316 247
#> [645] 255 391 401 253 200 207 221 248 289 420 226 178 256 198
#> [659] 222 268 389 307 175 182 214 246 309 394 286 310 253 200
#> [673] 305 317 421 269 208 253 264 393 370 476 315 217 482 285
#> [687] 358 465 410 308 290 229 245 236 403 561 342 237 302 248
#> [701] 275 359 458 368 268 318 233 322 418 492 403 354 311 356
#> [715] 315 516 577 527 424 427 454 473 712 942 690 839 1080 912
#> [729] 549 409 365 460 523 409 296 281 297 284 191 266 188 247
#> [743] 311 395 278 213 174 246 173 267 377 262 172 199 169 208
#> [757] 293 313 252 188 162 185 199 337 298 293 212 217 195 163
#> [771] 316 434 238 194 234 239 250 475 377 340 352 201 216 201
#> [785] 282 354 262 182 199 274 298 384 447 323 233 228 179 210
#> [799] 208 301 209 115 181 138 171 263 288 254 182 194 256 203
#> [813] 255 306 236 154 161 134 163 274 316 252 234 197 226 164
#> [827] 294 337 222 188 459 283 188 344 289 295 229 232 160 225
#> [841] 281 307 228 147 113 213 347 307 171 111 143 162 213 177
#> [855] 199 129 155 191 130 114 121 256 252 172 133 514 326 192
#> [869] 259 313 233 160 174 199 189 206 236 190 151 216 208 177
#> [883] 271 219 173 131 197 259 325 262 163 102 201 241 230 263
#> [897] 180 244 231 168 251 193 173 192 230 151 176 182 185 202
#> [911] 247 191 145 219 181 207 222 225 227 197 188 200 184 152
#> [925] 266 244 165 182 194 172 139 215 243 139 167 143 159 206
#> [939] 181 182 112 161 160 196 195 184 162 140 138 167 170 160
#> [953] 187 142 145 196 168 155 231 225 218 183 195 179 204 212
#> [967] 241 297 225 184 315 170 209 232 290 233 193 206 184 218
#> [981] 277 380 240 129 141 156 188 259 198 156 104 346 244 193
#> [995] 258 233 198 137 182 236 205 245 238 208 131 158 232 143
#> [1009] 259 249 207 140 192 184 167 259 234 180 156 183 140 165
#> [1023] 239 291 265 134 123 117 152 267 249
Kita akan ambil data item_cnt_day diatas 1 tahun
terakhir, yaitu dari 2013-01-02 hingga 2014-10-31, yang nantinya akan
kita gunakan sebagai prediktor untuk memprediksi data 2014-01-02 hingga
2015-10-31 (ceritanya data masa lalu yang digunakan sebagai prediktor di
masa kini).
simpan data item_cnt_day masa lalu
#> [1] 568 423 431 415 435 312 354 262 254 315 488 313 228 246 274
#> [16] 242 365 497 327 240 256 283 286 407 461 347 299 281 268 296
#> [31] 362 465 364 265 325 297 398 459 566 415 282 378 321 381 454
#> [46] 454 414 396 446 377 496 749 614 395 241 265 313 268 378 453
#> [61] 374 323 447 416 803 619 421 379 293 416 383 338 439 542 443
#> [76] 291 302 355 340 433 529 370 295 308 342 261 449 535 393 212
#> [91] 286 277 262 388 513 374 254 320 247 277 366 483 296 227 195
#> [106] 208 234 399 395 310 225 262 215 293 392 468 397 309 537 375
#> [121] 224 264 314 247 298 273 382 212 202 217 256 195 170 240 233
#> [136] 416 386 329 246 329 322 329 440 438 401 272 310 251 411 441
#> [151] 406 380 291 336 265 367 421 378 330 270 383 377 275 463 283
#> [166] 263 253 283 259 290 401 353 271 325 308 399 351 416 422 253
#> [181] 348 303 328 321 456 352 282 220 332 272 363 412 388 332 289
#> [196] 337 324 241 323 361 249 277 268 228 276 346 293 266 201 284
#> [211] 228 303 442 351 285 275 317 341 279 336 302 221 243 230 249
#> [226] 284 345 356 255 268 256 283 313 378 401 355 338 310 325 375
#> [241] 423 443 478 319 440 352 309 414 482 455 223 248 321 264 356
#> [256] 432 394 254 785 312 316 457 488 329 185 280 317 376 467 536
#> [271] 352 263 291 307 226 391 462 374 330 313 339 361 498 502 348
#> [286] 237 302 263 312 400 472 367 207 213 240 275 472 507 367 265
#> [301] 414 316 383 425 480 460 330 460 307 287 483 524 413 312 263
#> [316] 245 256 429 561 467 270 341 335 412 461 508 358 266 324 325
#> [331] 296 575 537 376 325 348 330 300 482 575 392 233 345 304 363
#> [346] 455 642 415 340 395 453 406 526 705 550 459 485 646 691 861
#> [361] 1028 962 1035 891 557 520 434 380 440 408 362 304 270 488 344
#> [376] 210 276 226 239 292 402 303 217 284 223 264 404 388 307 242
#> [391] 230 323 283 397 442 352 286 222 336 285 316 428 365 254 312
#> [406] 245 237 490 417 387 289 311 327 378 556 673 480 200 226 241
#> [421] 245 428 516 274 236 286 272 346 562 421 346 278 194 166 198
#> [436] 417 417 367 266 236 283 229 455 389 356 193 182 225 265 297
#> [451] 410 315 246 208 250 280 394 405 300 202 253 247 269 360 450
#> [466] 300 310 437 256 322 348 387 236 162 223 213 240 335 367 274
#> [481] 189 257 423 212 194 249 224 168 213 244 327 149 173 262 158
#> [496] 143 200 179 324 321 232 161 195 268 243 325 291 202 250 481
#> [511] 312 310 418 398 218 215 218 234 233 372 320 228 236 324 325
#> [526] 335 287 218 173 207 281 220 220 267 399 219 167 205 260 241
#> [541] 313 335 204 227 217 202 234 267 235 212 184 237 237 239 290
#> [556] 289 180 238 198 192 254 223 210 207 176 260 252 210 252 206
#> [571] 263 188 210 277 217 295 226 228 222 229 243 237 307 291 241
#> [586] 239 235 222 232 278 322 265 207 246 262 232 321 342 246 204
#> [601] 270 234 294 311 402 365 253 235 207 266 374 483 252 225 284
#> [616] 268 315 341 295 327 240 233 225 259 327 291 282 197 232 229
#> [631] 357 372 448 284 221 261 266 330 357 386 279 221 316 247 255
#> [646] 391 401 253 200 207 221 248 289 420 226 178 256 198 222 268
#> [661] 389 307 175 182 214 246 309
Kemudian, kita akan ubah data item_cnt_day dari
transaksi 1 tahun setelah transaksi pertama terjadi (setelah 2014-01-02)
dengan past_item_cnt yang merupakan transaksi 1 tahun
sebelumnya.
daily_transaction <- daily_transaction %>%
filter(ds >= "2014-01-02") %>%
mutate(item_cnt_day = past_item_cnt)
daily_transactionprophetKonsep dasar dalam pemahaman kasus time series adalah dengan melakukan pemecahan komponen dari data time series (decompose) dimana komponen terbagi menjadi 2, yaitu:
Decompose time series ini banyak macamnya dan yang digunakan
oleh Prophet secara default adalah metode General
Additive Model (GAM). Ide di balik GAM adalah ketiga komponen
di atas dijumlahkan untuk menyusun data time series kita, secara
matematis:
\[ Y(t) = T(t) + S(t) \]
Dimana \(Y(t)\) adalah observasi nilai time series kita.
Pada konsep time series, peramalan/forecasting time series didasari oleh kondisi/perilaku di masa lalu. Jika disimpulkan, maka konsep untuk melakukan forecasting nilai masa depan adalah memperhatikan kondisi trend dan seasonal dari data time series.
🔻 Setelah semua persiapan data selesai. Kini kita tugaskan
prophet untuk mencari pola dari data time series kita.
prophet()fit.prophet()Tambahkan regressor kolom item_cnt_day
Karena model kita telah belajar dari pola data masa lalu, kita akan
coba meramal/forecast data kita untuk 1 tahun ke
depan. Untuk itu kita harus mempersipakan dataframe baru yang
berisi informasi waktu yang ingin di-forecast. Hal ini dapat
dilakukan menggunakan method .make_future_dataframe() dari
objek model kita, yaitu model_prophet.
Parameter fungsi make_future_dataframe():
m : nama modelperiods: Banyaknya data yang ingin
di-forecastfreq: interval data. "day",
"month", dan lainnya.#> [1] 1031
Tambahkan kolom item_cnt_day pada future dataframe
dengan data item_cnt_day masa lalu hingga masa depan yang sebelumnya
sudah disimpan
Dataframe future berisi informasi tanggal tepat 364 hari
setelah data fitting berakhir. Kita akan menggunakan dataframe ini untuk
melakukan forecasting menggunakan method predict().
Dari berbagai nilai di atas kita akan mengambil beberapa informasi saja, yaitu:
ds: Tanggaltrend: Nilai trend (pola general)weekly: Nilai seasonal weekly (pola mingguan)yearly: Nilai seasonal yearly (pola tahunan)yhat: Nilai hasil forecastSetelah membuat model dan forecast, dapat dilakukan
visualisasi dengan method plot() dengan memasukan parameter
sebagai berikut:
x = object model prophet
model_prophetfcst = dataframe hasil dari fungsi
predict() yaitu object forecastKeterangan:
Dalam melakukan interpretasi model prophet, kita dapat
memvisualisasikan setiap komponennya menggunakan fungsi
prophet_plot_components()
m = object model prophet
model_prophetfcst = dataframe hasil dari fungsi
predict() yaitu object forecastTerdapat components baru setelah dilakukan add regressor yaitu nilai
item_cnt_day