Drehen Sie die PCA-Komponenten, um die Varianz in jeder Komponente auszugleichen

9

Ich versuche, die Dimensionalität und das Rauschen eines Datensatzes zu reduzieren, indem ich eine PCA für den Datensatz durchführe und die letzten PCs wegwerfe. Danach möchte ich einige Algorithmen für maschinelles Lernen auf den verbleibenden PCs verwenden und daher die Daten normalisieren, indem ich die Varianz der PCs anpasse, damit die Algorithmen besser funktionieren.

Eine einfache Möglichkeit besteht darin, die Varianz einfach auf Einheitswerte zu normalisieren. Der erste PC enthält jedoch mehr Abweichungen vom ursprünglichen Datensatz als die folgenden, und ich möchte ihm immer noch mehr "Gewicht" geben. Deshalb habe ich mich gefragt: Gibt es eine einfache Möglichkeit, die Varianz einfach aufzuteilen und mit weniger Abweichungen an die PCs weiterzugeben?

Eine andere Möglichkeit besteht darin, die PCs wieder dem ursprünglichen Merkmalsraum zuzuordnen. In diesem Fall würde sich jedoch auch die Dimensionalität auf den ursprünglichen Wert erhöhen.

Ich denke, es ist besser, die resultierenden Spalten orthogonal zu halten, aber es ist im Moment nicht notwendig.

Feilong
quelle
1
Nein ... varimax maximiert die Summe der quadratischen Varianzen der Ladungen und versucht, sie so ungleich wie möglich zu machen . Warum sollten Sie die Komponenten ausgleichen wollen? Der springende Punkt ist, so viele Variationen wie möglich in so wenigen Komponenten wie möglich zu erfassen.
2
Passt es Ihnen nicht, die Komponentenwerte einfach auf Einheitenabweichungen zu standardisieren? Warum dann? Was für ein Ergebnis möchten Sie - sollten die resultierenden Spalten zusätzlich zu gleichen Varianzen nicht korreliert sein?
ttnphns
2
Aus Ihrer Beschreibung geht hervor, dass Sie die Daten (mit reduzierter Dimensionalität) einfach "kugeln" möchten. Dies wird häufig als Vorverarbeitungsschritt beim maschinellen Lernen durchgeführt. Um dies zu erreichen, führen Sie einfach eine PCA durch, wählen einige Komponenten aus und standardisieren sie. Ich denke, es ist möglich, eine orthogonale Drehung (wie Varimax) zu finden, die standardisierte Komponenten so dreht, dass sie nicht korreliert bleiben, aber genau das gleiche Maß an Varianz erklären. Das ist eine interessante Frage, ich muss darüber nachdenken. Aber ich habe das noch nie gesehen, definitiv nicht beim maschinellen Lernen.
Amöbe
2
Was sind übrigens "einige Algorithmen für maschinelles Lernen", die Sie nach PCA anwenden möchten? Dies könnte relevant sein.
Amöbe
1
Beachten Sie, dass sich die Entfernungen beim Drehen Ihrer standardisierten PCs überhaupt nicht ändern! Es sollte also für keinen nachfolgenden entfernungsbasierten Algorithmus von Bedeutung sein.
Amöbe

Antworten:

10

Mir ist nicht ganz klar, dass Sie fragen, was Sie wirklich brauchen: Ein üblicher Vorverarbeitungsschritt beim maschinellen Lernen ist die Reduzierung der Dimensionalität + das Aufhellen, was bedeutet, PCA durchzuführen und die Komponenten zu standardisieren, sonst nichts. Aber ich werde mich trotzdem auf Ihre Frage konzentrieren, wie sie formuliert ist, weil sie interessanter ist.


Sei die zentrierte n × d- Datenmatrix mit Datenpunkten in Zeilen und Variablen in Spalten. PCA beträgt Singulärwertzergliederung X = U S VU k S k V k , wo die Dimensionsreduktion halten wir nur auszuführen k Komponenten. Eine orthogonale "Faktorrotation" dieser Komponenten impliziert die Auswahl einer orthogonalen k × k- Matrix R und deren Einfügung in die Zerlegung: XU k S k V.X.n×d

X.=U.S.V.U.kS.kV.k,
kk×kR.Hier
X.U.kS.kV.k=U.kR.R.S.kV.k=n- -1U.kR.Gedrehtstandardisierte ScoresR.S.kV.k/.n- -1Gedrehte Ladungen.
sind gedrehte standardisierte Komponenten und der zweite Term repräsentiert gedrehte gedrehte Belastungen. Die Varianz jeder Komponente nach der Drehung ist durch die Summe der Quadrate des entsprechenden Ladevektors gegeben; vor der Drehung ist es einfachs 2 i /(n-1). Nach der Rotation ist es etwas anderes.n- -1U.kR.sich2/.(n- -1)

