Analityk przy komputerze przetwarzający dane na kilku monitorach
Źródło: Pexels | Autor: Tima Miroshnichenko
Rate this post

Nawigacja po artykule:

Po co w ogóle PCA i kiedy ma sens w R

Typowe problemy, które rozwiązuje PCA

Analiza składowych głównych (PCA) w R przydaje się wszędzie tam, gdzie liczba zmiennych zaczyna męczyć bardziej niż pomaga. Gdy arkusz ma po kilkadziesiąt kolumn, korelacje są gęste, a modele regresji zaczynają się sypać przez współliniowość, PCA porządkuje sytuację. Zamiast kilkudziesięciu cech powstaje kilka nowych, ortogonalnych wymiarów – składowych głównych – które przechwytują większość zróżnicowania w danych.

Najczęstsze zastosowanie to redukcja wymiaru. Przykład: masz 30 pytań ankietowych dotyczących satysfakcji klienta. Część z nich mówi praktycznie o tym samym, współczynniki korelacji są wysokie i trudno od razu wskazać najważniejsze wymiary. PCA pozwala sprowadzić te 30 zmiennych do 2–5 składowych, które da się nazwać: „jakość obsługi”, „cena vs wartość”, „proces zakupu”. Na wykresie wyników widać, które grupy klientów różnią się między sobą w tych wymiarach.

Drugi klasyczny problem: współliniowość. W danych pomiarowych (chemia, omiki, sensoryka, pomiary jakości produktów) zmiennych jest często więcej niż obserwacji. Regresja liniowa na takich danych jest niewiarygodna. PCA pozwala przekształcić silnie skorelowane zmienne wejściowe w garść nieskorelowanych składowych, które następnie można podawać do modeli (np. regresja na składowych głównych, PLS).

Trzeci obszar to eksploracja danych. PCA pomaga szybko złapać intuicję: które obserwacje są podobne, czy istnieją naturalne grupy, w jakich kierunkach dane „rozchodzą się” najmocniej. Na biplocie łatwo zauważyć, że np. próbki pewnego segmentu rynku są związane z wysokimi wartościami zestawu cech, a inne z przeciwnym zestawem. W R połączenie PCA i pakietu factoextra daje bardzo czytelne wizualizacje, które można od razu wklejać do raportu.

Kiedy PCA nie pomoże albo wręcz zaszkodzi

Bywa, że PCA jest użyte „na siłę”, bo jest modne albo wygląda naukowo. Przy bardzo małej liczbie zmiennych, np. trzech cech, redukcja wymiaru rzadko ma sens – lepiej zwyczajnie obejrzeć wykresy rozrzutu i korelacje. PCA przy trzech zmiennych może być dodatkiem, ale rzadko przynosi nową wiedzę.

Druga pułapka to silna nieliniowość. PCA to metoda liniowa. Szuka prostych kombinacji liniowych zmiennych, które najlepiej opisują wariancję. Jeśli struktura jest nieliniowa (dane leżą na krzywej, kole, spirali), PCA będzie ją spłaszczać w niezbyt intuicyjny sposób. Na wykresach może być widoczny dziwny „banan” albo zakrzywione chmury punktów. W takich sytuacjach lepiej rozważyć metody nieliniowe, np. t-SNE, UMAP, czy kernel PCA.

Trzeci przypadek to dane z przewagą zmiennych kategorycznych. Klasyczny PCA wymaga miar ilościowych. Przy danych czysto nominalnych lub mieszanych lepiej korzystać z metod takich jak MCA (Multiple Correspondence Analysis), FAMD (dla zmiennych jakościowych i ilościowych jednocześnie) czy Gower + metody wielowymiarowe. W R służy do tego również FactoMineR, ale z innymi funkcjami niż PCA().

PCA jako eksploracja, a nie magiczne „podkręcanie modeli”

PCA nie jest uniwersalnym polepszaczem wyników. W modelach predykcyjnych redukcja wymiaru czasem poprawia działanie, zwłaszcza przy małej liczbie obserwacji i dużej liczbie cech, ale równie często nic nie zmienia lub wręcz pogarsza interpretowalność bez istotnego zysku jakości.

Składowe główne są abstrakcyjne – to kombinacje liniowe oryginalnych zmiennych. Jeśli Twoim celem jest przede wszystkim zrozumienie zjawiska, a nie wyciśnięcie ostatniego procenta dokładności modelu, PCA traktuj przede wszystkim jako narzędzie eksploracji: do wizualizacji, sprawdzania struktury zależności i identyfikowania grup. Dopiero w drugim kroku można rozważyć ich użycie jako predyktorów.

Warto też unikać automatycznego „puszczania PCA” jako pierwszego kroku każdej analizy. Czasem lepszy efekt da zwykła selekcja zmiennych na podstawie wiedzy dziedzinowej, sprawdzenie korelacji, a dopiero potem PCA, jeśli nadal jest gęsto i chaotycznie.

Zespół analizujący wykresy danych na laptopach podczas spotkania
Źródło: Pexels | Autor: fauxels

Jakie dane nadają się do PCA i jak je wstępnie ogarnąć

Wymagania PCA wobec zmiennych

Klasyczne przygotowanie danych do PCA w R zakłada, że używane są zmienne ilościowe w skali przynajmniej przedziałowej. Przykłady: pomiary fizyczne (masa, długość, stężenie), wyniki testów, liczby punktów na skalach Likerta traktowane jako przybliżenie zmiennych ciągłych.

Przy zmiennych porządkowych (np. skale 1–5) można je uwzględnić, jeśli mają dość poziomów i są w miarę równomiernie rozłożone. Jednak gdy większość to odpowiedzi 1 lub 5, PCA łatwo staje się niestabilne. Dla typowych ankiet z wieloma pytaniami na 5-stopniowych skalach sensowną alternatywą jest traktowanie ich jako przybliżenia zmiennych ciągłych, ale z solidnym sprawdzeniem rozkładu i wariancji.

