r Sys.Date(){r setup, include=FALSE} knitr::opts_chunk$set(echo = TRUE)
Klastrová (zhluková) analýza patrí medzi najpoužívanejšie metódy exploratívnej štatistiky. V tomto dokumente ju aplikujem nie na krajiny, ale na štyri európske akciové indexy:
Cieľ:
```{r} data(“EuStockMarkets”)
stocks <- as.data.frame(EuStockMarkets) head(stocks)
Pre každý index (DAX, SMI, CAC, FTSE) vytvorím súhrnnú tabuľku:
- priemerná hodnota (mean),
- štandardná odchýlka (sd),
- minimum (min),
- maximum (max).
```{r}
index_names <- c("DAX", "SMI", "CAC", "FTSE")
stock_summary <- data.frame(
Index = index_names,
mean_level = sapply(stocks[ , index_names], mean),
sd_level = sapply(stocks[ , index_names], sd),
min_level = sapply(stocks[ , index_names], min),
max_level = sapply(stocks[ , index_names], max)
)
row.names(stock_summary) <- stock_summary$Index
stock_summary
Každý riadok = jeden index, stĺpce = jeho „profil“.
Aby boli premenné na porovnateľnej škále, použijem z-škálovanie:
\[ z = \frac{x - \mu}{\sigma} \]
kde \(\mu\) je priemer a \(\sigma\) štandardná odchýlka danej premennej (napr. mean_level).
{r} stock_scaled <- scale(stock_summary[ , -1]) # bez stĺpca Index head(stock_scaled)
Prehľad rozloženia z-škálovaných hodnôt:
{r} boxplot( stock_scaled, main = "Z-škálované hodnoty charakteristík indexov", ylab = "z-skóre" )
Tu nebudeme vylučovať odľahlé hodnoty – každý index je dôležitý.
Pri zhlukovej analýze je dôležitá aj korelácia medzi premennými – ak sú silne korelované, niektoré môžu dominovať.
{r} cor_matrix <- cor(stock_summary[ , -1]) # len numerické stĺpce cor_matrix
Ak by niektoré korelácie boli |r| > 0.9, zvažovali by sme
vyhodenie jednej z premenných
alebo použitie PCA. V našom jednoduchom príklade ponecháme všetky štyri
premenné.
Každý index má 4-rozmerný vektor \((\text{mean}, \text{sd}, \text{min}, \text{max})\) (po z-škálovaní). Euklidovská vzdialenosť medzi indexami \(i\) a \(j\):
\[ d_{ij} = \sqrt{\sum_k (x_{ik} - x_{jk})^2} \]
Spočítame maticu vzdialeností na z-škálovaných dátach.
{r} dist_mat <- dist(stock_scaled, method = "euclidean") as.matrix(dist_mat)
Každá bunka predstavuje „nepodobnosť“ medzi dvojicou indexov.
Použijeme Wardovu metódu, ktorá minimalizuje nárast vnútornej variability pri spájaní klastrov.
```{r} hc <- hclust(dist_mat, method = “ward.D2”)
plot( hc, main = “Hierarchické zhlukovanie (Wardova metóda)”, xlab = “Index”, ylab = “Vzdialenosť” )
Môžeme sa rozhodnúť napr. pre **2 klastre** (pre 4 indexy je to logické):
```{r}
k <- 2
clusters <- cutree(hc, k = k)
cluster_assignment <- data.frame(
Index = row.names(stock_scaled),
cluster = as.factor(clusters)
)
cluster_assignment
Budeme počítať pre každú premennú:
Počítame to na z-škálovaných dátach stock_scaled.
```{r} vars <- colnames(stock_scaled) n <- nrow(stock_scaled)
overall_means <- colMeans(stock_scaled) TSS <- colSums( (stock_scaled - matrix(overall_means, nrow = n, ncol = length(vars), byrow = TRUE))^2 )
WSS <- setNames(rep(0, length(vars)), vars)
for (cl in sort(unique(clusters))) { idx <- clusters == cl cluster_data <- stock_scaled[idx, , drop = FALSE] m_cl <- colMeans(cluster_data) WSS <- WSS + colSums( (cluster_data - matrix(m_cl, nrow = nrow(cluster_data), ncol = length(vars), byrow = TRUE))^2 ) }
BSS <- TSS - WSS Prop_Between <- BSS / TSS
cluster_var_stats <- data.frame( Variable = vars, TSS = TSS, WSS = WSS, BSS = BSS, Prop_Between = Prop_Between )
cluster_var_stats
Interpretácia:
- čím je **Prop_Between** bližšie k 1, tým lepšie daná premenná „separuje“ klastre,
- ak je Prop_Between nízke, premenná veľmi neprispieva k rozlíšeniu indexov.
---
# 7. Centroidy – priemerné hodnoty premenných v klastroch
Teraz spočítame priemerné hodnoty (v pôvodnej škále) pre každý klaster:
```{r}
centroids <- aggregate(
stock_summary[ , -1], # bez stĺpca Index
by = list(cluster = clusters),
FUN = mean
)
centroids
Každý riadok = klaster, stĺpce = priemerné charakteristiky indexov v danom klastri.
Na základe výsledkov (tabuľky cluster_assignment,
cluster_var_stats a centroids), ktoré vidíš po
spustení:
Prop_Between lepšie rozlišujú
medzi indexmi,GDP analóg v našom prípade (tu mean_level alebo
sd_level) má vysoký Prop_Between, znamená to, že práve táto
charakteristika najviac oddeľuje indexy.Na základe zhlukovej analýzy stock údajov (EuStockMarkets) sa podarilo: