Gire los componentes de PCA para igualar la varianza en cada componente

9

Estoy tratando de reducir la dimensionalidad y el ruido de un conjunto de datos al realizar PCA en el conjunto de datos y descartar las últimas PC. Después de eso, quiero usar algunos algoritmos de aprendizaje automático en las PC restantes y, por lo tanto, quiero normalizar los datos igualando la varianza de las PC para que los algoritmos funcionen mejor.

Una forma simple es simplemente normalizar la varianza a los valores unitarios. Sin embargo, la primera PC contiene más variaciones del conjunto de datos original que las siguientes, y todavía quiero darle más "peso". Por lo tanto, me preguntaba: ¿hay una manera simple de dividir su variación y compartirla con las PC con menos variaciones?

Otra forma es mapear las PC al espacio de características original, pero en ese caso la dimensionalidad también aumentaría al valor original.

Supongo que es mejor mantener las columnas resultantes ortogonales, pero no es necesario en este momento.

Feilong
fuente
1
No ... varimax maximiza la suma de las desviaciones cuadradas de las cargas, por lo que intenta hacerlas lo más desiguales posible. Además, ¿por qué quieres ecualizar los componentes? El objetivo es capturar tanta variación como sea posible en la menor cantidad de componentes posible.
2
¿Simplemente no le conviene estandarizar las puntuaciones de los componentes a las variaciones de unidades? ¿Porqué entonces? ¿Qué tipo de resultado desea? ¿Deberían las columnas resultantes no estar correlacionadas además de las variaciones iguales?
ttnphns
2
A partir de su descripción, se parece mucho a que quiere simplemente "esferas" de los datos (de dimensionalidad reducida). Con frecuencia se realiza como un paso de preprocesamiento en el aprendizaje automático. Para lograrlo, simplemente realiza PCA, elige algunos componentes y los estandariza. Supongo que es posible encontrar una rotación ortogonal (como varimax) que rote los componentes estandarizados de manera que no estén correlacionados pero expliquen exactamente la misma cantidad de varianza; esa es una pregunta interesante, tengo que pensarlo. Pero nunca he visto esto hecho, definitivamente no en el aprendizaje automático.
ameba
2
Por cierto, ¿cuáles son "algunos algoritmos de aprendizaje automático" que desea aplicar después de PCA? Esto puede ser relevante.
ameba
1
Tenga en cuenta que si gira sus PC estandarizadas, ¡las distancias no cambiarán en absoluto! Por lo tanto, realmente no debería importar ningún algoritmo posterior basado en la distancia.
ameba

Respuestas:

10

Para mí no está completamente claro que lo que está preguntando es lo que realmente necesita: un paso de preprocesamiento común en el aprendizaje automático es la reducción de dimensionalidad + blanqueamiento, lo que significa hacer PCA y estandarizar los componentes, nada más. Sin embargo, me centraré en su pregunta, ya que está formulada, porque es más interesante.


Sea la matriz de datos n × d centrada con puntos de datos en filas y variables en columnas. PCA equivale a la descomposición de valores singulares X = U S VU k S k V k , donde para realizar la reducción de dimensionalidad solo conservamos k componentes. Un "factor de rotación" ortogonal de estos componentes implica elegir una matriz ortogonal k × k R y conectarla a la descomposición: XU k S k VXn×re

X=USVUkSkVk,
kk×kRAquí
XUkSkVk=UkRRSkVk=norte-1UkRRotadopuntajes estandarizadosRSkVk/ /norte-1Cargas rotadas.
son componentes estandarizados rotados y el segundo término representa cargas rotadas transpuestas. La varianza de cada componente después de la rotación viene dada por la suma de cuadrados del vector de carga correspondiente; antes de la rotación es simplementes 2 i /(n-1). Después de la rotación es otra cosa.norte-1UkRsyo2/ /(norte-1)