Zmiennych kategorycznych nominalnych (tak/nie, typ produktu A/B/C) PCA nie obsłuży bezpośrednio. Jednym obejściem są kodowania 0/1 i użycie ich w PCA, ale może to prowadzić do nieintuicyjnych wyników. Do analizy struktury zmiennych jakościowych lepiej użyć MCA lub innych metod z rodziny analizy korespondencji.

Wybór obserwacji i zmiennych do PCA

Nie trzeba wrzucać wszystkiego do PCA. Lepiej podejść selektywnie i wybrać tylko te zmienne, które są merytorycznie sensowne i mają wystarczającą zmienność. Zmienne o niemal stałej wartości (np. prawie wszyscy klienci odpowiedzieli 5 na dane pytanie) mają bardzo małą wariancję i nie wnoszą istotnej informacji – w PCA praktycznie nic nie wyjaśnią.

Przy wyborze obserwacji ogranicz się do spójnej grupy. Łączenie bardzo różnych populacji (np. dane z innych krajów, innych typów produktów) może wytworzyć składowe, które w dużej mierze odzwierciedlają różnice „techniczne” zamiast merytorycznych. Gdy takie zróżnicowanie jest celem, w porządku. Jeśli nie – lepiej przeprowadzić oddzielne analizy.

Kryteria techniczne są proste:

  • wystarczająca liczba obserwacji (zwykle co najmniej kilka razy więcej niż liczba zmiennych),
  • brak gigantycznych braków danych w kluczowych kolumnach,
  • rozsądny rozkład wartości – brak ekstremalnej skośności bez żadnej transformacji.

Liczba obserwacji vs liczba zmiennych

Relacja liczby obserwacji do liczby zmiennych mocno wpływa na stabilność PCA. Przy bardzo małej liczbie obserwacji względem liczby zmiennych (np. 40 próbek i 100 zmiennych) PCA wciąż można obliczyć, ale wyniki są wrażliwe na pojedyncze obserwacje, a wariancje składowych mogą być trudne do interpretacji.

Przybliżona, zdroworozsądkowa zasada mówi: przynajmniej 5–10 obserwacji na zmienną to wygodny punkt wyjścia. Nie jest to twarda reguła, ale warto mieć ją z tyłu głowy. Gdy macierz jest prawie kwadratowa (np. 30 obserwacji i 25 zmiennych), każdy punkt ma duży wpływ na wynik. To nie wyklucza PCA, ale wymaga szczególnie ostrożnej interpretacji i dodatkowych analiz wrażliwości (np. PCA po usunięciu kilku punktów odstających).

W praktyce omicznej (genomy, transkryptomy) relacja jest zwykle odwrotna: tysiące zmiennych, dziesiątki obserwacji. Tam PCA działa często jako narzędzie wizualizacji, ale wybór liczby składowych i interpretacja ładunków jest szczególnie delikatna. Dobrą praktyką jest wtedy łączenie PCA z filtracją cech (np. wybór genów o największej wariancji przed PCA), a nie liczenie składowych na wszystkich zmiennych naraz.

Przygotowanie danych do PCA krok po kroku w R

Wczytanie danych i pierwsze czyszczenie

Pierwszy etap przygotowania danych do PCA w R to solidny przegląd tabeli. Przykładowy workflow może wyglądać tak:


library(readr)
library(dplyr)
library(tidyr)

dane <- read_csv("dane_pca.csv")

glimpse(dane)
summary(dane)

glimpse() z pakietu tibble/dplyr pokazuje typy zmiennych oraz pierwsze wartości, summary() daje podstawowe statystyki: minima, maksima, kwartyle. Na tym etapie wychodzą na jaw oczywiste błędy, takie jak wartości spoza zakresu, zamienione kropki na przecinki czy tekst w kolumnie, która powinna być numeryczna.

Następnie warto odfiltrować ewidentne błędne rekordy, np. wiersze z wiekiem < 0 lub masą produktu równą 0 tam, gdzie nie powinno jej być. Zamiast usuwać je w ciemno, lepiej oznaczyć te obserwacje i sprawdzić ich wpływ na wstępne analizy. Jednak do PCA finalnie zwykle trafia już oczyszczony podzbiór:


dane_czyste <- dane |> 
  filter(wiek >= 18, wiek <= 90)

Selekcja zmiennych i tworzenie zestawu do PCA

W kolejnym kroku powstaje ramka zawierająca tylko zmienne używane do PCA. Przykładowo, jeśli celem jest analiza cech produktów, wybierasz tylko zmienne ilościowe opisujące produkt, bez identyfikatorów, dat czy etykiet kategorycznych:


zmienne_do_pca <- dane_czyste |>
  select(masa, wysokosc, szerokosc, dlugosc, twardosc, wilgotnosc)

Przy dużych zbiorach selekcję zmiennych można wesprzeć prostą diagnostyką:

  • sprawdzenie korelacji (funkcja cor() lub wykresy z GGally::ggpairs()),
  • usunięcie zmiennych o zerowej lub bardzo małej wariancji (np. caret::nearZeroVar()),
  • scalenie cech, które są prostymi przekształceniami innych (np. wysokość w cm i w metrach – wybierz jedną).

Kiedy cech jest dużo i trudno z góry określić, co jest istotne, można wykonać najpierw PCA na większym zbiorze, a po wstępnej interpretacji zawęzić się do kluczowych zmiennych i ponowić analizę na bardziej precyzyjnym zestawie.

Transformacje: log, sqrt, Box–Cox i centrowanie wokół punktu odniesienia

Wiele zmiennych pomiarowych jest silnie skośnych (np. czas, dochody, liczniki). Zbyt duża skośność utrudnia PCA, bo kilka ekstremów może dominować strukturę wariancji. Pomagają proste transformacje:

  • logarytmiczna – dla wartości dodatnich, np. stężenia, liczebności, przychodów,
  • pierwiastkowa – łagodzi umiarkowaną skośność, gdy log jest zbyt agresywny,
  • Box–Cox – automatyczny wybór rodziny transformacji (np. z pakietu MASS).

Przykład zastosowania w R:


zmienne_do_pca <- zmienne_do_pca |>
  mutate(
    masa_log = log(masa),
    wilgotnosc_sqrt = sqrt(wilgotnosc)
  )

Inny rodzaj transformacji to centrowanie wokół wartości istotnej biznesowo. Jeśli ważna jest różnica względem poziomu referencyjnego (np. docelowej wilgotności produktu), można utworzyć zmienną „odchylenie od celu” zamiast używać surowego poziomu. Tak przekształcona cecha często jest bardziej zrozumiała podczas interpretacji ładunków składowych.

Checklist przed startem PCA w R

Poniższa krótka checklista pomaga upewnić się, że dane są w sensownym stanie przed uruchomieniem prcomp() lub FactoMineR::PCA():

  • Wszystkie wybrane zmienne do PCA są ilościowe (lub sensownie traktowane jako ilościowe).
  • Nie ma kolumn z prawie stałą wartością (prawie zerowa wariancja).
  • Rozkłady nie są skrajnie skośne – jeśli są, przetestowano log/sqrt/inne transformacje.
  • Braki danych zostały przeanalizowane i obsłużone (imputacja lub sensowne usunięcie).
  • Outliery są zidentyfikowane, a ich wpływ przynajmniej wstępnie oceniony.
  • Powstała oddzielna ramka danych zawierająca wyłącznie zmienne do PCA.
Kobieta analizuje dane finansowe na dwóch monitorach w biurze
Źródło: Pexels | Autor: Kampus Production

Skalowanie, standaryzacja i macierz kowariancji vs korelacji

Kiedy skalować zmienne, a kiedy nie

Przygotowanie danych do PCA w R niemal zawsze wiąże się z pytaniem: skalować czy nie? Skalowanie (standaryzacja) polega na przekształceniu każdej zmiennej do porównywalnej skali, najczęściej do średniej 0 i odchylenia standardowego 1. W R odpowiada za to argument scale = TRUE w funkcji prcomp() lub scale.unit = TRUE w FactoMineR::PCA().

Skalowanie w praktyce: przykłady i pułapki

Intuicyjny sposób myślenia o skalowaniu jest prosty: jeśli zmienne mają zupełnie różne jednostki lub rzędy wielkości, PCA bez standaryzacji będzie w praktyce analizą zmiennej o największej wariancji. Sytuacje, w których skalowanie jest praktycznie obowiązkowe:

  • łączenie cech w metrach, kilogramach, złotówkach, sztukach,
  • mieszanie surowych wartości (np. sprzedaż w sztukach) z indeksami procentowymi,
  • analiza ankiet, w których pytania mają różne zakresy (np. skala 1–5 i 0–100).

Dla kontrastu, nie trzeba od razu skalować wszystkiego mechanicznie. Gdy wszystkie zmienne są w tych samych jednostkach i w podobnych zakresach (np. wymiary produktów w cm o podobnych wariancjach), można świadomie uruchomić PCA na macierzy kowariancji zamiast korelacji, czyli bez standaryzacji. Wtedy składowe bardziej podkreślą cechy o naturalnie większej zmienności (np. długość różni się między produktami bardziej niż szerokość).

Najczęstsze pułapki:

  • skalowanie zmiennych już wyrażonych jako znormalizowane indeksy (np. wyniki w [0,1]) razem z surowymi wartościami – wtedy indeksy stają się „równoprawne” z dużymi zmiennymi, co nie zawsze ma sens biznesowy,
  • stosowanie scale = TRUE „z rozpędu”, bez zastanowienia, co w praktyce oznacza interpretacja ładunków na standaryzowanych, a nie oryginalnych zmiennych.

Macierz kowariancji a macierz korelacji w R

W R przełączanie się między obiema wersjami jest bardzo proste. Funkcja prcomp() zawsze działa na macierzy kowariancji danych wejściowych. Jeżeli podasz dane nieprzeskalowane, otrzymujesz PCA na kowariancji; jeśli wcześniej zeskalujesz dane (lub użyjesz scale = TRUE), wynik odpowiada PCA na macierzy korelacji.


# PCA na macierzy kowariancji (bez standaryzacji)
pca_cov <- prcomp(zmienne_do_pca, scale. = FALSE)

# PCA na macierzy korelacji (standaryzacja zmiennych)
pca_cor <- prcomp(zmienne_do_pca, scale. = TRUE)

Gdy cechy są mierzone w różnych jednostkach lub mają bardzo różną wariancję, analizę struktury zależności zwykle buduje się na macierzy korelacji. Jeżeli natomiast kluczowe jest zachowanie rzeczywistej skali zjawiska (np. fizyczne rozmiary elementu), macierz kowariancji bywa bardziej naturalna, bo pokazuje faktyczny wkład każdej zmiennej w łączną zmienność.

Jeśli pojawia się wątpliwość, który wariant wybrać, dobrze jest policzyć i porównać oba PCA. Na wykresach wyników często widać od razu, który lepiej oddaje znaną strukturę danych.

Obsługa braków danych przed PCA

Braki danych nie blokują PCA całkowicie, ale wymagają świadomej decyzji. Najprostszy ruch – usunięcie wszystkich wierszy z NA w analizowanych zmiennych – bywa kuszący, ale przy większym odsetku braków może dramatycznie zmniejszyć próbę.

