Untuk membantu polisi memberantas kejahatan, kita bisa melihat prediksi di jam tertentu yang sering terjadi tindak kejahatan, agar polisi bisa tau kapan melakukan patroli atau sebagainya. Agar permasalahan itu terhindar, kita akan menggunakan pemodelan Machine Learning Time Series & Forcasting.
data ini diambil dari data.cityofchicago.org
Load Library
library(dplyr)
library(padr)
library(lubridate)
library(forecast)
library(padr)
library(ggplot2)
library(zoo)
library(MLmetrics)
Read data
read <- read.csv("crime.csv")
read
ID : Pengidentifikasi unik untuk catatan.
Case Number : Nomor RD Departemen Kepolisian Chicago (Nomor Divisi Catatan), yang unik untuk insiden tersebut.
Date : Tanggal saat kejadian itu terjadi. ini terkadang merupakan perkiraan terbaik.
Block : Alamat yang diedit sebagian di mana insiden terjadi, menempatkannya di blok yang sama dengan alamat sebenarnya.
IUCR : Kode Pelaporan Kejahatan Seragam Illinois. Ini terkait langsung dengan Tipe dan Deskripsi Utama. Lihat daftar kode IUCR di https://data.cityofchicago.org/d/c7ck-438e.
Primary Type : Deskripsi utama kode IUCR.
Description : Deskripsi sekunder kode IUCR, subkategori dari deskripsi utama.
Ubah tipe data, format dan bulatkan menjadi satuan hari
crime_agg <-
read %>%
mutate(Date = mdy_hms(Date),
Date = ymd_hms(format(Date,"%Y-%m-%d %H:00:00")))
crime_agg
Grouping dengan kolom Date yang sudah di bulatkan menjadi satuan jam dengan ID karena jumlah dalam sebuah baris di kolom visitor bergantung pada jumlah keunikan ID, grouping ini diperlukan untuk memperlihatkan jumlah tindak kejahatan perjamnya.
crime_agg <-
crime_agg %>%
group_by(Date) %>%
summarise(total = n_distinct(ID)) %>%
ungroup()
crime_agg
Time Series forcasting membutuhkan data yang terurut, karena datanya lumayan banyak akan sulit jika diperiksa manual satu per satu, kita akan menggunakan fungsi pad() dari package padr untuk mengetahui data perjamnya yang tidak terurut dan jika ada yang kosong kita mengisinya dengan nilai 0
crime <- crime_agg %>%
pad(start_val = min(crime_agg$Date), end_val = max(crime_agg$Date))
crime
cek apakah ada baris yang kosong
crime %>%
anyNA()
## [1] FALSE
crime_ts <-
crime$total %>%
ts(frequency = 24)
crime_ts %>%
decompose() %>%
autoplot
Bisa di plot bahwa trend masih naik turun dengan smooth, kejadian itu bisa mengindikasikan bahwa time series object itu adalah multiseosonal.
Dikarenakan itu kita bisa menggunakan fungsi msts(Multi-Seosonal time series)
crime_msts <-
crime$total %>%
msts(seasonal.periods = 24)
untuk melakukan decompose pada Multi Seosonal kita bisa menggunakan fungsi mstl
crime_msts %>%
mstl() %>%
autoplot()
Setelah itu kita akan cross validation atau membagi 2 data untuk data train dan test, ketika melakukan cross validation kita harus menmbaginnya dengan terurut, dengan kondisi data train lebih banyak daripada data test
train_msts <-
crime_msts %>%
head(-24)
test_msts <-
crime_msts %>%
tail(24)
Setelah melakukan cross validation kita akan melakukan membuat model dengan arima dan ETS Holt-Winters manakah yang menghasilkan nilai error terkecil.
# SARIMA
crime_arima <- stlm(train_msts, method = "arima")
# ets Holt-Winters
crime_ets <- stlm(train_msts, method = "ets")
# SARIMA
forecast_arima <- forecast(crime_arima, h = 24)
# ets Holt-Winters
forecast_ets <- forecast(crime_ets, h = 24)
test_msts %>%
autoplot()+
autolayer(forecast_arima$mean, series = "Forecast Sarima") +
autolayer(forecast_ets$mean, series = "Forecast ETS") +
autolayer(test_msts, series = "Data Actual")
data.frame(
row.names = "MAE",
ARIMA = MAE(forecast_arima$mean, test_msts),
ETS = MAE( forecast_ets$mean, test_msts))
Bisa dilihat bahwa nilai MAE(Mean Absolute Error) ETS(4.023363) lebih baik dibandingkan nilai MAE ARIMA(4.588295)