Deskripsi

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.

Kelompok 7

# --- 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

Kesimpulan

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.