Typowe strategie w R:

  • proste usuwanie wierszy:
    
    dane_pca_complete <- zmienne_do_pca |> 
      drop_na()
    

    Sprawdza się, gdy braki są rzadkie i wydają się losowe.

  • prosta imputacja (średnia/mediana w kolumnie):
    
    library(dplyr)
    
    dane_pca_imputed <- zmienne_do_pca |> 
      mutate(across(
        .cols = everything(),
        .fns  = ~ if_else(is.na(.x), median(.x, na.rm = TRUE), .x)
      ))
    

    Działa zaskakująco dobrze przy małych odsetkach NA, ale spłaszcza wariancję.

  • imputacja wielowymiarowa, np. missMDA::imputePCA() lub mice. To już poważniejsze rozwiązanie, przydatne przy bardziej złożonych brakach.

Gdy braków jest dużo w pojedynczych kolumnach, czasem rozsądniej jest pominąć te zmienne w PCA i przeanalizować je osobno niż ratować je agresywną imputacją.

Uruchamianie PCA w R: prcomp() i FactoMineR::PCA()

Po przygotowaniu danych można przejść do samego obliczenia PCA. Najprostsza ścieżka prowadzi przez stats::prcomp():


pca_model <- prcomp(
  dane_pca_imputed,
  center = TRUE,   # centrowanie zmiennych
  scale. = TRUE    # skalowanie do sd = 1
)

summary(pca_model)

center = TRUE ustawia średnią każdej zmiennej na 0, a scale. = TRUE dodatkowo dzieli przez odchylenie standardowe. Jeżeli centrowanie lub skalowanie wykonano wcześniej ręcznie, można tu zostawić domyślne wartości (TRUE/FALSE odpowiednio do sytuacji).

Do bardziej rozbudowanej analizy i automatycznego generowania wykresów wygodny jest pakiet FactoMineR razem z factoextra:


library(FactoMineR)
library(factoextra)

pca_fm <- PCA(
  dane_pca_imputed,
  scale.unit = TRUE,   # odpowiednik scale. = TRUE
  graph      = FALSE   # bez automatycznych wykresów
)

fviz_screeplot(pca_fm)

PCA() od razu oblicza wiele statystyk użytecznych później przy interpretacji, m.in. wkłady zmiennych w składowe czy miary jakości reprezentacji punktów.

Wybór liczby składowych w R: wykres osypiska i kryteria liczbowe

Po uruchomieniu PCA pojawia się kolejne pytanie: ile składowych zachować. Zbyt mało – utracisz istotną część struktury. Zbyt dużo – wykresy stają się chaotyczne, a interpretacja męcząca.

Podstawowe narzędzia w R to:

  • wykres osypiska (scree plot) – wykres wartości własnych lub procentu wyjaśnionej wariancji:

library(factoextra)

fviz_eig(pca_fm, addlabels = TRUE, ylim = c(0, 60))

Zwykle szuka się „kolanka” na wykresie – miejsca, w którym dalsze składowe przestają wnosić dużo nowej wariancji.

  • kryterium Kaisera – zachowanie składowych o wartości własnej > 1 (dla PCA na macierzy korelacji). W FactoMineR wartości własne są dostępne w pca_fm$eig.

pca_fm$eig
  • łączny procent wariancji – często stosuje się pragmatyczne progi, np. 70–90% łącznej wariancji, w zależności od zastosowania.

Przykładowy sposób wyboru na podstawie tabeli eigenvalues:


eigs <- pca_fm$eig
eigs

# Ile składowych potrzeba, by osiągnąć >= 80% wariancji?
which(cumsum(eigs[, "cumulative percentage of variance"]) >= 80)[1]

W praktyce biznesowej częściej kończy się na 2–4 składowych, bo tyle da się komfortowo pokazać i omówić. Jeśli kryteria liczbowe sugerują np. 7 składowych, warto najpierw zadać pytanie, które z nich mają jasną, interpretowalną strukturę ładunków, a dopiero potem decydować, które pokazywać interesariuszom.

Jak czytać wyniki PCA w R

Struktura obiektu prcomp()

Obiekt zwracany przez prcomp() zawiera kilka kluczowych elementów, które są niezbędne przy interpretacji:

  • pca_model$x – współrzędne obserwacji w przestrzeni składowych (scores),
  • pca_model$rotation – ładunki (loadings), czyli współczynniki liniowe w definicji składowych,
  • pca_model$sdev – odchylenia standardowe składowych (pierwiastki z wartości własnych),
  • pca_model$center, pca_model$scale – użyte do centrowania i skalowania.

Podsumowanie daje szybki przegląd mocy składowych:


summary(pca_model)

W tabeli Importance of components znajdziesz:

  • Standard deviation – siłę każdej składowej,
  • Proportion of Variance – procent całkowitej wariancji wyjaśniany przez daną składową,
  • Cumulative Proportion – wariancja skumulowana.

To dobry punkt startu przed zagłębieniem się w interpretację ładunków i wyników.

Ładunki (loadings) składowych: jak je interpretować

Ładunki to współczynniki mówiące, jak bardzo każda zmienna źródłowa „wchodzi” w daną składową. Dla centrów i skalowanych danych PCA można traktować ładunki jako coś zbliżonego do skorelowania zmiennej ze składową (choć formalnie to nie to samo).

Aby obejrzeć ładunki pierwszych składowych:


loadings <- pca_model$rotation
round(loadings[, 1:3], 3)

Prosty sposób czytania ładunków:

  • duże wartości dodatnie – zmienne rosną razem ze składową,
  • duże wartości ujemne – zmienne maleją, gdy składowa rośnie (czyli są skorelowane ujemnie ze składową),
  • wartości bliskie zera – zmienne słabo powiązane z daną składową.

