Analýza hlavných komponentov (PCA)

Softvér na analýzu údajov — Projektová správa

Author

Artem Vara

Published

April 29, 2026

1 Úvod

Moderná analýza dát sa čoraz častejšie stretáva s problémom vysokej dimenzionality — datasety môžu obsahovať desiatky až stovky premenných. Priama vizualizácia a interpretácia takýchto dát je prakticky nemožná. Jednou z najelegantnejších matematických metód na riešenie tohto problému je Analýza hlavných komponentov (PCA, z angl. Principal Component Analysis).

PCA je technika zo štatistiky a lineárnej algebry, ktorá transformuje pôvodné premenné na nové — navzájom nekorelované — premenné nazývané hlavné komponenty. Tieto komponenty sú usporiadané tak, aby prvý komponent vysvetľoval čo najväčší podiel celkovej variability dát, druhý komponent vysvetľoval čo najväčší podiel zo zvyšnej variability, atď.

Metóda nachádza uplatnenie v mnohých oblastiach:

  • Biológia: klasifikácia druhov podľa morfologických znakov (Jolliffe and Cadima 2016)
  • Ekonomika: redukcia makroekonomických indikátorov
  • Počítačové videnie: rozpoznávanie tvárí (Eigenfaces)
  • Chémia: spektroskopická analýza

V tomto projekte aplikujeme PCA na klasický dataset mtcars, ktorý obsahuje technické parametre 32 automobilov z roku 1974. Cieľom je ukázať, ako je možné 10-rozmerný priestor premenných zredukovať na 2–3 dimenzie bez výraznej straty informácie.

2 Teoretické pozadie

2.1 Kovariančná matica

Nech \(\mathbf{X}\) je dátová matica rozmeru \(n \times p\), kde \(n\) je počet pozorovaní a \(p\) je počet premenných. Po štandardizácii (odčítaním priemeru a delením smerodajnou odchýlkou) dostaneme maticu \(\mathbf{Z}\).

Kovariančná (resp. korelačná) matica je definovaná ako:

\[ \mathbf{C} = \frac{1}{n-1} \mathbf{Z}^\top \mathbf{Z} \]

Matica \(\mathbf{C}\) je symetrická a pozitívne semidefinitná rozmeru \(p \times p\).

2.2 Vlastné čísla a vlastné vektory

Jadrom PCA je spektrálny rozklad kovariančnej matice:

\[ \mathbf{C} \mathbf{v}_i = \lambda_i \mathbf{v}_i, \quad i = 1, \ldots, p \]

kde \(\lambda_i\)vlastné čísla (eigenvalues) a \(\mathbf{v}_i\) sú zodpovedajúce vlastné vektory (eigenvectors). Vlastné vektory sú navzájom ortogonálne:

\[ \mathbf{v}_i^\top \mathbf{v}_j = \begin{cases} 1 & i = j \\ 0 & i \neq j \end{cases} \]

2.3 Hlavné komponenty

Hlavné komponenty sú lineárne kombinácie pôvodných premenných:

\[ \mathbf{PC}_k = \mathbf{Z} \mathbf{v}_k \]

Podiel variability vysvetlenej \(k\)-tym komponentom:

\[ \text{PVE}_k = \frac{\lambda_k}{\sum_{i=1}^{p} \lambda_i} \]

Vlastné vektory \(\mathbf{v}_k\) sa nazývajú loadings (záťaže) a udávajú, ako silno každá pôvodná premenná prispieva k danému komponentu.

2.4 Algoritmus PCA — krok za krokom

  1. Štandardizácia dát: \(z_{ij} = \frac{x_{ij} - \bar{x}_j}{s_j}\)
  2. Výpočet kovariančnej matice: \(\mathbf{C} = \frac{1}{n-1}\mathbf{Z}^\top\mathbf{Z}\)
  3. Spektrálny rozklad: \(\mathbf{C} = \mathbf{V} \mathbf{\Lambda} \mathbf{V}^\top\)
  4. Zoradenie vlastných čísel: \(\lambda_1 \geq \lambda_2 \geq \ldots \geq \lambda_p\)
  5. Projekcia dát: \(\mathbf{PC} = \mathbf{Z} \mathbf{V}\)

3 Dáta

3.1 Popis datasetu

Použijeme vstavaný R dataset mtcars (R Core Team 2024), ktorý obsahuje informácie o 32 modeloch automobilov z roku 1974.

Code
head(mtcars) |>
  kable(digits = 2) |>
  kable_styling(bootstrap_options = c("striped", "hover"), font_size = 12)
Table 1: Prvých 6 riadkov datasetu mtcars
mpg cyl disp hp drat wt qsec vs am gear carb
Mazda RX4 21.0 6 160 110 3.90 2.62 16.46 0 1 4 4
Mazda RX4 Wag 21.0 6 160 110 3.90 2.88 17.02 0 1 4 4
Datsun 710 22.8 4 108 93 3.85 2.32 18.61 1 1 4 1
Hornet 4 Drive 21.4 6 258 110 3.08 3.21 19.44 1 0 3 1
Hornet Sportabout 18.7 8 360 175 3.15 3.44 17.02 0 0 3 2
Valiant 18.1 6 225 105 2.76 3.46 20.22 1 0 3 1

