Pemahaman & Persiapan Data

Data yang kita gunakan pada LBB Timeseries ini adalah data kriminal di chicago USA dari tahun 2011.

# read crimes_data_2011.csv
crime <- read.csv("data/crimes_data_2011.csv")

# ubah type kolom Date
crime$Date <- mdy_hms(crime$Date)

#hapus Date yang NA
crime <- crime[!is.na(crime$Date), ]

Kita hanya menggunakan tipe Robbery (pencurian).

crime_filter <- crime %>%
  filter(crime$Primary.Type == "ROBBERY") %>%
  arrange(Date)

Selanjutnya, kita akan menggunakan periode bulanan. Oleh karena itu, kita GROUP BY berdasarkan month pada kolom Date.

crime_bulanan <- crime_filter %>%
  mutate(year_month = floor_date(Date, "month")) %>%
  group_by(year_month) %>%
  summarise(total_kriminal = n())

Kita harus mengisi data missing setelah proses GROUP BY. Diberikan value = 0 untuk data bulanan yang tidak ada.

crime_bulanan_pad <- 
crime_bulanan %>% 
  pad(interval = "month")

crime_bulanan_pad <- crime_bulanan_pad %>%
  fill_by_value(value = 0, col_fill = "total_kriminal")

Sekarang kita membuat data timeseries atas data crime yang telah kita Group By dan padding.

ts_crime_bulanan_pad <- ts(crime_bulanan_pad$total_kriminal, start = c(year(min(crime_bulanan_pad$year_month)), month(min(crime_bulanan_pad$year_month))), frequency = 12)

ts_crime_bulanan_pad %>% 
  str()
#>  Time-Series [1:260] from 2001 to 2023: 4 2 0 3 2 0 0 0 0 0 ...

Explanatory Data Analysis

Sekarang kita melakukan visualisasi atas timeseries yang telah kita bentuk:

ts_crime_bulanan_pad %>% 
  autoplot()

Insight : - Tidak ada trend

Cross Validation

18 bulan terakhir untuk data test:

# Data Train
crime_train <- head(ts_crime_bulanan_pad, -18)

# Data Test
crime_test <- tail(ts_crime_bulanan_pad, 18)

Visualisasi Decomposition

Sebelum melakukan modeling forecasting, kita perlu mengamati hasil decompose berikut :

crime_bulanan_pad_decom <- crime_train %>% 
  decompose()

# visualisasi decompose
crime_bulanan_pad_decom %>% 
  autoplot()

Insight dari decompose : - Tidak ada Trend - Tidak ada Seasonal

Membuat Model

Kita menggunakan model ARIMA karena tidak ada trend dan tidak ada seasonal.

Cek apakah data sudah stasioner:

adf.test(crime_train)
#> 
#>  Augmented Dickey-Fuller Test
#> 
#> data:  crime_train
#> Dickey-Fuller = -2.2017, Lag order = 6, p-value = 0.491
#> alternative hypothesis: stationary

p-value > 0,05. Data dianggap tidak stasioner

Berikut adalah langkah membuat data stasioner :

ts_crime_bulanan_pad %>% autoplot()

data.frame(
  xt = c(crime_train),
  lag1 = lag(x = as.vector(crime_train), n = 1),
  lag2 = lag(x = as.vector(crime_train), n = 2),
  lag3 = lag(x = as.vector(crime_train), n = 3),
  lag4 = lag(x = as.vector(crime_train), n = 4),
  lag5 = lag(x = as.vector(crime_train), n = 5) 
) %>% 
  na.omit() %>% 
  GGally::ggcorr()

data.frame(
  xt = c(diff(crime_train)),
  lag1 = lag(x = as.vector(diff(crime_train)), n = 1),
  lag2 = lag(x = as.vector(diff(crime_train)), n = 2),
  lag3 = lag(x = as.vector(diff(crime_train)), n = 3),
  lag4 = lag(x = as.vector(diff(crime_train)), n = 4),
  lag5 = lag(x = as.vector(diff(crime_train)), n = 5) 
) %>% 
  na.omit() %>% 
  GGally::ggcorr(label = T)

melakukan proses differencing :

diff(crime_train,differences = 2) %>% 
  adf.test()
#> 
#>  Augmented Dickey-Fuller Test
#> 
#> data:  .
#> Dickey-Fuller = -8.1789, Lag order = 6, p-value = 0.01
#> alternative hypothesis: stationary

Simpan hasil differencing sebanyak 2.

ts_crime_bulanan_pad_diff <- diff(crime_train,differences = 2)

mencari nilai p:

ts_crime_bulanan_pad_diff %>%
  tsdisplay()

List kombinasi ARIMA : - p: 0,1,2,3,4,8,9,10,11,21 (melewati garis biru PACF) - d: 2 (2 diff) - q: 0,1,2,3,4,5,6,11,12,15,16,19,23

karena kombinasi terlalu banyak, kita menggunakan auto arima:

auto_arima <- auto.arima(y = crime_train)

Evaluasi

menggunakan fungsi accuracy:

accuracy(auto_arima)
#>                      ME     RMSE     MAE MPE MAPE      MASE        ACF1
#> Training set -0.1407877 91.87275 28.5767 NaN  Inf 0.2702567 -0.07393712

MAPE Inf karena beberapa data ada yang bernilai 0.