Jeśli w pierwszej składowej masie, długości i szerokości odpowiadają wysokie dodatnie ładunki, a twardości i wilgotności niskie – można ją nazwać np. „wielkością geometryczną produktu”. Gdy druga składowa ma wysokie ładunki na wilgotności, a ujemne na twardości, opis jako „gradient twardość–wilgotność” jest całkiem naturalny.

Przydatne jest też spojrzenie na wartości bezwzględne ładunków i wybranie zmiennych, które naprawdę napędzają składową:


# Zmienne o najmocniejszych ładunkach w PC1
pc1_loadings <- sort(abs(loadings[, 1]), decreasing = TRUE)
head(pc1_loadings)

Mapa zmiennych: wykres ładunków w R

Same liczby bywają trudne do ogarnięcia wzrokiem, zwłaszcza gdy cech jest dużo. Wygodne jest przejście do wykresu wektorowego, tzw. mapy zmiennych (circle of correlations). Z pakietem factoextra wygląda to następująco:


fviz_pca_var(
  pca_fm,
  col.var = "cos2", # intensywność koloru wg jakości reprezentacji
  repel   = TRUE    # odsuwanie etykiet, żeby się nie nakładały
)

Interpretacja takiego wykresu:

  • długość wektora – im dłuższy, tym lepiej zmienna jest reprezentowana przez analizowane dwie składowe,
  • kąt między wektorami – mały kąt oznacza silną dodatnią korelację, kąt bliski 180° – korelację ujemną, bliski 90° – brak związku (w przestrzeni tych dwóch składowych),
  • położenie na osi poziomej i pionowej – wskazuje, czy zmienna ma większy związek z PC1, PC2 czy z obydwiema.

Jeśli kilka wektorów leży blisko siebie, reprezentują zbliżone właściwości. To sygnał, że można je traktować jako jedną „grupę cech” przy opisie składowej.

Scores: współrzędne obserwacji w przestrzeni składowych

Współrzędne obserwacji w przestrzeni głównych składowych (scores) pokazują, jak poszczególne rekordy (produkty, klienci, próbki) układają się względem zidentyfikowanych osi. W prcomp() są w pca_model$x:


head(pca_model$x)

Typowy wykres wyników w R, łączący PCA z dodatkowymi informacjami (np. typ produktu), można narysować tak:


library(ggplot2)

scores_df <- as.data.frame(pca_model$x) |> 
  mutate(typ_produktu = dane_czyste$typ_produktu)

ggplot(scores_df, aes(x = PC1, y = PC2, color = typ_produktu)) +
  geom_point(alpha = 0.7) +
  coord_equal() +
  theme_minimal()

Na takim wykresie widać m.in.:

  • czy produkty/klienci tworzą naturalne klastry,
  • czy klasy, które znasz z biznesu (np. segmenty klientów), faktycznie różnią się w przestrzeni cech,
  • czy są obserwacje odległe od reszty (kandydaci na outliery).

Biplot: połączenie wyników i ładunków na jednym wykresie

Dla ogólnego podglądu struktury przydatny jest biplot – wspólny wykres wektorów zmiennych i punktów reprezentujących obserwacje. W R można użyć bazowego biplot() albo wygodniejszego narzędzia z factoextra:

Biplot w praktyce: jak czytać wspólny wykres zmiennych i obserwacji

Biplot bywa na początku przytłaczający – dużo strzałek, dużo punktów. Dobrze jest rozbić go na kilka prostych obserwacji. Wersja z factoextra bazująca na FactoMineR::PCA() może wyglądać tak:


fviz_pca_biplot(
  pca_fm,
  repel      = TRUE,        # odsuwanie etykiet
  col.var    = "steelblue", # kolor wektorów zmiennych
  col.ind    = "grey50",    # kolor punktów-obserwacji
  alpha.ind  = 0.7
)

Na co patrzeć, żeby nie zgubić się w szczegółach:

  • pozycja punktu względem osi – mówi, jakie ma wartości ukrytych cech (składowych), czyli gdzie leży w „krajobrazie” danych,
  • kierunek strzałki zmiennej – wskazuje, w którą stronę rosną wartości danej cechy,
  • rzut punktu na wektor – jeśli punkt leży w kierunku strzałki, zwykle oznacza to ponadprzeciętną wartość tej zmiennej; jeśli w kierunku przeciwnym – poniżej średniej.

Przykład: na składowej „wielkość produktu” punkty po prawej stronie układu odpowiadają dużym egzemplarzom. Jeśli wektor „masa” wskazuje w prawo i lekko do góry, a punkty konkretnego typu produktu leżą właśnie w tym kierunku, łatwo stwierdzić, że ten typ jest raczej cięższy i większy niż przeciętnie.

Gdy etykiet jest dużo, lepiej ograniczyć ich liczbę i wymusić skupienie na istotnym podzbiorze:


fviz_pca_biplot(
  pca_fm,
  label      = "var",     # podpisuj tylko zmienne
  habillage  = dane_czyste$typ_produktu, # kolory wg typu
  addEllipses = TRUE,     # elipsy dla grup
  ellipse.level = 0.95
)

Takie elipsy pomagają wychwycić, które grupy obserwacji nachodzą na siebie, a które zajmują wyraźnie inne obszary w przestrzeni głównych składowych.

Dodatkowe statystyki z FactoMineR: cos2 i wkłady (contrib)

Pakiet FactoMineR przechowuje w obiekcie PCA zestaw miar ułatwiających odpowiedź na dwie częste obawy:

  • na ile konkretna zmienna jest dobrze pokazana na danym wykresie,
  • które zmienne naprawdę „ciągną” daną składową.

Podstawowe elementy to:


str(pca_fm$var)