Jetzt sind wir bereit, das Problem in mathematischen Begriffen zu formulieren: gegebene nicht gedrehte Belastungen , finde die RotationsmatrixRso, dass die gedrehten LadungenLRin jeder Spalte die gleiche Quadratsumme haben.L.=V.kS.k/.n- -1R.L.R.

Lass es uns lösen. Spaltenquadratsummen nach der Drehung sind gleich den diagonalen Elementen von Dies ist sinnvoll: Durch Rotation werden einfach die Varianzen von Komponenten, die ursprünglich durchs 2 i /(n-1) gegebensind, gemäß dieser Formel zwischen ihnen neu verteilt. Wir müssen sie so umverteilen, dass sie alle gleich ihrem Durchschnittswertμ werden.

(L.R.)L.R.=R.S.2n- -1R..
sich2/.(n- -1)μ

Ich glaube nicht, dass es dafür eine geschlossene Lösung gibt, und tatsächlich gibt es viele verschiedene Lösungen. Eine Lösung kann jedoch leicht sequentiell erstellt werden:

  1. Nehmen Sie die erste Komponente und die te Komponente. Der erste hat die Varianz σ max > μ und der letzte hat die Varianz σ min < μ .kσmax>μσMindest<μ
  2. Drehen Sie nur diese beiden so, dass die Varianz der ersten gleich . Die Rotationsmatrix in 2D hängt nur von einem Parameter θ ab, und es ist einfach, die Gleichung aufzuschreiben und das erforderliche θ zu berechnen . Tatsächlich R 2D = ( cos θ sin θ - sin θ cos θ ) und nach der Transformation der erste PC erhalten Varianz cos 2 θ & sgr; max + sin 2 θ & sgr; min = cos 2 θ & sgr;μθθ
    R.2D=(cosθSündeθ- -Sündeθcosθ)
    woraus wir sofort cos 2 θ = μ - σ min erhalten
    cos2θσmax+Sünde2θσMindest=cos2θσmax+(1- -cos2θ)σMindest=μ,
    cos2θ=μσminσmaxσmin.
  3. Die erste Komponente ist nun fertig, sie hat die Varianz .μ
  4. Fahren Sie mit dem nächsten Paar fort und nehmen Sie die Komponente mit der größten Varianz und die mit der kleinsten Varianz. Gehe zu # 2.

(k1)R.


Beispiel

S2/(n1)

(10000060000300001).
5
  1. 51+(10- -5)=6

  2. 53+(6- -5)=4

  3. 54+(6- -1)=5

  4. Getan.

Ich habe das Matlab-Skript geschrieben, das diesen Algorithmus implementiert (siehe unten). Für diese Eingabematrix lautet die Folge der Drehwinkel:

48.1897   35.2644   45.0000

Komponentenabweichungen nach jedem Schritt (in Zeilen):

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

Die endgültige Rotationsmatrix (Produkt aus drei 2D-Rotationsmatrizen):

 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

(L.R.)L.R.

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

Hier ist der Code:

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

Hier ist der Code in Python, der von @feilong bereitgestellt wird:

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

kσich2k

Amöbe
quelle
Ich denke, für zwei beliebige Komponentenpaare (ihre Punktzahlen) würde der Drehwinkel 45 Grad betragen, um ihre Varianzen auszugleichen. Ich kann mir jedoch nicht vorstellen, wie ich die ganze Aufgabe mit mehr als 3 Komponenten paarweise erledigen soll.
ttnphns
1
@feilong, ich denke, das Ausgleichen der Varianz eines Komponentenpaares zu einem Zeitpunkt ist ein sehr suboptimaler Algorithmus. Was ich vorgeschlagen habe, ist, die Rotationen so zu wählen, dass die Varianz einer Komponente genau gleich der globalen mittleren Varianz wird. Dann ist diese Komponente "fertig" und man kann sich um den Rest kümmern. Dies garantiert, dass alle Abweichungen in einer endlichen Anzahl von Schritten ausgeglichen werden. Ein Beispiel finden Sie in meinem vorherigen Kommentar.
Amöbe
1
@amoeba Du hast recht, das ist eine bessere Lösung und sollte mit n-1 Schritten enden.
Feilong
1
@amoeba Ich habe meine minimale Implementierung mit Python hinzugefügt. Ich habe den Teil modifiziert, der die gesamte Matrix multipliziert, da dies für große Matrizen zeitaufwändig sein kann.
Feilong
1
@amoeba Speziell für Hauptkomponenten ist es möglich, mehr Zeit zu sparen, indem das Teil entfernt wird, das nach dem Maximum und Minimum sucht. Wir können einfach die 1. und 2. Komponente drehen (damit die 1. Komponente eine durchschnittliche Varianz aufweist), dann die 2. und 3. und so weiter. Wir müssen nur sicherstellen, dass die Gesamtvarianz jedes Paares größer als ist mu.
Feilong
2