Dataset obsahuje 32 pozorovaní a 11 premenných:

Premenná Popis
mpg Spotreba paliva (míle na galón)
cyl Počet valcov
disp Objem motora (cu.in.)
hp Výkon (konské sily)
drat Prevodový pomer zadnej nápravy
wt Hmotnosť (1000 lbs)
qsec Čas na 1/4 míle
vs Typ motora (V alebo priamy)
am Prevodovka (0 = automatická, 1 = manuálna)
gear Počet prevodových stupňov
carb Počet karburátorov

3.2 Korelácie medzi premennými

Pred PCA je užitočné preskúmať korelácie:

Code
# Výpočet korelačnej matice
cor_mat <- cor(mtcars)

# Vizualizácia
cor_df <- as.data.frame(as.table(cor_mat))
names(cor_df) <- c("Var1", "Var2", "Correlation")

ggplot(cor_df, aes(Var1, Var2, fill = Correlation)) +
  geom_tile(color = "white") +
  geom_text(aes(label = round(Correlation, 2)), size = 3) +
  scale_fill_gradient2(low = "#d73027", mid = "white", high = "#1a9850",
                       midpoint = 0, limits = c(-1, 1)) +
  theme_minimal() +
  theme(axis.text.x = element_text(angle = 45, hjust = 1)) +
  labs(x = NULL, y = NULL, fill = "Korelácia")
Figure 1: Korelačná matica premenných datasetu mtcars

Z korelačnej matice vidíme silné korelácie medzi premennými (napr. disp, cyl, hp, wt), čo naznačuje, že PCA dokáže tieto premenné efektívne zlúčiť.

4 Výpočet PCA

4.1 Ručný výpočet cez kovariančnú maticu

Najskôr ukážeme PCA “od základov” — priamo cez spektrálny rozklad:

Code
# Štandardizácia
Z <- scale(mtcars)

# Kovariančná matica
C <- cov(Z)

# Spektrálny rozklad
eig <- eigen(C)

# Vlastné čísla
lambda <- eig$values
cat("Vlastné čísla (prvých 5):\n")
Vlastné čísla (prvých 5):
Code
round(lambda[1:5], 4)
[1] 6.6084 2.6505 0.6272 0.2696 0.2235
Code
# Vlastné vektory (loadings)
V <- eig$vectors
cat("\nPrvé dva vlastné vektory (PC1 a PC2):\n")

Prvé dva vlastné vektory (PC1 a PC2):
Code
round(V[, 1:2], 3)
        [,1]   [,2]
 [1,]  0.363 -0.016
 [2,] -0.374 -0.044
 [3,] -0.368  0.049
 [4,] -0.330 -0.249
 [5,]  0.294 -0.275
 [6,] -0.346  0.143
 [7,]  0.200  0.463
 [8,]  0.307  0.232
 [9,]  0.235 -0.429
[10,]  0.207 -0.462
[11,] -0.214 -0.414

4.2 PCA pomocou funkcie prcomp()

Code
# PCA pomocou vstavanej funkcie
pca <- prcomp(mtcars, center = TRUE, scale. = TRUE)

# Súhrn
summary(pca)
Importance of components:
                          PC1    PC2     PC3     PC4     PC5     PC6    PC7
Standard deviation     2.5707 1.6280 0.79196 0.51923 0.47271 0.46000 0.3678
Proportion of Variance 0.6008 0.2409 0.05702 0.02451 0.02031 0.01924 0.0123
Cumulative Proportion  0.6008 0.8417 0.89873 0.92324 0.94356 0.96279 0.9751
                           PC8    PC9    PC10   PC11
Standard deviation     0.35057 0.2776 0.22811 0.1485
Proportion of Variance 0.01117 0.0070 0.00473 0.0020
Cumulative Proportion  0.98626 0.9933 0.99800 1.0000

4.3 Záťaže (Loadings)

Code
loadings_df <- as.data.frame(pca$rotation[, 1:4])
loadings_df |>
  kable(digits = 3) |>
  kable_styling(bootstrap_options = c("striped", "hover")) |>
  column_spec(2, bold = TRUE, color = ifelse(abs(loadings_df$PC1) > 0.3, "darkred", "black"))
Table 2: Záťaže prvých štyroch hlavných komponentov
PC1 PC2 PC3 PC4
mpg -0.363 0.016 -0.226 -0.023
cyl 0.374 0.044 -0.175 -0.003
disp 0.368 -0.049 -0.061 0.257
hp 0.330 0.249 0.140 -0.068
drat -0.294 0.275 0.161 0.855
wt 0.346 -0.143 0.342 0.246
qsec -0.200 -0.463 0.403 0.068
vs -0.307 -0.232 0.429 -0.215
am -0.235 0.429 -0.206 -0.030
gear -0.207 0.462 0.290 -0.265
carb 0.214 0.414 0.529 -0.127

