1 Latar Belakang

Analisis ini bertujuan untuk mengetahui sejauh mana penggunaan media sosial mempengaruhi perilaku menunda tugas (prokrastinasi) pada mahasiswa Statistika Angkatan 2024 Universitas Riau. Aktivitas menunda tugas dapat berdampak negatif terhadap prestasi akademik, sehingga perlu dilakukan penelitian untuk menemukan solusi yang tepat.


2 Pertanyaan Riset

  1. Berapa lama waktu yang dihabiskan untuk membuka media sosial?
  2. Media sosial apa yang paling sering dibuka?
  3. Seberapa sering menunda mengerjakan tugas karena bermain medsos?
  4. Apa alasan utama membuka media sosial saat belajar/mengerjakan tugas?
  5. Rata-rata berapa lama waktu belajar atau mengerjakan tugas dalam sehari?

3 Persiapan

3.1 Install & Load Library

# Jalankan install.packages() jika belum terinstall:
# install.packages(c("readxl","dplyr","ggplot2","MASS","rpart",
#                    "rpart.plot","caret","nnet","tidyr","knitr","kableExtra","scales"))

library(readxl)
library(MASS)        # polr – regresi logistik ordinal
library(rpart)       # decision tree
library(rpart.plot)
library(caret)       # confusion matrix & evaluasi
library(nnet)
library(tidyr)
library(ggplot2)
library(scales)
library(knitr)
library(kableExtra)
library(dplyr)       # dplyr SELALU terakhir agar select() tidak konflik

3.2 Import Data

df_raw <- read_excel("C:/Users/yolan/Downloads/Analisis_data_psd.xlsx",
                     sheet = "Form Responses 1")

glimpse(df_raw)
## Rows: 42
## Columns: 12
## $ Timestamp                                                                                               <dttm> …
## $ Nama                                                                                                    <chr> …
## $ NIM                                                                                                     <dbl> …
## $ `Usia (Tahun)\n(Contoh = 19)`                                                                           <dbl> …
## $ `Jenis kelamin`                                                                                         <chr> …
## $ `1. Platform media sosial apa yang paling sering Anda buka?`                                            <chr> …
## $ `2. Rata-rata berapa lama anda main media sosial dalam sehari?`                                         <chr> …
## $ `3. Seberapa sering Anda menunda dalam mengerjakan tugas karena bermain medsos?`                        <chr> …
## $ `4. Apa alasan utama Anda membuka media sosial saat sedang belajar atau mengerjakan tugas?`             <chr> …
## $ `5. Rata-rata berapa lama waktu yang anda gunakan untuk belajar atau mengerjakan tugas dalam sehari?\n` <chr> …
## $ `Column 11`                                                                                             <lgl> …
## $ `Column 12`                                                                                             <lgl> …

4 Analisis Data Eksploratif (EDA)

4.1 Standarisasi & Rename Kolom

df <- df_raw %>%
  rename(
    Timestamp      = 1,
    Nama           = 2,
    NIM            = 3,
    Usia           = 4,
    Jenis_Kelamin  = 5,
    Platform       = 6,
    Durasi_Medsos  = 7,
    Frek_Tunda     = 8,   # Variabel TARGET
    Alasan_Buka    = 9,
    Durasi_Belajar = 10
  ) %>%
  dplyr::select(Nama, NIM, Usia, Jenis_Kelamin, Platform,
                Durasi_Medsos, Frek_Tunda, Alasan_Buka, Durasi_Belajar)

head(df) %>%
  kable(caption = "5 Baris Pertama Dataset") %>%
  kable_styling(bootstrap_options = c("striped", "hover", "condensed"),
                full_width = FALSE)
5 Baris Pertama Dataset
Nama NIM Usia Jenis_Kelamin Platform Durasi_Medsos Frek_Tunda Alasan_Buka Durasi_Belajar
atiqah adawiyah 2403134967 19 Perempuan Tiktok > 5 jam Sangat Sering Menghilangkan rasa bosan atau jenuh terhadap tugas 2 - 3 jam
tiwi 2403111369 19 Perempuan Instagram 3 - 5 jam Sering Menghilangkan rasa bosan atau jenuh terhadap tugas 2 - 3 jam
Adel 2403111742 20 Perempuan Tiktok 3 - 5 jam Netral Menghilangkan rasa bosan atau jenuh terhadap tugas > 3 jam
Aynun 2403111419 20 Perempuan Instagram 3 - 5 jam Netral Menghilangkan rasa bosan atau jenuh terhadap tugas 2 - 3 jam
Siti Rahima 2403114778 20 Perempuan Instagram > 5 jam Sering Menghilangkan rasa bosan atau jenuh terhadap tugas 2 - 3 jam
Nur Azizah 2403111438 20 Perempuan Instagram 3 - 5 jam Netral Mendapat notifikasi (pesan, komentar, dll.) > 3 jam

