Dataset ini berisi statistik pemain dari turnamen Valorant
Champions Tour 2025: Pacific Kickoff.
Tujuan analisis ini adalah memprediksi Tingkat Adaptasi
pemain (Low, Medium, High) berdasarkan performa individu seperti
Rating, Average Combat Score,
Kills:Deaths, dan metrik lainnya.
Variabel target Tingkat.Adaptasi
bersifat
ordinal (Low < Medium < High), dan akan
dianalisis menggunakan regresi logistik ordinal.
# --- Load & Install Packages ---
if (!require(MASS)) install.packages("MASS")
if (!require(ggplot2)) install.packages("ggplot2")
if (!require(caret)) install.packages("caret")
library(MASS)
library(ggplot2)
library(caret)
# --- Load Dataset ---
csv_path <- "C:\\project_smt 4\\Analisis Multivariate\\preprocessed_players_stats_with_player_teams.csv"
if (!file.exists(csv_path)) {
stop("File CSV tidak ditemukan di: ", csv_path)
}
data <- read.csv(csv_path)
# --- Pemeriksaan Struktur Data ---
cat("Struktur Data:\n")
## Struktur Data:
str(data)
## 'data.frame': 4231 obs. of 14 variables:
## $ Player : chr "2GE" "2GE" "2GE" "2GE" ...
## $ Teams : chr "Team Secret" "Team Secret" "Team Secret" "Team Secret" ...
## $ Rating : num 0.67 1.02 0.84 0.67 1.46 ...
## $ Average.Combat.Score : int 140 192 166 134 271 179 152 153 153 174 ...
## $ Kills.Deaths : num 0.63 1 0.81 0.63 1.6 0.89 0.62 0.79 0.73 0.69 ...
## $ Kill..Assist..Trade..Survive..: num 66 78 72 64 100 75 71 69 70 NA ...
## $ Average.Damage.Per.Round : num 86 118 102 83 156 ...
## $ Kills.Per.Round : num 0.45 0.69 0.57 0.44 1 0.6 0.47 0.56 0.54 0.58 ...
## $ Assists.Per.Round : num 0.27 0.4 0.33 0.26 0.56 0.35 0.29 0.33 0.32 0.21 ...
## $ First.Kills.Per.Round : num 0.11 0.13 0.12 0.13 0.19 ...
## $ First.Deaths.Per.Round : num 0.18 0.09 0.14 0.15 0 ...
## $ Headshot.. : num 16 16 16 15 12 14 19 20 19 NA ...
## $ Clutch.Success.. : num NA 29 14 NA 33 11 NA 25 20 NA ...
## $ Tingkat.Adaptasi : chr "Medium" "High" "Medium" "Medium" ...
cat("\nRingkasan Data:\n")
##
## Ringkasan Data:
summary(data)
## Player Teams Rating Average.Combat.Score
## Length:4231 Length:4231 Min. :0.0800 Min. : 54.0
## Class :character Class :character 1st Qu.:0.8700 1st Qu.:163.0
## Mode :character Mode :character Median :0.9873 Median :193.0
## Mean :0.9873 Mean :195.2
## 3rd Qu.:1.1000 3rd Qu.:224.5
## Max. :2.3300 Max. :455.0
##
## Kills.Deaths Kill..Assist..Trade..Survive.. Average.Damage.Per.Round
## Min. :0.150 Min. : 35.00 Min. : 27
## 1st Qu.:0.770 1st Qu.: 66.00 1st Qu.:113
## Median :0.970 Median : 72.00 Median :128
## Mean :1.027 Mean : 71.69 Mean :128
## 3rd Qu.:1.200 3rd Qu.: 78.00 3rd Qu.:140
## Max. :4.330 Max. :100.00 Max. :289
## NA's :903
## Kills.Per.Round Assists.Per.Round First.Kills.Per.Round
## Min. :0.1400 Min. :0.000 Min. :0.00000
## 1st Qu.:0.5600 1st Qu.:0.190 1st Qu.:0.06000
## Median :0.6800 Median :0.280 Median :0.09817
## Mean :0.6852 Mean :0.298 Mean :0.09817
## 3rd Qu.:0.8000 3rd Qu.:0.390 3rd Qu.:0.12000
## Max. :1.7900 Max. :1.090 Max. :0.47000
##
## First.Deaths.Per.Round Headshot.. Clutch.Success.. Tingkat.Adaptasi
## Min. :0.00000 Min. : 4.00 Min. : 4.00 Length:4231
## 1st Qu.:0.06000 1st Qu.:23.00 1st Qu.: 14.00 Class :character
## Median :0.09953 Median :28.00 Median : 25.00 Mode :character
## Mean :0.09953 Mean :28.54 Mean : 28.81
## 3rd Qu.:0.12000 3rd Qu.:33.25 3rd Qu.: 33.00
## Max. :0.48000 Max. :80.00 Max. :100.00
## NA's :903 NA's :2636
cat("\nNilai Hilang Tiap Kolom:\n")
##
## Nilai Hilang Tiap Kolom:
colSums(is.na(data))
## Player Teams
## 0 0
## Rating Average.Combat.Score
## 0 0
## Kills.Deaths Kill..Assist..Trade..Survive..
## 0 903
## Average.Damage.Per.Round Kills.Per.Round
## 0 0
## Assists.Per.Round First.Kills.Per.Round
## 0 0
## First.Deaths.Per.Round Headshot..
## 0 903
## Clutch.Success.. Tingkat.Adaptasi
## 2636 0
# --- Distribusi Target ---
cat("\nDistribusi Tingkat Adaptasi:\n")
##
## Distribusi Tingkat Adaptasi:
table(data$Tingkat.Adaptasi)
##
## High Low Medium
## 769 780 2682
# Visualisasi distribusi
ggplot(data, aes(x = Tingkat.Adaptasi, fill = Tingkat.Adaptasi)) +
geom_bar() +
theme_minimal() +
labs(title = "Distribusi Tingkat Adaptasi Pemain",
x = "Tingkat Adaptasi",
y = "Jumlah Observasi") +
scale_fill_manual(values = c("Low" = "red", "Medium" = "blue", "High" = "green"))
# --- Bangun Model Regresi Logistik Ordinal ---
# --- Ubah Target jadi Faktor Ordinal ---
data$Tingkat.Adaptasi <- factor(data$Tingkat.Adaptasi, levels = c("Low", "Medium", "High"), ordered = TRUE)
# --- Validasi Kolom Penting ---
required_cols <- c("Rating", "Average.Combat.Score", "Kills.Deaths",
"Kill..Assist..Trade..Survive..", "Average.Damage.Per.Round",
"Kills.Per.Round", "Assists.Per.Round", "First.Kills.Per.Round",
"First.Deaths.Per.Round", "Headshot..", "Tingkat.Adaptasi")
missing_cols <- setdiff(required_cols, colnames(data))
if (length(missing_cols) > 0) {
stop("Kolom berikut hilang dari data: ", paste(missing_cols, collapse=", "))
}
model <- polr(Tingkat.Adaptasi ~ Rating + Average.Combat.Score + Kills.Deaths +
Kill..Assist..Trade..Survive.. + Average.Damage.Per.Round +
Kills.Per.Round + Assists.Per.Round + First.Kills.Per.Round +
First.Deaths.Per.Round + Headshot..,
data = data, Hess = TRUE)
# --- Ringkasan Model ---
cat("\nRingkasan Model:\n")
##
## Ringkasan Model:
summary(model)
## Call:
## polr(formula = Tingkat.Adaptasi ~ Rating + Average.Combat.Score +
## Kills.Deaths + Kill..Assist..Trade..Survive.. + Average.Damage.Per.Round +
## Kills.Per.Round + Assists.Per.Round + First.Kills.Per.Round +
## First.Deaths.Per.Round + Headshot.., data = data, Hess = TRUE)
##
## Coefficients:
## Value Std. Error t value
## Rating 4.2286636 0.512690 8.24799
## Average.Combat.Score 0.0069571 0.004976 1.39807
## Kills.Deaths 0.3366338 0.310156 1.08537
## Kill..Assist..Trade..Survive.. -0.0005694 0.005796 -0.09824
## Average.Damage.Per.Round -0.0022597 0.004711 -0.47970
## Kills.Per.Round -1.3010603 1.064286 -1.22247
## Assists.Per.Round 0.1897544 0.330675 0.57384
## First.Kills.Per.Round -0.7141067 0.687385 -1.03887
## First.Deaths.Per.Round -0.6032307 0.642277 -0.93921
## Headshot.. 0.0050130 0.004414 1.13565
##
## Intercepts:
## Value Std. Error t value
## Low|Medium 3.1924 0.3834 8.3275
## Medium|High 6.2326 0.3968 15.7056
##
## Residual Deviance: 5681.461
## AIC: 5705.461
## (903 observations deleted due to missingness)
variabel Tingkat.Adaptasi, dapat disimpulkan bahwa dari semua prediktor yang digunakan, hanya Rating yang secara signifikan memengaruhi kemungkinan seseorang berada pada tingkat adaptasi yang lebih tinggi. Dengan koefisien sebesar 4.23 dan nilai t yang tinggi (8.25), Rating menunjukkan pengaruh yang sangat kuat dalam meningkatkan log odds seseorang untuk berpindah dari tingkat adaptasi rendah ke sedang atau dari sedang ke tinggi. Artinya, semakin tinggi Rating seorang pemain, semakin besar kemungkinan mereka memiliki tingkat adaptasi yang lebih baik.
Sementara itu, variabel lain seperti Average.Combat.Score, Kills/Deaths, Kills.Per.Round, dan Headshot memang memiliki koefisien yang menunjukkan arah pengaruh (positif atau negatif), tetapi tidak signifikan secara statistik karena nilai t yang rendah. Beberapa bahkan menunjukkan arah yang tidak terduga — misalnya, Kills.Per.Round justru memiliki koefisien negatif yang besar (-1.30), yang mengindikasikan bahwa pemain dengan kill tinggi per ronde justru cenderung memiliki adaptasi yang lebih rendah. Hal ini bisa disebabkan oleh adanya multikolinearitas
# --- Hitung P-value Koefisien ---
ctable <- coef(summary(model))
p <- pnorm(abs(ctable[, "t value"]), lower.tail = FALSE) * 2
coef_table <- cbind(ctable, "p value" = p)
cat("\nKoefisien dan P-value:\n")
##
## Koefisien dan P-value:
print(coef_table)
## Value Std. Error t value
## Rating 4.2286636087 0.512690493 8.24798523
## Average.Combat.Score 0.0069570517 0.004976180 1.39807083
## Kills.Deaths 0.3366338467 0.310156159 1.08536889
## Kill..Assist..Trade..Survive.. -0.0005694324 0.005796217 -0.09824207
## Average.Damage.Per.Round -0.0022596941 0.004710669 -0.47969711
## Kills.Per.Round -1.3010603469 1.064286117 -1.22247235
## Assists.Per.Round 0.1897543950 0.330675037 0.57383949
## First.Kills.Per.Round -0.7141067233 0.687384671 -1.03887496
## First.Deaths.Per.Round -0.6032306703 0.642276680 -0.93920687
## Headshot.. 0.0050130418 0.004414242 1.13565180
## Low|Medium 3.1923670252 0.383351847 8.32751179
## Medium|High 6.2325845065 0.396838011 15.70561371
## p value
## Rating 1.610873e-16
## Average.Combat.Score 1.620918e-01
## Kills.Deaths 2.777583e-01
## Kill..Assist..Trade..Survive.. 9.217401e-01
## Average.Damage.Per.Round 6.314428e-01
## Kills.Per.Round 2.215291e-01
## Assists.Per.Round 5.660764e-01
## First.Kills.Per.Round 2.988629e-01
## First.Deaths.Per.Round 3.476245e-01
## Headshot.. 2.561023e-01
## Low|Medium 8.255919e-17
## Medium|High 1.384315e-55
Interpretasi singkat: Koefisien (+): meningkatkan kemungkinan adaptasi ke level lebih tinggi. Koefisien (−): mengurangi kemungkinan adaptasi. P-value < 0.05 = signifikan secara statistik.
Dari seluruh variabel, hanya Rating yang memiliki pengaruh yang signifikan secara statistik terhadap tingkat adaptasi, dengan koefisien sebesar 4.23 dan p-value yang sangat kecil (1.61e-16), jauh di bawah ambang signifikansi umum (0.05). Ini menandakan bahwa semakin tinggi rating seorang pemain, semakin besar kemungkinan mereka berada pada tingkat adaptasi yang lebih tinggi, dan hasil ini sangat meyakinkan secara statistik.
# --- Prediksi dan Evaluasi Model ---
predicted <- predict(model, data)
predicted <- factor(predicted, levels = c("Low", "Medium", "High"), ordered = TRUE)
cat("\nTabel Kontingensi (Aktual vs Prediksi):\n")
##
## Tabel Kontingensi (Aktual vs Prediksi):
conf_matrix <- table(data$Tingkat.Adaptasi, predicted)
print(conf_matrix)
## predicted
## Low Medium High
## Low 244 521 15
## Medium 124 1550 105
## High 8 503 258
# Visualisasi Confusion Matrix
conf_matrix_df <- as.data.frame(conf_matrix)
colnames(conf_matrix_df) <- c("Actual", "Predicted", "Freq")
ggplot(conf_matrix_df, aes(x = Actual, y = Predicted, fill = Freq)) +
geom_tile() +
geom_text(aes(label = Freq), color = "white") +
theme_minimal() +
labs(title = "Confusion Matrix: Tingkat Adaptasi",
x = "Aktual",
y = "Prediksi") +
scale_fill_gradient(low = "blue", high = "red")
# --- Hitung Akurasi Model ---
accuracy <- mean(predicted == data$Tingkat.Adaptasi, na.rm = TRUE)
cat("\nAkurasi model:", accuracy, "\n")
##
## Akurasi model: 0.6165865
Secara keseluruhan, model ini menunjukkan Rating sebagai variabel yang paling berpengaruh dalam memprediksi tingkat adaptasi pemain, dengan akurasi yang cukup baik (61.66%). Meskipun demikian, ada potensi untuk meningkatkan performa model ini, terutama dalam memprediksi kategori Low dengan lebih akurat.