[MoodOfTheSong] 9. Obracanie przestrzeni – PCA

W tym poście opiszę jedną z ciekawszych technik pomagających zarówno przygotować dane do klasyfikatora jak i do wizualizacji – analizę głównych składowych, znaną pod angielską nazwą Principal Component Analysis, lub w skrócie: PCA.

Definicja

Zacytuję Wikipedię ponieważ autor artykułu o PCA, w bardzo prosty i zrozumiały sposób opisał przedmiot tego wpisu:

Celem PCA jest taki obrót układu współrzędnych, aby maksymalizować w pierwszej kolejności wariancję pierwszej współrzędnej, następnie wariancję drugiej współrzędnej, itd..

Prosty przykład

Definicja definicją, ale nic nie działa na wyobraźnie tak jak dobry i kolorowy wykres. A więc do dzieła!

Wyobraźmy sobie zbiór danych składający się 50 obserwacji (próbek), z których każda ma dwie cechy, lub – inaczej mówiąc – dwa wymiary. Oto te dane:

Policzmy wariancję obu wymiarów. Po znormalizowaniu (obie wariancje podzieliłem przez ich sumę) otrzymujemy następujące wyniki:

  • x: 0.53536428163543992
  • y: 0.46463571836456014

Krótko mówiąc, zmienność na osi x i zmienność na osi y jest niemal taka sama. Mimo wszystko widzimy ciekawą zależność w danych – wszystkie punkty oscylują wokół „przekątnej” wykresu. Można się więc zastanowić czy nie dało by się tak obrócić ten wykres, aby dane oscylowały wokół osi x i właśnie jej wariancja była największa.

Otóż właśnie do tego służy PCA! Zobaczcie, oto te same dane po PCA:

Jak widać, nie jest to zwykły obrót, ale nieco bardziej skomplikowane przekształcenie, w wyniku którego wariancja pierwszego wymiaru została zmaksymalizowana przy zachowaniu wszystkich informacji. Oto jej wartości po znormalizowaniu:

  • x: 0.91031711
  • y: 0.08968289

Czyli na chłopski rozum: na osi x mamy 91% zmienności danych.

Co nam to dało?

Gdybyśmy teraz po prostu pominęli drugi wymiar, tzn. uznali, że współrzędna igrekowa każdego punktu to 0, stracilibyśmy mniej danych niż gdybyśmy zrobili to przed PCA. Brzmi pięknie, ale jakie to ma praktyczne zastosowania? Po co pomijać jakikolwiek wymiar? Czytajcie dalej!

Przykład (prawie) rzeczywisty

Wyobraźmy sobie, że tworzymy system rozpoznawania cyfr. Dostajemy plik JPEG z cyfrą i program ma zgadnąć co to za cyfra. Dla uproszczenia niech rozpoznaje tylko 0, 1 oraz 2.

Przygotowałem zbiór danych: 40 obrazów zawierających cyfrę 0, 40 z cyfrą 1 i 40 z dwójką. Wszystkie w formacie *.jpg oraz rozdzielczości 7 na 7 pikseli.

Oto kilka z nich:

Jak widzicie, są czarno-białe. Oznacza to, że każdy piksel ma wartość jasności albo 0 albo 255. Jako, że ich wymiary to 7 na 7 pikseli, możemy każdą próbkę potraktować jako punkt w 49-cio wymiarowej przestrzeni. Jego współrzędne to na ogół wektor zawierający liczbę 255 na kilku miejscach oraz zera na pozostałych.

Uwaga! W praktyce rzadko zdarzają się tak idealne warunki, że projektujemy system, który coś rozpoznaje i mamy gwarancję, że dane zawsze będą w formie 49-wymiarowego wektora. W prawdziwym życiu cyfry byłyby różnokolorowymi plikami w przeróżnych rozdzielczościach i formatach, musielibyśmy więc je sprowadzić do wspólnej formy.

Spróbujmy narysować te punkty. Oczywiście nie jestem w stanie wstawić tutaj obrazka przedstawiającego 120 punktów w 49-cio wymiarowej przestrzeni, ale spróbuję użyć następującej sztuczki: sprawdzę które trzy z 49 wymiarów mają największą wariancję i – ignorując pozostałe wymiary – narysuję wykres trójwymiarowy.

Oto wynik tego eksperymentu. Jak się można spodziewać, wygląda to bardzo biednie i zupełnie nie widać tego, że punkty reprezentujące różne cyfry mają różne kolory… bo po prostu mamy wiele punktów w jednym miejscu:

Dobra, teraz czas na PCA. Przekształcamy cały nasz zbiór danych i ponownie – wybieramy 3 współrzędne o największej wariancji i robimy wykres ignorując pozostałe. Spójrzmy na ten wykres pod trzema różnymi kątami:

Myślę, że wyraźnie widać, że punkty reprezentujące poszczególne cyfry zbierają się blisko siebie, w takie chmurki ^^

Jak widzicie więc, PCA, bardzo ułatwia wizualizację: możemy przekształcić przestrzeń o wielu wymiarach w taki sposób, że już na trójwymiarowym wykresie wyraźnie widać różnice pomiędzy klasami do których należą nasze obserwację.

Analiza głównych składowych jest też przydatna podczas przygotowania danych do klasyfikatora – ograniczenie liczby wymiarów (być może aż tak agresywne jak ograniczanie ich do trzech) poprzez usuwanie tych nieistotnych może wpłynąć na zwiększenie jakości klasyfikacji.

Pokażę jeszcze dwa ciekawe wykresy przedstawiające wariancję kolejnego wymiaru (na osi x numer wymiaru, na osi y wariancja). To, że punkty są połączone (wykres jest ciągły) jest oczywiście bardzo nieprofesjonalne, nie róbcie takich rzeczy w publikacjach naukowych i sprawozdaniach studenckich.

Przed PCA:

Po PCA (zwróćcie uwagę na skalę):

Python

Pakiet sklearn zawiera implementację algorytmu PCA. Jeśli więc chcemy go użyć, wystarczy napisać:

from sklearn.decomposition import PCA

A samej transformacji dokonujemy tak:

pca = PCA(n_components=3) # liczba docelowych wymiarów
pca.fit(all_digits)
for digit in digits:
  digit_transformed = pca.transform(digit)

gdzie: all_digits to zbiór wszystkich wektorów 49-elementowych – dla cyfr 0, 1 oraz 2, digits to lista cyfr, a digit to lista próbek dla każdej cyfry.

MoodOfTheSong

Zamierzam tą technikę wykorzystać w projekcie MoodOfTheSong, którego rozwój opisują na tym blogu. Na podstawię każdego nagrania będę obliczał kilka cech, a następnie stosował PCA oraz obcinał liczbę wymiarów do trzech aby ułatwić sobie wizualizację. Poza tym, kiedy już dojdę do etapu klasyfikatora, sprawdzę jak liczba wymiarów wpływa na jego skuteczność.