5 Výsledky a vizualizácia

5.1 Scree plot — vysvetlená variabilita

Code
# Výpočet PVE
pve <- lambda / sum(lambda) * 100
cumulative_pve <- cumsum(pve)

scree_df <- data.frame(
  PC = paste0("PC", 1:length(pve)),
  PVE = pve,
  Cumulative = cumulative_pve
)

ggplot(scree_df[1:10, ], aes(x = reorder(PC, -PVE))) +
  geom_col(aes(y = PVE), fill = "#2166ac", alpha = 0.8) +
  geom_line(aes(y = Cumulative, group = 1), color = "#d73027", size = 1.2) +
  geom_point(aes(y = Cumulative), color = "#d73027", size = 3) +
  geom_hline(yintercept = 80, linetype = "dashed", color = "gray50") +
  annotate("text", x = 9, y = 82, label = "80% hranica", color = "gray40", size = 3.5) +
  scale_y_continuous(sec.axis = sec_axis(~., name = "Kumulatívne PVE (%)")) +
  labs(x = "Hlavný komponent", y = "Vysvetlená variabilita (%)") +
  theme_minimal(base_size = 12)
Figure 2: Scree plot: podiel vysvetlenej variability jednotlivými komponentmi

Prvé dva komponenty vysvetľujú 84.2% celkovej variability, prvé tri komponenty 89.9%.

5.2 Biplót — projekcia do 2D priestoru

Code
# Pridáme typ prevodovky ako faktor
mtcars_labeled <- mtcars |>
  mutate(
    transmission = factor(am, labels = c("Automatická", "Manuálna")),
    car_name = rownames(mtcars)
  )

autoplot(pca, data = mtcars_labeled,
         colour = "transmission",
         loadings = TRUE,
         loadings.label = TRUE,
         loadings.label.size = 3.5,
         loadings.colour = "darkred",
         loadings.label.colour = "darkred") +
  scale_color_manual(values = c("#2166ac", "#d6604d")) +
  labs(color = "Prevodovka", title = "PCA biplót — dataset mtcars") +
  theme_minimal(base_size = 12) +
  theme(legend.position = "bottom")
Figure 3: Biplót PCA: projekcia automobilov do roviny PC1–PC2 s vektormi záťaží

5.3 Interpretácia komponentov

Code
loadings_long <- as.data.frame(pca$rotation[, 1:2]) |>
  mutate(variable = rownames(pca$rotation)) |>
  pivot_longer(cols = c(PC1, PC2), names_to = "PC", values_to = "loading")

ggplot(loadings_long, aes(x = reorder(variable, abs(loading)), y = loading, fill = loading > 0)) +
  geom_col() +
  facet_wrap(~PC) +
  coord_flip() +
  scale_fill_manual(values = c("#d73027", "#1a9850"), labels = c("Záporná", "Kladná")) +
  labs(x = NULL, y = "Záťaž", fill = "Smer") +
  theme_minimal(base_size = 12)
Figure 4: Záťaže premenných na prvých dvoch komponentoch

PC1 (vysvetľuje 60.1% variability) je silne spojený s výkonom a veľkosťou motora (hp, disp, cyl, wt) — môžeme ho interpretovať ako “silu vozidla”. Premenné mpg a drat majú záporné záťaže, čo znamená, že silnejšie autá majú vyššiu spotrebu.

PC2 (vysvetľuje 24.1% variability) je primárne spojený s qsec a vs — súvisí s typom a konfiguráciou motora.

6 Záver

V tejto správe sme aplikovali Analýzu hlavných komponentov na dataset mtcars s nasledujúcimi závermi:

  1. Redukcia dimenzionality: Z pôvodných 11 premenných stačia 2 komponenty na vysvetlenie 84.2% variability, 3 komponenty pokrývajú 89.9%.

  2. Interpretácia: PC1 reprezentuje “výkonnosť vozidla” (silne korelovaný s výkonom, objemom, hmotnosťou), PC2 reprezentuje “konfiguráciu motora”.

  3. Vizualizácia: Biplót jasne ukazuje separáciu manuálnych a automatických prevodoviek v priestore PC1–PC2, čo naznačuje, že typ prevodovky súvisí s celkovou výkonnosťou vozidla.

  4. Matematické základy: PCA je elegantná aplikácia lineárnej algebry — spektrálny rozklad kovariančnej matice poskytuje optimálnu lineárnu projekciu v zmysle maximalizácie rozptylu (Jolliffe and Cadima 2016).

PCA zostáva jednou z najpoužívanejších metód exploratívnej analýzy dát vďaka svojej matematickej jednoduchosti a širokej aplikovateľnosti (R Core Team 2024).

Literatúra

Jolliffe, Ian T., and Jorge Cadima. 2016. Principal Component Analysis. 2nd ed. New York: Springer. https://doi.org/10.1007/b98835.
R Core Team. 2024. R: A Language and Environment for Statistical Computing. Vienna, Austria: R Foundation for Statistical Computing. https://www.R-project.org/.