Ahora estamos listos para formular el problema en términos matemáticos: dadas cargas no rotadas , encuentre la matriz de rotaciónRtal que las cargas rotadas,LR, tengan la misma suma de cuadrados en cada columna.L=VkSk/ /norte-1RLR

Vamos a resolverlo Las sumas de cuadrados de la columna después de la rotación son iguales a los elementos diagonales de Esto tiene sentido: la rotación simplemente redistribuye las variaciones de los componentes, que originalmente se dan pors 2 i /(n-1), entre ellos, de acuerdo con esta fórmula. Necesitamos redistribuirlos para que todos sean iguales a su valor promedioμ.

(LR)LR=RS2norte-1R.
syo2/ /(norte-1)μ

No creo que haya una solución de forma cerrada para esto, y de hecho hay muchas soluciones diferentes. Pero una solución se puede construir fácilmente de manera secuencial:

  1. Tome el primer componente y el componente -ésimo. El primero tiene la varianza σ max > μ y el último tiene la varianza σ min < μ .kσmax>μσmin<μ
  2. Gire solo estos dos de modo que la varianza del primero sea igual a . Matriz de rotación en 2D sólo depende de un parámetro θ y es fácil de escribir la ecuación y calcular la necesaria θ . De hecho, R 2D = ( cos θ sen θ - sin θ cos θ ) y después de la transformación, la primera PC obtendrá varianza cos 2 θ σ max + sin 2 θ σ min = cos 2 θ σμθθ
    R2D=(cosθpecadoθ-pecadoθcosθ)
    de donde obtenemos inmediatamente cos 2 θ = μ - σ min
    cos2θσmax+pecado2θσmin=cos2θσmax+(1-cos2θ)σmin=μ,
    cos2θ=μ-σminσmax-σmin.
  3. El primer componente ya está hecho, tiene una varianza .μ
  4. Continúe con el siguiente par, tomando el componente con la varianza más grande y el que tiene la varianza más pequeña. Ir a # 2.

Esto redistribuirá todas las variaciones por igual por una secuencia de rotaciones 2D. Multiplicar todas estas matrices de rotación juntas producirá la R general .(k-1)R


Ejemplo

Considere la siguiente matriz : ( 10 0 0 0 0 6 0 0 0 0 3 0 0 0 0 1 ) . La varianza media es 5 . Mi algoritmo procederá de la siguiente manera:S2/ /(norte-1)

(100 00 00 00 06 60 00 00 00 030 00 00 00 01).
5 5
  1. 5 51+(10-5 5)=6 6

  2. 53+(65)=4

  3. 54+(61)=5

  4. Hecho.

Escribí el script de Matlab que implementa este algoritmo (ver más abajo). Para esta matriz de entrada, la secuencia de ángulos de rotación es:

48.1897   35.2644   45.0000

Desviaciones de componentes después de cada paso (en filas):

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