Najważniejsze pola w pca_fm$var to:

  • coord – współrzędne zmiennych (odpowiednik ładunków w prcomp),
  • cos2 – miara jakości reprezentacji zmiennej przez poszczególne składowe (od 0 do 1),
  • contrib – procentowy wkład zmiennej w wariancję danej składowej.

Przykład szybkiego przeglądu zmiennych najlepiej reprezentowanych przez pierwsze dwie składowe:


head(pca_fm$var$cos2[ , 1:2])

Wysokie cos2 w PC1–PC2 oznacza, że dana zmienna leży blisko okręgu korelacji na mapie zmiennych i jest dobrze rzutowana na tę dwuwymiarową płaszczyznę. Jeśli cos2 jest niskie dla obu składowych, zmienna „żyje” raczej w dalszych wymiarach i nie warto na siłę interpretować jej położenia na wykresie PC1–PC2.

Podobnie z wkładami:


# Zmienne o największym wkładzie do PC1
sort(pca_fm$var$contrib[, 1], decreasing = TRUE)[1:5]

# Zmienne o największym wkładzie do PC2
sort(pca_fm$var$contrib[, 2], decreasing = TRUE)[1:5]

Takie zestawienie szybko pokazuje, które cechy są kluczowe przy definiowaniu danej osi. Przy prezentowaniu wyników menedżerom można spokojnie ograniczyć się do 3–5 zmiennych o najwyższych wkładach na każdej z omawianych składowych.

Jakość reprezentacji obserwacji: cos2 i odległości

Podobne pytania pojawiają się przy interpretowaniu punktów. Gdy jakieś obserwacje leżą blisko środka, pojawia się wątpliwość: czy naprawdę „od czegoś” się różnią, czy po prostu są słabo odwzorowane na wykresie.

W FactoMineR współrzędne obserwacji i ich statystyki są w pca_fm$ind:


str(pca_fm$ind)
  • coord – współrzędne (scores),
  • cos2 – jakość reprezentacji obserwacji przez składowe,
  • contrib – wkład obserwacji w wariancję składowej (pomaga identyfikować „typowe” vs „skrajne” przypadki).

Szybki podgląd jakości reprezentacji na pierwszych dwóch składowych:


head(pca_fm$ind$cos2[ , 1:2])

Obserwacje z wysokim cos2 na PC1–PC2 są dobrze odwzorowane na standardowym wykresie wyników. Jeśli cos2 jest niskie, dana próbka może wymagać spojrzenia na inne pary składowych, np. PC2–PC3 lub PC1–PC3.

Analogicznie do zmiennych, wkłady obserwacji pomagają znaleźć „mocnych graczy” w danej składowej:


# Obserwacje o największym wkładzie do PC1
head(sort(pca_fm$ind$contrib[, 1], decreasing = TRUE))

To zazwyczaj punkty położone daleko od środka wzdłuż danej osi – często właśnie one są biznesowo najciekawsze (np. nietypowe zachowania klientów czy produkty z ekstremalnymi parametrami).

Kolorowanie i grupowanie na wykresach wyników

Przy pracy z klientami wewnętrznymi lub zespółami nietechnicznymi pytanie zwykle brzmi: „co to znaczy dla naszych segmentów / linii produktowych?”. Zamiast ogólnej chmury punktów, lepiej od razu pokazać wyniki z podziałem na grupy.

Przy użyciu factoextra można dość szybko dodać kolorowanie i elipsy:


fviz_pca_ind(
  pca_fm,
  habillage    = dane_czyste$segment_klienta, # zmienna grupująca
  addEllipses  = TRUE,
  ellipse.level = 0.95,
  palette      = "jco"
)

Taki wykres często wystarcza, żeby odpowiedzieć na kluczowe pytania:

  • czy segmenty faktycznie różnią się pod względem badanych cech,
  • czy jakieś klasy bardzo się nakładają (co może sugerować, że podział jest słaby),
  • czy istnieją pojedyncze punkty z każdego segmentu, które „wyskakują” z typowego wzorca.

Jeżeli grup jest dużo lub obserwacji są tysiące, wygodniej jest przeskoczyć do ggplot2 i przygotować wersję bardziej oszczędną:


scores_df <- as.data.frame(pca_fm$ind$coord) |>
  mutate(segment = dane_czyste$segment_klienta)

ggplot(scores_df, aes(Dim.1, Dim.2, color = segment)) +
  geom_point(alpha = 0.5, size = 1.5) +
  coord_equal() +
  theme_minimal()

Taka konfiguracja pozwala łatwo dopasować etykiety osi, kolory czy legendę do standardów raportowania w firmie.

Dodawanie zmiennych jakościowych i wykresy suplementarne

Częstorazowym marzeniem jest odpowiedź na pytanie: „czy ten schemat z PCA ma coś wspólnego z naszymi kategoriami jakościowymi, np. regionem sprzedaży albo typem sklepu?”. FactoMineR umożliwia włączenie zmiennych jakościowych jako suplementarnych:


pca_fm2 <- PCA(
  dane_pca_imputed,
  scale.unit = TRUE,
  quali.sup  = c(1, 3),  # indeksy kolumn jakościowych
  graph      = FALSE
)

Zmiennych jakościowych nie używa się do budowania składowych, ale można później sprawdzić, jak ich poziomy rozmieszczają się w przestrzeni PCA:


fviz_pca_ind(
  pca_fm2,
  habillage = 1,        # pierwsza zmienna jakościowa jako kolor
  addEllipses = TRUE
)

Taka konfiguracja pomaga odpowiedzieć na pytania typu: „czy pewien typ sklepu jest powiązany z wysokimi wartościami określonej składowej?”, albo „czy regiony geograficzne różnią się składem sprzedaży produktów?”.

Przejście z wyników PCA do prostych reguł biznesowych

