Obracaj komponenty PCA, aby wyrównać wariancję w każdym komponencie

9

Staram się zmniejszyć wymiarowość i hałas zestawu danych, wykonując PCA na zbiorze danych i wyrzucając kilka ostatnich komputerów. Następnie chcę użyć niektórych algorytmów uczenia maszynowego na pozostałych komputerach, dlatego chcę znormalizować dane, wyrównując wariancję komputerów, aby algorytmy działały lepiej.

Jednym prostym sposobem jest po prostu znormalizowanie wariancji wartości jednostkowych. Jednak pierwszy komputer zawiera więcej wariancji w stosunku do oryginalnego zestawu danych niż kolejne, a ja nadal chcę nadać mu większą „wagę”. Dlatego zastanawiałem się: czy istnieje prosty sposób, aby po prostu podzielić jego wariancję i udostępnić ją komputerom z mniejszymi wariancjami?

Innym sposobem jest odwzorowanie komputerów PC z powrotem do pierwotnej przestrzeni funkcji, ale w takim przypadku wymiar również by wzrósł do pierwotnej wartości.

Wydaje mi się, że lepiej jest zachować wynikowe kolumny prostopadłe, ale w tej chwili nie jest to konieczne.

feilong
źródło
1
Nie ... varimax maksymalizuje sumę kwadratowych wariancji obciążeń, więc stara się, aby były jak najbardziej nierówne . Ponadto, dlaczego chcesz wyrównać komponenty? Chodzi o to, aby uchwycić jak najwięcej zmian w jak najmniejszej liczbie komponentów.
2
Czy zwykłe ujednolicenie ocen składowych do wariancji jednostek nie jest dla Ciebie odpowiednie? Dlaczego więc? Jakiego wyniku chcesz - czy powstałe kolumny powinny być nieskorelowane oprócz równych wariancji?
ttnphns
2
Z twojego opisu wygląda to tak, jakbyś chciał po prostu „sferować” dane (o zmniejszonej wymiarowości). Często odbywa się to jako etap wstępnego przetwarzania w uczeniu maszynowym. Aby to osiągnąć, wystarczy wykonać PCA, wybrać niektóre komponenty i ujednolicić je. Wydaje mi się, że możliwe jest znalezienie ortogonalnego obrotu (takiego jak varimax), który obraca znormalizowane komponenty w taki sposób, że pozostają one nieskorelowane, ale wyjaśniają dokładnie tę samą wielkość wariancji; to ciekawe pytanie, muszę o tym pomyśleć. Ale nigdy tego nie widziałem, na pewno nie w uczeniu maszynowym.
ameba
2
Nawiasem mówiąc, jakie „algorytmy uczenia maszynowego” chcesz zastosować po PCA? To może być istotne.
ameba
1
Pamiętaj, że jeśli obrócisz standardowe komputery, odległości w ogóle się nie zmienią! Naprawdę nie powinno to mieć znaczenia dla żadnego kolejnego algorytmu opartego na odległości.
ameba

Odpowiedzi:

10

Nie jest dla mnie do końca jasne, że to, o co pytasz, jest tym, czego naprawdę potrzebujesz: wspólnym krokiem wstępnego przetwarzania w uczeniu maszynowym jest redukcja wymiarów + wybielanie, co oznacza robienie PCA i standaryzację komponentów, nic więcej. Niemniej jednak skupię się na twoim pytaniu w formie, w jakiej zostało sformułowane, ponieważ jest bardziej interesujące.


Niech będzie wyśrodkowaną macierzą danych z punktami danych w wierszach i zmiennymi w kolumnach. PCA równa się rozkładowi liczby pojedynczej gdzie do wykonania zmniejszenia wymiarów trzymamy tylko komponentów. Ortogonalna „rotacja czynnikowa” tych składników oznacza wybranie ortogonalnej macierzy macierzy i podłączenie jej do rozkładu:Xn×d

X=USVUkSkVk,
kk×kR
XUkSkVk=UkRRSkVk=n1UkRRotatedstandardized scoresRSkVk/n1Rotated loadings.
Tutaj są obróconymi znormalizowanymi komponentami, a drugi termin oznacza obrócone obciążenia obrócone. Wariancja każdego składnika po obrocie jest dana przez sumę kwadratów odpowiedniego wektora obciążenia; przed obrotem jest to po prostu . Po rotacji jest to coś innego.n1UkRsi2/(n1)

