Tujuan
❓Tujuan dari laporan ini ialah untuk analisis dan prediksi harga minyak dunia sebagai rangkaian proses seleksi project Data Science Intern di KALLA GROUP
<- read.csv("data_input/Copy of brentcrudeoil - dailybrentoil.csv")
data $Date <- as.POSIXct(data$Date, format="%m/%d/%Y %H:%M:%S") # Mengubah format kolom "Date" menjadi DateTime
data<- data[, -c(8:10)]
data glimpse(data)
Rows: 759
Columns: 7
$ Date <dttm> 2021-01-04 23:58:00, 2021-01-05 23:58:00, 2021-01-06 23:58…
$ Close <dbl> 50.23, 51.87, 52.02, 52.20, 53.33, 53.33, 54.12, 54.13, 54.…
$ chg.close. <dbl> 50.23, 1.64, 0.15, 0.18, 1.13, 0.00, 0.79, 0.01, 0.30, -0.9…
$ Low <dbl> 49.97, 50.01, 51.21, 51.89, 52.31, 52.66, 53.35, 53.75, 53.…
$ chg.low. <dbl> 49.97, 0.04, 1.20, 0.68, 0.42, 0.35, 0.69, 0.40, -0.07, -0.…
$ High <dbl> 51.88, 52.26, 52.37, 52.34, 53.61, 53.48, 54.23, 54.82, 54.…
$ chg.high. <dbl> 51.88, 0.38, 0.11, -0.03, 1.27, -0.13, 0.75, 0.59, -0.26, -…
Metadata
dari dataset tersebut adalah sebagai
berikut :
Date
: Tanggal data dalam format “YYYY-MM-DD
HH:MM:SS”.
Close
: Harga penutupan.
chg.close.
: Perubahan harga penutupan.
Low
: Harga terendah.
chg.low.
: Perubahan harga terendah.
High
: Harga tertinggi.
chg.high.
: Perubahan harga tertinggi.
# Ubah tipe data
$Date <- as.Date(data$Date)
datasummary(data)
Date Close chg.close. Low
Min. :2021-01-04 Min. : 50.23 Min. :-17.14000 Min. : 49.97
1st Qu.:2021-10-04 1st Qu.: 72.44 1st Qu.: -0.80000 1st Qu.: 71.48
Median :2022-07-07 Median : 79.82 Median : 0.21000 Median : 78.76
Mean :2022-07-06 Mean : 80.31 Mean : 0.09999 Mean : 79.18
3rd Qu.:2023-04-08 3rd Qu.: 88.20 3rd Qu.: 1.08000 3rd Qu.: 87.23
Max. :2024-01-10 Max. :114.19 Max. : 50.23000 Max. :113.39
chg.low. High chg.high.
Min. :-13.99000 Min. : 51.88 Min. :-18.0500
1st Qu.: -0.68000 1st Qu.: 73.44 1st Qu.: -0.5750
Median : 0.14000 Median : 80.75 Median : 0.1600
Mean : 0.09978 Mean : 81.37 Mean : 0.1024
3rd Qu.: 0.99500 3rd Qu.: 90.33 3rd Qu.: 0.8500
Max. : 49.97000 Max. :115.06 Max. : 51.8800
đź’ˇ Insight :
4 Januari 2021 hingga 10 Januari 2024
Close
) berkisar antara 50.23 hingga
114.19 dengan rata-rata harga closing sekitar 80.31chg.close
) memiliki nilai
minimum -17.14 dan maksimum 50.23, dengan rata-rata perubahan harga
closing sekitar 0.1Low
) berkisar antara 49.97 hingga
113.39, dengan rata-rata harga terendah berkisar 79.18chg.low
) memiliki nilai
minimum -13.99 dan maksimum 49.97 dengan rata-rata sekitar 0.10High
) berkisar antara 51.88 hingga
115.06, dengan rata-rata harga tertinggi sekitar 81.37chg.high
) memiliki nilai
minimum -18.05 dan maksimum 51.88Sebelum masuk tahapan selanjutnya, cek apakah ada
missing value
atau tidak
colSums(is.na(data))
Date Close chg.close. Low chg.low. High chg.high.
0 0 0 0 0 0 0
Tidak ada Missing Value
.
<- arrange(data, Date)
oil_data head(oil_data)
# Pembuatan Data Time Series
<- ts(oil_data$Close, frequency = 1)
oil_ts
plot(oil_ts, main = "Time Series Plot : Harga Penutupan Minyak")
Dalam contoh ini, saya menggunakan frekuensi 1 karena menggunakan
tipe data harian. Berdasarkan plot diatas data memiliki
trend
dan teramsuk multiplikatif
, pola musiman
dalam data sulit diidentifikasi, sehingga analisa lanjutan yang tepat
ialah menggunakan model ARIMA
. Namun, ada
beberapa yang perlu diperhatikan
:
Untuk kasus ini, kita abaikan pola musiman yang tidak signifikan,
karena tujuan kali ini ialah hanya untuk forecasting
.
đź’ˇ Pendekatan yang tepat dalam kasus ini adalah menggunakan model
ARIMA
untuk melakukan analisis dan prediksi. Model ARIMA
dapat membantu mengidentifikasi pola, tren, dan fluktuasi dalam data
time series. Dengan mempertimbangkan ketidakadaan pola musiman yang
jelas dalam data harian
# Menghitung mean dan varians
<- mean(oil_ts)
mean_ts <- var(oil_ts)
var_ts cat("Mean:", mean_ts, "\n")
Mean: 80.30797
cat("Variance:", var_ts, "\n")
Variance: 151.8757
ADF Test.
# Menggunakan library "tseries"
library(tseries)
# Melakukan ADF test
<- adf.test(oil_ts)
adf_test cat("ADF Test Results:\n")
ADF Test Results:
print(adf_test)
Augmented Dickey-Fuller Test
data: oil_ts
Dickey-Fuller = -1.8845, Lag order = 9, p-value = 0.6272
alternative hypothesis: stationary
Hasil uji ADF menunjukkan bahwa
nilai p adalah 0.62, yang lebih besar dari tingkat signifikansi 0.05
.
Oleh karena itu, kita gagal menolak hipotesis nol bahwa data tidak
stasioner. Ini menunjukkan bahwa kemungkinan data tersebut
tidak stasioner.
differencing
. Hal ini dilakukan agar ketika melakukan
prediksi tidak ada multicolinearity terhadap data-data sebelumnya.# differencing 1 kali
%>%
oil_ts diff() %>%
adf.test()
Augmented Dickey-Fuller Test
data: .
Dickey-Fuller = -10.307, Lag order = 9, p-value = 0.01
alternative hypothesis: stationary
đź’ˇ Berdasarkan hasil uji ADF, nilai p-value sebesar 0.01
yang artinya data termasuk stasioner.
ARIMA (p, 1, q)
<- auto.arima(oil_ts)
oil_auto oil_auto
Series: oil_ts
ARIMA(0,1,2)
Coefficients:
ma1 ma2
-0.1102 -0.1327
s.e. 0.0360 0.0360
sigma^2 = 3.989: log likelihood = -1598.9
AIC=3203.81 AICc=3203.84 BIC=3217.7
Setelah melakukan fitting model ARIMA, langkah selanjutnya adalah
melakukan evaluasi kualitas model. Pada bagian ini, kita akan
menggunakan fungsi accuracy()
dari package
forecast
untuk melihat MAPE
accuracy(oil_auto$fitted, oil_ts)
ME RMSE MAE MPE MAPE ACF1 Theil's U
Test set 0.04486349 1.993199 1.317777 0.03854151 1.608936 0.005880479 0.9912048
library(MLmetrics)
MAPE(y_pred = oil_auto$fitted,
y_true = oil_ts)*100
[1] 1.608936
đź’ˇ Hasil MAPE sebesar 1.608936 menunjukkan bahwa rata-rata persentase
kesalahan dalam prediksi harga minyak adalah sekitar1.6%.
Semakin rendah nilai MAPE, semakin baik kualitas prediksi.
Langkah selanjutnya adalah melakukan visualisasi dengan memperbarui jendela waktu menggunakan data bulan terakhir. Model ARIMA dibangun menggunakan data bulan terakhir untuk membuat prediksi.
# Memperbarui window dengan data tahun terakhir
<- tail(oil_ts, 260) # jumlah hari kerja dalam setahun
oil_ts_last_year
# Membuat model ARIMA dengan data tahun terakhir
<- auto.arima(oil_ts_last_year)
model_last_year
# Plot time series dan fitted values
autoplot(oil_ts_last_year) +
autolayer(fitted(model_last_year), lwd = 0.7) +
labs(x = "Tanggal", y = "Harga Minyak", title = "Time Series Plot dengan Fitted Values") +
+
temaku scale_y_continuous(limits = c(0, max(oil_ts_last_year, na.rm = TRUE) * 1.1))
Selanjutnya, data dibagi menjadi data training (sebagian besar data asli) dan data testing (30 data terakhir) untuk evaluasi model. Data training diuji menggunakan uji ADF untuk memastikan bahwa data stasioner.
<- head(oil_ts, n = length(oil_ts) - 30) # Data train tidak termasuk data test terakhir
data_train <- tail(oil_ts, n = 30) # Data test terakhir data_test
%>% adf.test() data_train
Augmented Dickey-Fuller Test
data: .
Dickey-Fuller = -1.9312, Lag order = 8, p-value = 0.6074
alternative hypothesis: stationary
%>%
data_train diff(lag = 1, differences = 1) %>%
adf.test()
Augmented Dickey-Fuller Test
data: .
Dickey-Fuller = -10.188, Lag order = 8, p-value = 0.01
alternative hypothesis: stationary
<- auto.arima(data_train)
train_auto_arima train_auto_arima
Series: data_train
ARIMA(1,1,1)
Coefficients:
ar1 ma1
0.6257 -0.7555
s.e. 0.1053 0.0879
sigma^2 = 4.054: log likelihood = -1541.55
AIC=3089.09 AICc=3089.12 BIC=3102.86
Selanjutnya, kita akan melakukan forecasting harga Minyak untuk periode ke depan. Kita akan menggunakan model ARIMA yang telah dibangun sebelumnya untuk melakukan prediksi selama 30 hari ke depan.
<- forecast(train_auto_arima, h =45) forecast
# Visualisasi
autoplot(oil_ts) +
autolayer(fitted(train_auto_arima), series = "Fitted Data") +
autolayer(forecast, series = "Forecast") +
autolayer(data_test, series = "Test Data") +
labs(x = "Waktu", y = "Harga Minyak", title = "Forecasting Harga Minyak Dunia") +
scale_y_continuous(limits = c(0, max(oil_ts, na.rm = TRUE) * 1.1)) +
temaku
Grafik tersebut menampilkan prediksi harga Minyak dunia selama 30 hari ke depan berdasarkan model ARIMA yang telah dibangun. Garis biru merupakan prediksi harga Minyak dunia, sedangkan area hijau menggambarkan interval prediksi.
Dengan melakukan forecasting, kita dapat memperoleh informasi tentang kemungkinan pergerakan harga Minyak dunia di masa mendatang. Namun, perlu diingat bahwa prediksi ini masih bersifat perkiraan dan dapat dipengaruhi oleh banyak faktor eksternal.
Bagian ini menggunakan LSTM bertujuan untuk melakukan prediksi harga minyak menggunakan pendekatan deep learning. Normalisasi dilakukan untuk memastikan bahwa nilai-nilai dalam data berada dalam skala yang sama.
library(tensorflow)
library(keras)
# Persiapkan data
<- arrange(data, Date)
oil_data <- ts(oil_data$Close, frequency = 1)
oil_ts
# Normalisasi data
<- scale(oil_ts)
normalized_data
# Pembagian data training dan testing
<- floor(length(normalized_data) * 0.8)
train_size <- normalized_data[1:train_size]
train_data <- normalized_data[(train_size + 1):length(normalized_data)] test_data
# Definisi model
<- keras_model_sequential() %>%
model layer_lstm(units = 128, activation = 'relu', input_shape = c(1, 1)) %>%
layer_dense(units = 64, activation = 'relu') %>%
layer_dense(units = 32, activation = 'relu') %>%
layer_dense(units = 1)
# Compile model
%>% compile(
model loss = 'mean_squared_error',
optimizer = optimizer_adam()
)
Setelah model dilatih, dilakukan prediksi terhadap data test dan hasilnya dinormalisasi kembali untuk mendapatkan prediksi dalam skala asli data.
# Fungsi untuk menghitung metrik evaluasi
<- function(y_true, y_pred) {
hitung_metrik <- data.frame(
metrics MAPE = MAPE(y_true = y_true, y_pred = y_pred),
MSE = MSE(y_true = y_true, y_pred = y_pred),
RMSE = RMSE(y_true = y_true, y_pred = y_pred),
MAE = MAE(y_true = y_true, y_pred = y_pred)
)return(metrics)
}
# Contoh penggunaan fungsi
<- hitung_metrik(y_true = oil_data$Close[(train_size + 1):length(oil_data$Close)], y_pred = predicted_values)
metrik_hasil
# Menampilkan hasil metrik dalam bentuk dataframe
print(metrik_hasil)
MAPE MSE RMSE MAE
1 0.0002822752 0.0008663908 0.02943452 0.02248515
# Membuat dataframe dari hasil prediksi
<- data.frame(
hasil_prediksi_df Tanggal = seq(Sys.Date() + 1, by = "days", length.out = days_to_predict),
Prediksi_Harga_Minyak = predicted_values_future
)
# Menampilkan dataframe hasil prediksi
print(hasil_prediksi_df)
Tanggal Prediksi_Harga_Minyak
1 2024-01-14 75.96765
2 2024-01-15 76.04511
3 2024-01-16 76.12223
4 2024-01-17 76.19780
5 2024-01-18 76.27145
6 2024-01-19 76.33994
7 2024-01-20 76.40359
8 2024-01-21 76.46273
9 2024-01-22 76.51765
10 2024-01-23 76.56863
11 2024-01-24 76.61516
12 2024-01-25 76.65723
13 2024-01-26 76.69526
14 2024-01-27 76.72963
15 2024-01-28 76.76069
# Plot prediksi masa depan dengan Plotly
library(plotly)
# Membuat dataframe untuk plot
<- data.frame(Days = 1:(length(oil_ts) + days_to_predict),
future_plot Price = c(oil_ts, rep(NA, days_to_predict)),
Predicted_Price = c(rep(NA, length(oil_ts)), predicted_values_future))
# Membuat plot interaktif menggunakan Plotly
plot_ly(data = future_plot, type = 'scatter', mode = 'lines') %>%
add_trace(x = ~Days, y = ~Price, name = 'Harga Minyak', line = list(color = 'black', width = 1)) %>%
add_trace(x = ~Days, y = ~Predicted_Price, name = 'Prediksi Harga Minyak', line = list(color = 'red', width = 1.5, dash = 'solid')) %>%
layout(title = 'Prediksi Harga Minyak 15 Hari ke Depan',
xaxis = list(title = 'Hari'),
yaxis = list(title = 'Harga Minyak'))
Dalam laporan ini, telah dilakukan analisis time series untuk kasus data harga Minyak Dunia. Berdasarkan hasil analisis, ditemukan beberapa insight penting tentang pola dan tren harga Minyak. Terdapat perbandingan antara model ARIMA dan LSTM dalam meramalkan harga minyak. Evaluasi model LSTM menghasilkan performa yang sangat baik dengan MAPE sebesar 0.00395825 sebaliknya, model ARIMA memiliki nilai MAPE sebesar 1.608936, menunjukkan tingkat kesalahan yang lebih tinggi dibandingkan dengan LSTM.
Kedua model telah dibangun dan dievaluasi untuk melakukan prediksi harga Minyak ke depan. Prediksi ini dapat memberikan gambaran tentang kemungkinan pergerakan harga Minyak di masa mendatang, namun tetap perlu diperhatikan bahwa prediksi ini masih memiliki tingkat ketidakpastian.
Dalam analisis lanjutan, dapat dilakukan pengembangan lebih lanjut seperti eksplorasi pola musiman yang lebih detail, pengujian model dengan metrik lain, atau penggunaan model lainnya…