4.2 Cek Missing Value & Duplikat

mv <- colSums(is.na(df))
kable(data.frame(Kolom = names(mv), Missing = mv),
      row.names = FALSE,
      caption = "Jumlah Missing Value per Kolom") %>%
  kable_styling(bootstrap_options = c("striped", "hover"), full_width = FALSE)
Jumlah Missing Value per Kolom
Kolom Missing
Nama 0
NIM 0
Usia 0
Jenis_Kelamin 0
Platform 0
Durasi_Medsos 0
Frek_Tunda 0
Alasan_Buka 0
Durasi_Belajar 0
cat("Jumlah baris duplikat:", sum(duplicated(df)))
## Jumlah baris duplikat: 0
df <- df %>% drop_na()
cat("\nTotal responden valid:", nrow(df))
## 
## Total responden valid: 42

4.3 Konversi ke Faktor Ordinal

level_tunda          <- c("Sangat Tidak Sering","Tidak Sering","Netral","Sering","Sangat Sering")
level_durasi_medsos  <- c("< 1 jam","1 - 3 jam","3 - 5 jam","> 5 jam")
level_durasi_belajar <- c("< 1 jam","1 - 2 jam","2 - 3 jam","> 3 jam")

df <- df %>%
  mutate(
    Frek_Tunda     = factor(Frek_Tunda,     levels = level_tunda,          ordered = TRUE),
    Durasi_Medsos  = factor(Durasi_Medsos,  levels = level_durasi_medsos,  ordered = TRUE),
    Durasi_Belajar = factor(Durasi_Belajar, levels = level_durasi_belajar, ordered = TRUE),
    Platform       = factor(Platform),
    Jenis_Kelamin  = factor(Jenis_Kelamin),
    Alasan_Buka    = factor(Alasan_Buka)
  )

str(df)
## tibble [42 × 9] (S3: tbl_df/tbl/data.frame)
##  $ Nama          : chr [1:42] "atiqah adawiyah" "tiwi" "Adel" "Aynun" ...
##  $ NIM           : num [1:42] 2.4e+09 2.4e+09 2.4e+09 2.4e+09 2.4e+09 ...
##  $ Usia          : num [1:42] 19 19 20 20 20 20 19 20 19 19 ...
##  $ Jenis_Kelamin : Factor w/ 2 levels "Laki-Laki","Perempuan": 2 2 2 2 2 2 2 2 1 2 ...
##  $ Platform      : Factor w/ 5 levels "Instagram","Tiktok",..: 2 1 2 1 1 1 2 2 1 2 ...
##  $ Durasi_Medsos : Ord.factor w/ 4 levels "< 1 jam"<"1 - 3 jam"<..: 4 3 3 3 4 3 4 3 2 4 ...
##  $ Frek_Tunda    : Ord.factor w/ 5 levels "Sangat Tidak Sering"<..: 5 4 3 3 4 3 3 4 4 2 ...
##  $ Alasan_Buka   : Factor w/ 4 levels "Berkomunikasi dengan teman",..: 4 4 4 4 4 3 4 4 2 4 ...
##  $ Durasi_Belajar: Ord.factor w/ 4 levels "< 1 jam"<"1 - 2 jam"<..: 3 3 4 3 3 4 4 4 3 4 ...

4.4 Statistik Deskriptif

freq_tunda <- as.data.frame(table(df$Frek_Tunda)) %>%
  rename(Kategori = Var1, Frekuensi = Freq) %>%
  mutate(Persentase = round(Frekuensi / sum(Frekuensi) * 100, 1))

kable(freq_tunda, caption = "Distribusi Frekuensi Menunda Tugas (Variabel Target)") %>%
  kable_styling(bootstrap_options = c("striped","hover"), full_width = FALSE)
Distribusi Frekuensi Menunda Tugas (Variabel Target)
Kategori Frekuensi Persentase
Sangat Tidak Sering 2 4.8
Tidak Sering 7 16.7
Netral 15 35.7
Sering 14 33.3
Sangat Sering 4 9.5