Teraz jesteśmy gotowi sformułować problem w kategoriach matematycznych: biorąc pod uwagę , znajdź macierz obrotu tak, że obrócone ładunki , ma równą sumę kwadratów w każdej kolumnie.L=VkSk/n1RLR

Rozwiążmy to. Sumy kolumn kwadratów po obrocie są równe elementom ukośnym Ma to sens: obrót po prostu redystrybuuje wariancje składników, które pierwotnie podano przez , między nimi, zgodnie z tym wzorem. Musimy je redystrybuować, aby wszystkie stały się równe ich średniej wartości .

(LR)LR=RS2n1R.
si2/(n1)μ

Nie sądzę, aby istniało rozwiązanie w formie zamkniętej, a tak naprawdę istnieje wiele różnych rozwiązań. Ale rozwiązanie można łatwo zbudować sekwencyjnie:

  1. Weź pierwszy składnik i ty składnik. Pierwszy ma wariancję a ostatni ma wariancję .kσmax>μσmin<μ
  2. Obróć tylko te dwa, aby wariancja pierwszego stała się równa . Macierz rotacji w 2D zależy tylko od jednego parametru i łatwo jest zapisać równanie i obliczyć niezbędną . Rzeczywiście, a po transformacji pierwszy komputer otrzyma wariancję z którego natychmiast otrzymujemyμθθ
    R2D=(cosθsinθsinθcosθ)
    cos2θσmax+sin2θσmin=cos2θσmax+(1cos2θ)σmin=μ,
    cos2θ=μσminσmaxσmin.
  3. Pierwszy komponent jest już gotowy, ma wariancję .μ
  4. Przejdź do następnej pary, biorąc komponent o największej wariancji i ten o najmniejszej wariancji. Idź do 2.

Spowoduje to równomierne rozłożenie wszystkich wariancji przez sekwencję obrotów 2D. Mnożenie macierzy rotacji wszystkie te wspólnie uzyskując całkowitą .(k1)R


Przykład

Rozważ następującą :Średnia wariancja wynosi . Mój algorytm będzie działał w następujący sposób:S2/(n1)

(10000060000300001).
5
  1. Krok 1: Obróć PC1 i PC4, aby PC1 otrzymało wariancję . W rezultacie PC4 dostaje wariancję .51+(105)=6

  2. Krok 2: obróć PC2 (nowa maksymalna wariancja) i PC3, aby PC2 otrzymało wariancję . W rezultacie PC3 otrzymuje wariancję .53+(65)=4

  3. Krok 3: obróć PC4 (nowa maksymalna wariancja) i PC3, aby PC4 otrzymało wariancję . W rezultacie PC3 otrzymuje wariancję .54+(61)=5

  4. Gotowy.

Napisałem skrypt Matlab, który implementuje ten algorytm (patrz poniżej). Dla tej macierzy wejściowej sekwencja kątów obrotu wynosi:

48.1897   35.2644   45.0000

Warianty komponentów po każdym kroku (w rzędach):

10     6     3     1
 5     6     3     6
 5     5     4     6
 5     5     5     5

Ostateczna macierz obrotu (iloczyn trzech macierzy obrotu 2D):

 0.6667         0    0.5270    0.5270
      0    0.8165    0.4082   -0.4082
      0   -0.5774    0.5774   -0.5774
-0.7454         0    0.4714    0.4714

I ostatnia to:(LR)LR

5.0000         0    3.1623    3.1623
     0    5.0000    1.0000   -1.0000
3.1623    1.0000    5.0000    1.0000
3.1623   -1.0000    1.0000    5.0000

Oto kod:

S = diag([10 6 3 1]);
mu = mean(diag(S));
R = eye(size(S));

vars(1,:) = diag(S);
Supdated = S;

for i = 1:size(S,1)-1
    [~, maxV] = max(diag(Supdated));
    [~, minV] = min(diag(Supdated));

    w = (mu-Supdated(minV,minV))/(Supdated(maxV,maxV)-Supdated(minV,minV));
    cosTheta = sqrt(w);
    sinTheta = sqrt(1-w);

    R2d = eye(size(S));
    R2d([maxV minV], [maxV minV]) = [cosTheta sinTheta; -sinTheta cosTheta];
    R = R * R2d;

    Supdated = transpose(R2d) * Supdated * R2d;    

    vars(i+1,:) = diag(Supdated);
    angles(i) = acosd(cosTheta);
end

angles                %// sequence of 2d rotation angles
round(vars)           %// component variances on each step
R                     %// final rotation matrix
transpose(R)*S*R      %// final S matrix

