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.
# 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 konflikdf_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> …
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)| 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 | 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 | 3 - 5 jam | Netral | Menghilangkan rasa bosan atau jenuh terhadap tugas | 2 - 3 jam | |
| Siti Rahima | 2403114778 | 20 | Perempuan | > 5 jam | Sering | Menghilangkan rasa bosan atau jenuh terhadap tugas | 2 - 3 jam | |
| Nur Azizah | 2403111438 | 20 | Perempuan | 3 - 5 jam | Netral | Mendapat notifikasi (pesan, komentar, dll.) | > 3 jam |
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)| 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 |
## Jumlah baris duplikat: 0
##
## Total responden valid: 42
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 ...
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)| 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 |
Tujuan: Mengetahui hubungan antara durasi penggunaan media sosial dan frekuensi menunda tugas menggunakan pendekatan regresi linear sederhana.
df_reg <- df %>%
mutate(
Skor_Medsos = as.numeric(Durasi_Medsos),
Skor_Tunda = as.numeric(Frek_Tunda)
)
head(df_reg)##
## 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
## Koefisien korelasi Spearman (rho) = -0.032
## Tidak terdapat hubungan yang signifikan antara durasi penggunaan media sosial dan frekuensi menunda tugas (p-value >= 0,05).
##
## 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
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)| Estimate | Std. Error | t value | Pr(>|t|) | |
|---|---|---|---|---|
| (Intercept) | 3.3757 | 0.8071 | 4.1826 | 0.0002 |
| Skor_Medsos | -0.0351 | 0.2444 | -0.1438 | 0.8864 |
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))## Nilai R-squared = 5e-04
## Koefisien regresi bernilai negatif, yang menunjukkan bahwa semakin tinggi durasi penggunaan media sosial maka kecenderungan menunda tugas menurun.
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
## Ukuran data testing : 6 baris
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.
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
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")| 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|Tidak Sering | -5.0407 | 1.8602 | -2.7097 | 0.0067 |
| Tidak Sering|Netral | -2.4229 | 1.3661 | -1.7735 | 0.0761 |
| Netral|Sering | -0.1405 | 1.3622 | -0.1031 | 0.9179 |
| Sering|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).
# 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
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).
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"
)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")
}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
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)| Model | Tujuan |
|---|---|
| Regresi Linear Sederhana | Melihat hubungan awal antar variabel |
| Regresi Logistik Ordinal | Memprediksi tingkat prokrastinasi ordinal |
| Decision Tree | Mengidentifikasi pola dan aturan keputusan |
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)| 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.
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
## 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.
| 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 |
Analisis ini menggunakan tiga pendekatan:
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.