X.Y.σmeinx2σmichn2X.μ2Y.σmeinx2+σmichn2- -μ2

cosθ

μ2=cos2θ(σmeinx2)+Sünde2θ(σmichn2)

hat aber nicht gezeigt, woher diese Gleichung kommt; wahrscheinlich denken, dass es ohne Erklärung offensichtlich ist. Offensichtlich oder nicht, ich glaube, es lohnt sich zu erklären - irgendwie. Meine Antwort zeigt einen Weg.

X.Y.θX.xx

Darstellung der Rotation

x X.x'=xcosθxx'x'- -xyySündeθ

x=x'- -(x'- -x)=xcosθ- -ySündeθ

μ2X.

μ2=x2=(xcosθ- -ySündeθ)2=(x2cos2θ+y2Sünde2θ- -2xycosθSündeθ)=cos2θx2+Sünde2θy2- -2cosθSündeθxy= 0 (X und Y sind nicht korreliert)=cos2θ(σmeinx2)+Sünde2θ(σmichn2)

cosθ

ttnphns
quelle
2
(cosθSündeθ- -Sündeθcosθ)(σmax200σMindest2)(cosθSündeθ- -Sündeθcosθ),
Amöbe
Und ich denke, dass Ihre geometrische Erklärung und "direkte" Berechnung (ohne Matrizen) einfacher zu verstehen und sehr hilfreich ist, um die richtigen Intuitionen zu entwickeln.
Amöbe
0

Wenn ich die Dinge richtig interpretiere, meinen Sie, dass die erste Hauptkomponente (Eigenwert) den größten Teil der Varianz in den Daten erklärt. Dies kann passieren, wenn Ihre Komprimierungsmethode linear ist. Möglicherweise gibt es jedoch nichtlineare Abhängigkeiten in Ihrem Feature-Space.

TL / DR: PCA ist eine lineare Methode. Verwenden Sie Autoencoder (nichtlineare pca) zur Reduzierung der Dimensionalität. Wenn der Teil des maschinellen Lernens überwacht wird, überwachen Sie einfach Ihre Verlustfunktion, während Sie die (Hyper-) Parameter für den Autoencoder anpassen. Auf diese Weise erhalten Sie eine weitaus besser komprimierte Version Ihrer Originaldaten.

Hier ist ein Scikit-Beispiel, in dem sie eine Rastersuche durchführen, um die optimale Anzahl von Hauptkomponenten zu finden, die mithilfe von PCA beibehalten werden sollen (Hyperparameter). Schließlich wenden sie die logistische Regression auf den unteren Dimensionsraum an: http://scikit-learn.org/stable/auto_examples/plot_digits_pipe.html#example-plot-digits-pipe-py

Protip: Autoencoder haben keine Closed-Form-Lösung (afaik). Wenn Ihr Kontext also Daten überträgt, können Sie Ihren Autoencoder kontinuierlich aktualisieren (komprimierte Darstellung) und so Dinge wie Konzeptdrift kompensieren. Mit pca müssen Sie den Batch-Modus von Zeit zu Zeit neu trainieren, wenn neue Daten eingehen.

Informationen zum "Gewicht" einiger Funktionen finden Sie unter Regularisierung (ich gehe von den Normen https://en.wikipedia.org/wiki/Norm_(mathematics aus ). Sie könnten auch überrascht sein, wie ähnlich die logistische Regression dem Perzeptron ist.

shuriken x blau
quelle
Ich sehe nicht, wie dies die Frage des OP beantwortet; Ihre Antwort scheint völlig unabhängig von der Frage zu sein.
Amöbe
Deshalb habe ich mich gefragt: Gibt es eine einfache Möglichkeit, die Varianz einfach aufzuteilen und mit weniger Abweichungen an die PCs weiterzugeben? OP möchte die Dimensionalität reduzieren. Ich habe eine Alternative angeboten, um sein Problem zu lösen, da das, was OP will, letztendlich nicht zu einer besseren Leistung führt, wenn die Leistung nicht gemessen wird. Arbeiten in hilbert-Räumen / normierten Räumen garantiert keine besseren Ergebnisse. Das Messen der Leistung führt zu besseren Ergebnissen.
Shuriken x blau