Sama interpretacja wykresów rzadko jest celem samym w sobie. Zwykle chodzi o prostą regułę lub opis, którym da się posłużyć w decyzjach. PCA dobrze się tu sprawdza jako narzędzie kondensujące wiedzę.

Przykładowy schemat pracy:

  1. Wybór 2–3 pierwszych, interpretowalnych składowych (z jasnymi ładunkami).
  2. Nadanie im opisowych nazw, np. „wielkość i masa produktu”, „komfort użytkowania”, „intensywność korzystania z usługi”.
  3. Sprawdzenie rozkładu kluczowych grup (segmentów, linii, kanałów) względem tych osi.
  4. Przekucie obserwacji w proste zdania:
  • „Segment A to klienci z wysoką intensywnością korzystania i niską wrażliwością cenową”.
  • „Linia premium skupia produkty o wysokiej jakości sensorycznej i ponadprzeciętnej cenie”.

Do dalszej pracy w R można zachować scores jako nowe zmienne, które potem trafią do modeli, reguł lub dashboardów:


dane_z_scores <- dane_czyste |>
  cbind(as.data.frame(pca_model$x[, 1:3]))  # np. trzy pierwsze PC

Tak przygotowane kolumny PC1, PC2, PC3 można później traktować jak nowe cechy wejściowe do modeli regresyjnych, klasyfikacyjnych czy klasteryzacji. Dla zespołów biznesowych ich opisowe nazwy i proste interpretacje są zwykle dużo strawniejsze niż kilkadziesiąt pierwotnych zmiennych.

Porównywanie wyników PCA między podgrupami danych

Częsta obawa brzmi: „czy wynik PCA nie jest specyficzny tylko dla całej próby, a u konkretnej grupy klientów sprawa wygląda inaczej?”. Rzeczywiście, struktura korelacji może się różnić w zależności od podzbioru danych.

Jeden z praktycznych sposobów sprawdzenia tego w R:

  1. Przeprowadzić PCA na całej próbce i zachować ładunki.
  2. Przeprowadzić osobne PCA dla wybranych podgrup (np. regionów, typów klientów).
  3. Porównać ładunki (znaki i rzędy wielkości) między modelami.

Przykładowa implementacja dla dwóch segmentów:


segA <- subset(dane_pca_imputed, segment == "A")[, zmienne_numeryczne]
segB <- subset(dane_pca_imputed, segment == "B")[, zmienne_numeryczne]

pca_A <- prcomp(segA, center = TRUE, scale. = TRUE)
pca_B <- prcomp(segB, center = TRUE, scale. = TRUE)

round(pca_A$rotation[, 1:2], 3)
round(pca_B$rotation[, 1:2], 3)

Jeżeli wzorce ładunków są podobne (te same zmienne mają wysokie dodatnie/ujemne wartości na danej składowej), można spokojniej korzystać z jednego wspólnego modelu. Jeśli jednak różnice są duże, sensowniejsze bywa osobne PCA dla każdej grupy lub uwzględnienie informacji o grupie w dalszym modelowaniu.

Praktyczne pułapki interpretacyjne przy PCA

PCA jest kusząco proste na poziomie kodu, a przy tym łatwo wpaść w kilka typowych pułapek. Świadomość ich istnienia często oszczędza nerwów przy obronie wyników przed bardziej dociekliwą publicznością.

  • Nadmierne przywiązywanie się do znaków ładunków. Zmiana znaku wszystkich ładunków w danej składowej nie zmienia niczego istotnego – to nadal ta sama oś, tylko „odwrócona”. Dla spójności warto po prostu trzymać się jednej konwencji nazewnictwa.
  • Interpretowanie słabo reprezentowanych zmiennych. Zmienna o bardzo krótkim wektorze na mapie zmiennych lub niskim cos2 dla PC1–PC2 nie powinna być mocno „czytana” z tego wykresu. W razie potrzeby lepiej sięgnąć do innych par składowych.
  • Przeładowanie wykresów. Dla kilkudziesięciu zmiennych circle of correlations zamienia się w jeżozwierza. Czasem lepiej wybrać 10–15 najważniejszych cech (wg contrib) niż pokazać wszystko naraz.
  • Mylenie korelacji z przyczynowością. To, że dwie cechy „wchodzą” w tę samą składową, nie znaczy, że jedna powoduje drugą. PCA mówi o współzmienności, nie o kierunkach wpływu.
  • Wrażliwość na skalowanie i zakresy. Inne decyzje o centrowaniu i skalowaniu potrafią diametralnie zmienić wynik. Kiedy pokazuje się dwa różne PCA, dobrze jednoznacznie zaznaczyć, czy pracuje się na macierzy korelacji, czy kowariancji.

Najczęściej zadawane pytania (FAQ)

Kiedy w ogóle warto stosować PCA w R, a kiedy to strata czasu?

PCA ma sens wtedy, gdy masz dużo zmiennych ilościowych, silne korelacje między nimi i zaczynasz gubić się w ich interpretacji. Typowe sytuacje to: długie ankiety (kilkadziesiąt pytań), dane pomiarowe z laboratorium, sensoryka, omiki – wszędzie tam, gdzie zmiennych jest więcej niż kilka–kilkanaście.

Jeśli masz 3–4 zmienne, PCA zwykle niewiele wniesie ponad zwykłe wykresy rozrzutu i macierz korelacji. Niezbyt przydaje się też wtedy, gdy dane są mocno nieliniowe (np. leżą na okręgu) albo gdy przeważają zmienne kategoryczne – wtedy lepsze będą inne metody, jak MCA, FAMD czy t-SNE/UMAP.

Jak przygotować dane do PCA w R – jakie zmienne mogę uwzględnić?

