Stress Level Project
Introduction
Sejak pandemi COVID-19 yang terjadi pada tahun 2020, sistem pembelajaran beralih ke pembelajaran jarak jauh (PJJ). Selama PJJ, penelitian menunjukkan 50,5% pelajar mengalami stres berat (E-Journal Kemkes).
Setelah pandemi COVID-19 sudah mereda dan pembelajaran sudah kembali luring, masalah kesehatan mental pada pelajar masih terus berlanjut. Hasil Survei I-NAMHS menunjukkan 1 dari 3 remaja memilki masalah kesehatan mental (UGM News). Oleh sebab itu, menganalisis faktor yang menjadi alasan pelajar mengalami gangguan mental atau stres perlu dianalisis sehingga dapat dilakukan langkah untuk menangani hal tersebut.
Pada kesempatan kali ini, kita akan mencoba menganalisis beberapa faktor yang dapat berpengaruh kepada tingkat stres pelajar menggunakan dataset yang didapat dari Kaggle. Selanjutnya, kita akan membuat model machine learning untuk memprediksi tingkat stres pelajar berdasarkan faktor - faktor penyebab stres yang tersedia.
Preparation
Libraries
Import Dataset
Data yang digunakan merupakan data faktor - faktor yang dapat mempengaruhi tingkat stress pelajar. Data tersebut diambil dari Kaggle: Student Stress Factors by CHHABII. Model machine learning yang akan dibuat berguna untuk memprediksi tingkat stres pelajar berdasarkan faktor - faktor yang ada. Target variabel pada data ini adalah ‘stress_level’ yang memiliki kelas tingkatan stres siswa dari level 0 sampai level 2.
Data Description
anxiety_level: tingkat rasa cemas (skala: 1 - 21).self_esteem: tingkat penghargaan terhadap diri sendiri (skala: 1 - 30).mental_health_history: riwayat kesehatan mental (0: No, 1: Yes).depression: tingkat depresi (skala: 1 - 27).headache: tingkat sakit kepala (skala: 1 - 5).blood_pressure: tingkat tekanan darah (skala: 1 - 3).sleep_quality: tingkat kualitas tidur (skala: 0 - 5).breathing_problem: tingkat gangguan pernapasan (skala: 0 - 5).noise_level: tingkat kebisingan di lingkungan sekitar (skala: 0 - 5).living_conditions: tingkat kondisi hidup (skala: 0 - 5).safety: tingkat keamanan (skala: 0 - 5).basic_needs: tingkat kebutuhan dasar (skala: 0 -5).academic_performance: tingkat performa akademik (skala: 0 - 5).study_load: tingkat beban studi (skala: 0 - 5).teacher_student_relationship: tingkat hubungan guru dengan siswa (skala: 0 - 5).future_career_concerns: tingkat kekhawatiran akan karir masa depan (skala: 0 -5).social_support: tingkat dukungan sosial (skala: 0 - 3).peer_pressure: tingkat tekanan dari teman sebaya (skala: 0 - 5).extracurricular_activities: tingkat aktivitas ekstrakurikuler (skala: 0 - 5).bullying: tingkat bullying (skala: 0 - 5).stress_level: tingkat stress (skala: 0 - 2).
Data Wrangling
Pada dataset ini, terdapat tiga kolom yang akan diubah menjadi
kategori berdasarkan skala - skala tertentu. Ketiga kolom tersebut
adalah anxiety_level, self_esteem, dan
depression.
Pertama, skala tingkat anxiety akan merujuk pada Generalized Anxiety Disorder 7-item (GAD-7).
Kedua, skala tingkat depresi akan merujuk pada Patient Health Questionnaire-9 (PHQ-9).
Ketiga, skala tingkat self esteem akan merujuk pada Rosenberg’s Self-Esteem Scale.
Kemudian, ketiga kolom tersebut akan diubah dan disesuaikan menjadi kategori - kategori berdasarkan skala - skala yang telah disebutkan di atas.
stres$anxiety_level <- ifelse(stres$anxiety_level < 5, "Minimal",
ifelse(stres$anxiety_level >=5 & stres$anxiety_level < 10, "Mild",
ifelse(stres$anxiety_level >=10 & stres$anxiety_level < 15, "Moderate", "Severe")))
stres$depression <- ifelse(stres$depression < 5, "None-Minimal",
ifelse(stres$depression >=5 & stres$depression < 10, "Mild",
ifelse(stres$depression >=10 & stres$depression < 15, "Moderate",
ifelse(stres$depression >=15 & stres$depression < 20, "Moderately Severe", "Severe"))))
stres$self_esteem <- ifelse(stres$self_esteem < 15, "Low",
ifelse(stres$self_esteem >=15 & stres$self_esteem <= 25, "Normal", "High"))Exploratory Data Analysis (EDA)
Sebelum melakukan eksplorasi data lebih lanjut, kelengkapan data perlu untuk diperiksa terlebih dahulu apakah ada missing value atau tidak.
Missing Value Check
#> anxiety_level self_esteem
#> 0 0
#> mental_health_history depression
#> 0 0
#> headache blood_pressure
#> 0 0
#> sleep_quality breathing_problem
#> 0 0
#> noise_level living_conditions
#> 0 0
#> safety basic_needs
#> 0 0
#> academic_performance study_load
#> 0 0
#> teacher_student_relationship future_career_concerns
#> 0 0
#> social_support peer_pressure
#> 0 0
#> extracurricular_activities bullying
#> 0 0
#> stress_level
#> 0
Tidak terdapat data yang hilang (missing value) pada dataset dan dataset siap dilakukan eksplorasi lebih lanjut.
Structure Data Check
Untuk melakukan pengecekan struktur pada dataset, dapat digunakan
fungsi glimpse dari package dplyr.
#> Rows: 1,100
#> Columns: 21
#> $ anxiety_level <chr> "Moderate", "Severe", "Moderate", "Severe…
#> $ self_esteem <chr> "Normal", "Low", "Normal", "Low", "High",…
#> $ mental_health_history <int> 0, 1, 1, 1, 0, 1, 0, 1, 1, 0, 1, 1, 0, 1,…
#> $ depression <chr> "Moderate", "Moderately Severe", "Moderat…
#> $ headache <int> 2, 5, 2, 4, 2, 3, 1, 4, 3, 4, 4, 3, 1, 4,…
#> $ blood_pressure <int> 1, 3, 1, 3, 3, 3, 2, 3, 1, 3, 3, 3, 2, 3,…
#> $ sleep_quality <int> 2, 1, 2, 1, 5, 1, 4, 1, 2, 1, 1, 1, 4, 1,…
#> $ breathing_problem <int> 4, 4, 2, 3, 1, 4, 1, 5, 4, 2, 3, 5, 2, 0,…
#> $ noise_level <int> 2, 3, 2, 4, 3, 3, 1, 3, 3, 0, 4, 5, 2, 1,…
#> $ living_conditions <int> 3, 1, 2, 2, 2, 2, 4, 1, 3, 5, 2, 2, 3, 2,…
#> $ safety <int> 3, 2, 3, 2, 4, 2, 4, 1, 3, 2, 1, 1, 5, 4,…
#> $ basic_needs <int> 2, 2, 2, 2, 3, 1, 4, 1, 3, 2, 1, 1, 5, 3,…
#> $ academic_performance <int> 3, 1, 2, 2, 4, 2, 5, 1, 3, 2, 1, 1, 5, 1,…
#> $ study_load <int> 2, 4, 3, 4, 3, 5, 1, 3, 3, 2, 3, 3, 2, 2,…
#> $ teacher_student_relationship <int> 3, 1, 3, 1, 1, 2, 4, 2, 2, 1, 1, 1, 4, 3,…
#> $ future_career_concerns <int> 3, 5, 2, 4, 2, 5, 1, 4, 3, 5, 4, 4, 1, 3,…
#> $ social_support <int> 2, 1, 2, 1, 1, 1, 3, 1, 3, 1, 1, 1, 3, 0,…
#> $ peer_pressure <int> 3, 4, 3, 4, 5, 4, 2, 4, 3, 5, 4, 5, 1, 1,…
#> $ extracurricular_activities <int> 3, 5, 2, 4, 0, 4, 2, 4, 2, 3, 4, 5, 1, 0,…
#> $ bullying <int> 2, 5, 2, 5, 5, 5, 1, 5, 2, 4, 5, 4, 1, 1,…
#> $ stress_level <int> 1, 2, 1, 2, 1, 2, 0, 2, 1, 1, 2, 2, 0, 2,…
Dataset memiliki 1100 baris data dan 21 kolom. Tipe data setiap kolom
dapat diubah menjadi tipe factor melihat dari dataset memiliki jumlah
kelas yang tergolong sedikit, yaitu 2 sampai 6 kelas. Setelah mengubah
tipe data, level kelas pada kolom anxiety_level,
self_esteem, dan depression diatur dari kelas
terkecil ke tertinggi.
# Mengubah tipe data
stres <- stres %>%
mutate_all(as.factor)
# Mengatur level pada kolom
stres$anxiety_level <- factor(stres$anxiety_level, levels=c("Minimal", "Mild", "Moderate", "Severe"))
stres$self_esteem <- factor(stres$self_esteem, levels=c("Low", "Normal", "High"))
stres$depression <- factor(stres$depression, levels=c("None-Minimal", "Mild", "Moderate", "Moderately Severe", "Severe"))
glimpse(stres)#> Rows: 1,100
#> Columns: 21
#> $ anxiety_level <fct> Moderate, Severe, Moderate, Severe, Sever…
#> $ self_esteem <fct> Normal, Low, Normal, Low, High, Low, High…
#> $ mental_health_history <fct> 0, 1, 1, 1, 0, 1, 0, 1, 1, 0, 1, 1, 0, 1,…
#> $ depression <fct> Moderate, Moderately Severe, Moderate, Mo…
#> $ headache <fct> 2, 5, 2, 4, 2, 3, 1, 4, 3, 4, 4, 3, 1, 4,…
#> $ blood_pressure <fct> 1, 3, 1, 3, 3, 3, 2, 3, 1, 3, 3, 3, 2, 3,…
#> $ sleep_quality <fct> 2, 1, 2, 1, 5, 1, 4, 1, 2, 1, 1, 1, 4, 1,…
#> $ breathing_problem <fct> 4, 4, 2, 3, 1, 4, 1, 5, 4, 2, 3, 5, 2, 0,…
#> $ noise_level <fct> 2, 3, 2, 4, 3, 3, 1, 3, 3, 0, 4, 5, 2, 1,…
#> $ living_conditions <fct> 3, 1, 2, 2, 2, 2, 4, 1, 3, 5, 2, 2, 3, 2,…
#> $ safety <fct> 3, 2, 3, 2, 4, 2, 4, 1, 3, 2, 1, 1, 5, 4,…
#> $ basic_needs <fct> 2, 2, 2, 2, 3, 1, 4, 1, 3, 2, 1, 1, 5, 3,…
#> $ academic_performance <fct> 3, 1, 2, 2, 4, 2, 5, 1, 3, 2, 1, 1, 5, 1,…
#> $ study_load <fct> 2, 4, 3, 4, 3, 5, 1, 3, 3, 2, 3, 3, 2, 2,…
#> $ teacher_student_relationship <fct> 3, 1, 3, 1, 1, 2, 4, 2, 2, 1, 1, 1, 4, 3,…
#> $ future_career_concerns <fct> 3, 5, 2, 4, 2, 5, 1, 4, 3, 5, 4, 4, 1, 3,…
#> $ social_support <fct> 2, 1, 2, 1, 1, 1, 3, 1, 3, 1, 1, 1, 3, 0,…
#> $ peer_pressure <fct> 3, 4, 3, 4, 5, 4, 2, 4, 3, 5, 4, 5, 1, 1,…
#> $ extracurricular_activities <fct> 3, 5, 2, 4, 0, 4, 2, 4, 2, 3, 4, 5, 1, 0,…
#> $ bullying <fct> 2, 5, 2, 5, 5, 5, 1, 5, 2, 4, 5, 4, 1, 1,…
#> $ stress_level <fct> 1, 2, 1, 2, 1, 2, 0, 2, 1, 1, 2, 2, 0, 2,…
Struktur data sudah sesuai menjadi factor dan level factor untuk kolom ‘anxiety_level’, ‘self_esteem’, dan ‘depression’ sudah diatur berurutan dari tingkatan terkecil ke tertinggi.
Data Summary
Selanjutnya, kita dapat mengetahui proporsi kelas pada setiap
variabel kategori dengan menggunakan fungsi inspect_cat
dari package inspectdf seperti berikut:
Berdasarkan plot tersebut, beberapa insights yang dapat diambil
adalah proporsi kelas target stress_level cukup seimbang
untuk tiap kelasnya. Selain itu, untuk variabel lainnya tidak dapat
dikatakan cukup seimbang untuk setiap kelasnya, kecuali kelas 0 untuk
beberapa variabel.
Selanjutnya, kita akan mencoba untuk melihat korelasi antara variabel
anxiety_level terhadap variabel target
stress_level. Plot kita lakukan dengan menggunakan fungsi
ggplot dari library ggplot2 dan fungsi
ggplotly dari library plotly.
Dari plot tersebut, tingkat anxiety cenderung berbanding lurus dengan tingkat stres pelajar. Ketika tingkat anxiety semakin meningkat maka tingkat stres juga cenderung untuk meningkat. Selanjutnya, kita juga akan melihat korelasi antara riwayat terkait kesehatan mental dengan tingkatan stres menggunakan fungsi yang sama dengan plot sebelumnya.
Dari plot tersebut, pelajar yang tidak memiliki riwayat terkait kesehatan mental cenderung memiliki tingkat stres yang lebih rendah. Sementara itu, pelajar yang memilki riwayat terkait kesehatan mental cenderung memiliki tingkat stres yang lebih tinggi.
Modelling
Naive-Bayes Model
Model machine learning yang akan digunakan kali ini adalah Naive-Bayes Model. Model Naive Bayes adalah metode klasifikasi yang didasari oleh Bayes’ Theorem of Probability dan merupakan salah satu model yang sering dipakai. Model Naive-Bayes baik digunakan untuk dataset yang memiliki variabel prediktor bertipe factor. Karakteristik Naive Bayes memiliki 2 asumsi, yaitu:
- Variabel target dependen terhadap variabel - variabel prediktornya.
- Hubungan antar variabel prediktor adalah independen.
Cross-Validation
Sebelum melakukan pemodelan, kita perlu membagi dataset menjadi data train dan data test. Proporsi yang akan digunakan adalah 80% untuk data train dan 20% untuk data test. Data train akan digunakan untuk membangun model dan data test akan digunakan untuk melakukan evaluasi model nantinya.
RNGkind(sample.kind = "Rounding")
set.seed(172)
# Train-Test Splitting
index <- sample(x = nrow(stres), size= nrow(stres)*0.8)
stres_train <- stres[index, ]
stres_test <- stres[-index, ]Lalu, kita memeriksa proporsi tiap kelas pada variabel target
stress_level. Hasil menunjukkan proporsinya untuk tiap
kelasnya sudah cukup seimbang.
#>
#> 0 1 2
#> 0.3375 0.3250 0.3375
Model Fitting
Pemodelan Naive-Bayes dilakukan terhadap data train dengan
menggunakan fungsi naiveBayes dari library
e1071. Pemodelan disimpan pada object
model_nb.
Evaluation
Confusion Matrix
#> Confusion Matrix and Statistics
#>
#> Reference
#> Prediction 0 1 2
#> 0 64 4 2
#> 1 4 63 2
#> 2 8 5 68
#>
#> Overall Statistics
#>
#> Accuracy : 0.8864
#> 95% CI : (0.8368, 0.9251)
#> No Information Rate : 0.3455
#> P-Value [Acc > NIR] : <2e-16
#>
#> Kappa : 0.8296
#>
#> Mcnemar's Test P-Value : 0.1804
#>
#> Statistics by Class:
#>
#> Class: 0 Class: 1 Class: 2
#> Sensitivity 0.8421 0.8750 0.9444
#> Specificity 0.9583 0.9595 0.9122
#> Pos Pred Value 0.9143 0.9130 0.8395
#> Neg Pred Value 0.9200 0.9404 0.9712
#> Prevalence 0.3455 0.3273 0.3273
#> Detection Rate 0.2909 0.2864 0.3091
#> Detection Prevalence 0.3182 0.3136 0.3682
#> Balanced Accuracy 0.9002 0.9172 0.9283
Untuk melihat seberapa baik model_nb secara keseluruhan,
kita dapat melihat melalui metrik akurasi. Hasil confusion matrix
menunjukkan model_nb memiliki akurasi sebesar 88.64%.
Selain itu, metrik lain yang penting dalam memprediksi tingkat stres
pelajar adalah Sensitivity atau Recall. Metrik Sensitivity penting
karena kondisi False Negative (FN) menjadi concern pada kasus ini.
Kondisi False Negative dari kelas 2 adalah ketika pelajar diprediksi
memiliki tingkat stres kelas 0 atau kelas 1, namun aktualnya memiliki
tingkat stres kelas 2. Metrik Sensitivity pada kelas 2 sebesar 94,44%.
Berdasarkan kedua metrik tersebut, model ini dapat dikatakan sebagai
model dengan performa yang baik.
ROC and AUC
Selain menggunakan Confusion Matrix, kita juga dapat menggunakan Receiver-Operating Curve (ROC) dan Area Under Curve (AUC) untuk melakukan evaluasi model. ROC merupakan kurva yang menggambarkan hubungan antara True Positive Rate dengan False Positive Rate untuk setiap ambang atau threshold. Model dengan performa yang baik idealnya memiliki True Positive Rate yang tinggi dan False Positive Rate yang rendah. Sementara itu, AUC adalah luas area di bawah kurva. Semakin mendekati nilai 1, performa model semakin baik.
Hasil menunjukkan nilai AUC untuk setiap hubungan antar kelas
mendekati nilai 1. Hal ini menunjukkan model_nb sudah cukup
baik untuk memprediksi variabel target stress_level
berdasarkan faktor - faktor yang ada.
Conclusion
Model Naive-Bayes yang dibuat (model_nb) merupakan model
yang cukup baik dalam memprediksi tingkat stres pelajar berdasarkan
faktor - faktor penyebab stres yang ada. Performa yang baik dari model
ini terlihat dari metrik akurasi yang bernilai 88,64% dan metrik
sensitivity yang bernilai 94,44%. Dengan hasil pemodelan ini, harapannya
dapat dijadikan salah satu tools atau pertimbangan untuk menentukan
tingkat stres seorang pelajar sehingga dapat diberikan treatment atau
penanganan yang tepat.
References
- Dataset from Kaggle : https://www.kaggle.com/datasets/rxnach/student-stress-factors-a-comprehensive-analysis
- GAD-7 Scale : https://www.hiv.uw.edu/page/mental-health-screening/gad-7
- PHQ-9 Scale : https://www.hiv.uw.edu/page/mental-health-screening/phq-9
- Rosenberg’s Self-Esteem Scale : https://wwnorton.com/college/psych/psychsci/media/rosenberg.htm
- E-Journal Kemkes: http://ejournal2.bkpk.kemkes.go.id/index.php/mpk/article/view/4375
- UGM News : https://ugm.ac.id/id/berita/23086-hasil-survei-i-namhs-satu-dari-tiga-remaja-indonesia-memiliki-masalah-kesehatan-mental/