Time series data merupakan data yang berhubungan dengan waktu yang memiliki interval waktu yang sama
Forecasting merupakan suatu metode untuk memprediksi/meramalkan data di masa depan
Discussion: Apa perbedaan Time Series dengan Regresi?
Perbedaan mendasar antara time series dengan regresi adalah jika pada regresi untuk memprediksi suatu nilai Y dipengaruhi oleh beberapa faktor yaitu x1,x2,..,xn. Sedangkan jika time series, untuk memprediksi suatu nilai Y dipengaruhi oleh nilai Y itu sendiri pada masa lampau (\(Y_{t-1}\)).
Regression
\[y = \beta_0+\beta_1*x_1+\beta_2*x_2+...+\beta_n*x_n\]
Time Series
\[y_t = \beta_0+\beta_1*y_{t-1}+\beta_2*y_{t-2}+...+\beta_n*y_{t-n}\]
Analisis time series berhubungan dengan suatu data yang memiliki nilai numerik pada interval waktu tertentu. Proses untuk memprediksi nilai pada anilisis time series disebut sebagai peramalan atau forecasting. Ide utama dalam melakukan forecasting itu adalah korelasi dari data numerik.
1. Data harus terurut berdasarkan periode waktunya
dat <- data.frame(year = c(2011, 2012, 2014, 2016, 2015, 2013),
value = c(1,2,3,4,5,6))
dat#> year value
#> 1 2011 1
#> 2 2012 2
#> 3 2014 3
#> 4 2016 4
#> 5 2015 5
#> 6 2013 6
dat %>%
arrange(year)#> year value
#> 1 2011 1
#> 2 2012 2
#> 3 2013 6
#> 4 2014 3
#> 5 2015 5
#> 6 2016 4
2. Tidak boleh ada waktu atau periode yang terlewat/bolong
dat <- data.frame(date = as.Date(c("2020-02-01","2020-02-03","2020-02-04")),
value = c(23,34,20))
dat#> date value
#> 1 2020-02-01 23
#> 2 2020-02-03 34
#> 3 2020-02-04 20
library(padr)
dat <- dat %>% pad()3. Data tidak boleh ada yang missing
library(zoo)
dat %>% mutate(value = na.fill(value, fill = "extend"))#> date value
#> 1 2020-02-01 23.0
#> 2 2020-02-02 28.5
#> 3 2020-02-03 34.0
#> 4 2020-02-04 20.0
Selain menggunakan function na.fill dari package zoo, kita juga dapat menggunakan berbagai fungsi imputasi dari package imputeTS untuk mengisi nilai NA pada objek time series Package imputeTS
Untuk membuat sebuah object time series pada R kita bisa menggunakan function ts() dengan parameter yang diperlukan yaitu :
ts(data, start, frequency)
data = data yang akan kita prediksistart = waktu awal mula data yang akan diprediksifrequency = pola berulang dari data#> Data Minute Hour Day Week Month Year
#> 1 Daily - - - 7 7*4 7*4*12
#> 2 Hourly - - 24 24*7 24*7*4 24*7*4*12
#> 3 Minutes - 60 60*24 60*24*7 60*24*7*4 60*24*7*4*12
#> 4 Seconds 60 60*60 60*60*24 60*60*24*7 60*60*24*7*4 60*60*24*7*4*12
Dive deeper :
Langkah awal dalam membuat object time series:
Kita akan menggunakan data emisi CO2 di Indonesia dimana datanya sudah tersimpan dalam folder data_input dengan nama environment_1970f.csv. Dari data co2 ini, kita akan menggunakan 2 kolom yang kita butuhkan yaitu kolom year untuk menunjukkan waktu dan CO2.emissions..metric.tons.per.capita. sebagai nilai Y yang kita amati untuk membuat object ts.
# read data co
co2 <- read.csv("data_input/environment_1970f.csv")
head(co2)#> year CO2.emissions..kt. CO2.emissions..metric.tons.per.capita.
#> 1 1970 35822.92 0.3119519
#> 2 1971 38987.54 0.3306215
#> 3 1972 43340.27 0.3580080
#> 4 1973 49134.13 0.3954703
#> 5 1974 51260.99 0.4021567
#> 6 1975 53963.57 0.4128050
#> Methane.emissions..kt.of.CO2.equivalent.
#> 1 126665
#> 2 119293
#> 3 195338
#> 4 136928
#> 5 122570
#> 6 121065
#> Nitrous.oxide.emissions..thousand.metric.tons.of.CO2.equivalent.
#> 1 51908.88
#> 2 49004.80
#> 3 79261.42
#> 4 56928.71
#> 5 50997.79
#> 6 50922.15
#> Other.greenhouse.gas.emissions..HFC..PFC.and.SF6..thousand.metric.tons.of.CO2.equivalent.
#> 1 130405.80
#> 2 94658.48
#> 3 422459.50
#> 4 174340.90
#> 5 110213.86
#> 6 109630.88
#> Total.greenhouse.gas.emissions..kt.of.CO2.equivalent.
#> 1 339677.1
#> 2 294004.9
#> 3 733432.9
#> 4 409241.7
#> 5 329453.2
#> 6 329119.3
Data co2 terdiri dari 43 observasi yang mewakili kontribusi gas emisi per tahun terhadap atmosfer Indonesia (43 tahun, 1970-2012). Data ini terdiri dari 7 variabel, yaitu:
year: tahun.emisi co2 (kt): emisi yang berasal dari pembakaran bahan bakar fosil dan pembuatan semen, termasuk yang dihasilkan selama konsumsi.emisi co2 (metrik ton per kapita): idem.emisi metana (kt setara co2): emisi yang berasal dari aktivitas manusia (pertanian) dan dari produksi metana industri.emisi nitro oksida (ribu metrik ton setara co2): emisi dari pembakaran biomassa pertanian, kegiatan industri, dan pengelolaan ternak.emisi gas rumah kaca dan lainnya, HFC, PFC dan SF6 (ribu metrik ton setara co2): emisi hasil samping dari hidrofluorokarbon, perfluorokarbon, dan sulfur hexafluoride.total emisi gas rumah kaca (setara dengan co2): total CO2 tidak termasuk pembakaran biomassa siklus pendek (pembakaran limbah pertanian dan savannah), tetapi termasuk pembakaran biomassa lainnya (kebakaran hutan, pembusukan pasca-pembakaran, kebakaran gambut, dan pembusukan lahan gambut yang dikeringkan), semua sumber CH4 antropogenik, sumber N2O dan gas-F (HFC, PFC, dan SF6).Dari data co2 ini, kita akan menggunakan 2 kolom sebagai informasi yang kita butuhkan yaitu kolom year untuk menunjukkan waktu dan CO2.emissions..metric.tons.per.capita. sebagai nilai Y yang kita amati untuk membuat object ts.
untuk mengetahui periode waktu data time series dari awal hingga akhir kita bisa menggunakan fungsi range().
# range waktu
range(co2$year)#> [1] 1970 2012
untuk mengetahui frequency data yang dimiliki dapat diinspect berdasarkan:
ts() function# simpan dalam object co2_ts
co2_ts <- ts(data = co2$CO2.emissions..metric.tons.per.capita.,
start = 1970,
frequency = 1)
co2_ts#> Time Series:
#> Start = 1970
#> End = 2012
#> Frequency = 1
#> [1] 0.3119519 0.3306215 0.3580080 0.3954703 0.4021567 0.4128050 0.4612390
#> [8] 0.6002978 0.6677802 0.6601457 0.6426495 0.6634071 0.6822242 0.6640976
#> [15] 0.6944021 0.7347680 0.7229173 0.7184145 0.7552095 0.7348064 0.8243417
#> [22] 0.9735380 1.0788747 1.1452296 1.1416286 1.1420774 1.2669930 1.3738789
#> [29] 1.0218517 1.1599925 1.2452416 1.3748183 1.4102338 1.4364045 1.5098982
#> [36] 1.5084806 1.5015768 1.6118554 1.7638951 1.8651654 1.7679079 2.3335854
#> [43] 2.4089201
co2_ts# class ts object
class(co2_ts)#> [1] "ts"
# inspect pola data
co2_ts %>% autoplot() Note :
Pergerakan emisi gas co2 di indonesia secara umum naik terus (trend naik). Terjadi penurunan pada tahun 1998, pada saat itu indonesia sedang terjadi krismon (krisis moneter) dimana bisa saja banyak pabrik yang tutup sehingga menyebabkan adanya menurunan emisi gas co2. Dan dari tahun 2010 kenaikan emisi co2 semakin meningkat tajam, bisa saja disebabkan adanya peningkatan jumlah kendaraan bermotor di indonesia yang semakin banyak.
Gunakan function window() untuk subset periode tertentu
window(x = co2_ts, start = 1995, end = 2000) %>%
autoplot()nybirth.csvbirth <- read.csv("data_input/nybirth.csv")
head(birth, 210)#> date births
#> 1 1946-01-01 26.663
#> 2 1946-02-01 23.598
#> 3 1946-03-01 26.931
#> 4 1946-04-01 24.740
#> 5 1946-05-01 25.806
#> 6 1946-06-01 24.364
#> 7 1946-07-01 24.477
#> 8 1946-08-01 23.901
#> 9 1946-09-01 23.175
#> 10 1946-10-01 23.227
#> 11 1946-11-01 21.672
#> 12 1946-12-01 21.870
#> 13 1947-01-01 21.439
#> 14 1947-02-01 21.089
#> 15 1947-03-01 23.709
#> 16 1947-04-01 21.669
#> 17 1947-05-01 21.752
#> 18 1947-06-01 20.761
#> 19 1947-07-01 23.479
#> 20 1947-08-01 23.824
#> 21 1947-09-01 23.105
#> 22 1947-10-01 23.110
#> 23 1947-11-01 21.759
#> 24 1947-12-01 22.073
#> 25 1948-01-01 21.937
#> 26 1948-02-01 20.035
#> 27 1948-03-01 23.590
#> 28 1948-04-01 21.672
#> 29 1948-05-01 22.222
#> 30 1948-06-01 22.123
#> 31 1948-07-01 23.950
#> 32 1948-08-01 23.504
#> 33 1948-09-01 22.238
#> 34 1948-10-01 23.142
#> 35 1948-11-01 21.059
#> 36 1948-12-01 21.573
#> 37 1949-01-01 21.548
#> 38 1949-02-01 20.000
#> 39 1949-03-01 22.424
#> 40 1949-04-01 20.615
#> 41 1949-05-01 21.761
#> 42 1949-06-01 22.874
#> 43 1949-07-01 24.104
#> 44 1949-08-01 23.748
#> 45 1949-09-01 23.262
#> 46 1949-10-01 22.907
#> 47 1949-11-01 21.519
#> 48 1949-12-01 22.025
#> 49 1950-01-01 22.604
#> 50 1950-02-01 20.894
#> 51 1950-03-01 24.677
#> 52 1950-04-01 23.673
#> 53 1950-05-01 25.320
#> 54 1950-06-01 23.583
#> 55 1950-07-01 24.671
#> 56 1950-08-01 24.454
#> 57 1950-09-01 24.122
#> 58 1950-10-01 24.252
#> 59 1950-11-01 22.084
#> 60 1950-12-01 22.991
#> 61 1951-01-01 23.287
#> 62 1951-02-01 23.049
#> 63 1951-03-01 25.076
#> 64 1951-04-01 24.037
#> 65 1951-05-01 24.430
#> 66 1951-06-01 24.667
#> 67 1951-07-01 26.451
#> 68 1951-08-01 25.618
#> 69 1951-09-01 25.014
#> 70 1951-10-01 25.110
#> 71 1951-11-01 22.964
#> 72 1951-12-01 23.981
#> 73 1952-01-01 23.798
#> 74 1952-02-01 22.270
#> 75 1952-03-01 24.775
#> 76 1952-04-01 22.646
#> 77 1952-05-01 23.988
#> 78 1952-06-01 24.737
#> 79 1952-07-01 26.276
#> 80 1952-08-01 25.816
#> 81 1952-09-01 25.210
#> 82 1952-10-01 25.199
#> 83 1952-11-01 23.162
#> 84 1952-12-01 24.707
#> 85 1953-01-01 24.364
#> 86 1953-02-01 22.644
#> 87 1953-03-01 25.565
#> 88 1953-04-01 24.062
#> 89 1953-05-01 25.431
#> 90 1953-06-01 24.635
#> 91 1953-07-01 27.009
#> 92 1953-08-01 26.606
#> 93 1953-09-01 26.268
#> 94 1953-10-01 26.462
#> 95 1953-11-01 25.246
#> 96 1953-12-01 25.180
#> 97 1954-01-01 24.657
#> 98 1954-02-01 23.304
#> 99 1954-03-01 26.982
#> 100 1954-04-01 26.199
#> 101 1954-05-01 27.210
#> 102 1954-06-01 26.122
#> 103 1954-07-01 26.706
#> 104 1954-08-01 26.878
#> 105 1954-09-01 26.152
#> 106 1954-10-01 26.379
#> 107 1954-11-01 24.712
#> 108 1954-12-01 25.688
#> 109 1955-01-01 24.990
#> 110 1955-02-01 24.239
#> 111 1955-03-01 26.721
#> 112 1955-04-01 23.475
#> 113 1955-05-01 24.767
#> 114 1955-06-01 26.219
#> 115 1955-07-01 28.361
#> 116 1955-08-01 28.599
#> 117 1955-09-01 27.914
#> 118 1955-10-01 27.784
#> 119 1955-11-01 25.693
#> 120 1955-12-01 26.881
#> 121 1956-01-01 26.217
#> 122 1956-02-01 24.218
#> 123 1956-03-01 27.914
#> 124 1956-04-01 26.975
#> 125 1956-05-01 28.527
#> 126 1956-06-01 27.139
#> 127 1956-07-01 28.982
#> 128 1956-08-01 28.169
#> 129 1956-09-01 28.056
#> 130 1956-10-01 29.136
#> 131 1956-11-01 26.291
#> 132 1956-12-01 26.987
#> 133 1957-01-01 26.589
#> 134 1957-02-01 24.848
#> 135 1957-03-01 27.543
#> 136 1957-04-01 26.896
#> 137 1957-05-01 28.878
#> 138 1957-06-01 27.390
#> 139 1957-07-01 28.065
#> 140 1957-08-01 28.141
#> 141 1957-09-01 29.048
#> 142 1957-10-01 28.484
#> 143 1957-11-01 26.634
#> 144 1957-12-01 27.735
#> 145 1958-01-01 27.132
#> 146 1958-02-01 24.924
#> 147 1958-03-01 28.963
#> 148 1958-04-01 26.589
#> 149 1958-05-01 27.931
#> 150 1958-06-01 28.009
#> 151 1958-07-01 29.229
#> 152 1958-08-01 28.759
#> 153 1958-09-01 28.405
#> 154 1958-10-01 27.945
#> 155 1958-11-01 25.912
#> 156 1958-12-01 26.619
#> 157 1959-01-01 26.076
#> 158 1959-02-01 25.286
#> 159 1959-03-01 27.660
#> 160 1959-04-01 25.951
#> 161 1959-05-01 26.398
#> 162 1959-06-01 25.565
#> 163 1959-07-01 28.865
#> 164 1959-08-01 30.000
#> 165 1959-09-01 29.261
#> 166 1959-10-01 29.012
#> 167 1959-11-01 26.992
#> 168 1959-12-01 27.897
Data di atas merupakan data persentase kelahiran di New York per bulan. Terdiri dari:
date: tanggal saat dilakukan pencatatan persentase kelahiran
births: persentase kelahiran.
class(birth)#> [1] "data.frame"
# manipulate data
birth_clean <- birth %>% mutate(date = ymd(date),
month = month(date, label = T))?locales
Sys.setlocale("LC_TIME", "English")#> [1] "English_United States.1252"
# cek range
range(birth_clean$date)#> [1] "1946-01-01" "1959-12-01"
Eksplorasi data
cek kelengkapan interval waktu
birth_clean %>% pad() %>% is.na() %>% colSums()#> date births month
#> 0 0 0
ggplot(data = birth_clean, aes(x = date, y = births))+
geom_point(col = "blue")+
geom_point(data = birth_clean %>%
filter(month %in% c("Jan")), col = "red")+
geom_line()Insight:
birth dan disimpan dalam object birth_ts. Pola yang ingin dilihat adalah pola tahunan.# answer here
birth_ts <- ts(data = birth_clean$births, start = c(1946,1), frequency = 12)
birth_ts#> Jan Feb Mar Apr May Jun Jul Aug Sep Oct
#> 1946 26.663 23.598 26.931 24.740 25.806 24.364 24.477 23.901 23.175 23.227
#> 1947 21.439 21.089 23.709 21.669 21.752 20.761 23.479 23.824 23.105 23.110
#> 1948 21.937 20.035 23.590 21.672 22.222 22.123 23.950 23.504 22.238 23.142
#> 1949 21.548 20.000 22.424 20.615 21.761 22.874 24.104 23.748 23.262 22.907
#> 1950 22.604 20.894 24.677 23.673 25.320 23.583 24.671 24.454 24.122 24.252
#> 1951 23.287 23.049 25.076 24.037 24.430 24.667 26.451 25.618 25.014 25.110
#> 1952 23.798 22.270 24.775 22.646 23.988 24.737 26.276 25.816 25.210 25.199
#> 1953 24.364 22.644 25.565 24.062 25.431 24.635 27.009 26.606 26.268 26.462
#> 1954 24.657 23.304 26.982 26.199 27.210 26.122 26.706 26.878 26.152 26.379
#> 1955 24.990 24.239 26.721 23.475 24.767 26.219 28.361 28.599 27.914 27.784
#> 1956 26.217 24.218 27.914 26.975 28.527 27.139 28.982 28.169 28.056 29.136
#> 1957 26.589 24.848 27.543 26.896 28.878 27.390 28.065 28.141 29.048 28.484
#> 1958 27.132 24.924 28.963 26.589 27.931 28.009 29.229 28.759 28.405 27.945
#> 1959 26.076 25.286 27.660 25.951 26.398 25.565 28.865 30.000 29.261 29.012
#> Nov Dec
#> 1946 21.672 21.870
#> 1947 21.759 22.073
#> 1948 21.059 21.573
#> 1949 21.519 22.025
#> 1950 22.084 22.991
#> 1951 22.964 23.981
#> 1952 23.162 24.707
#> 1953 25.246 25.180
#> 1954 24.712 25.688
#> 1955 25.693 26.881
#> 1956 26.291 26.987
#> 1957 26.634 27.735
#> 1958 25.912 26.619
#> 1959 26.992 27.897
birth_ts dari Jan 1950-Des 1955library(TSstudio)
# answer here
birth_ts %>% ts_plot(slider = T)Decomposition adalah suatu tahapan dalam time series analisis yang digunakan untuk menguraikan beberapa komponen dalam time series data.
Komponen/unsur dalam time series :
Trend : pola data secara general, cenderung untuk naik atau turun. Jika pada trend masih terdapat pola (fluktuatif) artinya masih ada pola yang belum tertangkap dengan baik.
Seasonal : pola musiman yang membentuk pola berulang pada periode waktu yang tetap
Residual/Error : pola yang tidak dapat ditangkap dalam trend dan seasonal
Sebelum melakukan model forecasting kita perlu mengamati objek time series dari hasil decompose. Ide utama dari decomposition adalah untuk menguraikan ketiga komponen dari objek ts (trend, seasonal, residual).
Jika pada hasil decompose, trend masih membetuk sebuah pola maka dapat dicurigai masih ada seasonality yang belum ditangkap. Seharusnya trend cenderung naik atau cendurung turun.
Untuk dapat menguraikan object time series kita menjadi 3 komponen tersebut, kita dapat menggunakan fungsi decompose().
# decompose
birth_dc <- birth_ts %>%
decompose()Memvisualisasikan hasil decompose menggunakan autoplot() dari package forecast
# visualize
birth_dc %>% autoplot()Pada hasil decompose kita mendapatkan informasi visualisasi:
Terdapat 2 jenis model pada data time series, yaitu :
\(Y_t = T_t + S_t + E_t\)
Data = Trend + Seasonal + Error
\(Y_t = T_t * S_t * E_t\)
Data = Trend * Seasonal * Error
Berikut ini contoh data time series yang bertipe additive :
Berikut ini contoh data time series yang bertipe multiplicative :
AirPassengers %>% autoplot()birth_ts1 <- ts(data = birth_clean$births, start = c(1946,1), frequency = 4)
birth_ts1 %>% ts_plot(slider = T)birth_dc1 <- birth_ts1 %>%
decompose()
birth_dc1 %>% autoplot()ts(data, start, frequency)data : data yang ingin di forecaststart : awal mula dari data time seriesfrequency : pola berulang yang ingin diamati\(X = T+S+E\)
\(X = T*S*E\)
Jika kita perhatikan lagi pada data birth_ts memiliki pola additive, karena varians dari polanya tetap atau konstan. Untuk melakukan decompose pada pola additive tambahkan parameter type = "additive" dimana secara default fungsi decompose() memiliki type = “additive”.
Melakukan inspect komponen time series padaa data birth_dc
1. Trend
Trend diperoleh dari hasil perhintungan center moving average (CMA). Tujuan utamanya untuk smoothing data sehingga diperoleh trend yang cenderung naik/ cenderung turun.
birth_dc %>% autoplot()Trend = Data - Seasonality - Error
birth_dc$trend %>% autoplot()Pendekatan manual menddungkan Center Moving Average
birth_trend <- ma(x = birth_ts, order = 12, centre = T) # menggunakan CMA 12
birth_trend %>% autoplot()birth_dc$trend %>% autoplot()# contoh
dat <- c(2,3,1,2,1)
dat_ts <- ts(dat,frequency = 2)
dat_ts#> Time Series:
#> Start = c(1, 1)
#> End = c(3, 1)
#> Frequency = 2
#> [1] 2 3 1 2 1
ma(dat_ts,order = 2,centre = T)#> Time Series:
#> Start = c(1, 1)
#> End = c(3, 1)
#> Frequency = 2
#> [1] NA 2.25 1.75 1.50 NA
2. Seasonal
Karena polanya additive maka:
Seasonal + Error = Data - Trend
birth_dc$seasonal %>% autoplot()Pendekatan manual:
# matematic didalamnya
sea.err_birth <- birth_ts-birth_trend
sea.err_birth %>% autoplot()
# mean of each month
mean.month_birth <- sea.err_birth %>%
matrix(ncol = 12, byrow = T) %>%
colMeans(na.rm = T)
# mean global
mean.glob_birth <- mean(mean.month_birth)
# Seasonality Calculation
birth_seasonal <- ts(rep(mean.month_birth - mean.glob_birth, 15), start = start(birth_ts), frequency = 12)
birth_seasonal %>% autoplot()3. Error
Untuk memperoleh informasi error pada model additive, dapat menggunakan rumus:
Error = Data - Trend - Seasonal
birth_dc$random %>% autoplot()
# matematis didalamnya
birth_error <- birth_ts - (birth_trend + birth_seasonal)
birth_error %>% autoplot()Decompose dapat kita gunakan untuk melakukan analisis seasonal dengan tujuan untuk mendapatkan insight dari efek seasonal yang ada.
Tujuan dan manfaat melakukan decompose : 1. Mengetahui tipe time series yang kita miliki, multiplicative atau additive 2. Kita mengetahui komponen trend, seasonal, dan error pada data kita
Jika kita memiliki pola multiplicative pada data time series dan ingin membuat decomposenya cukup menambahkan type = "multiplicative" pada fungsi decompose().
Ketika kita menemukan pola data kita mengandung multiplikative :
cara 1: membuat data multiplikative tersebut menjadi additive dengan fungsi
log. Setelah memperoleh hasil forecast kita dapat mengembalikan nilainya denganexp.
# menggunakan AirPassenger
AirPassengers %>% autoplot()log(AirPassengers) %>% autoplot()decompose(log(AirPassengers)) %>% autoplot()cara 2: Tetap menggunakan model multiplikatif, kemudian nanti hasil dibandingkan dengan memilih model error yang paling kecil.
# menggunakan AirPassenger
air_decom <- decompose(AirPassengers)
decompose(AirPassengers, type = "multiplicative") %>% autoplot()Trend
air_decom$trend %>% autoplot()# proff manual
air_trend <- ma(AirPassengers, order = 12, centre = T)
air_trend %>% autoplot()Seasonality
SEASONALITY * ERROR = DATA / TREND
air_decom$seasonal %>% autoplot()# proff manual
air_seaserr <- AirPassengers / air_trend
mean_seas <- air_seaserr %>%
matrix(ncol = 12, byrow = T) %>%
colMeans(na.rm = T)
air_seasonal <- ts(rep(mean_seas, 12), start = c(1949, 1), frequency = 12)
air_seasonal %>% autoplot()Error ERROR = DATA / (TREND * SEASONALITY)
air_decom$random %>% autoplot()# proff manual
air_error <- AirPassengers/(air_trend*air_seasonal)
air_error %>% autoplot()Untuk dapat melakukan analisis seasonal, kita dapat mengamati komponen seasonal secara visual:
# using ts_seasonal
ts_seasonal(ts.obj = birth_ts, type = "all")Forecasting Model:
Metode yang menggunakan rataan beregerak untuk melakukan forecasting. Karena menggunakan rataan, bobot yang digunakan sama untuk setiap observasi di masa lalu. Metode ini sering digunakan untuk data yang tidak mengandung trend dan seasonal (datanya bergerak disekitar rata-rata).
SMA tepat digunakan ketika data yang kita miliki tidak memiliki trend maupun seasonal.
Fungsi yang digunakan untuk forecasting SMA adalah SMA(objek time series, n) dari library TTR. Parameter yang digunakan, yaitu:
x :objek time series yang akan di forecast
n: jumlah observasi di masa lalu yang digunakan untuk forecasting
Kita akan coba melakukan forecasting pada data curah hujan tahunan sejak 1813-1912 yang tersimpan pada folder data_input dengan nama file precip1.dat.
scan()# read data rain
rain <- scan("data_input/precip1.dat", skip = 1)
head(rain)#> [1] 23.56 26.07 21.86 31.24 23.65 23.88
rain_ts <- ts(data = rain, start = 1813, frequency = 1)
rain_ts#> Time Series:
#> Start = 1813
#> End = 1912
#> Frequency = 1
#> [1] 23.56 26.07 21.86 31.24 23.65 23.88 26.41 22.67 31.69 23.86 24.11 32.43
#> [13] 23.26 22.57 23.00 27.88 25.32 25.08 27.76 19.82 24.78 20.12 24.34 27.42
#> [25] 19.44 21.63 27.49 19.43 31.13 23.09 25.85 22.65 22.75 26.36 17.70 29.81
#> [37] 22.93 19.22 20.63 35.34 25.89 18.65 23.06 22.21 22.18 18.77 28.21 32.24
#> [49] 22.27 27.57 21.59 16.93 29.48 31.60 26.25 23.40 25.42 21.32 25.02 33.86
#> [61] 22.67 18.82 28.44 26.16 28.17 34.08 33.82 30.28 27.92 27.14 24.40 20.35
#> [73] 26.64 27.01 19.21 27.74 23.85 21.23 28.15 22.61 19.80 27.94 21.47 23.52
#> [85] 22.86 17.69 22.54 23.28 22.17 20.84 38.10 20.65 22.97 24.26 23.01 23.67
#> [97] 26.75 25.36 24.79 27.88
rain_ts %>% autoplot()Data curah hujan yang kita miliki bergerak disekitar rata-rata
SMA() dengan ordo 3rain_sma3 <- SMA(x = rain_ts, n = 3)
rain_sma10 <- SMA(x = rain_ts, n = 10)Memvisualisasikan data historis dengan hasil forecast
rain_ts %>% autoplot() +
autolayer(rain_sma3) +
autolayer(rain_sma10)Metode SMA hanya mempertimbangkan n observasi di masa lampau untuk melakukan forecast baik pola trend maupun seasonal cenderung tidak tertangkap sehingga dibutuhkan metode lain yang memperhitungkan keseluruhan data di masa lampau, yaitu metode eksponensial.
Simple Exponential Smoothing digunakan untuk data time series yang tidak mengandung trend dan seasonal. Fungsi yang digunakan untuk membuat model exponential smoothing, yaitu:
ets() dari library forecast yang merupakan error, trend, dan seasonal. Parameter yang digunakan, yaitu:error, trend, dan seasonal.
A: aditifM: multiplikatifN: noneZ: autoalpha: bobot untuk smoothing, nilainya antara 0 - 1.
beta: bobot untuk smoothing trend, nilainya antara 0 - 1.gamma: bobot untuk smoothing seasonal, nilainya antara 0 - 1.SES: ets(data, model = "*NN")
Holts exponential: ets(data, model = "**N")
Holts Winter: ets(data, model = "***")
HoltWinters(), parameter yang digunakan, yaitu:alpha, beta, dan gamma adalah NULL, dimana apabila kita tidak mendefinisikan nilainya, maka model HolWinters() akan mencari nilai parameternya hingga mendapatkan nilai paling optimum. Sehingga jika objek time series tidak mengandung trend dan seasonal parameter beta dan gamma harus diubah menjadi FALSE.Simple Eksponential Smoothing: HoltWinters(data, beta = F, gamma = F)
Holt’s Exponential: HoltWinters(data, gamma = F)
Holt’s Winter Explonential: HoltWinters(data)
Simple Exponential Smoothing merupakan metode forecasting yang tepat digunakan untuk data yang tidak memiliki trend maupun seasonal1.
Kita akan coba menggunakan data rain_ts yang kita miliki untuk melakukan forecasting menggunakan SES.
# visualisasikan rain
rain_ses <- ets(rain_ts, model = "ANN") # ZZZ : Aoto
rain_ses #> ETS(A,N,N)
#>
#> Call:
#> ets(y = rain_ts, model = "ANN")
#>
#> Smoothing parameters:
#> alpha = 1e-04
#>
#> Initial states:
#> l = 24.8243
#>
#> sigma: 4.2362
#>
#> AIC AICc BIC
#> 753.2297 753.4797 761.0452
Data rain_ts tidak memiliki pola trend maupun seasonal. Karena datanya polanya tahunan, oleh karena itu data rain tidak memiliki pola seasonal yang dapat dilihat.
SES: ets(data, model = "*NN")
Melakukan forecasting data rain_ts dengan metode SES (tidak mempertimbangkan pola trend)
# menggunakan fungsi `ets()`
rain_ses <- ets(rain_ts, model = "ZZZ")# untuk memperoleh hasil prediksi
rain_ses$fitted#> Time Series:
#> Start = 1813
#> End = 1912
#> Frequency = 1
#> [1] 24.82431 24.82418 24.82431 24.82401 24.82465 24.82454 24.82444 24.82460
#> [9] 24.82439 24.82507 24.82498 24.82490 24.82566 24.82551 24.82528 24.82510
#> [17] 24.82541 24.82546 24.82548 24.82577 24.82527 24.82527 24.82480 24.82475
#> [25] 24.82501 24.82447 24.82415 24.82442 24.82388 24.82451 24.82434 24.82444
#> [33] 24.82422 24.82401 24.82417 24.82345 24.82395 24.82376 24.82320 24.82278
#> [41] 24.82384 24.82394 24.82332 24.82315 24.82289 24.82262 24.82202 24.82236
#> [49] 24.82310 24.82284 24.82312 24.82279 24.82201 24.82247 24.82315 24.82329
#> [57] 24.82315 24.82321 24.82286 24.82288 24.82378 24.82357 24.82297 24.82333
#> [65] 24.82346 24.82380 24.82472 24.82562 24.82617 24.82648 24.82671 24.82667
#> [73] 24.82622 24.82640 24.82662 24.82606 24.82635 24.82625 24.82589 24.82622
#> [81] 24.82600 24.82550 24.82581 24.82547 24.82534 24.82515 24.82443 24.82420
#> [89] 24.82405 24.82378 24.82339 24.82471 24.82430 24.82411 24.82405 24.82387
#> [97] 24.82376 24.82395 24.82400 24.82400
Untuk membuat model SES menggunakan HolWinters() kita bisa setup beta = F, dan gamma = F karena dalam model SES tidak memperhitungkan efek trend dan seasonal. (default alpha, beta, dan gamma = NULL)
# HoltWinters(x = rain_ts, alpha = T, beta = F, gamma = F)
rain_ses2 <- ets(y = rain_ts, model = "ANN", alpha = .6)
rain_ses2#> ETS(A,N,N)
#>
#> Call:
#> ets(y = rain_ts, model = "ANN", alpha = 0.6)
#>
#> Smoothing parameters:
#> alpha = 0.6
#>
#> Initial states:
#> l = 24.3141
#>
#> sigma: 5.1751
#>
#> AIC AICc BIC
#> 791.2695 791.3932 796.4799
Kesimpulan: > Ketika alpha mendekati 1: yang terjadi adalah model akan memberikan bobot yang paling besar untuk data terbaru, namun perubahan bobotnya sangat signifikan
Ketika alpha mendekati 0: yang terjadi adalah model akan memberikan bobot yang paling besar untuk data terbaaru, namun perubahan bobotnya secara perlahan
Visualisasi data historis dengan hasil forecast
# gunakan autolayer()
rain_ts %>%
autoplot() +
autolayer(rain_ses$fitted, series = "SES alpha = 0.0001") + # fitted adalah data hasil prediksi dari data yang digunakan
autolayer(rain_ses2$fitted, series = "SES alpha = 0.06")Model evaluation
Karena kita melakukan pemodelan tanpa cross validation kita tidak perlu melakukan prediksi/forecast sebab hasil forecast data historis sudah terdapat pada output hasil pemodelan. Kita dapat menghitung error yang dihasilkan oleh model dengan menggunakan fungsi accuracy() dari library forecast.
# use accuracy
accuracy(object = rain_ses2$fitted, x = rain_ts)#> ME RMSE MAE MPE MAPE ACF1 Theil's U
#> Test set 0.04047917 5.123114 4.056663 -2.692735 16.35586 -0.331274 0.8526713
accuracy(object = rain_ses$fitted, x = rain_ts)#> ME RMSE MAE MPE MAPE ACF1
#> Test set -0.0004906603 4.193615 3.339691 -2.758248 13.61432 -0.06601945
#> Theil's U
#> Test set 0.6795944
Untuk melihat nilai error menggunakan MAPE(Mean Absolute Percentage Error), kita bisa mengetahui seberapa persen nilai error dari prediksi kita.
Holt’s exponential (Double Exponential Smoothing) digunakan untuk data time series yang tidak mengandung efek seasonal2.
Melakukan forecasting data co2_ts dengan metode Holt’s Exponential menggunakan fungsi HolWinters()
co2_ts %>% autoplot()co2_holt <- HoltWinters(x = co2_ts, gamma = F)
co2_holt2 <- HoltWinters(x = co2_ts, alpha = .9, beta = .1, gamma = F)Alpha = 0.9 karena juka diperhatikan data terbaru itu nilainya jauh berbeda dengan data terdahulu (1970) itulah kenapa kita ingin memberikan bobot yang sangat besar untuk data terbaru, sedangkan data terdahulu diberikan bobot yang sangat kecil. Data terdahulu kurang relevan dengan kondisi saat ini.
Visualisasi data historis dengan hasil forecast
# gunakan autolayer()
co2_ts %>% autoplot() +
autolayer(co2_holt$fitted[,1]) +
autolayer(co2_holt2$fitted[,1])Model evaluation
# gunakan accuracy()
accuracy(co2_holt$fitted[,1], x = co2_ts)#> ME RMSE MAE MPE MAPE ACF1
#> Test set 0.02267075 0.1162543 0.07175926 1.255456 6.427522 -0.01218677
#> Theil's U
#> Test set 0.904001
accuracy(co2_holt2$fitted[,1], x = co2_ts)#> ME RMSE MAE MPE MAPE ACF1 Theil's U
#> Test set 0.0199014 0.1174784 0.06970157 1.105452 6.279417 -0.1491025 0.8963148
MAPE : 6.27% artinya kesalahan model kita terhadap
Holt’s Winters Exponential (Triple Exponential Smoothing) merupakan metode forecasting yang tepat digunakan untuk data yang memiliki efek trend dan seasonal3.
fancy.dat dan simpan dengan nama object souvenir# read data souvenir
souvenir <- scan("data_input/fancy.dat")
head(souvenir)#> [1] 1664.81 2397.53 2840.71 3547.29 3752.96 3714.74
Data souvenir terdiri dari 84 observasi penjualan souvenir per bulan dari tahun 1987.
souvenir_ts# object souvenir_ts
souvenir_ts <- ts(data = souvenir, start = c(1987,1), frequency = 12)souvenir_tsApakah tipe data time series yang terbentuk dari data souvenir_ts?
souvenir_ts %>%
autoplot()Tujuannya untuk menguraikan tipe-tipe data pada setiap komponen time series yang ada agar tepat dalam penentuan pemilihan model untuk forecast nya.
# menguraikan komponen data time series
souvenir_ts %>%
decompose(type = "multiplicative") %>%
autoplot()souvenir_trainsouvenir_test# test menggunakan `tail()`
test <- tail(souvenir_ts, 12)
# train menggunakan `head()`
train <- head(souvenir_ts, 6*12)
# train <- head(souvenir_ts, length(souvenir_ts)-length(test))train# ets(model = "MMM")
model_souvenir <- HoltWinters(x = train, seasonal = "multiplicative")
model_souvenir#> Holt-Winters exponential smoothing with trend and multiplicative seasonal component.
#>
#> Call:
#> HoltWinters(x = train, seasonal = "multiplicative")
#>
#> Smoothing parameters:
#> alpha: 0.3469842
#> beta : 0.07501578
#> gamma: 0.5711478
#>
#> Coefficients:
#> [,1]
#> a 2.758252e+04
#> b 8.079173e+02
#> s1 4.676809e-01
#> s2 6.030877e-01
#> s3 9.592971e-01
#> s4 7.056491e-01
#> s5 6.754072e-01
#> s6 7.911595e-01
#> s7 8.912119e-01
#> s8 8.937350e-01
#> s9 8.856460e-01
#> s10 9.134738e-01
#> s11 1.392572e+00
#> s12 2.915102e+00
souvenir_test dengan menggunakan fungsi forecast() dari library forecastobject = model time seriesh = berapa banyak data kedepan yang akan di forecast# forecast menggunakan model multiplicative
souvenir_forecast <- forecast(object = model_souvenir, h = 12)
souvenir_forecast#> Point Forecast Lo 80 Hi 80 Lo 95 Hi 95
#> Jan 1993 13277.67 11237.89 15317.44 10158.10 16397.24
#> Feb 1993 17609.17 15156.03 20062.32 13857.41 21360.94
#> Mar 1993 28784.94 25268.64 32301.23 23407.23 34162.65
#> Apr 1993 21744.01 18610.83 24877.19 16952.23 26535.79
#> May 1993 21357.80 18034.65 24680.95 16275.49 26440.12
#> Jun 1993 25657.32 21616.65 29698.00 19477.65 31837.00
#> Jul 1993 29622.05 24836.99 34407.12 22303.93 36940.18
#> Aug 1993 30427.98 25296.39 35559.56 22579.90 38276.06
#> Sep 1993 30868.11 25438.75 36297.48 22564.62 39171.61
#> Oct 1993 32576.03 26643.50 38508.56 23503.01 41649.05
#> Nov 1993 50786.55 41491.30 60081.80 36570.70 65002.41
#> Dec 1993 108667.82 88629.46 128706.18 78021.79 139313.85
h = 12 artinya kita akan melakukan forecasting untuk 12 bulan ke depan. Jumlah h yang kita tentukan, akan sesuai dengan data test yang kita siapkan.
Point forecast adalah forecast yang dihasilkan. 80 dan 95 ini adalah confidence interval * Lo : menandakan batas bawah * Hi : menandakan batas atas
Summary:
Perkenalan entang model-model yang ada. ada SMA yaitu data yang tidak memiliki train dan seasonal. liat ordo nya, jika 10, berarti liat rata2 10 periode terakhir, semua data dianggpap penting, ga semua dihitung. penentuan ordonya user yang menentukan.
Exponential smoothing ada 3 model, SES, Holt dan Holt Winter, komponen yang akan digunakan untuk melakukan smoothing adalah
alpha -> smoothing error beta -> smoothing trend theta -> smoothing seasonal
Simple Exponential memberikan bobot terbesar untuk data terbaru, seberapa kecil atau besar bisa dilihat dari paramete alpha theta gamma nya. alpha makin besar berarti data kondisi sekarang makin berpengaruh dan data makin ke belakan makin tidak berpengaruh.
Holt Exponential Smoothing digunakan untuk data yang memiliki trend
Holt winters Smoothing digunakan pada data yang memiliki trend dan juga seasonal yang semuanya multiplikatif
Intrepretasi hasil forecast :
Visualisasi hasil forecast
# visualisasi hasil forecast dari model multiplicative
train %>%
autoplot()+
autolayer(model_souvenir$fitted[,1], series = "fitted")+
autolayer(souvenir_forecast$mean, series = "forecast")+
autolayer(test, series = "data test")souvenir_test# model multiplicative
accuracy(object = souvenir_forecast$mean, test)#> ME RMSE MAE MPE MAPE ACF1 Theil's U
#> Test set -4060.199 4541.688 4060.199 -21.15116 21.15116 0.5148249 0.6278038
MAPE: Mean Absolute percentage error
Dive Deeper
Gunakanlah data nybirth.csv. Buatlah model time series yang tepat untuk data tersebut, analisislah pola time series yang ada pada data tersebut, apakah multiplicative atau additive? Lakukanlah forecasting dan lihatlah model evaluationnya.
birth <- read.csv("data_input/nybirth.csv")birth_ts <- ts(data = birth$births, start = c(1946,1), frequency = 12)
birth_ts %>% autoplot()birth_ts %>% decompose(type = "additive") %>% autoplot()# test
birth_test <- tail(birth_ts, 2*12)
# train menggunakan `head()`
birth_train <- head(birth_ts, 12*12)decompose(x = birth_train, type = "additive") %>% autoplot()# a
model_birth_auto <- HoltWinters(x = birth_train, seasonal = "additive")
# b
model_birth_manual <- HoltWinters(x = birth_train, alpha = 0.5, beta = 0.01, gamma = 0.005, seasonal = "additive")
model_birth_hanung <- HoltWinters(x = birth_train, alpha = 0.1, beta = 0.4, gamma = 0.1, seasonal = "additive")birth_forecast_auto <- forecast(object = model_birth_auto, h = 24)
birth_forecast_manual <- forecast(object = model_birth_manual, h = 24)
birth_forecast_hanung <- forecast(object = model_birth_hanung, h = 24)birth_train %>%
autoplot()+
autolayer(birth_test, series = "test")+
autolayer(birth_forecast_manual$mean, series = "forecast_manual")+
autolayer(birth_forecast_auto$mean, series = "forecast_auto")+
autolayer(birth_forecast_hanung$mean, series = "forecast Hanung")+
autolayer(model_birth_manual$fitted[,1], series = "fitted")accuracy(birth_forecast_manual$mean, birth_test)#> ME RMSE MAE MPE MAPE ACF1 Theil's U
#> Test set -0.2765909 1.090862 0.9364968 -1.172147 3.456039 0.6976645 0.6511813
accuracy(birth_forecast_auto$mean, birth_test)#> ME RMSE MAE MPE MAPE ACF1 Theil's U
#> Test set -1.231122 1.579416 1.249804 -4.612144 4.674416 0.7004142 0.965476
accuracy(birth_forecast_hanung$mean, birth_test)#> ME RMSE MAE MPE MAPE ACF1
#> Test set 0.01246057 0.7761363 0.6616637 -0.06608348 2.418264 0.6171999
#> Theil's U
#> Test set 0.4560637
Additive, lebih mudah diprediksi/diforecast karena perubahan pada data time series tersebut cenderung tetap/statis.
Multiplicative, lebih sulit diprediksi/diforecast karena perubahan pada data time series cenderung dinamis/berubah-ubah biasanya kelipatannya/multiplikatif (perubahan yang terjadi bisa semakin membesar/mengecil). Sehingga, umumnya dilakukan transformasi data dengan pola multiplicative menjadi additive dengan transformasi `log()
SMA(Single moving average) : memperhitungkan beberapa data terakhir saja tanpa melihat pola data secara keseluruhan. Cara kerja dari SMA selain dia merata-ratakan datanya, sebenarnya setiap datanya diberikan bobot yang sama sesuai ordonya, misalnya ordo 3, maka setiap data diberikan bobot 1/3.
Simple exponential smoothing (SES) : cocok untuk data yang tidak memiliki pola trend dan seasonal. Parameter smoothing didalamnya yaitu alpha (untuk eror).
Holt Exponential : cocok untuk data yang tidak memiliki pola seasonal. Parameter smoothing didalamnya yaitu alpha (untuk eror) dan beta (untuk trend).
ets() dan HoltWinters().fungsi ets(object_ts, model = "ZZZ")
fungsi HoltWinters(object_ts, alpha = NULL/FALSE, beta = NULL/FALSE, gamma = NULL/FALSE, seasonal = "additive/multiplicative")
—–End Of day 2———-
Knowledge check:
untuk pemodelan minimal data yang kita miliki setidaknya 2 periode
untuk validasi data test setidaknya siapkan 1 periode
untuk mengidentifikasi pola error, trend, dan seasonal untuk mempermudah memilih model yang tepat
Ketika nilai freq = 1 tidak bisa dilakukan decompose, karena dia tidak memiliki pembanding dengan periode sebelumnya
Kapan menggunakan simple moving average?
Bagaimana karakteristik simple moving average?
Kapan menggunakan model simple exponential smoothing, holt exponential smoothing, dan holt winter?
Bagaimana peran alpha beta dan gamma pada modelling?
ARIMA adalah gabungan antara dua metode, yaitu Auto Regressive (AR) dan Moving Average (MA). I nya menjelaskan Integrated. Tujuan utama dari ARIMA adalah melakukan autocorrelation pada data.
Stasionarity time series memiliki arti bahwa pada data time series yang kita miliki tidak memiliki trend maupun seasonal dan memiliki variansi konstan. Berdasarkan gambar dibawah ini, manakah yang termasuk data time series yang stasioner?
knitr::include_graphics("assets/TS_Variation.PNG")Apabila data yang kita miliki belum stasioner, maka kita bisa melakukan differencing.
Jadi untuk membuat datanya stasioner, cara yang paling umum digunakan adalah dengan melakukan differencing diff, yaitu mengurangi data saat ini dengan data sebelumnya4. Terkadang, tergantung pada kompleksitas data, jumlah differencing bisa lebih dari 1 kali.
x <- c(5, -3, 6, 7)
x#> [1] 5 -3 6 7
diff(x) # differencing 1 kali#> [1] -8 9 1
diff(diff(x)) # differencing 2 kali#> [1] 17 -8
Pemahaman konsep mengapa perlu differencing???
AirPassengers %>%
diff() %>%
autoplot()data.frame(
xt = c(AirPassengers),
lag1 = lag(x = as.vector(AirPassengers), n = 1),
lag2 = lag(x = as.vector(AirPassengers), n = 2),
lag3 = lag(x = as.vector(AirPassengers), n = 3),
lag4 = lag(x = as.vector(AirPassengers), n = 4),
lag5 = lag(x = as.vector(AirPassengers), n = 5)
) %>%
na.omit() %>%
GGally::ggcorr()data.frame(
xt = c(diff(AirPassengers)),
lag1 = lag(x = as.vector(diff(AirPassengers)), n = 1),
lag2 = lag(x = as.vector(diff(AirPassengers)), n = 2),
lag3 = lag(x = as.vector(diff(AirPassengers)), n = 3),
lag4 = lag(x = as.vector(diff(AirPassengers)), n = 4),
lag5 = lag(x = as.vector(diff(AirPassengers)), n = 5)
) %>%
na.omit() %>%
GGally::ggcorr()Ide utama melakukan differencing adalah agar ketika melakukan prediksi, tidak ada multicolinearity terhadap data-data sebelumnya.
summary:
model arima > melakukan regresi > antar lag tidak boleh memiliki hubungan yang kuat > data harus stasioner > ketika data kita tidak stasioner > kita haru membuat data menjadi stasioner dengan cara lakukan differencing > differencing akan menghilangkan efek multikolinearitas
Quick Summary
ARIMA memerlukan model dalam keadaan stasioner. Teknik yang bisa dilakukan untuk membuat data menjadi stasioner adalah dengan menggunakan differencing. Kestasioneran data diperlukan karena model regresi memerlukan kondisi korelasi antar variabel tidak kuat. Jika dibiarkan kuat, maka akan terjadi masalah multikolinearitas.
Auto regressive di ARIMA artinya kita membuat model linear regression berdasarkan lag dari datanya sebagai prediktor5. Linear regression models, baik ketika prediktornya tidak ada korelasi dan independen satu dengan lainnya. Nilai p berarti berapa banyak data yang akan dipakai ketika melakukan auto regressive.
Model autoregressive dapat dituliskan sebagai berikut.
\[Y_t = \alpha + \beta_1Y_{t-1}+\beta_2Y_{t-2}+...+\beta_pY_{t-p}+ \epsilon_1\]
dimana, \(Y_{t-1}\) adalah lag1, \(\beta_1\) adalah coefficient dari lag1, dan \(\alpha\) adalah intercept.
Moving Average dalam ARIMA artinya kita melakukan rata-rata berjalan terhadap data time series itu sendiri6.
Moving Average Model (MA model).
\[Y_t = \alpha + \epsilon_t + \phi_1\epsilon_{t-1}+\phi_2\epsilon_{t-2}+...+\phi_q\epsilon_{t-q}\]
Arima memiliki bentuk model (p,d,q) dimana7 :
p berarti berapa banyak data yang akan dipakai ketika melakukan auto regressive.Untuk mencari order p untuk model AR, kita dapat melihat dari plot PACF (Partial Autocorrelation Function).
autokorelasi pada saat t dan t - k tanpa dipengaruhi oleh korelasi periode ditengahnya (intermediate lags). Misalnya autokorelasi untuk lag(2) maka bisa dikatakan ingin mencari autokorelasi antara hari rabu ke jumat secara langsung.
Integrated -> I(d)
Integrated adalah berapa kali data dilakukan differencing untuk membuat suatu data stationer. Nilai d dapat diketahui dengan mencari tahu berapa kali differencing yang dilakukan pada data.
Moving Average -> MA(q)
MA digunakan untuk melakukan smoothing error. Nilai q berarti berapa banyak data yang diperlukan untuk smoothing error menggunakan moving average.
Untuk mencari order q untuk model MA, kita dapat melihat dari plot ACF (Auto correlation Function)
mencari autokorelasi pada saat t dan t - k, dan dipengaruhi oleh periode ditengahnya. Misal: autokorelasi untuk lag(2) maka bisa dikatakan, akan dihitung nilai autokorelasi di hari jumat ke rabu, namun mempertimbangkan korelasi antara jumat ke kamis dan kamis ke rabu.
Tahap analisis menggunakan metode ARIMA:
adf.testH0 : data tidak stasioner H1 : data stasioner
kita mengharapkan p-value < alpha, sehingga pola data stasioner
Catat informasi berapa kali dilakukan differencing sampai data menjadi stasioner
Lakukan pembuatan model arima menggunakan auto.arima(objek_ts, seasonal = F).
Tuning model dengan mencari ordo (p) dan (q) secara manual.
tails off atau cuts of lag.tails off: garis saat lag ke-1 mengalami penurunan yang lambat.cuts off lag: garis saat lag ke-1 mengalami penurunan yang cepat.Model evaluation dengan nilai MAPE
Cek asumsi time series
Kita akan coba melakukan forecast pada data environment_1970f.csv, dimana yang akan kita ubah kedalam bentuk object time series adalah data Nitrous.oxide.emissions..thousand.metric.tons.of.CO2.equivalent.
# read data environment_1970f.csv
no <- read.csv("data_input/environment_1970f.csv")
head(no)#> year CO2.emissions..kt. CO2.emissions..metric.tons.per.capita.
#> 1 1970 35822.92 0.3119519
#> 2 1971 38987.54 0.3306215
#> 3 1972 43340.27 0.3580080
#> 4 1973 49134.13 0.3954703
#> 5 1974 51260.99 0.4021567
#> 6 1975 53963.57 0.4128050
#> Methane.emissions..kt.of.CO2.equivalent.
#> 1 126665
#> 2 119293
#> 3 195338
#> 4 136928
#> 5 122570
#> 6 121065
#> Nitrous.oxide.emissions..thousand.metric.tons.of.CO2.equivalent.
#> 1 51908.88
#> 2 49004.80
#> 3 79261.42
#> 4 56928.71
#> 5 50997.79
#> 6 50922.15
#> Other.greenhouse.gas.emissions..HFC..PFC.and.SF6..thousand.metric.tons.of.CO2.equivalent.
#> 1 130405.80
#> 2 94658.48
#> 3 422459.50
#> 4 174340.90
#> 5 110213.86
#> 6 109630.88
#> Total.greenhouse.gas.emissions..kt.of.CO2.equivalent.
#> 1 339677.1
#> 2 294004.9
#> 3 733432.9
#> 4 409241.7
#> 5 329453.2
#> 6 329119.3
Nitrous.oxide.emissions..thousand.metric.tons.of.CO2.equivalent.no_ts <- ts(data = no$Nitrous.oxide.emissions..thousand.metric.tons.of.CO2.equivalent., start = 1970, frequency = 1)Stasioner adalah data yang bergerak disekitar rata-rata globalnya.
no_ts %>% autoplot()adf.test()adf.test(no_ts)#>
#> Augmented Dickey-Fuller Test
#>
#> data: no_ts
#> Dickey-Fuller = -2.7827, Lag order = 3, p-value = 0.2645
#> alternative hypothesis: stationary
Menguji stasioneritas data H0: data tidak stasioner H1: data stasioner
pvalue>alpha, artinya data belum stasioner
no_ts dengan satu kali differencing# melihat secara visual
no_ts %>% diff %>% autoplot()Untuk mengetahui data stasioner atau tidak kita akan menggunakan adf.test()
# lakukan uji statistik
no_ts %>% diff() %>% adf.test()#>
#> Augmented Dickey-Fuller Test
#>
#> data: .
#> Dickey-Fuller = -6.1019, Lag order = 3, p-value = 0.01
#> alternative hypothesis: stationary
H0 : Data tidak stasioneer H1 : Data Stasioner
Data stasioner menunjukkan bahwa data lag(prediktor) saling berkorelasi.
Kesimpulan:
p = melihat lag yang keluar dari plot PACF (partial autocorrelation function) q = melihat lag yang keluar dari plot ACF (autocorrelation function)
ACF untuk melihat korelasi suatu data dengan mempertimbangkan data tengahnya. misal ingin melihat korelasi hari senin dengan hari rabu, kita harus mempertimbangkan:
PACF untuk melihat korelasi data tanpa mempertimbangkan data tengahnya. misal ingin melihat korelasi hari senin dengan rabu, cukup melihat nilai korelasi hari senin - rabu saja
melihat plot pacf dan acf untuk menemukan nilai p dan q
# melihat plot acf dan pacf menggunakan `tsdisplay()`
no_ts %>% diff() %>% tsdisplay()Dies down/decay: mengalami penurunan atau kenaikan secara lambat, ordo yang dipakai adalah 0
cuts off lag: mengalami penurunan atau kenaikan secara cepat
PACF untuk ordo p ACF untuk ordo q kalo dies down diisi dengan 0 kalo cut-off liat dimana, sampai Lag yang masih signifikan.
Asumsi pertama : ACF itu cut off, PACF itu dies down PACF -> dies down berarti q = 0 ACF -> cut-off, terakhir di Lag 1 berarti q = 1 Kalau seandainya, ACF punya 2 yang signifikan misalnya Lag 2 juga signifikan, maka ACF nya = 2
ARIMA(p,d,q) = ARIMA(0,1,1)
Kombinasi model ARIMA yang terbentuk 8:
ARIMA(p,d,q)
Asumsi kedua : Keduanya cut-off PACF = q = 1 ACF -> p = 1,2,4 (karena cut-off di lag 1,2,4) ARIMA(p,d,q) 1. ARIMA(1,1,1) 2. ARIMA(2,1,1) 3. ARIMA(4,1,1)
parameter pada fungsi Arima()
# create model
no_arima1 <- Arima(y = no_ts, order = c(0,1,1), seasonal = F)
no_arima2 <- Arima(y = no_ts, order = c(1,1,1), seasonal = F)
no_arima3 <- Arima(y = no_ts, order = c(2,1,1), seasonal = F)
no_arima4 <- Arima(y = no_ts, order = c(4,1,1), seasonal = F)
no_arima3#> Series: no_ts
#> ARIMA(2,1,1)
#>
#> Coefficients:
#> ar1 ar2 ma1
#> -0.0038 -0.2197 -0.7690
#> s.e. 0.1780 0.1634 0.1224
#>
#> sigma^2 estimated as 3.227e+09: log likelihood=-518.45
#> AIC=1044.9 AICc=1045.98 BIC=1051.85
cek aic masing-masing model
no_arima1$aic#> [1] 1042.681
no_arima2$aic#> [1] 1044.575
no_arima3$aic#> [1] 1044.902
no_arima4$aic#> [1] 1048.008
Kita ingin mendapatkan nilai AIC terendah karena AIC menandakan banyaknya informasi yang hilang.
auto.arima()auto.arima(no_ts, seasonal = F)#> Series: no_ts
#> ARIMA(0,1,1)
#>
#> Coefficients:
#> ma1
#> -0.8244
#> s.e. 0.0842
#>
#> sigma^2 estimated as 3.21e+09: log likelihood=-519.34
#> AIC=1042.68 AICc=1042.99 BIC=1046.16
Untuk pemilihan model terbaik kita bisa melihat nilai AIC dari masing-masing model yang paling kecil
accuracy(no_arima1)#> ME RMSE MAE MPE MAPE MASE
#> Training set 7917.811 55326.04 33952.52 -2.335425 25.68435 0.7884324
#> ACF1
#> Training set 0.003779372
accuracy(no_arima2)#> ME RMSE MAE MPE MAPE MASE ACF1
#> Training set 8204.36 55267.96 33751.68 -2.00415 25.36724 0.7837685 -0.03222488
accuracy() dari package forecast untuk melihat MAPEno_ts %>% autoplot() +
autolayer(no_arima1$fitted, series = "fitted 1") +
autolayer(no_arima2$fitted, series = "fitted 2")Seasonal arima adalah metode arima dimana object time series yang ada memiliki pola seasonal9. Tahapan dalam melakukan pemodelan menggunakan SARIMA sama seperti saat membuat pemodelan ARIMA.
Order Model pada SARIMA(p,d,q)(P,D,Q)[seasonal]
ARIMA: (p, d, q)
SARIMA: (p, d, q)(P, D, Q)[m]
(p, d, q) untuk index utama
(P, D, Q) untuk index seasonal
seasonal merupakan frequency
Jika kita menggunakan model SARIMA, diperlukan langkah tambahan ketika melakukan differencing untuk seasonal data, yaitu differencing sesuai pola berulang/frequency data time series untuk menghilangkan pola musiman.
Pada bagian ini, kita akan menggunakan data DAUTONSA.csv
# read data DAUTONSA.csv
sales <- read.csv("data_input/DAUTONSA.csv") %>%
mutate(DATE = ymd (DATE))
tail(sales, 20)#> DATE DAUTONSA
#> 611 2017-11-01 340.959
#> 612 2017-12-01 362.059
#> 613 2018-01-01 280.479
#> 614 2018-02-01 328.988
#> 615 2018-03-01 416.105
#> 616 2018-04-01 326.924
#> 617 2018-05-01 394.895
#> 618 2018-06-01 372.417
#> 619 2018-07-01 321.267
#> 620 2018-08-01 338.095
#> 621 2018-09-01 329.564
#> 622 2018-10-01 329.158
#> 623 2018-11-01 306.410
#> 624 2018-12-01 342.587
#> 625 2019-01-01 277.863
#> 626 2019-02-01 285.093
#> 627 2019-03-01 372.433
#> 628 2019-04-01 295.505
#> 629 2019-05-01 346.105
#> 630 2019-06-01 327.864
Data di atas merupakan data rata-rata penjualan motor di suatu dealer dari tahun 1967-2019.
DATE: tanggal saat dilakukan pencatatan penjualan
DAUTONSA: rata-rata penjualan.
untuk kebutuhan analisis, datanya akan kita subset dari tahun 2011 keatas
# filter tahun 2011 keatas
sales_clean <- sales %>% filter(DATE >= "2011-01-01")
sales_clean#> DATE DAUTONSA
#> 1 2011-01-01 258.576
#> 2 2011-02-01 338.615
#> 3 2011-03-01 445.315
#> 4 2011-04-01 405.418
#> 5 2011-05-01 362.214
#> 6 2011-06-01 348.950
#> 7 2011-07-01 329.517
#> 8 2011-08-01 340.459
#> 9 2011-09-01 327.466
#> 10 2011-10-01 321.021
#> 11 2011-11-01 304.949
#> 12 2011-12-01 363.464
#> 13 2012-01-01 323.424
#> 14 2012-02-01 430.209
#> 15 2012-03-01 528.054
#> 16 2012-04-01 431.834
#> 17 2012-05-01 491.050
#> 18 2012-06-01 459.854
#> 19 2012-07-01 393.252
#> 20 2012-08-01 452.837
#> 21 2012-09-01 411.972
#> 22 2012-10-01 369.820
#> 23 2012-11-01 382.692
#> 24 2012-12-01 444.846
#> 25 2013-01-01 383.879
#> 26 2013-02-01 446.362
#> 27 2013-03-01 544.516
#> 28 2013-04-01 466.742
#> 29 2013-05-01 519.361
#> 30 2013-06-01 499.660
#> 31 2013-07-01 446.915
#> 32 2013-08-01 516.827
#> 33 2013-09-01 383.073
#> 34 2013-10-01 398.003
#> 35 2013-11-01 406.615
#> 36 2013-12-01 421.205
#> 37 2014-01-01 344.189
#> 38 2014-02-01 409.921
#> 39 2014-03-01 534.342
#> 40 2014-04-01 470.222
#> 41 2014-05-01 564.577
#> 42 2014-06-01 499.801
#> 43 2014-07-01 479.974
#> 44 2014-08-01 556.870
#> 45 2014-09-01 414.495
#> 46 2014-10-01 430.949
#> 47 2014-11-01 428.752
#> 48 2014-12-01 475.786
#> 49 2015-01-01 386.010
#> 50 2015-02-01 419.495
#> 51 2015-03-01 525.027
#> 52 2015-04-01 477.314
#> 53 2015-05-01 563.176
#> 54 2015-06-01 491.397
#> 55 2015-07-01 481.665
#> 56 2015-08-01 496.815
#> 57 2015-09-01 446.569
#> 58 2015-10-01 447.743
#> 59 2015-11-01 387.789
#> 60 2015-12-01 472.123
#> 61 2016-01-01 361.397
#> 62 2016-02-01 427.270
#> 63 2016-03-01 502.115
#> 64 2016-04-01 447.760
#> 65 2016-05-01 468.254
#> 66 2016-06-01 452.263
#> 67 2016-07-01 437.189
#> 68 2016-08-01 433.380
#> 69 2016-09-01 419.560
#> 70 2016-10-01 377.266
#> 71 2016-11-01 374.906
#> 72 2016-12-01 444.215
#> 73 2017-01-01 307.619
#> 74 2017-02-01 368.826
#> 75 2017-03-01 446.580
#> 76 2017-04-01 411.024
#> 77 2017-05-01 433.909
#> 78 2017-06-01 399.619
#> 79 2017-07-01 376.212
#> 80 2017-08-01 394.215
#> 81 2017-09-01 406.634
#> 82 2017-10-01 345.309
#> 83 2017-11-01 340.959
#> 84 2017-12-01 362.059
#> 85 2018-01-01 280.479
#> 86 2018-02-01 328.988
#> 87 2018-03-01 416.105
#> 88 2018-04-01 326.924
#> 89 2018-05-01 394.895
#> 90 2018-06-01 372.417
#> 91 2018-07-01 321.267
#> 92 2018-08-01 338.095
#> 93 2018-09-01 329.564
#> 94 2018-10-01 329.158
#> 95 2018-11-01 306.410
#> 96 2018-12-01 342.587
#> 97 2019-01-01 277.863
#> 98 2019-02-01 285.093
#> 99 2019-03-01 372.433
#> 100 2019-04-01 295.505
#> 101 2019-05-01 346.105
#> 102 2019-06-01 327.864
sales_ts <- ts(data = sales_clean$DAUTONSA, start = c(2011,1), frequency = 12)Melihat visualisasi data secara umum
sales_ts %>% autoplot()Test data : sisanya Train data : diambil 7 tahun pertama
# data train selama 7 tahun
sales_train <- head(sales_ts, 7*12)
# data test 1.5 tahun (12+6)
sales_test <- tail(sales_ts, 18)# mencoba dengan seasonal period (frequency)
sales_train %>% adf.test()#>
#> Augmented Dickey-Fuller Test
#>
#> data: .
#> Dickey-Fuller = -2.9359, Lag order = 4, p-value = 0.192
#> alternative hypothesis: stationary
H0: data tidak stasioner H1: data stasioner
Differencing based on frequency, cek apakah sudah stasioner atau belum
sales_train %>% diff() %>% autoplot() # lansung hilangin efek trendsales_train %>% diff(lag = 12) %>% diff() %>% autoplot() # hilangin efek seasonal dulu sales_train %>% diff(lag = 12) %>% diff() %>% adf.test()#>
#> Augmented Dickey-Fuller Test
#>
#> data: .
#> Dickey-Fuller = -4.7557, Lag order = 4, p-value = 0.01
#> alternative hypothesis: stationary
Pertama, buang data seasonal. D menyatakan nilai differencing seasonal. disini diff bisa dua kali, ada data yg tahunan dua kali Lalu data trend di buang. d menyatakan differencing trend
Tentukan nilai differrence untuk index utama dan seasonal:
d = 1
D = 1
sales_train %>% diff(lag = 12) %>% diff(lag = 1) %>%
tsdisplay()Untuk seasosal, AR murni
* P : 0 * D : 1 * Q : 0
untuk keseluruhan data, MA murni * p: 0 * d: 1 * q: 1
Kombinasi model yang mungkin terbentuk adalah :
SARIMA: (p, d, q)(P, D, Q)[m]
auto.arima()# create model using auto.arima()
sarima1 <- Arima(y = sales_train, order = c(0,1,1), seasonal = c(0,1,0))
sarima2 <- Arima(y = sales_train, order = c(0,1,1), seasonal = c(2,1,0))
sarima.auto <- auto.arima(y = sales_train, seasonal = T)# cek nilai AIC
sarima1$aic#> [1] 687.4144
sarima2$aic#> [1] 690.8078
model forecast yang baik akan menghasilkan residual yang tidak berkorelasi. Apabila terdapat residual yang berkorelasi, artinya masih terdapat informasi yang tertinggal yang seharusnya digunakan untuk menghitung hasil forecast.
Menentukan nilai (p,d,q)(P,D,Q)[m]
Langkah 1: Tentukan D.
Langkah 2: Tentukan d.
Langkah 3: Tentukan P dan Q. Untuk index seasonal, amati berapa banyak lag yang keluar di ACF/PACF ketika lag = freq/kelipatan freq.
Kombinasi model yang mungkin terbentuk adalah :
ARIMA ( )( )[ ]
SARIMA
# create modelsales_forecast <- forecast(sarima1, h = 18)kalau data di log(), lakukan exp() disini
Visualisasi
sales_train %>% autoplot() +
autolayer(sales_test, series = "data test") +
autolayer(sarima1$fitted, series = "fitted") +
autolayer(sales_forecast$mean, series = "forecast")accuracy() dari package forecast dan melihat nilai MAPEnya# accuracy
accuracy(sales_forecast$mean, sales_test)#> ME RMSE MAE MPE MAPE ACF1 Theil's U
#> Test set 14.06787 27.57037 23.20688 4.370293 7.204645 0.08457512 0.515082
Kesimpulan:
Asumsi pada time series diujikan untuk mengukur apakah residual yang peroleh dari hasil modeling sudah cukup baik untuk menggambarkan dan menangkap informasi pada data. Mengapa menggunakan residual data? Karena dengan menggunakan residual data, kita dapat mendapatkan informasi dari data aktual maupun dari hasil prediksi menggunakan model. Metode forecasting yang baik menghasilkan nilai residual berikut ini10:
Untuk memastikan bahwa residual yang dihasilkan memiliki kriteria diatas, maka terdapat asumsi untuk mengujinya.
\(H_0\): residual has no-autocorrelation \(H_1\): residual has autocorrelation
yang diinginkan p-value > 0.05 (alpha), no-autocorrelation
Untuk mengecek ada/tidaknya autokorelasi pada hasil forecasting time series bisa menggunakan beberapa cara, yaitu:
acf(residual model)Box.test(residual model, type = "Ljung-Box)# menggunakan visualisasi
acf(sarima1$residuals) >
# menggunakan Ljung-Box test
Box.test(sarima1$residuals, type = "Ljung-Box")#>
#> Box-Ljung test
#>
#> data: sarima1$residuals
#> X-squared = 0.075662, df = 1, p-value = 0.7833
\(H_0\): residual has no-autocorrelation > 0.05 \(H_1\): residual has autocorrelation < 0.05
Kesimpulan: nilai p-value (0.78) > (0.75) artinya residual kita tidak terjadi autokorelasi
jika terjadi autokorelasi 1. diff() 2. log 3. cek data, harusnya ada yang outlier -> hist. boxplot 4. ## Normality residual
\(H_0\): residual menyebar normal \(H_1\): residual tidak menyebar normal
yang diinginkan p-value > 0.05 (alpha), residual menyebar normal
Untuk mengecek normality residual pada hasil forecasting time series kita bisa melakukan uji normality (shapiro test) dengan menggunakan fungsi shapiro.test(residual model)
shapiro.test(sarima1$residuals)#>
#> Shapiro-Wilk normality test
#>
#> data: sarima1$residuals
#> W = 0.96645, p-value = 0.02739
p-value > alpha maka data tidak normally distributed
hist(sarima1$residuals)Mau mentolerir error ini ga, kemampuan model kita hanya bisa memprediksi kurleb 50 observasi saja, antara -50 sampai 50 saja.
Note : Untuk mengecek asumsi cukup di model akhir yang akan dipilih
Apabila dalam decompose biasa, dalam mendapatkan komponen trend dengan cara central moving average (CMA) dimana secara konsep setiap data yang ingin dirata-ratakan diberikan bobot yang sama sesuai ordo yang ditetapkan. Karena merata-ratakan data tengahnya hasilnya kita kehilangan data awal dan data akhirnya, sehingga ada beberapa informasi yang hilang. Ada salah satu cara untuk mendapatkan decompose data namun tetap mempertahankan informasi dari seluruh data yang kita miliki yaitu dengan menggunakan STL(Seasonal Trend with Loess). STL secara konsep akan melakukan smoothing terhadap data tetangga setiap masing-masing observasi dengan memberikan bobot yang lebih berat terhadap data yang dekat dengan observed data. Kekurangan dari STL hanya bisa melakukan decompose pada additive data, apabila terdapat multiplicative data dapat menggunakan transformasi log()11.
Untuk memodelkan hasil STL, kita bisa menerapkan STLM(Seasonal Trend with Loess Model) dimana kita bisa menerapkan metode exponential smoothing (ETS) dan ARIMA. Selain itu, STLM dapat digunakan sebagai alternative cara untuk menangkap seasonal yang belum bisa ditangkap oleh metode ETS dan ARIMA biasa.
stl()Dengan menggunakan data rata-rata penjualan per bulan yang kita miliki, kita kan coba melakukan decompose dengan stl() dan memodelkan dengan menggunakan fungsi stlm() dengan menerapkan metode arima.
Perlu mengatur parameter s.window untuk mendefinisikan pola seasonal yang ingin ditangkap
sales_train %>%
stl(s.window = 12) %>%
autoplot()Dengan menggunakan informasi data train train dan test test, kita akan coba untuk membuat model dengan menggunakan metode stlm() dengan mengatur parameter method = "ets" dan method = "arima".
Parameter stlm() yang harus di atur:
y : object time series
s.window : pola seasonal yang ingin ditangkap
method : metode forecast yang akan digunakan, tersedia ets dan arima
modeling
ets_stlm <- stlm(y = sales_train, s.window = 12, method = "ets")
arima_stlm <- stlm(y = sales_train, s.window = 12, method = "arima")
arima_stlm$model#> Series: x
#> ARIMA(2,1,1)
#>
#> Coefficients:
#> ar1 ar2 ma1
#> -1.3573 -0.5765 0.970
#> s.e. 0.0903 0.0897 0.046
#>
#> sigma^2 estimated as 562.9: log likelihood=-380.07
#> AIC=768.15 AICc=768.66 BIC=777.82
cek nilai aic
ets_stlm$model$aic#> [1] 920.6818
arima_stlm$model$aic#> [1] 768.1463
Melakukan forecast untuk 18 bulan mendatang
forecast_stlm_arima <- forecast(arima_stlm , h =18)Visualisasi hasil forecast
sales_train %>%
autoplot()+
autolayer(sales_test, series = "test")+
autolayer(forecast_stlm_arima$mean, series = "forecast")Gunakan data euretail untuk forecasting, data euretail ini sudah dalam bentuk object time series dengan frequency = 4
data("euretail")
class(euretail)#> [1] "ts"
frequency(euretail)#> [1] 4
inspect data
euretail %>% autoplot()split data train dan data test
#data test (kita akan melakukan prediksi 3 tahun terakhir)
eur_test <- tail(euretail, 3*4)
#data train (sisa dari data test)
eur_train <- head(euretail, 13*4)eur_train %>% adf.test()#>
#> Augmented Dickey-Fuller Test
#>
#> data: .
#> Dickey-Fuller = -0.40927, Lag order = 3, p-value = 0.9826
#> alternative hypothesis: stationary
eur_train %>% diff(lag = 4) %>% adf.test()#>
#> Augmented Dickey-Fuller Test
#>
#> data: .
#> Dickey-Fuller = -3.8857, Lag order = 3, p-value = 0.02218
#> alternative hypothesis: stationary
eur_train %>% diff(lag = 4) %>% diff() %>% adf.test()#>
#> Augmented Dickey-Fuller Test
#>
#> data: .
#> Dickey-Fuller = -5.1876, Lag order = 3, p-value = 0.01
#> alternative hypothesis: stationary
Differencing pada data seasonal membuat data menjadi stasioner
eur_train %>% diff(lag = 4) %>% tsdisplay()p: 1 d: 0 q: 0
P: 0 D: 1 Q: 3
Buatlah model dari kombinasi di atas
eur_sarima1 <- Arima(y = eur_train, order = c(1,0,0), seasonal = c(0,1,3))
eur_sarima2 <- Arima(y = eur_train, order = c(1,0,0), seasonal = c(0,1,0))Cek aic model
eur_sarima1$aic#> [1] 68.18751
eur_sarima2$aic#> [1] 81.93948
forecast data test
eur_forecast <- forecast(object = eur_sarima1, h = 12)visualisasi hasil forecast dan data actual
eur_train %>%
autoplot() +
autolayer(object = eur_sarima1$fitted, series = "fitted") +
autolayer(object = eur_test, series = "test") +
autolayer(object = eur_forecast$mean, series = "forecast")Evaluasi model
accuracy(eur_forecast$mean, eur_test)#> ME RMSE MAE MPE MAPE ACF1 Theil's U
#> Test set -3.985693 4.194059 3.985693 -4.129324 4.129324 0.6565622 9.408637
More resource to learn more :