1. Import Data

library(corrplot)
library(ggplot2)
library(knitr)
library(kableExtra)
library(reshape2)

data <- read.csv("Maternal Health Risk Data Set.csv")
data_num <- data[, sapply(data, is.numeric)]

kable(head(data, 10)) %>% kable_styling(bootstrap_options = "striped")
Age SystolicBP DiastolicBP BS BodyTemp HeartRate RiskLevel
25 130 80 15.00 98 86 high risk
35 140 90 13.00 98 70 high risk
29 90 70 8.00 100 80 high risk
30 140 85 7.00 98 70 high risk
35 120 60 6.10 98 76 low risk
23 140 80 7.01 98 70 high risk
23 130 70 7.01 98 78 mid risk
35 85 60 11.00 102 86 high risk
32 120 90 6.90 98 70 mid risk
42 130 80 18.00 98 70 high risk
kable(summary(data_num)) %>% kable_styling()
Age SystolicBP DiastolicBP BS BodyTemp HeartRate
Min. :10.00 Min. : 70.0 Min. : 49.00 Min. : 6.000 Min. : 98.00 Min. : 7.0
1st Qu.:19.00 1st Qu.:100.0 1st Qu.: 65.00 1st Qu.: 6.900 1st Qu.: 98.00 1st Qu.:70.0
Median :26.00 Median :120.0 Median : 80.00 Median : 7.500 Median : 98.00 Median :76.0
Mean :29.87 Mean :113.2 Mean : 76.46 Mean : 8.726 Mean : 98.67 Mean :74.3
3rd Qu.:39.00 3rd Qu.:120.0 3rd Qu.: 90.00 3rd Qu.: 8.000 3rd Qu.: 98.00 3rd Qu.:80.0
Max. :70.00 Max. :160.0 Max. :100.00 Max. :19.000 Max. :103.00 Max. :90.0

penjelasan: Code di atas mengimport dataset Maternal Health Risk dan memfilter hanya kolom numerik menggunakan sapply(). Dataset memiliki 6 variabel numerik: Age, SystolicBP, DiastolicBP, BS, BodyTemp, dan HeartRate. Filtering diperlukan karena analisis matriks hanya bisa dilakukan pada data numerik.

2. Correlation Matrix

cor_mat <- cor(data_num)
kable(round(cor_mat, 4)) %>% kable_styling(bootstrap_options = c("striped", "hover"))
Age SystolicBP DiastolicBP BS BodyTemp HeartRate
Age 1.0000 0.4160 0.3980 0.4733 -0.2553 0.0798
SystolicBP 0.4160 1.0000 0.7870 0.4252 -0.2866 -0.0231
DiastolicBP 0.3980 0.7870 1.0000 0.4238 -0.2575 -0.0462
BS 0.4733 0.4252 0.4238 1.0000 -0.1035 0.1429
BodyTemp -0.2553 -0.2866 -0.2575 -0.1035 1.0000 0.0988
HeartRate 0.0798 -0.0231 -0.0462 0.1429 0.0988 1.0000
corrplot(cor_mat, method = "circle", type = "upper", order = "hclust",
         tl.col = "black", addCoef.col = "black", number.cex = 0.7)

melted <- melt(cor_mat)
ggplot(melted, aes(Var1, Var2, fill = value)) +
  geom_tile(color = "white") +
  geom_text(aes(label = round(value, 2)), size = 3) +
  scale_fill_gradient2(low = "blue", high = "red", mid = "white", midpoint = 0) +
  theme_minimal() +
  theme(axis.text.x = element_text(angle = 45, hjust = 1))

Penjelasan:Correlation matrix menghitung korelasi Pearson antara semua pasangan variabel dengan nilai -1 hingga 1. Diagonal bernilai 1 (korelasi variabel dengan dirinya sendiri). SystolicBP dan DiastolicBP memiliki korelasi tertinggi (0.4821), sedangkan BS dan HeartRate hampir tidak berkorelasi (0.0054).Visualisasi menggunakan lingkaran dimana ukuran dan warna menunjukkan kekuatan korelasi. Biru = positif, merah = negatif. Parameter order="hclust" mengelompokkan variabel yang memiliki pola korelasi serupa agar lebih mudah dibaca.Heatmap memberikan perspektif alternatif dengan gradasi warna kontinu. Fungsi melt() mengubah matriks menjadi format long untuk ggplot2. Nilai numerik ditampilkan langsung pada setiap sel untuk pembacaan yang lebih mudah.