4.5 Visualisasi

4.5.1 Distribusi Frekuensi Menunda Tugas

ggplot(df, aes(x = Frek_Tunda, fill = Frek_Tunda)) +
  geom_bar(color = "black", width = 0.7) +
  scale_fill_brewer(palette = "RdYlGn", direction = -1) +
  geom_text(stat = "count", aes(label = after_stat(count)), vjust = -0.5, size = 4) +
  labs(title = "Distribusi Frekuensi Menunda Tugas",
       x = "Frekuensi Menunda", y = "Jumlah Mahasiswa") +
  theme_minimal(base_size = 13) +
  theme(legend.position = "none",
        axis.text.x = element_text(angle = 15, hjust = 1))

4.5.2 Platform Media Sosial vs Frekuensi Menunda

ggplot(df, aes(x = Platform, fill = Frek_Tunda)) +
  geom_bar(position = "fill", color = "black") +
  scale_fill_brewer(palette = "RdYlGn", direction = -1) +
  scale_y_continuous(labels = scales::percent) +
  labs(title = "Proporsi Frekuensi Menunda Berdasarkan Platform",
       x = "Platform", y = "Proporsi", fill = "Frek. Menunda") +
  theme_minimal(base_size = 13) +
  theme(axis.text.x = element_text(angle = 20, hjust = 1))

4.5.3 Durasi Medsos vs Frekuensi Menunda

ggplot(df, aes(x = Durasi_Medsos, fill = Frek_Tunda)) +
  geom_bar(position = "fill", color = "black") +
  scale_fill_brewer(palette = "RdYlGn", direction = -1) +
  scale_y_continuous(labels = scales::percent) +
  labs(title = "Proporsi Frekuensi Menunda Berdasarkan Durasi Medsos",
       x = "Durasi Medsos per Hari", y = "Proporsi", fill = "Frek. Menunda") +
  theme_minimal(base_size = 13)

4.5.4 Durasi Belajar vs Frekuensi Menunda

ggplot(df, aes(x = Durasi_Belajar, fill = Frek_Tunda)) +
  geom_bar(position = "fill", color = "black") +
  scale_fill_brewer(palette = "RdYlGn", direction = -1) +
  scale_y_continuous(labels = scales::percent) +
  labs(title = "Proporsi Frekuensi Menunda Berdasarkan Durasi Belajar",
       x = "Durasi Belajar per Hari", y = "Proporsi", fill = "Frek. Menunda") +
  theme_minimal(base_size = 13)


5 Model 0 – Regresi Linear Sederhana

Tujuan: Mengetahui hubungan antara durasi penggunaan media sosial dan frekuensi menunda tugas menggunakan pendekatan regresi linear sederhana.

5.1 Konversi Data ke Skor Numerik

df_reg <- df %>%
  mutate(
    Skor_Medsos = as.numeric(Durasi_Medsos),
    Skor_Tunda  = as.numeric(Frek_Tunda)
  )

head(df_reg)

5.2 Uji Korelasi Spearman

cor_spear <- cor.test(
  df_reg$Skor_Medsos,
  df_reg$Skor_Tunda,
  method = "spearman"
)

cor_spear
## 
##  Spearman's rank correlation rho
## 
## data:  df_reg$Skor_Medsos and df_reg$Skor_Tunda
## S = 12740, p-value = 0.8389
## alternative hypothesis: true rho is not equal to 0
## sample estimates:
##        rho 
## -0.0323416

5.3 Interpretasi Korelasi Spearman

## Koefisien korelasi Spearman (rho) = -0.032
## Tidak terdapat hubungan yang signifikan antara durasi penggunaan media sosial dan frekuensi menunda tugas (p-value >= 0,05).

5.4 Fit Model Regresi Linear

model_lm <- lm(Skor_Tunda ~ Skor_Medsos, data = df_reg)
summary(model_lm)
## 
## Call:
## lm(formula = Skor_Tunda ~ Skor_Medsos, data = df_reg)
## 
## Residuals:
##     Min      1Q  Median      3Q     Max 
## -2.2351 -0.2703 -0.2351  0.7297  1.7649 
## 
## Coefficients:
##             Estimate Std. Error t value Pr(>|t|)    
## (Intercept)  3.37568    0.80708   4.183 0.000153 ***
## Skor_Medsos -0.03514    0.24440  -0.144 0.886412    
## ---
## Signif. codes:  0 '***' 0.001 '**' 0.01 '*' 0.05 '.' 0.1 ' ' 1
## 
## Residual standard error: 1.026 on 40 degrees of freedom
## Multiple R-squared:  0.0005164,  Adjusted R-squared:  -0.02447 
## F-statistic: 0.02067 on 1 and 40 DF,  p-value: 0.8864