Oto kod w Pythonie dostarczony przez @feilong:

def amoeba_rotation(s2):
    """
    Parameters
    ----------
    s2 : array
        The diagonal of the matrix S^2.

    Returns
    -------
    R : array
        The rotation matrix R.

    Examples
    --------
    >>> amoeba_rotation(np.array([10, 6, 3, 1]))
    [[ 0.66666667  0.          0.52704628  0.52704628]
     [ 0.          0.81649658  0.40824829 -0.40824829]
     [ 0.         -0.57735027  0.57735027 -0.57735027]
     [-0.74535599  0.          0.47140452  0.47140452]]

    http://stats.stackexchange.com/a/177555/87414
    """
    n = len(s2)
    mu = s2.mean()
    R = np.eye(n)
    for i in range(n-1):
        max_v, min_v = np.argmax(s2), np.argmin(s2)
        w = (mu - s2[min_v]) / (s2[max_v] - s2[min_v])
        cos_theta, sin_theta = np.sqrt(w), np.sqrt(1-w)
        R[:, [max_v, min_v]] = np.dot(
            R[:, [max_v, min_v]],
            np.array([[cos_theta, sin_theta], [-sin_theta, cos_theta]]))
        s2[[max_v, min_v]] = [mu, s2[max_v] + s2[min_v] - mu]
    return R

Zauważ, że ten problem jest całkowicie równoważny z następującym: biorąc pod uwagę zmiennych nieskorelowanych z wariancjami , znajdź obrót (tj. Nową podstawę ortogonalną), który da zmiennych o równych wariancjach (ale oczywiście już nieskorelowanych).kσi2k

ameba
źródło
Wydaje mi się, że dla dowolnych dwóch par składników (ich wyników) kąt obrotu wyniósłby 45 stopni, aby wyrównać ich wariancje. Nie mogę sobie jednak wyobrazić, jak wykonać całe zadanie z komponentami 3+ parami.
ttnphns,
1
@feilong, myślę, że wyrównywanie wariancji pary elementów jednocześnie jest bardzo nieoptymalnym algorytmem. Sugerowałem, aby wybrać takie obroty, aby wariancja jednego składnika stała się dokładnie równa globalnej średniej wariancji. Następnie ten komponent jest „gotowy” i można sobie poradzić z resztą. Gwarantuje to wyrównanie wszystkich wariancji w skończonej liczbie kroków. Zobacz mój poprzedni komentarz jako przykład.
ameba
1
@amoeba Masz rację, to lepsze rozwiązanie i powinno zakończyć się krokami n-1.
feilong
1
@amoeba Dodałem moją minimalną implementację za pomocą Pythona. Zmodyfikowałem część mnożąc całą macierz, ponieważ może to być czasochłonne w przypadku dużych matryc.
feilong
1
@amoeba Specjalnie dla głównych elementów można zaoszczędzić więcej czasu, usuwając część szukając maksimum i minimum. Możemy po prostu obrócić 1. i 2. komponent (aby pierwszy komponent miał średnią wariancję), a następnie 2. i 3. itd. Musimy tylko upewnić się, że całkowita wariancja każdej pary jest większa niż mu.
feilong
2

W swojej szczegółowej i wyczerpującej odpowiedzi @amoeba pokazał - jako część odpowiedzi - w jaki sposób można obrócić dwie nieskorelowane zmienne (takie jak na przykład główne składniki), aby uzyskać dla nich pożądane wariancje (oczywiście kosztem utraty nieskorelacji) . Niech zmienne ortogonalne i mają odpowiednio wariancje (większy) i (mniejszy). Obróć je, aby uzyskał dowolną, zmniejszoną wariancję (podczas gdy w konsekwencji stanie się wariancją ).XYσmax2σmin2Xμ2Yσmax2+σmin2μ2

@amoeba pokazuje wzór, na podstawie którego możemy obliczyć kąt takiego obrotu, :cosθ

μ2=cos2θ(σmax2)+sin2θ(σmin2)

ale nie wykazał, skąd pochodzi to równanie; prawdopodobnie myśląc, że to oczywiste bez wyjaśnienia. Oczywiste czy nie, uważam, że warto to w jakiś sposób wyjaśnić. Moja odpowiedź przedstawia jeden sposób.

I tak, mamy elipsoidalne, koncentrujące danych chmura w przestrzeni zmiennych nieskorelowanych i . Musimy obrócić osie o kąt . Punkt danych w chmurze (taki jak zielony punkt na zdjęciu) o współrzędnej będzie miał tę współrzędną jako po obrocie.XYθXxx