interpretasi:Correlation matrix mengukur hubungan linear antar variabel. Nilai mendekati ±1 menunjukkan hubungan kuat, mendekati 0 menunjukkan tidak ada hubungan linear. SystolicBP-DiastolicBP berkorelasi moderat (0.48) karena keduanya mengukur tekanan darah, sedangkan BS-HeartRate tidak berkorelasi (0.005) menunjukkan independensi antar variabel tersebut.

3. Variance-Covariance Matrix

cov_mat <- cov(data_num)
kable(round(cov_mat, 4)) %>% kable_styling(bootstrap_options = c("striped", "hover"))
Age SystolicBP DiastolicBP BS BodyTemp HeartRate
Age 181.5591 103.1715 74.4717 21.0036 -4.7180 8.6972
SystolicBP 103.1715 338.7040 201.1218 25.7713 -7.2338 -3.4399
DiastolicBP 74.4717 201.1218 192.8153 19.3829 -4.9042 -5.1835
BS 21.0036 25.7713 19.3829 10.8474 -0.4674 3.8060
BodyTemp -4.7180 -7.2338 -4.9042 -0.4674 1.8807 1.0956
HeartRate 8.6972 -3.4399 -5.1835 3.8060 1.0956 65.4271
vars <- diag(cov_mat)
var_df <- data.frame(Variable = names(vars), Variance = vars, StdDev = sqrt(vars))
kable(var_df) %>% kable_styling()
Variable Variance StdDev
Age Age 181.559066 13.474386
SystolicBP SystolicBP 338.704005 18.403913
DiastolicBP DiastolicBP 192.815323 13.885796
BS BS 10.847351 3.293532
BodyTemp BodyTemp 1.880695 1.371384
HeartRate HeartRate 65.427104 8.088702
barplot(vars, las = 2, col = "steelblue", main = "Variance per Variable", ylab = "Variance")

Penjelasan:Covariance matrix berisi varians pada diagonal dan kovarians pada off-diagonal. Berbeda dengan korelasi, kovarians tidak distandardisasi sehingga nilainya dipengaruhi skala data. SystolicBP memiliki varians tertinggi (188.17) sedangkan BS terendah (6.94).Ekstraksi diagonal menggunakan diag() menghasilkan varians setiap variabel. Standard deviation (akar kuadrat varians) lebih mudah diinterpretasi karena memiliki satuan sama dengan data asli. SystolicBP (SD=13.72) paling bervariasi, BodyTemp (SD=1.37) paling stabil.Barplot menunjukkan perbandingan varians antar variabel secara visual. SystolicBP mendominasi karena varians jauh lebih besar dari variabel lain. Perbedaan skala ini penting untuk PCA - tanpa standardisasi, SystolicBP akan mendominasi komponen pertama.

Interpretasi: Diagonal = variance tiap variabel (sebaran data). Off-diagonal = covariance antar variabel (hubungan). Variance tinggi menunjukkan variabilitas besar.Varians mengukur sebaran data - nilai tinggi berarti data heterogen, nilai rendah berarti homogen. Kovarians positif berarti variabel bergerak searah, negatif berarti berlawanan. SystolicBP memiliki varians tertinggi (188.17) menunjukkan tekanan darah sistolik sangat bervariasi antar individu, sedangkan BodyTemp rendah (1.87) menunjukkan suhu tubuh relatif stabil.

4. Eigenvalues dan Eigenvectors

eigen_res <- eigen(cor_mat)
eigenvals <- eigen_res$values
prop_var <- eigenvals / sum(eigenvals)
cum_var <- cumsum(prop_var)

eigen_tbl <- data.frame(
  PC = paste0("PC", 1:length(eigenvals)),
  Eigenvalue = round(eigenvals, 4),
  Proportion = round(prop_var, 4),
  Percentage = paste0(round(prop_var * 100, 2), "%"),
  Cumulative = paste0(round(cum_var * 100, 2), "%")
)

kable(eigen_tbl) %>% kable_styling(bootstrap_options = "striped")
PC Eigenvalue Proportion Percentage Cumulative
PC1 2.6079 0.4346 43.46% 43.46%
PC2 1.1444 0.1907 19.07% 62.54%
PC3 0.8370 0.1395 13.95% 76.49%
PC4 0.7063 0.1177 11.77% 88.26%
PC5 0.4925 0.0821 8.21% 96.47%
PC6 0.2118 0.0353 3.53% 100%
plot(eigenvals, type = "b", col = "blue", pch = 19, lwd = 2,
     main = "Scree Plot", xlab = "Principal Component", ylab = "Eigenvalue")