5.5 Tabel Koefisien Regresi

coef_lm <- summary(model_lm)$coefficients

kable(round(coef_lm, 4),
      caption = "Koefisien Regresi Linear Sederhana") %>%
  kable_styling(bootstrap_options = c("striped","hover"), full_width = FALSE)
Koefisien Regresi Linear Sederhana
Estimate Std. Error t value Pr(>&#124;t&#124;)
(Intercept) 3.3757 0.8071 4.1826 0.0002
Skor_Medsos -0.0351 0.2444 -0.1438 0.8864

5.6 Visualisasi Garis Regresi

ggplot(df_reg, aes(x = Skor_Medsos, y = Skor_Tunda)) +
  geom_jitter(width = 0.15, height = 0.15, size = 3, alpha = 0.7) +
  geom_smooth(method = "lm", se = TRUE, linewidth = 1) +
  scale_x_continuous(breaks = 1:4, labels = level_durasi_medsos) +
  scale_y_continuous(breaks = 1:5, labels = level_tunda) +
  labs(title = "Regresi Linear: Durasi Medsos vs Frekuensi Menunda",
       x = "Durasi Medsos", y = "Frekuensi Menunda") +
  theme_minimal(base_size = 13) +
  theme(axis.text.x = element_text(angle = 15, hjust = 1))

5.7 Nilai Koefisien Determinasi (R²)

cat("Nilai R-squared =", round(summary(model_lm)$r.squared, 4))
## Nilai R-squared = 5e-04

5.8 Interpretasi Regresi Linear

## Koefisien regresi bernilai negatif, yang menunjukkan bahwa semakin tinggi durasi penggunaan media sosial maka kecenderungan menunda tugas menurun.

6 Training Model

6.1 Split Data (80% Train / 20% Test)

set.seed(42)

idx_train <- createDataPartition(df$Frek_Tunda, p = 0.8, list = FALSE)
train <- df[idx_train, ]
test  <- df[-idx_train, ]

# Hapus level faktor yang tidak terpakai di masing-masing set
train <- droplevels(train)
test  <- droplevels(test)

# Sinkronkan level faktor test agar sama persis dengan train
faktor_cols <- c("Platform","Alasan_Buka","Jenis_Kelamin",
                 "Durasi_Medsos","Durasi_Belajar","Frek_Tunda")

for (col in faktor_cols) {
  test[[col]] <- factor(test[[col]], levels = levels(train[[col]]))
}

cat("Ukuran data training :", nrow(train), "baris\n")
## Ukuran data training : 36 baris
cat("Ukuran data testing  :", nrow(test),  "baris\n")
## Ukuran data testing  : 6 baris

7 Model 1 – Regresi Logistik Ordinal

Alasan pemilihan: Variabel target (Frek_Tunda) bersifat ordinal dengan 5 tingkat berurutan. Regresi logistik ordinal (polr) mempertahankan informasi urutan tersebut, sehingga lebih tepat dibanding regresi multinomial biasa.

7.1 Fit Model

model_ordinal <- polr(
  Frek_Tunda ~ Durasi_Medsos + Durasi_Belajar + Platform + Alasan_Buka,
  data   = train,
  Hess   = TRUE,
  method = "logistic"
)

summary(model_ordinal)
## Call:
## polr(formula = Frek_Tunda ~ Durasi_Medsos + Durasi_Belajar + 
##     Platform + Alasan_Buka, data = train, Hess = TRUE, method = "logistic")
## 
## Coefficients:
##                                                                 Value
## Durasi_Medsos.L                                                0.2692
## Durasi_Medsos.Q                                               -0.6898
## Durasi_Belajar.L                                              -1.3112
## Durasi_Belajar.Q                                              -1.9384
## PlatformTiktok                                                 2.8089
## PlatformTwitter/X                                              1.2682
## PlatformWhattsapp                                              0.5581
## PlatformYouTube                                               -2.7569
## Alasan_BukaMencari hiburan                                    -0.4149
## Alasan_BukaMendapat notifikasi (pesan, komentar, dll.)        -1.4261
## Alasan_BukaMenghilangkan rasa bosan atau jenuh terhadap tugas -2.2607
##                                                               Std. Error
## Durasi_Medsos.L                                                   0.8648
## Durasi_Medsos.Q                                                   0.7054
## Durasi_Belajar.L                                                  0.8731
## Durasi_Belajar.Q                                                  0.7189
## PlatformTiktok                                                    1.0878
## PlatformTwitter/X                                                 1.9652
## PlatformWhattsapp                                                 1.1318
## PlatformYouTube                                                   1.6159
## Alasan_BukaMencari hiburan                                        2.0084
## Alasan_BukaMendapat notifikasi (pesan, komentar, dll.)            1.3999
## Alasan_BukaMenghilangkan rasa bosan atau jenuh terhadap tugas     1.3288
##                                                               t value
## Durasi_Medsos.L                                                0.3113
## Durasi_Medsos.Q                                               -0.9779
## Durasi_Belajar.L                                              -1.5017
## Durasi_Belajar.Q                                              -2.6963
## PlatformTiktok                                                 2.5823
## PlatformTwitter/X                                              0.6454
## PlatformWhattsapp                                              0.4931
## PlatformYouTube                                               -1.7062
## Alasan_BukaMencari hiburan                                    -0.2066
## Alasan_BukaMendapat notifikasi (pesan, komentar, dll.)        -1.0187
## Alasan_BukaMenghilangkan rasa bosan atau jenuh terhadap tugas -1.7013
## 
## Intercepts:
##                                  Value   Std. Error t value
## Sangat Tidak Sering|Tidak Sering -5.0407  1.8602    -2.7097
## Tidak Sering|Netral              -2.4229  1.3661    -1.7735
## Netral|Sering                    -0.1405  1.3622    -0.1031
## Sering|Sangat Sering              2.4473  1.4494     1.6885
## 
## Residual Deviance: 78.92827 
## AIC: 108.9283

7.2 Koefisien & P-Value

ctable <- coef(summary(model_ordinal))
p_val  <- pnorm(abs(ctable[, "t value"]), lower.tail = FALSE) * 2
ctable <- cbind(ctable, "p value" = round(p_val, 4))

kable(ctable, digits = 4,
      caption = "Koefisien Regresi Logistik Ordinal beserta P-Value") %>%
  kable_styling(bootstrap_options = c("striped","hover","condensed"),
                full_width = FALSE) %>%
  row_spec(which(p_val < 0.05), bold = TRUE, color = "white", background = "#2ecc71")
Koefisien Regresi Logistik Ordinal beserta P-Value
Value Std. Error t value p value
Durasi_Medsos.L 0.2692 0.8648 0.3113 0.7556
Durasi_Medsos.Q -0.6898 0.7054 -0.9779 0.3281
Durasi_Belajar.L -1.3112 0.8731 -1.5017 0.1332
Durasi_Belajar.Q -1.9384 0.7189 -2.6963 0.0070
PlatformTiktok 2.8089 1.0878 2.5823 0.0098
PlatformTwitter/X 1.2682 1.9652 0.6454 0.5187
PlatformWhattsapp 0.5581 1.1318 0.4931 0.6219
PlatformYouTube -2.7569 1.6159 -1.7062 0.0880
Alasan_BukaMencari hiburan -0.4149 2.0084 -0.2066 0.8363
Alasan_BukaMendapat notifikasi (pesan, komentar, dll.) -1.4261 1.3999 -1.0187 0.3084
Alasan_BukaMenghilangkan rasa bosan atau jenuh terhadap tugas -2.2607 1.3288 -1.7013 0.0889
Sangat Tidak Sering&#124;Tidak Sering -5.0407 1.8602 -2.7097 0.0067
Tidak Sering&#124;Netral -2.4229 1.3661 -1.7735 0.0761
Netral&#124;Sering -0.1405 1.3622 -0.1031 0.9179
Sering&#124;Sangat Sering 2.4473 1.4494 1.6885 0.0913

Catatan: Baris yang disorot hijau menunjukkan variabel dengan p-value < 0,05 (signifikan secara statistik).

7.3 Evaluasi – Confusion Matrix

# prediksi manual via model matrix ketika ada level kategori di train yang tidak muncul di test (sampel kecil)

# Buat model matrix dari train sebagai referensi kolom
X_train <- model.matrix(
  ~ Durasi_Medsos + Durasi_Belajar + Platform + Alasan_Buka,
  data = train)[, -1]

# Buat model matrix dari test
X_test_raw <- model.matrix(
  ~ Durasi_Medsos + Durasi_Belajar + Platform + Alasan_Buka,
  data = test)[, -1]

# Tambah kolom yang ada di train tapi tidak ada di test (isi dengan 0)
for (k in setdiff(colnames(X_train), colnames(X_test_raw))) {
  X_test_raw <- cbind(X_test_raw, setNames(data.frame(0), k))
}

# Urutkan kolom test sama persis dengan train
X_test_fix <- X_test_raw[, colnames(X_train), drop = FALSE]

# Hitung linear predictor
coef_b <- coef(model_ordinal)
zeta   <- model_ordinal$zeta
eta    <- as.vector(X_test_fix %*% coef_b)

# Hitung probabilitas tiap kelas via proportional odds
lv_ord   <- levels(train$Frek_Tunda)
n_kelas  <- length(lv_ord)
prob_mat <- matrix(NA, nrow = nrow(X_test_fix), ncol = n_kelas)
colnames(prob_mat) <- lv_ord

for (i in seq_len(n_kelas)) {
  cum_lo <- if (i < n_kelas) plogis(zeta[i] - eta) else 1
  cum_hi <- if (i > 1)       plogis(zeta[i - 1] - eta) else 0
  prob_mat[, i] <- cum_lo - cum_hi
}

# Pilih kelas dengan probabilitas tertinggi
pred_idx     <- apply(prob_mat, 1, which.max)
pred_ordinal <- factor(lv_ord[pred_idx],
                       levels = levels(test$Frek_Tunda),
                       ordered = TRUE)

cm_ordinal <- confusionMatrix(pred_ordinal, test$Frek_Tunda)
print(cm_ordinal)
## Confusion Matrix and Statistics
## 
##                      Reference
## Prediction            Sangat Tidak Sering Tidak Sering Netral Sering
##   Sangat Tidak Sering                   0            0      0      0
##   Tidak Sering                          0            0      1      0
##   Netral                                0            0      1      1
##   Sering                                0            1      0      1
##   Sangat Sering                         0            0      1      0
##                      Reference
## Prediction            Sangat Sering
##   Sangat Tidak Sering             0
##   Tidak Sering                    0
##   Netral                          0
##   Sering                          0
##   Sangat Sering                   0
## 
## Overall Statistics
##                                           
##                Accuracy : 0.3333          
##                  95% CI : (0.0433, 0.7772)
##     No Information Rate : 0.5             
##     P-Value [Acc > NIR] : 0.8906          
##                                           
##                   Kappa : 0.04            
##                                           
##  Mcnemar's Test P-Value : NA              
## 
## Statistics by Class:
## 
##                      Class: Sangat Tidak Sering Class: Tidak Sering
## Sensitivity                                  NA              0.0000
## Specificity                                   1              0.8000
## Pos Pred Value                               NA              0.0000
## Neg Pred Value                               NA              0.8000
## Prevalence                                    0              0.1667
## Detection Rate                                0              0.0000
## Detection Prevalence                          0              0.1667
## Balanced Accuracy                            NA              0.4000
##                      Class: Netral Class: Sering Class: Sangat Sering
## Sensitivity                 0.3333        0.5000                   NA
## Specificity                 0.6667        0.7500               0.8333
## Pos Pred Value              0.5000        0.5000                   NA
## Neg Pred Value              0.5000        0.7500                   NA
## Prevalence                  0.5000        0.3333               0.0000
## Detection Rate              0.1667        0.1667               0.0000
## Detection Prevalence        0.3333        0.3333               0.1667
## Balanced Accuracy           0.5000        0.6250                   NA

8 Model 2 – Decision Tree (CART)

Alasan pemilihan: Semua variabel prediktor bersifat kategorikal. Decision tree dapat menangani data kategorikal secara langsung tanpa encoding tambahan, dan hasilnya mudah diinterpretasi dalam bentuk aturan (rule-based).

8.1 Fit Model

model_dt <- rpart(
  Frek_Tunda ~ Durasi_Medsos + Durasi_Belajar + Platform + Alasan_Buka,
  data   = train,
  method = "class",
  control = rpart.control(cp = 0.01, minsplit = 5, minbucket = 2)
)

8.2 Pruning

model_dt_pruned <- prune(model_dt, cp = 0.03)

8.3 Visualisasi Pohon Keputusan

rpart.plot(
  model_dt_pruned,
  type          = 2,
  extra         = 104,
  fallen.leaves = TRUE,
  box.palette   = "GnBu",
  shadow.col    = "gray",
  nn            = TRUE,
  cex           = 0.8,
  tweak         = 1.2,
  main          = "Decision Tree Setelah Pruning"
)

8.4 Variable Importance

vi <- model_dt$variable.importance

if (!is.null(vi)) {
  vi_df <- data.frame(Variabel   = names(vi),
                      Importance = round(vi, 2)) %>%
    arrange(desc(Importance))

  kable(vi_df, row.names = FALSE,
        caption = "Variable Importance – Decision Tree") %>%
    kable_styling(bootstrap_options = c("striped","hover"), full_width = FALSE)

  ggplot(vi_df, aes(x = reorder(Variabel, Importance),
                    y = Importance, fill = Importance)) +
    geom_col(color = "black") +
    coord_flip() +
    scale_fill_gradient(low = "#f9e784", high = "#e74c3c") +
    labs(title = "Variable Importance – Decision Tree",
         x = "Variabel", y = "Importance") +
    theme_minimal(base_size = 13) +
    theme(legend.position = "none")
} else {
  cat("Tidak ada split yang signifikan pada decision tree.\n")
}

8.5 Evaluasi – Confusion Matrix

pred_dt <- predict(model_dt, newdata = test, type = "class")

# Samakan level prediksi dengan level aktual
pred_dt <- factor(pred_dt, levels = levels(test$Frek_Tunda), ordered = TRUE)

cm_dt <- confusionMatrix(pred_dt, test$Frek_Tunda)
print(cm_dt)
## Confusion Matrix and Statistics
## 
##                      Reference
## Prediction            Sangat Tidak Sering Tidak Sering Netral Sering
##   Sangat Tidak Sering                   0            0      1      0
##   Tidak Sering                          0            0      0      1
##   Netral                                0            0      1      0
##   Sering                                0            1      1      1
##   Sangat Sering                         0            0      0      0
##                      Reference
## Prediction            Sangat Sering
##   Sangat Tidak Sering             0
##   Tidak Sering                    0
##   Netral                          0
##   Sering                          0
##   Sangat Sering                   0
## 
## Overall Statistics
##                                           
##                Accuracy : 0.3333          
##                  95% CI : (0.0433, 0.7772)
##     No Information Rate : 0.5             
##     P-Value [Acc > NIR] : 0.8906          
##                                           
##                   Kappa : 0.0769          
##                                           
##  Mcnemar's Test P-Value : NA              
## 
## Statistics by Class:
## 
##                      Class: Sangat Tidak Sering Class: Tidak Sering
## Sensitivity                                  NA              0.0000
## Specificity                              0.8333              0.8000
## Pos Pred Value                               NA              0.0000
## Neg Pred Value                               NA              0.8000
## Prevalence                               0.0000              0.1667
## Detection Rate                           0.0000              0.0000
## Detection Prevalence                     0.1667              0.1667
## Balanced Accuracy                            NA              0.4000
##                      Class: Netral Class: Sering Class: Sangat Sering
## Sensitivity                 0.3333        0.5000                   NA
## Specificity                 1.0000        0.5000                    1
## Pos Pred Value              1.0000        0.3333                   NA
## Neg Pred Value              0.6000        0.6667                   NA
## Prevalence                  0.5000        0.3333                    0
## Detection Rate              0.1667        0.1667                    0
## Detection Prevalence        0.1667        0.5000                    0
## Balanced Accuracy           0.6667        0.5000                   NA

9 Ringkasan Model yang Digunakan

ringkasan_model <- data.frame(
  Model = c("Regresi Linear Sederhana",
            "Regresi Logistik Ordinal",
            "Decision Tree"),
  Tujuan = c("Melihat hubungan awal antar variabel",
             "Memprediksi tingkat prokrastinasi ordinal",
             "Mengidentifikasi pola dan aturan keputusan")
)

kable(ringkasan_model, caption = "Ringkasan Model yang Digunakan") %>%
  kable_styling(bootstrap_options = c("striped","hover"), full_width = FALSE)
Ringkasan Model yang Digunakan
Model Tujuan
Regresi Linear Sederhana Melihat hubungan awal antar variabel
Regresi Logistik Ordinal Memprediksi tingkat prokrastinasi ordinal
Decision Tree Mengidentifikasi pola dan aturan keputusan

10 Metrik Evaluasi & Perbandingan Model

hasil_eval <- data.frame(
  Model   = c("Regresi Logistik Ordinal", "Decision Tree"),
  Akurasi = round(c(cm_ordinal$overall["Accuracy"],
                    cm_dt$overall["Accuracy"]), 4),
  Kappa   = round(c(cm_ordinal$overall["Kappa"],
                    cm_dt$overall["Kappa"]), 4)
)

kable(hasil_eval, row.names = FALSE,
      caption = "Perbandingan Metrik Evaluasi Antar Model") %>%
  kable_styling(bootstrap_options = c("striped","hover","bordered"),
                full_width = FALSE) %>%
  column_spec(2:3, bold = TRUE)
Perbandingan Metrik Evaluasi Antar Model
Model Akurasi Kappa
Regresi Logistik Ordinal 0.3333 0.0400
Decision Tree 0.3333 0.0769

Metrik yang digunakan:

  • Akurasi → proporsi prediksi yang benar dari keseluruhan data test.
  • Kappa Cohen → mengukur persetujuan prediksi vs aktual dengan memperhitungkan kebetulan; lebih adil untuk distribusi kelas yang tidak seimbang.

11 Cross-Validation 5-Fold (Decision Tree)

Karena ukuran sampel terbatas (~40 responden), digunakan k-fold cross-validation agar estimasi performa lebih stabil dan tidak bergantung pada satu split tertentu.

ctrl_cv     <- trainControl(method = "cv", number = 5)
model_dt_cv <- train(
  Frek_Tunda ~ Durasi_Medsos + Durasi_Belajar + Platform + Alasan_Buka,
  data       = df,
  method     = "rpart",
  trControl  = ctrl_cv,
  tuneLength = 5
)

cat("Akurasi CV Decision Tree:", round(max(model_dt_cv$results$Accuracy), 4), "\n")
## Akurasi CV Decision Tree: 0.375
print(model_dt_cv)
## CART 
## 
## 42 samples
##  4 predictor
##  5 classes: 'Sangat Tidak Sering', 'Tidak Sering', 'Netral', 'Sering', 'Sangat Sering' 
## 
## No pre-processing
## Resampling: Cross-Validated (5 fold) 
## Summary of sample sizes: 34, 34, 33, 34, 33 
## Resampling results across tuning parameters:
## 
##   cp          Accuracy   Kappa       
##   0.00000000  0.3750000   0.031428571
##   0.03703704  0.3750000   0.031428571
##   0.07407407  0.3500000   0.005454545
##   0.11111111  0.3305556  -0.021212121
##   0.14814815  0.2833333  -0.094545455
## 
## Accuracy was used to select the optimal model using the largest value.
## The final value used for the model was cp = 0.03703704.

12 Kendala yang Masih Dihadapi

No Kendala Dampak Solusi yang Diterapkan
1 Sampel terbatas (~40 responden) Test set sangat kecil (~8 obs), akurasi tidak stabil 5-fold cross-validation pada seluruh data
2 Distribusi kelas tidak seimbang (Netral & Sering dominan) Akurasi bisa misleading Menggunakan Kappa sebagai metrik tambahan
3 Decision tree rawan overfitting pada data kecil Model terlalu spesifik ke data training Pruning via parameter cp pada rpart.control
4 Banyak kategori pada variabel Platform & Alasan Pohon keputusan menjadi kompleks Bisa dipertimbangkan penggabungan kategori serupa

13 Kesimpulan

Analisis ini menggunakan tiga pendekatan:

  1. Regresi Linear Sederhana digunakan untuk melihat hubungan awal antara durasi penggunaan media sosial dan frekuensi menunda tugas. Hasil menunjukkan arah hubungan berdasarkan nilai koefisien regresi dan korelasi Spearman.
  2. Regresi Logistik Ordinal digunakan sebagai model utama karena variabel respon bersifat ordinal dengan 5 tingkatan berurutan.
  3. Decision Tree digunakan untuk mengidentifikasi pola dan aturan yang menjelaskan perilaku prokrastinasi mahasiswa secara visual dan interpretatif.

Hasil evaluasi (akurasi & Kappa) dapat dilihat pada tabel perbandingan di atas. Mengingat keterbatasan sampel, hasil cross-validation 5-fold lebih direkomendasikan sebagai acuan performa model yang sesungguhnya.