library(keras)
## Warning: package 'keras' was built under R version 3.6.3
library(caret)
## Warning: package 'caret' was built under R version 3.6.2
## Loading required package: lattice
## Loading required package: ggplot2
## Warning: package 'ggplot2' was built under R version 3.6.2
library(dplyr)
## Warning: package 'dplyr' was built under R version 3.6.3
##
## Attaching package: 'dplyr'
## The following objects are masked from 'package:stats':
##
## filter, lag
## The following objects are masked from 'package:base':
##
## intersect, setdiff, setequal, union
library(readr)
## Warning: package 'readr' was built under R version 3.6.2
library(GGally)
## Warning: package 'GGally' was built under R version 3.6.2
## Registered S3 method overwritten by 'GGally':
## method from
## +.gg ggplot2
##
## Attaching package: 'GGally'
## The following object is masked from 'package:dplyr':
##
## nasa
library(rsample)
## Warning: package 'rsample' was built under R version 3.6.2
## Loading required package: tidyr
## Warning: package 'tidyr' was built under R version 3.6.2
concrete_nn<- read.csv("data/data-train.csv")
concrete_nn_cl <- concrete_nn[,-1]
boxplot(concrete_nn_cl)
b <- data.frame(concrete_nn_cl,plot=FALSE)
c <- boxplot(b$cement,plot=FALSE)$out
d<- boxplot(b$slag,plot=FALSE)$out
e<- boxplot(b$flyash,plot=FALSE)$out
f <- boxplot(b$water,plot=FALSE)$out
g<- boxplot(b$super_plast,plot=FALSE)$out
h<- boxplot(b$coarse_agg,plot=FALSE)$out
i<- boxplot(b$fine_agg,plot=FALSE)$out
j<- boxplot(b$age,plot=FALSE)$out
k<- b %>%
filter(!slag==d) %>%
filter(!water==f) %>%
filter(!super_plast==g)
## Warning in slag == d: longer object length is not a multiple of shorter object
## length
## Warning in water == f: longer object length is not a multiple of shorter object
## length
## Warning in super_plast == g: longer object length is not a multiple of shorter
## object length
k <- k[,-10]
ggcorr(concrete_nn_cl,label=T,label_size = 3)
Berdasarkan plot hasil korelasi diatas dapat disimpulkan bahwa: - ‘strength’ memliki korelasi positif dengan ‘age’ - ‘strength’ memliki korelasi positif yang cukup kuat dengan ‘cement’ yaitu sebesar 0.5 - ‘super_plast’ berkorelasi linear dengan ‘strength’
# Jumlah proporsi yang digunakan adalah sebesar 90% untuk data train
set.seed(100)
idx <- initial_split(k, prop = 0.9)
concrete_train <- training(idx)
concrete_val <- testing(idx)
mtrain <- data.matrix(concrete_train)
mval<- data.matrix(concrete_val)
train_x <- mtrain[,-9]
val_x <- mval[,-9]
train_y <- mtrain[,9]
val_y <- mval[,9]
train_x_array<- array_reshape(train_x,dim(train_x))
val_x_array<- array_reshape(val_x,dim(val_x))
# Scalling pada data prediktor.
train_x_keras<- scale(train_x_array,scale=T)
val_x_keras <- scale(val_x_array, scale=T)
set.seed(100)
initializer <- initializer_random_normal(seed = 100)
model_sgd <- keras_model_sequential() %>%
layer_dense(units = 256, activation = "relu",input_shape = 8,
kernel_initializer = initializer, bias_initializer = initializer) %>%
layer_dense(units = 1,activation = "linear",
kernel_initializer = initializer, bias_initializer = initializer)
model_sgd%>%
compile(loss = "mean_absolute_error",
optimizer = optimizer_sgd(lr = 0.001),
metrics="mean_absolute_error")
set.seed(123)
initializer <- initializer_random_normal(seed = 123)
model_adam <- keras_model_sequential() %>%
layer_dense(units = 256, activation = "tanh",input_shape = 8,
kernel_initializer = initializer, bias_initializer = initializer) %>%
layer_dense(units = 1,activation = "linear",
kernel_initializer = initializer, bias_initializer = initializer)
model_adam%>%
compile(loss = "mean_absolute_error",
optimizer = optimizer_adam(lr = 0.001),
metrics="mean_absolute_error")
history_sgd <- model_sgd %>%
fit(train_x_keras, train_y, epoch = 70, batch_size = 1)
history_adam <- model_adam %>%
fit(train_x_keras, train_y, epoch = 70, batch_size = 1)
pred_sgd <- predict(model_sgd,val_x_keras)
pred_adam <- predict(model_adam,val_x_keras)
evaluation_sgd <- caret::postResample(pred_sgd,val_y)
evaluation_sgd
## RMSE Rsquared MAE
## 7.4702353 0.8113981 5.5800289
evaluation_adam <- caret::postResample(pred_adam,val_y)
evaluation_adam
## RMSE Rsquared MAE
## 6.6320764 0.8587906 4.8375245
Berdasarkan penjabaran di atas dapat dilihat bahwa Rsquared dan MAE yang lebih baik dihasilkan oleh model yang sudah dituning menggunakan activation function pada hidden layer = “tanh” dengan optimizer adam.
Berikutnya adalah step untuk mengetahui apakah model Neural Network terbaik secara MAE dan Rquared (yaitu model_adam) overfit atau tidak
# Rsquared dan MAE pada data train
history_adam
## Trained on 739 samples (batch_size=1, epochs=70)
## Final epoch (plot to see history):
## loss: 4.102
## mean_absolute_error: 4.102
fit_adam <- predict(model_adam,train_x_keras)
evaluation_fit_adam <- caret::postResample(fit_adam,train_y)
evaluation_fit_adam
## RMSE Rsquared MAE
## 5.7312280 0.8839779 4.1968297
Berdasarkan Jabaran diatas dapat dilihat bahwa Rsquared pada data train dengan model_adam= 88.37% sementara MAE berkisar antara 4.125 sampai 4.298. Jika dibandingkan dengan data val dimana Rsquared hanya 85.6 persen dan MAE yang lebih besar yaitu 4.839, dapatdisimpulkan bahwa model terbaik neural network ini (model Adam) Overfit
Kesimpulan: model_adam ini masih belum memberikan Rsquared dan MAE yang memuaskan ketika dicobakan ke data validasi dimana Rquared = 0.8565853 (masih dibawah 90%) dan MAE = 4.8394606 (Masih lebih besar dari 4). Oleh karena itu model ini tidak direkomendasikan sebagai model FINAL
concrete<- read.csv("data/data-train.csv")
glimpse(concrete)
## Observations: 825
## Variables: 10
## $ id <fct> S1, S2, S3, S4, S5, S6, S7, S8, S9, S10, S11, S12, S13,...
## $ cement <dbl> 540.0, 540.0, 332.5, 332.5, 198.6, 380.0, 380.0, 475.0,...
## $ slag <dbl> 0.0, 0.0, 142.5, 142.5, 132.4, 95.0, 95.0, 0.0, 132.4, ...
## $ flyash <dbl> 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0...
## $ water <dbl> 162, 162, 228, 228, 192, 228, 228, 228, 192, 192, 228, ...
## $ super_plast <dbl> 2.5, 2.5, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, ...
## $ coarse_agg <dbl> 1040.0, 1055.0, 932.0, 932.0, 978.4, 932.0, 932.0, 932....
## $ fine_agg <dbl> 676.0, 676.0, 594.0, 594.0, 825.5, 594.0, 594.0, 594.0,...
## $ age <int> 28, 28, 270, 365, 360, 365, 28, 28, 90, 28, 28, 90, 90,...
## $ strength <dbl> 79.99, 61.89, 40.27, 41.05, 44.30, 43.70, 36.45, 39.29,...
concrete_clean<- concrete[,-1]
#melihat outlier dengan menggunaan argument 'boxplot' terhadap data 'concrete'
boxplot(concrete_clean)
# Remove Outlier
b <- data.frame(concrete_clean)
c <- boxplot(b$cement,plot = FALSE)$out
d<- boxplot(b$slag,plot = FALSE)$out
e<- boxplot(b$flyash,plot = FALSE)$out
f <- boxplot(b$water,plot = FALSE)$out
g<- boxplot(b$super_plast,plot = FALSE)$out
h<- boxplot(b$coarse_agg,plot = FALSE)$out
i<- boxplot(b$fine_agg,plot = FALSE)$out
j<- boxplot(b$age,plot = FALSE)$out
k<- b %>%
filter(!slag==d) %>%
filter(!water==f) %>%
filter(!super_plast==g)
## Warning in slag == d: longer object length is not a multiple of shorter object
## length
## Warning in water == f: longer object length is not a multiple of shorter object
## length
## Warning in super_plast == g: longer object length is not a multiple of shorter
## object length
boxplot(k)
Terdapat outlier pada variabel ‘slag’, ‘water’,‘super_plast’,‘fine_agg’ dan ‘age’. SElanjutnya outlier ‘slag’, ‘water’,‘super_plast’ dibuang untuk meningkatkan performance pada model nantinya. Selain itu pada data ini scalling jug tidak dilakukan karena 2 hal:
Model yang digunakan adalah random forest, dimana random forest tidak membutuhkan proses scalling
Hasil scalling juga tidak memberikan dampak yang signifikan terhadap keakuratan model maupun hasil prediksi
Melihat korelasi antar variabel
ggcorr(concrete_clean,label=T,label_size = 3)
Berdasarkan plot hasil korelasi diatas dapat disimpulkan bahwa: - ‘strength’ memliki korelasi positif dengan ‘age’ - ‘strength’ memliki korelasi positif yang cukup kuat dengan ‘cement’ yaitu sebesar 0.5 - ‘super_plast’ berkorelasi linear dengan ‘strength’
# Berikut adalah proses cross validation dengan proporsi data train sebesar 90 persen
library(rsample)
set.seed(100)
idx <- initial_split(k, prop = 0.90)
concrete_train <- training(idx)
concrete_val <- testing(idx)
set.seed(100)
# Model tanpa tuning ;"number" dan "repeats"
notune <- trainControl(method = "repeatedcv")
forest_notune <- train(strength ~.,data=concrete_train,method = "rf", trControl= notune)
forest_notune
## Random Forest
##
## 739 samples
## 8 predictor
##
## No pre-processing
## Resampling: Cross-Validated (10 fold, repeated 1 times)
## Summary of sample sizes: 666, 665, 665, 666, 666, 664, ...
## Resampling results across tuning parameters:
##
## mtry RMSE Rsquared MAE
## 2 5.831381 0.8980418 4.384775
## 5 5.123437 0.9096274 3.749203
## 8 5.166639 0.9069800 3.723833
##
## RMSE was used to select the optimal model using the smallest value.
## The final value used for the model was mtry = 5.
# Model dengan menggunakan tuning;"number" = 10 dan "repeats" = 1
tune <- trainControl(method = "repeatedcv",number = 10,repeats = 1)
forest_tune <- train(strength ~.,data=concrete_train,method = "rf", trControl= tune)
forest_tune
## Random Forest
##
## 739 samples
## 8 predictor
##
## No pre-processing
## Resampling: Cross-Validated (10 fold, repeated 1 times)
## Summary of sample sizes: 664, 666, 666, 665, 665, 666, ...
## Resampling results across tuning parameters:
##
## mtry RMSE Rsquared MAE
## 2 5.941214 0.8937821 4.415363
## 5 5.277163 0.9037886 3.817438
## 8 5.331403 0.8999934 3.785199
##
## RMSE was used to select the optimal model using the smallest value.
## The final value used for the model was mtry = 5.
# fb_forest
# # saveRDS(fb_forest, file = "concrete_model.rds")
#
# concrete_model <- readRDS("concrete_model.rds")
# concrete_model
# concrete_model$finalModel
Berdasarkan jaaran di atas dapat dilihat hasil evaluasi error MAE dan Rsquared cukup tinggi yaitu 90.6 dan 3.72 untuk model forest_notune dan Rsquared= 0.89, MAE=3.78 namun masih harus dibandingkan dengan prediksi pada data validasi (val) untuk membandingkan model terbaik. Untuk model Random Forest, normalisasi atau scale tidak berpengaruh sgnifikan. Olehkarena itu normalisasi tidak dilakukan. Begitu juga dengan transformasi data seperti log-transform juga tidak dibutuhkan karena target memiliki kelas numerik
#prediction tanpa tune
pred_notune <- predict(forest_notune,concrete_val)
#Prediction dengan tune
pred_tune <- predict(forest_tune,concrete_val)
Mengevaluasi model random forest
library(caret)
eval_notune <- caret::postResample(pred_notune,concrete_val$strength)
eval_tune <- caret::postResample(pred_tune,concrete_val$strength)
eval_notune
## RMSE Rsquared MAE
## 5.0801937 0.9108537 3.6154340
eval_tune
## RMSE Rsquared MAE
## 5.0088060 0.9136723 3.5325130
Berdasarkan hasil komparasi di atas dapat dilihat model yang dituning (forest_tune) menggunkan tuning;“number” dan “repeats” memberikan Rsquared maupun MAE yang lebih baik yaitu Rsquared = 0.913 dan MAE=3.53.
Model yang saya pilih di sini adalah model terbaik secara hasil menggunakan data validasi yaitu forest_tune
Rsquared MAE
0.8999934 3.785199
Rsquared MAE 0.9136723 3.5325130
Berdasarkan jabaran di atas dapat disimpulkan baha model terbaik random forest yaitu model “forest_tune” tidak overfit. Dan selanjutnya akan digunakan sebagai model FINAL dengan alasan selain tidak overfit model ini juga memberikan performance yang baik dimana Rsquared =0.9136723 (sudah lebih dari 90%) dan MAE = 3.5325130 (sudah mencapai nilai < 4)
concrete_test <- read.csv("data/data-test.csv")
concrete_test_clean <- concrete_test[,-1]
pred_test <- predict(forest_tune,concrete_test_clean)
Menggabungkan dengan data test
strength <- data.frame (pred_test)
concrete_id <- data.frame(concrete_test$id)
colnames(concrete_id)[1] = "id"
colnames(strength)[1] = "strength"
Z<- cbind(concrete_id,strength)
submit<- write.csv(Z,"submission.csv",row.names=FALSE)
Interpretasi menggunakan lime Setelah memabandingkan model 2 model yaitu Deep Learning dan Random Forest dapat disimpulkan bahwa Model Random Forest memberikan Rsquared dan MAE yang lebih baik. Adapun model Deep Learning dari yang saya amati sekalipun masih berpotensi memberikan RQuared yang besar namun nilai MAE nya selalu memberikan hasil yang kurang baik. Oleh karena itu Interpretasi akan dilakukan pada model terbaik yaitu model RANDOM FOREST
library(lime)
## Warning: package 'lime' was built under R version 3.6.3
##
## Attaching package: 'lime'
## The following object is masked from 'package:dplyr':
##
## explain
set.seed(124)
explainer <- lime(x=concrete_clean[,-9],model =forest_notune)
explanation <- explain(x=concrete_clean[,-9] %>% slice(1:5),
explainer = explainer,
n_features = 8,
n_permutations = 10)
plot.f<- plot_features(explanation)
plot.f
Berikut adalah faktor yang paling banyak dan paling sedikti berpengaruh
Observation 1 “fine_agg” merupakan faktor yang paling berpengaruh untuk kekuatan beton. semakin besar fine_agg maka akan semakin tinggi pula nilai “strength”. fine_agg akan berkorelasi positif dan berpengaruh besar jika nilainya lebih <=734. “slag” merupakan factor dengan pengaruh terkecil pada observasi ini
Observation 2 “flyash” merupakann factor paling berpengaruh. “flyash” <= 118 akan berpengaruh positif terhadap “strength”. Faktor yang paling tidak berpengaruh adalah “age”
Observation 3 “fine_agg” merupakan faktor yang paling berpengaruh untuk kekuatan beton. semakin besar fine_agg maka akan semakin tinggi pula nilai “strength”. fine_agg akan berkorelasi positif dan berpengaruh besar jika nilainya lebih <=734. faktor yang paling tidak berpengaruh adalah “coarse_agg”
Observation 4 “flyash” merupakann factor paling berpengaruh. “flyash” <= 118 akan berpengaruh positif terhadap “strength”. faktor yang paling tidak berpengaruh adalah “water”
Observation 5 “age” dan “slag” merupakan faktor berpengaruh kuat.sedangkan “fine_agg” merupakan faktor yang paling tidak berpengaruh