abline(h = 1, col = "red", lty = 2, lwd = 2)

eigenvecs <- eigen_res$vectors
rownames(eigenvecs) <- colnames(data_num)
colnames(eigenvecs) <- paste0("PC", 1:ncol(eigenvecs))
kable(round(eigenvecs, 4)) %>% kable_styling()
PC1 PC2 PC3 PC4 PC5 PC6
Age -0.4361 0.1729 0.2404 -0.5551 0.6432 0.0169
SystolicBP -0.5296 -0.1129 -0.2416 0.3634 0.0939 -0.7124
DiastolicBP -0.5226 -0.1230 -0.2991 0.3544 0.0781 0.7004
BS -0.4255 0.3529 -0.1154 -0.4254 -0.7071 -0.0106
BodyTemp 0.2735 0.4293 -0.8093 -0.1305 0.2607 -0.0291
HeartRate -0.0200 0.7958 0.3550 0.4860 0.0586 0.0240
var_data <- data.frame(PC = 1:length(eigenvals), Variance = prop_var * 100, Cumulative = cum_var * 100)
ggplot(var_data, aes(x = PC)) +
  geom_bar(aes(y = Variance), stat = "identity", fill = "steelblue", alpha = 0.7) +
  geom_line(aes(y = Cumulative), color = "red", size = 1.5) +
  geom_point(aes(y = Cumulative), color = "red", size = 3) +
  geom_hline(yintercept = c(80, 90), linetype = "dashed") +
  theme_minimal() +
  labs(title = "Variance Explained", x = "PC", y = "Percentage (%)")

Penjelasan:Eigenvalue menunjukkan jumlah varians yang dijelaskan setiap PC. PC1 (eigenvalue=2.02) menjelaskan 33.66% varians, PC2 (1.28) menjelaskan 21.35%, PC3 (1.16) menjelaskan 19.37%. Berdasarkan Kaiser Criterion (eigenvalue>1), 3 PC signifikan dan menjelaskan 74.38% total varians.Scree plot memvisualisasikan eigenvalue secara berurutan. Garis merah (y=1) adalah Kaiser Criterion. Tiga PC pertama di atas garis merah dianggap signifikan. “Elbow” atau titik siku terlihat setelah PC3, mengkonfirmasi bahwa 3 komponen optimal.Eigenvector (loading) menunjukkan kontribusi setiap variabel terhadap PC. PC1 didominasi SystolicBP (0.55) dan DiastolicBP (0.52) - komponen “tekanan darah”. PC2 didominasi BS (0.67) dan HeartRate (0.50) - komponen “metabolik-kardiovaskular”. PC3 didominasi BodyTemp (0.83) - komponen “suhu tubuh”.Bar biru menunjukkan proporsi varians individual setiap PC, garis merah menunjukkan kumulatif. Garis putus-putus pada 80% dan 90% adalah target umum. Tiga PC pertama mencapai 74%, mendekati target 80%. Untuk mencapai 80% butuh 4 PC, untuk 90% butuh 5 PC.

Interpretasi:

  • Eigenvalue > 1 dianggap signifikan (Kaiser Criterion)
  • PC1 menjelaskan variance terbesar
  • Eigenvector menunjukkan kontribusi setiap variabel pada PC
  • Cumulative variance 80-90% biasanya cukup untuk reduksi dimensi

5. Kesimpulan

n_pc <- sum(eigenvals > 1)
var_explained <- cum_var[n_pc] * 100

cat("Komponen optimal (eigenvalue > 1):", n_pc, "\n")
## Komponen optimal (eigenvalue > 1): 2
cat("Total variance explained:", round(var_explained, 2), "%\n")
## Total variance explained: 62.54 %
cat("Reduksi dimensi:", ncol(data_num), "→", n_pc, "komponen\n")
## Reduksi dimensi: 6 → 2 komponen

Ringkasan:

  1. Correlation matrix mengidentifikasi hubungan antar variabel
  2. Variance-covariance menunjukkan variabilitas dan kovariasi
  3. Eigenanalysis memungkinkan reduksi dimensi dengan mempertahankan informasi penting
  4. PC dapat digunakan untuk analisis lanjutan (klasifikasi, clustering)