Kesehatan mental merujuk kepada kondisi kesejahteraan emosional, psikologis, dan sosial seseorang. Ini mencakup cara kita berpikir, merasakan, dan berperilaku. Pentingnya Kesehatan Mental karena dapat memengaruhi cara kita berpikir, merasa, dan berinteraksi dengan orang lain. Kesehatan Mental juga vital untuk kesejahteraan secara keseluruhan dan dapat mempengaruhi kesehatan fisik. Di sini terdapat dataset terkait Mental Health yang diperoleh dari Kaggle. Dari dataset tersebut kita akan coba untuk melakukan clustering analysis menggunakan metode K-means.
library(dplyr)
library(FactoMineR)
library(factoextra)
library(ggiraphExtra)
library(ggplot2)
library(reshape2)
library(GGally)
library(plotly)
#> Rows: 10,000
#> Columns: 14
#> $ age <int> 56, 46, 32, 60, 25, 38, 56, 36, 40, 28, 28, 41,…
#> $ gender <chr> "Male", "Female", "Female", "Non-binary", "Fema…
#> $ employment_status <chr> "Employed", "Student", "Employed", "Self-employ…
#> $ work_environment <chr> "On-site", "On-site", "On-site", "On-site", "On…
#> $ mental_health_history <chr> "Yes", "No", "Yes", "No", "Yes", "Yes", "No", "…
#> $ seeks_treatment <chr> "Yes", "Yes", "No", "No", "Yes", "Yes", "Yes", …
#> $ stress_level <int> 6, 10, 7, 4, 3, 3, 2, 8, 7, 8, 6, 10, 10, 5, 1,…
#> $ sleep_hours <dbl> 6.2, 9.0, 7.7, 4.5, 5.4, 9.9, 5.5, 7.1, 6.5, 3.…
#> $ physical_activity_days <int> 3, 4, 2, 4, 0, 3, 1, 5, 6, 0, 2, 7, 1, 6, 1, 3,…
#> $ depression_score <int> 28, 30, 24, 6, 24, 17, 25, 25, 28, 7, 14, 13, 1…
#> $ anxiety_score <int> 17, 11, 7, 0, 12, 9, 3, 8, 6, 18, 9, 2, 17, 7, …
#> $ social_support_score <int> 54, 85, 62, 95, 70, 63, 87, 72, 46, 88, 85, 23,…
#> $ productivity_score <dbl> 59.7, 54.9, 61.3, 97.0, 69.0, 69.3, 63.1, 58.4,…
#> $ mental_health_risk <chr> "High", "High", "Medium", "Low", "High", "Mediu…
Dari hasil pembacaan dataset di atas, terdapat 10.000 data observasi dengan 14 kolom. Adapun untuk penjelasan masing-masing kolom adalah sebagai berikut.
Karena masih terdapat beberapa kolom yang belum sesuai dengan tipe datanya maka perlu melakukan penyesuaian tipe data.
mental_clean <- mental %>%
mutate_at(vars(sleep_hours, productivity_score), as.numeric) %>%
mutate_at(vars(gender, employment_status, work_environment, mental_health_history, seeks_treatment, mental_health_risk), as.factor)
Kemudian kita akan mengecek apakah terdapat Missing Value pada dataset kita.
#> age gender employment_status
#> 0 0 0
#> work_environment mental_health_history seeks_treatment
#> 0 0 0
#> stress_level sleep_hours physical_activity_days
#> 0 0 0
#> depression_score anxiety_score social_support_score
#> 0 0 0
#> productivity_score mental_health_risk
#> 0 0
Apakah antar variable memiliki skala yang sama? Mari kita cek range untuk tiap kolom.
#> age stress_level sleep_hours physical_activity_days
#> Min. :18.00 Min. : 1.000 Min. : 3.000 Min. :0.000
#> 1st Qu.:30.00 1st Qu.: 3.000 1st Qu.: 5.500 1st Qu.:2.000
#> Median :41.50 Median : 6.000 Median : 6.500 Median :4.000
#> Mean :41.56 Mean : 5.572 Mean : 6.473 Mean :3.506
#> 3rd Qu.:53.00 3rd Qu.: 8.000 3rd Qu.: 7.500 3rd Qu.:5.000
#> Max. :65.00 Max. :10.000 Max. :10.000 Max. :7.000
#> depression_score anxiety_score social_support_score productivity_score
#> Min. : 0.00 Min. : 0.00 Min. : 0.00 Min. : 42.80
#> 1st Qu.: 7.00 1st Qu.: 5.00 1st Qu.: 25.00 1st Qu.: 65.80
#> Median :15.00 Median :11.00 Median : 50.00 Median : 77.60
#> Mean :15.04 Mean :10.56 Mean : 50.12 Mean : 77.31
#> 3rd Qu.:23.00 3rd Qu.:16.00 3rd Qu.: 76.00 3rd Qu.: 89.20
#> Max. :30.00 Max. :21.00 Max. :100.00 Max. :100.00
Dari hasil pengecekan di atas, range dari masing-masing kolom numerik memiliki skala yang berbeda. Hal ini dapat memengaruhi hasil clustering analysis nantinya sehingga kita perlu melakukan scaling.
#> age stress_level sleep_hours
#> Min. :-1.713332 Min. :-1.5832 Min. :-2.35626
#> 1st Qu.:-0.840578 1st Qu.:-0.8907 1st Qu.:-0.66013
#> Median :-0.004189 Median : 0.1482 Median : 0.01832
#> Mean : 0.000000 Mean : 0.0000 Mean : 0.00000
#> 3rd Qu.: 0.832200 3rd Qu.: 0.8408 3rd Qu.: 0.69677
#> Max. : 1.704954 Max. : 1.5334 Max. : 2.39290
#> physical_activity_days depression_score anxiety_score
#> Min. :-1.5357 Min. :-1.672803 Min. :-1.67047
#> 1st Qu.:-0.6596 1st Qu.:-0.894232 1st Qu.:-0.87966
#> Median : 0.2165 Median :-0.004438 Median : 0.06931
#> Mean : 0.0000 Mean : 0.000000 Mean : 0.00000
#> 3rd Qu.: 0.6546 3rd Qu.: 0.885357 3rd Qu.: 0.86012
#> Max. : 1.5308 Max. : 1.663927 Max. : 1.65092
#> social_support_score productivity_score
#> Min. :-1.714640 Min. :-2.45443
#> 1st Qu.:-0.859334 1st Qu.:-0.81872
#> Median :-0.004027 Median : 0.02047
#> Mean : 0.000000 Mean : 0.00000
#> 3rd Qu.: 0.885492 3rd Qu.: 0.84543
#> Max. : 1.706587 Max. : 1.61350
Dalam tahap Data Preprocessing ini kita akan melakukan pemisahan data numerik dan data non-numerik karena pada saat melakukan PCA (Principal Component Analysis) hanya dapat diterapkan pada data numerik sehingga data non-numerik perlu diproses atau diubah menjadi bentuk numerik.
Kenapa data non-numerik harus diubah ke data numerik karena jika data non-numerik digabungkan dengan data numerik, algoritma PCA dapat memberikan bobot yang tidak pantas pada data non-numerik, yang dapat menyesatkan hasil analisis.
Dengan mengikutsertakan data non-numerik ke dalam analisis dapat membantu memahami kelompok atau klasifikasi dalam data setelah PCA diterapkan, memberikan konteks tambahan terhadap distribusi titik-titik data.
# nama kolom numerik (quantitative)
quantiy <- mental_clean %>%
select_if(is.numeric) %>%
colnames()
# indeks kolom numerik
quantiyvar <- which(colnames(mental_clean) %in% quantiy)
# nama kolom kategorik (qualitative)
qualiy <- mental_clean %>%
select_if(is.factor) %>%
colnames()
# indeks kolom kategorik
qualiyvar <- which(colnames(mental_clean) %in% qualiy)
Clustering adalah pengelompokan data berdasarkan karakteristiknya. Clustering bertujuan untuk menghasilkan cluster dimana:
Kita bisa menggunakan K-means Clustering untuk pendekatan ini.
K-means adalah salah satu algoritma clustering yang centroid-based, artinya tiap cluster memiliki satu centroid yang mewakili cluster tersebut. Banyaknya cluster \(k\) ditentukan oleh user.
Penentuan nilai k yang optimum menggunakan methode Elbow dimana
metode ini memperhitungkan Within Sum of Squares
($withinss
) yaitu jumlah jarak kuadrat dari tiap observasi
ke centroid tiap cluster. Interpretasinya adalah k yang optimum dipilih
ketika nilai \(k\) ditambah, penurunan
Total WSS tidak terlalu drastis (atau dapat dikatakan melandai).
Dari hasil visualisasi metode Elbow di atas, penurunan WSS melandai ketika k berada di angka 3 sehingga kita akan menggunakan nilai k = 3.
# k-means dengan 3 cluster
RNGkind(sample.kind = "Rounding")
set.seed(100)
mental_km <- kmeans(x = mental_scale, # data yang sudah di scaling
centers = 3) # jumlah k (cluster yang diinginkan)
# memasukkan label cluster ke data awal dengan nama kelompok
mental$kelompok1 <- as.factor(mental_km$cluster)
mental
# cluster profiling
mental %>%
group_by(kelompok1) %>%
summarise_all(.funs = "mean") %>%
select(-c(gender, employment_status, work_environment, mental_health_history, seeks_treatment, mental_health_risk))
Dari hasil profiling di atas, kita dapatkan sebuah insight:
Ide dasar dari PCA adalah untuk membuat sumbu (axis) baru yang dapat menangkap variasi data sebanyak mungkin. Sumbu baru ini adalah yang dinamakan sebagai Principal Component (PC).
# melakukan PCA dengan FactoMineR
mental_pca <- PCA(X = mental_clean, # data awal
scale.unit = T, # scaling
quali.sup = qualiyvar, # index kolom qualitative
graph = F, # tidak menampilkan graph
ncp = 8) # jumlah PC atau jumlah kolom numerik dari data awal
Hasil PCA dapat kita visualisasikan untuk memahami pola hubungan antara variabel dan individu menggunakan biplot. Biplot (dua plot) adalah grafik yang menggambarkan posisi variabel dan individu dalam satu plot.
Karena plot yang akan dibuat hanya bisa 2 dimensi sehingga PC yang dapat divisualisasikan hanyalah PC1 dan PC2 saja.
Dari hasil pembuatan biplot yang berisi posisi variabel dan posisi individu di atas sulit untuk digunakan dalam pengambilan insight. Maka kita akan membagi plot tersebut menjadi 2 plot yaitu plot individual serta plot variabel.
Plot yang menunjukkan posisi setiap individu atau observasi data dalam analisis PCA, yang membantu kita mengidentifikasi pencilan (outlier) dan melihat pola hubungan antara individu dalam dataset.
plot.PCA(x = mental_pca, # objek PCA
choix = "ind", # pilihan untuk menampilkan visualisasi individu
invisible = "quali", # untuk menghilangkan nama variabel, karena mengganggu visual
select = "contrib 5", # jumlah outlier yang ditampilkan
habillage = "mental_health_risk" # opsional: untuk mewarnai titik observasi berdasarkan category
)
Dari hasil visualisasi di atas 5 responden yang menjadi outlier adalah responden dengan baris observasi : 964, 3066, 6353, 7495 dan 8701. Namun dengan melihat sebaran data secara keseluruhan, outlier tersebut masih terbilang normal karena masih dekat dengan mayoritas data.
Dengan plot ini kita bisa mengetahui kontribusi variabel ke tiap PC dan seberapa banyak informasi yang dijelaskan oleh setiap variabel ke setiap PC. Serta dapat Mengetahui correlation antar variable awal.
Insight yang didapat dari plot di atas adalah:
depression_score
dan productivity_score
. Dan
jika melihat arah panah dari masing-masing variabel yang bertolak
belakang (180 derajat), hal tersebut menandakan kedua variabel memiliki
korelasi negatif.depression_score
dan productivity_score
. Namun
dari plot di atas terdapat hal yang menjadi sorotan yaitu panjang panah
dari masing-masing yang berbeda-beda, hal tersebut menjadi paramter
untuk menentukan besarnya kontribusi masing-masing variabel terhadap PC.
Untuk lebih jelasnya bisa divisualisasikan dengan
fviz_contrib()
.Dari hasil visualisasi menggunakan fviz_contrib()
di
atas, variabel yang berkontribusi terhadap PC adalah variabel yang
jumlahnya melewati batas nilai kontribusi yang diharapkan (Garis
horizontal putus-putus merah). Terdapat 3 variabel yang berkontribusi
terhadap PC2 yaitu anxiety_score
, age
dan
social_support_score
.
Untuk mereduksi jumlah kolom dalam data, kita akan menggunakan hasil
PCA, yaitu mental_pca$ind$coord
. Kita akan memanipulasi
data ini dengan menghapus beberapa kolomnya.
Adapun untuk langkah-langkah melakukan reduksi dimensi dari hasil PCA adalah sebagai berikut.
1️⃣ Lihat Eigenvalues: Periksa nilai eigenvalues dari
$eig
untuk semua PC.
#> eigenvalue percentage of variance cumulative percentage of variance
#> comp 1 1.93972016 24.2465020 24.24650
#> comp 2 1.02839009 12.8548761 37.10138
#> comp 3 1.02041883 12.7552354 49.85661
#> comp 4 1.01366270 12.6707837 62.52740
#> comp 5 0.99764543 12.4705679 74.99797
#> comp 6 0.99124380 12.3905475 87.38851
#> comp 7 0.94810242 11.8512803 99.23979
#> comp 8 0.06081658 0.7602072 100.00000
2️⃣ Tentukan Jumlah PC: Pilih jumlah PC yang menjelaskan proporsi kumulatif variasi yang cukup besar.
Kita perlu mereduksi kolom dari belakang. Untuk mengetahui berapa banyak kolom yang perlu direduksi, kita bisa melihat seberapa banyak kumulatif variasi yang dijelaskan secara total oleh setiap variabel.
Kita ingin mempertahankan informasi minimal 80%, maka PC yang kita gunakan adalah PC 1 - 6 karena pada PC tersebut kumulatif variansi yang ditangkap sebesar 87%.
3️⃣ Reduksi Dimensi: Subset PC terpilih untuk mereduksi dimensi.
# mengambil data hasil PCA sebanyak PC yang dibutuhkan
mental_keep <- mental_pca$ind$coord[ , 1:6 ] %>% as.data.frame()
mental_keep
Yang selanjutnya data gabungan tersebut yaitu
mental_keep
bisa digunakan untuk pemodelan
menggunakan salah satu algoritma supervised learning sesuai dengan
dataset tersebut.
Kita bisa menarik beberapa kesimpulan dari clustering analysis dan principle component analysis sebelumnya antara lain:
Berikut 3D-plot Visualization for Multidimentional Data terhadap PCA.
mental_xc <- cbind(mental_keep, cluster = mental$kelompok1)
plot_ly(mental_xc, x = ~Dim.1, y = ~Dim.2, z = ~Dim.3, color = ~cluster, colors = c('black', 'red', 'green')) %>%
add_markers() %>%
layout(scene = list(xaxis = list(title = 'Dim.1'),
yaxis = list(title = 'Dim.2'),
zaxis = list(title = 'Dim.3')))