Human Activity Recognition
Intro
Analisis report ini mengambil data yang bersumber dari Kaggle . Data diperoleh melalui percobaan dengan subjek sebanyak 30 responden yang melakukan kegiatan mulai dari berjalan, menaiki dan menuruni tangga, berdiri, tidur, serta duduk. Pengambilan data terekam melalui alat ukur akselerometer dan gyroscope pada smartphone yang terletak pada tas pinggang yang dikenakan responden. Berdasarkan permasalahan ini, kita ingin membuat model yang dapat memprediksikan kegiatan yang dilakukan responden. Sehingga pada analisis report ini kita coba buat model naive bayes, decision tree, dan random forest dalam memprediksikan kelas target yaitu Activity.
Tahap cross validation tidak dilakukan hal ini disebabkan dataset sudah terbagi menjadi data train dan data test
Informasi Atribut
Dalam dataset berikut terdapat beberapa informasi atribut yang perlu kita ketahui:
Triaxial acceleration from the accelerometer (total acceleration) and the estimated body acceleration.
Triaxial Angular velocity from the gyroscope.
A 561-feature vector with time and frequency domain variables.
Its activity label.
Subject experiment.
Library
Berikut beberapa library yang digunakan dalam mendukung analisis terhadap permasalahan kita
library(dplyr) # data wrangling
library(ggplot2) # data visual
library(e1071) # naive bayes
library(caret) # predict()
library(ROCR)
library(partykit) # decision tree
library(randomForest) # random forest
library(rattle)Input Data
options(scipen = 999)
# input data train
har_train <- read.csv("har/train.csv")
# input data test
har_test <- read.csv("har/test.csv")
# rbind data train dengan data test
har <- rbind(har_train, har_test)Data Wrangling
# rapihkan semua nama kolom
names(har) <- gsub(x = names(har),
pattern = "\\.", replacement = "")
# ubah tipe data kolom pada data train
har_train <- har_train %>%
mutate_at(c('subject', 'Activity'), as.factor) %>%
mutate_at(vars(-subject, -Activity), as.numeric)
# ubah tipe data kolom pada data test
har_test <- har_test %>%
mutate_at(c('subject', 'Activity'), as.factor) %>%
mutate_at(vars(-subject, -Activity), as.numeric)
# ubah tipe data kolom pada dataset
har <- har %>%
mutate_at(c('subject', 'Activity'), as.factor) %>%
mutate_at(vars(-subject, -Activity), as.numeric)Cek duplicate and missing value pada dataset har
# cek duplicate
cat("Number of duplicated rows:", sum(duplicated(har_train)))## Number of duplicated rows: 0
cat("Number of duplicated rows:", sum(duplicated(har_test)))## Number of duplicated rows: 0
cat("Number of duplicated rows:", sum(duplicated(har)))## Number of duplicated rows: 0
# cek missing value
cat("Number of duplicated rows:", sum(is.na(har_train)))## Number of duplicated rows: 0
cat("Number of duplicated rows:", sum(is.na(har_test)))## Number of duplicated rows: 0
cat("Number of duplicated rows:", sum(is.na(har)))## Number of duplicated rows: 0
Tidak ada yang berduplikasi dan missing pada keseluruhan data
Cek imbalance dataset masing-masing dataset
prop.table(table(har$Activity))##
## LAYING SITTING STANDING WALKING
## 0.1887562 0.1725410 0.1850665 0.1672007
## WALKING_DOWNSTAIRS WALKING_UPSTAIRS
## 0.1365181 0.1499175
prop.table(table(har_train$Activity))##
## LAYING SITTING STANDING WALKING
## 0.1913765 0.1749184 0.1868879 0.1667573
## WALKING_DOWNSTAIRS WALKING_UPSTAIRS
## 0.1341132 0.1459467
prop.table(table(har_test$Activity))##
## LAYING SITTING STANDING WALKING
## 0.1822192 0.1666101 0.1805226 0.1683068
## WALKING_DOWNSTAIRS WALKING_UPSTAIRS
## 0.1425178 0.1598235
Berdasarkan hasil ini, proporsi kelas pada target tidak ada perbedaan yang signifikan sehingga dapat kita katakan proporsi kelas target cukup seimbang
EDA
Pada bagian eksplorasi data, pertama kita dapat membagi dua jenis Activity berdasarkan pergerakannya secara diam dan bergerak. Kegiatan yang pergerakannya secara diam seperti berdiri dan duduk. Sedangkan jenis kegiatan secara bergerak yaitu berjalan, menaiki dan menuruni tangga. Kita ingin melihat distribusi rata-rata dari triaxial magnitude of body acceleration signals (tBodyAccMagmean)
har %>%
ggplot(aes(x = tBodyAccMagmean, group = Activity, fill = Activity)) +
geom_density(alpha = .5) +
annotate('text', x = -.8, y = 25, label = "Stationary activities") +
annotate('text', x = -.0, y = 5, label = "Moving activities")+
ylab("")Interpretasi dari hasil kedua visualisi yaitu:
Jenis kegiatan secara diam pergerakan tubuhnya sangat sedikit dibandingkan jenis kegiatan secara bergerak
Jika nilai
tBodyAccMagmean> -0,5 kemungkinan kegiatan yang dilakukan seperti berjalan, menaiki dan menuruni tanggaSedangkan jika nilai nilai
tBodyAccMagmean< -0,5 kemungkinan kegiatan yang dilakukan seperti duduk, berdiri, dan tidur
Berikutnya kita akan melihat perbedaan antar jenis kegiatan berdasarkan orientasi smartphone. Untuk melihat nya kita coba bandingkan terhadap sumbu X, Y, dan Z terhadap rata-rat gravity acceleration signals masing-masing sumbu (angleXgravityMean, angleYgravityMean, dan angleZgravityMean)
har %>%
ggplot(aes(y = Activity, x = tBodyAccMagmean, group = Activity, fill = Activity)) +
geom_boxplot(show.legend = FALSE)for (coor in c('angleXgravityMean', 'angleYgravityMean', 'angleZgravityMean')) {
print(
ggplot(har,
aes_string(y = 'Activity', x = coor, group = 'Activity', fill = 'Activity')) +
geom_boxplot(show.legend = FALSE)
)
}Interpretasi yang dapat kita peroleh seperti:
Orientasi smartphone pada jenis kegiatan tidur perbedaan nya sangat signifikan dibandingkan jenis kegiatan lainnya
Jika nilai
angleXgravityMean> 0 kemungkinan jenis kegiatan seperti tidur/kegiatan lain sebaliknya.Jika nilai
angleYgravityMean< -0.25 atauangleZgravityMean< -0.25, kemungkinan jenis kegiatan seperti tidur/kegiatan lain sebaliknya
Modeling
Pembuatan model dalam analisis ini terbagi menjadi tiga bagian, yaitu model naive bayes, decision tree dan random forest. Berdasarkan dari tujuan permasalahan kita, metriks evaluasi yang digunakan yaitu Accuracy karena kita hanya ingin memprediksikan seluruh kelas (netral).
Naive Bayes
Buat model naive bayes
model_naive <- naiveBayes(har_train %>% select(-Activity),
har_train$Activity)Prediksi class dari data test
naive_pred <- predict(model_naive, har_test, type = "class")Evaluasi model dengan confusion matrix
confusionMatrix(naive_pred, reference = har_test$Activity)## Confusion Matrix and Statistics
##
## Reference
## Prediction LAYING SITTING STANDING WALKING WALKING_DOWNSTAIRS
## LAYING 322 5 8 0 0
## SITTING 212 368 54 0 0
## STANDING 0 111 455 0 0
## WALKING 0 0 0 416 80
## WALKING_DOWNSTAIRS 0 0 0 42 257
## WALKING_UPSTAIRS 3 7 15 38 83
## Reference
## Prediction WALKING_UPSTAIRS
## LAYING 0
## SITTING 0
## STANDING 0
## WALKING 9
## WALKING_DOWNSTAIRS 11
## WALKING_UPSTAIRS 451
##
## Overall Statistics
##
## Accuracy : 0.7699
## 95% CI : (0.7543, 0.785)
## No Information Rate : 0.1822
## P-Value [Acc > NIR] : < 0.00000000000000022
##
## Kappa : 0.7237
##
## Mcnemar's Test P-Value : NA
##
## Statistics by Class:
##
## Class: LAYING Class: SITTING Class: STANDING
## Sensitivity 0.5996 0.7495 0.8553
## Specificity 0.9946 0.8917 0.9540
## Pos Pred Value 0.9612 0.5804 0.8039
## Neg Pred Value 0.9177 0.9468 0.9677
## Prevalence 0.1822 0.1666 0.1805
## Detection Rate 0.1093 0.1249 0.1544
## Detection Prevalence 0.1137 0.2151 0.1921
## Balanced Accuracy 0.7971 0.8206 0.9047
## Class: WALKING Class: WALKING_DOWNSTAIRS
## Sensitivity 0.8387 0.61190
## Specificity 0.9637 0.97903
## Pos Pred Value 0.8238 0.82903
## Neg Pred Value 0.9672 0.93819
## Prevalence 0.1683 0.14252
## Detection Rate 0.1412 0.08721
## Detection Prevalence 0.1714 0.10519
## Balanced Accuracy 0.9012 0.79547
## Class: WALKING_UPSTAIRS
## Sensitivity 0.9575
## Specificity 0.9410
## Pos Pred Value 0.7554
## Neg Pred Value 0.9915
## Prevalence 0.1598
## Detection Rate 0.1530
## Detection Prevalence 0.2026
## Balanced Accuracy 0.9493
Nilai Accuracy dari model naive bayes dalam memprediksikan kelas target sebesar 77%. Berikutnya kita coba bandingkan dengan model decision tree
Decision Tree
Buat model decision tree
Dalam tahap pembuatan model decision tree, perlu kita ketahui bahwa model ini memiliki kelemahan yaitu rawan akan overfitting. Untuk mengatasi hal tersebut kita lakukan tahap tuning berupa Post-Pruning (memangkas percabangan pohon). Hal ini dilakukan agar model kita tidak terlalu kompleks.
har_tree <- ctree(formula = Activity~., har_train,
control = ctree_control(
mincriterion = 0.95,
minbucket = 1000,
minsplit = 100
))Visualisasi decision tree
plot(har_tree, type = "simple")Dari hasil visualisasi dapat kita interpretasikan seperti:
jika nilai
fBodyAccJerkentropyX<= -0.047 dan nilaitGravityAccenergyX<= -0.731 kemungkinan kegiatan yang dilakukan yaitu tidurjika nilai
fBodyAccJerkentropyX<= -0.047 dan nilaitGravityAccenergyX> -0.731 kemungkinan kegiatan yang dilakukan seperti berdiri dan dudukjika nilai
fBodyAccJerkentropyX> -0.047 dan nilaifBodyAccMagstd> -0.228 kemungkinan kegiatan yang dilakukan menuruni tanggajika nilai
fBodyAccJerkentropyX> -0.047, nilaifBodyAccMagstd<= -0.228, dan nilaitGravityAccarCoeffY1> -0.324 kemungkinan kegiatan yang dilakukan berjalanjika nilai
fBodyAccJerkentropyX> -0.047, nilaifBodyAccMagstd<= -0.228, dan nilaitGravityAccarCoeffY1<= -0.324 kemungkinan kegiatan yang dilakukan menaiki tangga
Prediksi kelas target pada data test
pred_har_tree_test <- predict(har_tree, har_test, type ="response")pred_har_tree_train <- predict(har_tree, har_train, type ="response")Model evaluation
Pada tahap evaluasi ini kita tidak ingin model decision tree yang telah kita buat overfitting, oleh sebab itu kita coba bandingkan metriks evalusi Accuracy pada prediksi baik menggunakan data test dan data train dengan fungsi confusionMatrix()
# data train
confusionMatrix(pred_har_tree_test, reference = har_test$Activity)## Confusion Matrix and Statistics
##
## Reference
## Prediction LAYING SITTING STANDING WALKING WALKING_DOWNSTAIRS
## LAYING 536 0 0 0 0
## SITTING 1 318 388 0 0
## STANDING 0 173 144 0 0
## WALKING 0 0 0 442 58
## WALKING_DOWNSTAIRS 0 0 0 6 305
## WALKING_UPSTAIRS 0 0 0 48 57
## Reference
## Prediction WALKING_UPSTAIRS
## LAYING 0
## SITTING 0
## STANDING 0
## WALKING 66
## WALKING_DOWNSTAIRS 24
## WALKING_UPSTAIRS 381
##
## Overall Statistics
##
## Accuracy : 0.7214
## 95% CI : (0.7048, 0.7375)
## No Information Rate : 0.1822
## P-Value [Acc > NIR] : < 0.00000000000000022
##
## Kappa : 0.6654
##
## Mcnemar's Test P-Value : NA
##
## Statistics by Class:
##
## Class: LAYING Class: SITTING Class: STANDING
## Sensitivity 0.9981 0.6477 0.27068
## Specificity 1.0000 0.8416 0.92836
## Pos Pred Value 1.0000 0.4498 0.45426
## Neg Pred Value 0.9996 0.9228 0.85247
## Prevalence 0.1822 0.1666 0.18052
## Detection Rate 0.1819 0.1079 0.04886
## Detection Prevalence 0.1819 0.2399 0.10757
## Balanced Accuracy 0.9991 0.7446 0.59952
## Class: WALKING Class: WALKING_DOWNSTAIRS
## Sensitivity 0.8911 0.7262
## Specificity 0.9494 0.9881
## Pos Pred Value 0.7809 0.9104
## Neg Pred Value 0.9773 0.9560
## Prevalence 0.1683 0.1425
## Detection Rate 0.1500 0.1035
## Detection Prevalence 0.1921 0.1137
## Balanced Accuracy 0.9203 0.8572
## Class: WALKING_UPSTAIRS
## Sensitivity 0.8089
## Specificity 0.9576
## Pos Pred Value 0.7840
## Neg Pred Value 0.9634
## Prevalence 0.1598
## Detection Rate 0.1293
## Detection Prevalence 0.1649
## Balanced Accuracy 0.8833
Nilai Accuracy model decision tree dengan data train sebesar 72%
# data test
confusionMatrix(pred_har_tree_train, reference = har_train$Activity)## Confusion Matrix and Statistics
##
## Reference
## Prediction LAYING SITTING STANDING WALKING WALKING_DOWNSTAIRS
## LAYING 1402 0 0 0 0
## SITTING 2 814 809 0 0
## STANDING 0 471 565 0 0
## WALKING 0 0 0 1054 80
## WALKING_DOWNSTAIRS 3 0 0 12 833
## WALKING_UPSTAIRS 0 1 0 160 73
## Reference
## Prediction WALKING_UPSTAIRS
## LAYING 0
## SITTING 0
## STANDING 0
## WALKING 103
## WALKING_DOWNSTAIRS 191
## WALKING_UPSTAIRS 779
##
## Overall Statistics
##
## Accuracy : 0.7409
## 95% CI : (0.7307, 0.7509)
## No Information Rate : 0.1914
## P-Value [Acc > NIR] : < 0.00000000000000022
##
## Kappa : 0.6883
##
## Mcnemar's Test P-Value : NA
##
## Statistics by Class:
##
## Class: LAYING Class: SITTING Class: STANDING
## Sensitivity 0.9964 0.6330 0.41121
## Specificity 1.0000 0.8663 0.92121
## Pos Pred Value 1.0000 0.5009 0.54537
## Neg Pred Value 0.9992 0.9176 0.87191
## Prevalence 0.1914 0.1749 0.18689
## Detection Rate 0.1907 0.1107 0.07685
## Detection Prevalence 0.1907 0.2210 0.14091
## Balanced Accuracy 0.9982 0.7496 0.66621
## Class: WALKING Class: WALKING_DOWNSTAIRS
## Sensitivity 0.8597 0.8448
## Specificity 0.9701 0.9676
## Pos Pred Value 0.8521 0.8017
## Neg Pred Value 0.9719 0.9758
## Prevalence 0.1668 0.1341
## Detection Rate 0.1434 0.1133
## Detection Prevalence 0.1683 0.1413
## Balanced Accuracy 0.9149 0.9062
## Class: WALKING_UPSTAIRS
## Sensitivity 0.7260
## Specificity 0.9627
## Pos Pred Value 0.7690
## Neg Pred Value 0.9536
## Prevalence 0.1459
## Detection Rate 0.1060
## Detection Prevalence 0.1378
## Balanced Accuracy 0.8444
Sedangkan nilai Accuracy dengan menggunakan data test sebesar 74%. Dari kedua hasil ini dapat kita katakan bahwa model masih belum overfitting (selisih 2%)
Selain dengan kedua model yang telah kita buat, kita coba lakukan pembuatan model lagi dengan metode random forest
Random Forest
Sebelum melakukan tahap pemodelan, terlebih dahulu kita hilangkan kolom subject pada data train dan data test untuk mempermudah proses pemodelan random forest sampai tahap evaluasi model
new_train <- har_train %>% select(-subject)
new_test <- har_test %>% select(-subject)Modeling
set.seed(999)
har_rf <- randomForest(Activity~., data = new_train)
har_rf##
## Call:
## randomForest(formula = Activity ~ ., data = new_train)
## Type of random forest: classification
## Number of trees: 500
## No. of variables tried at each split: 23
##
## OOB estimate of error rate: 1.65%
## Confusion matrix:
## LAYING SITTING STANDING WALKING WALKING_DOWNSTAIRS
## LAYING 1407 0 0 0 0
## SITTING 0 1236 49 0 0
## STANDING 0 40 1334 0 0
## WALKING 0 0 0 1213 6
## WALKING_DOWNSTAIRS 0 0 0 4 973
## WALKING_UPSTAIRS 0 0 0 0 5
## WALKING_UPSTAIRS class.error
## LAYING 0 0.000000000
## SITTING 1 0.038880249
## STANDING 0 0.029112082
## WALKING 7 0.010603589
## WALKING_DOWNSTAIRS 9 0.013184584
## WALKING_UPSTAIRS 1068 0.004659832
# prediksi kelas target
pred_har_rf <- predict(har_rf, new_test)Model Evaluation
confusionMatrix(pred_har_rf, reference = new_test$Activity)## Confusion Matrix and Statistics
##
## Reference
## Prediction LAYING SITTING STANDING WALKING WALKING_DOWNSTAIRS
## LAYING 537 0 0 0 0
## SITTING 0 440 45 0 0
## STANDING 0 51 487 0 0
## WALKING 0 0 0 481 19
## WALKING_DOWNSTAIRS 0 0 0 9 355
## WALKING_UPSTAIRS 0 0 0 6 46
## Reference
## Prediction WALKING_UPSTAIRS
## LAYING 0
## SITTING 0
## STANDING 0
## WALKING 30
## WALKING_DOWNSTAIRS 7
## WALKING_UPSTAIRS 434
##
## Overall Statistics
##
## Accuracy : 0.9277
## 95% CI : (0.9178, 0.9368)
## No Information Rate : 0.1822
## P-Value [Acc > NIR] : < 0.00000000000000022
##
## Kappa : 0.9131
##
## Mcnemar's Test P-Value : NA
##
## Statistics by Class:
##
## Class: LAYING Class: SITTING Class: STANDING
## Sensitivity 1.0000 0.8961 0.9154
## Specificity 1.0000 0.9817 0.9789
## Pos Pred Value 1.0000 0.9072 0.9052
## Neg Pred Value 1.0000 0.9793 0.9813
## Prevalence 0.1822 0.1666 0.1805
## Detection Rate 0.1822 0.1493 0.1653
## Detection Prevalence 0.1822 0.1646 0.1826
## Balanced Accuracy 1.0000 0.9389 0.9471
## Class: WALKING Class: WALKING_DOWNSTAIRS
## Sensitivity 0.9698 0.8452
## Specificity 0.9800 0.9937
## Pos Pred Value 0.9075 0.9569
## Neg Pred Value 0.9938 0.9748
## Prevalence 0.1683 0.1425
## Detection Rate 0.1632 0.1205
## Detection Prevalence 0.1798 0.1259
## Balanced Accuracy 0.9749 0.9195
## Class: WALKING_UPSTAIRS
## Sensitivity 0.9214
## Specificity 0.9790
## Pos Pred Value 0.8930
## Neg Pred Value 0.9850
## Prevalence 0.1598
## Detection Rate 0.1473
## Detection Prevalence 0.1649
## Balanced Accuracy 0.9502
Nilai Accuracy model random forest lebih baik dibandingkan kedua model lain yaitu sebesar 93%
Interpretation
Performance Random Forest dapat diunggulkan dibandingkan model yang lain, namun tidak terlalu dapat diinterpretasi karena banyak faktor random yang terlibat. Namun setidaknya kita dapat melihat prediktor apa saja yang paling penting dalam pembuatan Random Forest melalui variable importancenya:
interpret <- varImp(har_rf)
interpret %>% arrange(-Overall) %>% head(10)## Overall
## tGravityAcc.energy...X 211.2820
## tGravityAcc.min...X 191.9883
## tGravityAcc.mean...X 167.7176
## angle.Y.gravityMean. 156.4591
## tGravityAcc.max...Y 152.2429
## tGravityAcc.mean...Y 148.7735
## tGravityAcc.max...X 143.6573
## tGravityAcc.min...Y 138.2051
## angle.X.gravityMean. 135.5493
## tGravityAcc.energy...Y 112.6870
Dalam kasus ini, prediktor yang memiliki pengaruh besar terhadap pembuatan model random forest adalah tGravityAccenergyX.
Kesimpulan
Kesimpulan yang diperoleh dalam analisis ini yaitu semua model yang telah kita buat berhasil dalam memprediksikan kegiatan manusia yang terekam lewat smartphone. Dikarenakan kita ingin memprediksikan semua kelas target maka kita gunakan metriks evaluasi Accuracy. Berdasarkan nilai metrik evaluasi Accuracy, model random forest adalah yang terbaik dibanding model lain. Nilai Accuracy model random forest sebesar 93%
Sebagai saran ke depan, akan lebih baik jika menambahkan nilai AUC ataupun menampilkan plot ROC. Dikarenakan, Accuracy memiliki kekurangan untuk memperlihatkan kebaikan model dalam mengklasifikasi seluruh kelas. Oleh sebab itu AUC dan ROC dapat mengatasi permasalahan Accuracy tersebut di mana sebagai alat evaluasi selain confusionMatrix()