La matriz de rotación final (producto de tres matrices de rotación 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

(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

Aquí está el código:

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

Aquí está el código en Python proporcionado por @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

kσi2k

ameba
fuente
Supongo que, para dos pares de componentes (sus puntajes), el ángulo de rotación sería de 45 grados, para igualar sus variaciones. Sin embargo, no puedo imaginar cómo hacer toda la tarea con más de 3 componentes emparejados sabiamente.
ttnphns
1
@feilong, creo que igualar la varianza de un par de componentes a la vez es un algoritmo muy subóptimo. Lo que sugerí es elegir las rotaciones de modo que la varianza de un componente se vuelva exactamente igual a la varianza media global. Entonces este componente está "listo", y uno puede ocuparse del resto. Esto garantiza igualar todas las variaciones en un número finito de pasos. Vea mi comentario anterior para un ejemplo.
ameba
1
@amoeba Tienes razón, esa es una mejor solución y debería terminar con n-1 pasos.
feilong
1
@amoeba He agregado mi implementación mínima usando Python. Modifiqué la parte multiplicando toda la matriz, ya que puede llevar mucho tiempo para matrices grandes.
feilong
1
@amoeba Específicamente para componentes principales, es posible ahorrar más tiempo al eliminar la pieza buscando el máximo y el mínimo. Simplemente podemos rotar los componentes primero y segundo (para hacer que el primer componente tenga una varianza promedio), y luego el segundo y el tercero, y así sucesivamente. Solo necesitamos asegurarnos de que la varianza total de cada par sea mayor que mu.
feilong
2

XYσmax2σmin2Xμ2Yσmax2+σmin2μ2

cosθ

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

pero no ha demostrado de dónde viene esta ecuación; Probablemente pensando que es obvio sin explicación. Obvio o no, creo que vale la pena dilucidar, de alguna manera. Mi respuesta se presenta de una manera.

XYθXxx

ilustración de la rotación

x Xx=xcosθxxxxyysinθ

X=X-(X-X)=Xcosθ-ypecadoθ

μ2X

μ2=X2=(Xcosθ-ypecadoθ)2=(X2cos2θ+y2pecado2θ-2Xycosθpecadoθ)=cos2θX2+pecado2θy2-2cosθpecadoθXy= 0 (X e Y no están correlacionados)=cos2θ(σmetrounaX2)+pecado2θ(σmetroyonorte2)

cosθ

ttnphns
fuente
2
(cosθpecadoθ-pecadoθcosθ)(σmax20 00 0σmin2)(cosθpecadoθ-pecadoθcosθ),
ameba
Y creo que su explicación geométrica y el cálculo "directo" (sin matrices) es más fácil de entender y muy útil para desarrollar las intuiciones correctas.
ameba
0

Si interpreto las cosas correctamente, quiere decir que el primer componente principal (valor propio) explica la mayor parte de la varianza en los datos. Esto puede suceder cuando su método de compresión es lineal. Sin embargo, puede haber dependencias no lineales en su espacio de características.

TL / DR: PCA es un método lineal. Use Autoencoders (pca no lineal) para la reducción de dimensionalidad. Si la parte de aprendizaje automático es aprendizaje supervisado, simplemente controle su función de pérdida mientras ajusta los parámetros (hiper) para el codificador automático. De esta manera, obtendrá una versión comprimida mucho mejor de sus datos originales.

Aquí hay un ejemplo de scikit donde hacen una búsqueda de cuadrícula para encontrar el número óptimo de componentes principales para mantener (hiperparámetro) usando PCA. Finalmente, aplican la Regresión logística en el espacio dimensional inferior: http://scikit-learn.org/stable/auto_examples/plot_digits_pipe.html#example-plot-digits-pipe-py

Protip: los codificadores automáticos no tienen una solución de forma cerrada (afaik), por lo que si su contexto está transmitiendo datos, esto significa que puede actualizar continuamente su codificador automático (representación comprimida) y, por lo tanto, puede compensar cosas como la deriva del concepto. Con pca, debe volver a entrenar el modo por lotes de vez en cuando a medida que ingresan nuevos datos.

En cuanto a dar algunas características más "peso", vea la regularización (comenzaría por las normas https://en.wikipedia.org/wiki/Norm_(mathematics) ). También te sorprenderá cuán similar es la regresión logística al perceptrón.

shuriken x azul
fuente
No veo cómo esto responde la pregunta del OP; su respuesta parece no estar relacionada con la pregunta.
ameba
Por lo tanto, me preguntaba: ¿hay una manera simple de dividir su variación y compartirla con las PC con menos variaciones? OP quiere hacer reducción de dimensionalidad. Ofrecí una alternativa para resolver su problema, ya que, en última instancia, lo que OP quiere no garantiza un mejor rendimiento a menos que se mida el rendimiento. Trabajar en espacios hilbert / espacios normados no garantiza mejores resultados. Medir el rendimiento conduce a mejores resultados.
shuriken x azul