ilustracja obrotu

Zauważ, że rzut współrzędnej wycięcie na obróconą oś jest dana przez (cathetus jako przeciwprostokątna i kąt między nimi). Zauważ też, że jest mniejsze niż o wycięcie długości obliczalne ze współrzędnej : (inny katefus i przeciwprostokątna). A więc,x Xx=xcosθxxxxyysinθ

x=x(xx)=xcosθysinθ

Znamy (patrz początek) wariancje (lub sumy kwadratów) dwóch zmiennych i wariancję (suma kwadratów) z . Potem następuje:μ2X

μ2=x2=(xcosθysinθ)2=(x2cos2θ+y2sin2θ2xycosθsinθ)=cos2θx2+sin2θy22cosθsinθxy=0 (X and Y are uncorrelated)=cos2θ(σmax2)+sin2θ(σmin2)

Z którego szacujesz , jak pokazano @amoeba, i wykonuj obrót.cosθ

ttnphns
źródło
2
+1. Nie sądziłem, że to oczywiste (nie jest), ale raczej pomyślałem, że łatwo to zweryfikować :-) Można to również pokazać za pomocą algebry bezpośredniej, zapisując (jak w mojej odpowiedzi) i obliczenie lewego górnego elementu produktu. To oczywiście to samo rozumowanie, po prostu wyrażone inaczej. Dzięki!
(cosθsinθsinθcosθ)(σmax200σmin2)(cosθsinθsinθcosθ),
ameba
Myślę też, że twoje geometryczne objaśnienie i „bezpośrednie” obliczenia (bez macierzy) są łatwiejsze do zrozumienia i bardzo pomocne w rozwijaniu właściwych intuicji.
ameba
0

Jeśli interpretuję wszystko poprawnie, masz na myśli to, że pierwszy składnik podstawowy (wartość własna) wyjaśnia większość wariancji danych. Może się to zdarzyć, gdy metoda kompresji jest liniowa. Jednak w przestrzeni obiektów mogą występować zależności nieliniowe .

TL / DR: PCA jest metodą liniową. Użyj Autoencoderów (nieliniowe PCA) do zmniejszenia wymiarów. Jeśli część uczenia maszynowego jest uczeniem nadzorowanym, po prostu monitoruj swoją funkcję utraty, jednocześnie dostosowując (hiper) parametry dla autoencodera. W ten sposób uzyskasz znacznie lepiej skompresowaną wersję oryginalnych danych.

Oto przykład scikit, w którym przeprowadzają wyszukiwanie siatki w celu znalezienia optymalnej liczby głównych składników, które należy zachować (hiperparametr) za pomocą PCA. Na koniec stosują regresję logistyczną w dolnej przestrzeni wymiarowej: http://scikit-learn.org/stable/auto_examples/plot_digits_pipe.html#example-plot-digits-pipe-py

Protip: Autoencodery nie mają zamkniętego formularza (afaik), więc jeśli twój kontekst przesyła strumieniowo dane, oznacza to, że możesz ciągle aktualizować autoencoder (skompresowana reprezentacja), a tym samym może kompensować takie rzeczy, jak dryf koncepcji. Dzięki PCA musisz od czasu do czasu ponownie trenować tryb wsadowy, gdy pojawiają się nowe dane.

Jeśli chodzi o nadawanie niektórym funkcjom większej „wagi”, zobacz regularyzację (zacznę od norm https://en.wikipedia.org/wiki/Norm_(mathematics) ). Możesz być również zaskoczony, jak podobna jest regresja logistyczna do perceptronu.

shuriken x niebieski
źródło
Nie widzę odpowiedzi na pytanie PO; twoja odpowiedź wydaje się być całkowicie niezwiązana z pytaniem.
ameba
Dlatego zastanawiałem się: czy istnieje prosty sposób, aby po prostu podzielić jego wariancję i udostępnić ją komputerom z mniejszymi wariancjami? OP chce zmniejszyć wymiarowość. Zaproponowałem alternatywę rozwiązania jego problemu, ponieważ ostatecznie to, czego chce OP, nie gwarantuje lepszej wydajności, chyba że zostanie zmierzona. Praca w przestrzeniach Hilberta / przestrzeniach normowanych nie gwarantuje lepszych wyników. Pomiar wydajności prowadzi do lepszych wyników.
shuriken x blue