Do klasycznego PCA w R używaj przede wszystkim zmiennych ilościowych, najlepiej w skali przedziałowej (pomiary, wyniki testów, zsumowane skale). Skale Likerta 1–5 można potraktować jako przybliżenie zmiennych ciągłych, ale dobrze najpierw sprawdzić rozkłady – jeśli prawie wszyscy zaznaczają jedną odpowiedź, taka kolumna nic nie wnosi.

Zmiennych nominalnych (tak/nie, typ produktu A/B/C) PCA nie obsłuży sensownie bezpośrednio. Można je zenkodować 0/1, ale interpretacja bywa wtedy sztuczna. Przy przewadze kategorii lepiej przejść na MCA lub inne metody dla danych jakościowych. Dobrą praktyką jest też usuwanie zmiennych o bardzo małej wariancji (prawie stałych).

Ile obserwacji muszę mieć do PCA i jaki stosunek liczby obserwacji do zmiennych jest bezpieczny?

Prosta, praktyczna zasada mówi o kilku–kilkunastu obserwacjach na jedną zmienną (np. 5–10). To nie jest sztywne prawo, ale przy takim stosunku wyniki PCA są zwykle stabilniejsze i mniej zależne od pojedynczych punktów odstających.

Jeśli masz podobną liczbę obserwacji i zmiennych (np. 30 obserwacji i 25 cech), PCA wciąż da się policzyć, ale każdy punkt mocno „ciągnie” składowe. W skrajnych przypadkach omicznych (kilka–kilkanaście próbek i tysiące zmiennych) PCA służy głównie do wizualizacji, a przed analizą często filtruje się cechy, np. zostawiając tylko te o największej wariancji.

Czy przed PCA w R muszę standaryzować zmienne i jak to zrobić?

Jeśli zmienne są w różnych jednostkach (np. zł, kilogramy, punkty w skali), standaryzacja jest praktycznie obowiązkowa. Bez niej składowe będą zdominowane przez zmienne o największej skali lub wariancji. W R najprościej użyć argumentu scale. = TRUE w funkcji prcomp() lub samemu przeskalować dane funkcją scale().

Wyjątkiem są sytuacje, gdy wszystkie zmienne są w tej samej skali i interesuje Cię właśnie „surowa” wariancja (np. kilka podobnych pomiarów tego samego zjawiska). W praktyce analitycznej większość PCA w R wykonuje się jednak na danych standaryzowanych.

Jak czytać wykres wyników (scores) z PCA w R – co oznaczają punkty?

Wykres wyników (scores plot) pokazuje obserwacje w przestrzeni składowych głównych, zwykle PC1 vs PC2. Każdy punkt to jedna obserwacja (np. klient, próbka, produkt) opisana już nie oryginalnymi zmiennymi, ale wartościami składowych. Odległości między punktami mówią, które obserwacje są do siebie podobne w sensie wszystkich użytych cech naraz.

Jeśli widzisz wyraźne skupiska, można je interpretować jako potencjalne grupy lub segmenty. Pojedyncze punkty daleko od reszty to kandydaci na obserwacje odstające. Dodatkowe kolorowanie punktów (np. według grupy klientów czy typu produktu) pomaga ocenić, czy te grupy rzeczywiście różnią się w wymiarach PC1/PC2.

Jak interpretować wykres ładunków (loadings) w PCA i co mi mówi biplot?

Ładunki (loadings) pokazują, jak bardzo i w jakim kierunku każda zmienna „ładuje się” na daną składową. Duże wartości bezwzględne oznaczają, że zmienna silnie wpływa na daną składową. Zmienne z podobnymi ładunkami na PC1 i PC2 są do siebie podobne, a przeciwne znaki wskazują na przeciwstawne zachowanie.

Biplot łączy wykres wyników i ładunków: punkty to obserwacje, strzałki – zmienne. Długi wektor zmiennej sugeruje silny związek z którymś kierunkiem w przestrzeni składowych. Jeśli jakaś grupa punktów leży w kierunku konkretnej strzałki, można to czytać jako „ta grupa ma zwykle wyższe wartości tej zmiennej (lub zestawu zmiennych)”.

Kiedy PCA nie poprawi wyników modelu i lepiej go używać tylko eksploracyjnie?

Redukcja wymiaru przez PCA nie jest gwarantowanym sposobem na lepszy model predykcyjny. Jeśli masz dużo obserwacji, rozsądną liczbę cech i brak poważnej współliniowości, PCA może wręcz pogorszyć interpretację modelu bez zysku na jakości predykcji. Składowe są abstrakcyjne, trudno je odnieść do zrozumiałych pojęć biznesowych czy naukowych.

PCA błyszczy przede wszystkim w eksploracji: do wizualizacji struktury danych, wstępnego wykrywania grup, oceny współliniowości. Dopiero gdy widać, że liczba zmiennych rzeczywiście „dusi” model (np. regresja niestabilna, bardzo mało obserwacji względem liczby cech), można świadomie spróbować modeli na składowych głównych i porównać je z prostszymi alternatywami, np. selekcją zmiennych opartą na wiedzy dziedzinowej.

Poprzedni artykułAnaliza wiarygodności skali w R: alfa Cronbacha, omega i interpretacja wyników
Jacek Zieliński
Jacek Zieliński łączy doświadczenie w analizie danych z podejściem inżynierskim: liczy się poprawność, przejrzystość i możliwość odtworzenia analizy. Na itplock.pl tłumaczy testy statystyczne bez nadmiaru teorii, ale z naciskiem na sens założeń i interpretację wielkości efektu. Przygotowuje tutoriale narzędziowe, w których krok po kroku prowadzi przez import, czyszczenie i wizualizację danych oraz weryfikację wyników. W tekstach jasno oddziela fakty od interpretacji i wskazuje, kiedy metoda nie pasuje do problemu.