Gire os componentes do PCA para equalizar a variação em cada componente

9

Estou tentando reduzir a dimensionalidade e o ruído de um conjunto de dados executando o PCA no conjunto de dados e jogando fora os últimos PCs. Depois disso, quero usar alguns algoritmos de aprendizado de máquina nos PCs restantes e, portanto, quero normalizar os dados equalizando a variação dos PCs para fazer com que os algoritmos funcionem melhor.

Uma maneira simples é simplesmente normalizar a variação para os valores unitários. No entanto, o primeiro PC contém mais variação do conjunto de dados original do que os seguintes, e ainda quero dar mais "peso" a ele. Por isso, fiquei pensando: existe uma maneira simples de dividir sua variação e compartilhá-la com os PCs com menos variações?

Outra maneira é mapear os PCs de volta ao espaço original, mas nesse caso a dimensionalidade também aumentaria para o valor original.

Eu acho que é melhor manter as colunas resultantes ortogonais, mas não é necessário neste momento.

feilong
fonte
11
Não ... o varimax maximiza a soma das variações quadradas das cargas, portanto, está tentando torná-las o mais desigual possível. Além disso, por que você deseja equalizar os componentes? O objetivo é capturar o máximo de variação possível no menor número possível de componentes.
2
Simplesmente padronizar as pontuações dos componentes para variações de unidade não combina com você? Porquê então? Que tipo de resultado você deseja - as colunas resultantes devem ser correlacionadas, além de variações iguais?
ttnphns
2
A partir da sua descrição, parece que você deseja simplesmente "esfera" os dados (de dimensionalidade reduzida). É frequentemente feito como uma etapa de pré-processamento no aprendizado de máquina. Para alcançá-lo, basta executar o PCA, escolher alguns componentes e padronizá-los. Eu acho que é possível encontrar uma rotação ortogonal (como o varimax) que gira componentes padronizados de forma que eles não sejam correlacionados, mas explicam exatamente a mesma quantidade de variação; essa é uma pergunta interessante, eu preciso pensar sobre isso. Mas nunca vi isso feito, definitivamente não no aprendizado de máquina.
Ameba
2
A propósito, quais são "alguns algoritmos de aprendizado de máquina" que você deseja aplicar após o PCA? Isso pode ser relevante.
Ameba
11
Observe que, se você girar seus PCs padronizados, as distâncias não mudarão! Portanto, isso realmente não deve importar para nenhum algoritmo subsequente baseado em distância.
Ameba

Respostas:

10

Não está totalmente claro para mim que o que você está perguntando é o que realmente precisa: uma etapa comum de pré-processamento no aprendizado de máquina é redução de dimensionalidade + clareamento, o que significa fazer PCA e padronizar os componentes, nada mais. No entanto, vou me concentrar na sua pergunta conforme ela é formulada, porque é mais interessante.


Seja a matriz de dados centralizada com pontos de dados em linhas e variáveis ​​em colunas. O PCA equivale a decomposição de valor singular onde executar a redução de dimensionalidade mantemos apenas componentes. Uma "rotação fatorial" ortogonal desses componentes implica escolher uma matriz ortogonal e conectá-lo à decomposição:Xn×d

X=USVUkSkVk,
kk×kR
XUkSkVk=UkRRSkVk=n1UkRRotatedstandardized scoresRSkVk/n1Rotated loadings.
Aqui são componentes padronizados rotacionados e o segundo termo representa cargas rotacionadas transpostas. A variação de cada componente após a rotação é dada pela soma dos quadrados do vetor de carregamento correspondente; antes da rotação é simplesmente . Após a rotação, é outra coisa.n1UkRsi2/(n1)

Agora, estamos prontos para formular o problema em termos matemáticos: considerando cargas não rotacionadas , encontre a matriz de rotação modo que as cargas rotadas, , possui soma igual de quadrados em cada coluna.L=VkSk/n1RLR

Vamos resolver isso. As somas de quadrados da coluna após a rotação são iguais aos elementos diagonais de Isso faz sentido: a rotação simplesmente redistribui as variações dos componentes, que são originalmente fornecidos por , entre eles, de acordo com esta fórmula. Precisamos redistribuí-los para que todos se tornem iguais ao seu valor médio .

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

Não acho que exista uma solução de formulário fechado para isso e, de fato, existem muitas soluções diferentes. Mas uma solução pode ser facilmente criada de maneira sequencial:

  1. Pegue o primeiro componente e o ésimo componente. O primeiro possui a variação e o último possui a variação .kσmax>μσmin<μ
  2. Gire apenas esses dois para que a variação do primeiro se torne igual a . A matriz de rotação em 2D depende apenas de um parâmetro e é fácil escrever a equação e calcular o necessário . De fato, e após a transformação, o primeiro PC terá variação do qual obtemos imediatamenteμθθ
    R2D=(cosθsinθsinθcosθ)
    cos2θσmax+sin2θσmin=cos2θσmax+(1cos2θ)σmin=μ,
    cos2θ=μσminσmaxσmin.
  3. O primeiro componente está pronto, possui variação .μ
  4. Prossiga para o próximo par, levando o componente com a maior variação e o componente com a menor variação. Vá para o 2.

Isso redistribuirá todas as variações igualmente por uma sequência de rotações 2D. A multiplicação de todas essas matrizes de rotação resultará no geral .(k1)R


Exemplo

Considere a seguinte matriz :A variação média é . Meu algoritmo continuará da seguinte maneira:S2/(n1)

(10000060000300001).
5
  1. Etapa 1: gire PC1 e PC4 para que PC1 obtenha variação . Como resultado, PC4 obtém a variação .51+(105)=6

  2. Etapa 2: gire PC2 (nova variação máxima) e PC3 para que PC2 obtenha a variação . Como resultado, PC3 obtém variação .53+(65)=4

  3. Etapa 3: gire PC4 (nova variação máxima) e PC3 para que o PC4 obtenha a variação . Como resultado, PC3 obtém variação .54+(61)=5

  4. Feito.

Eu escrevi o script Matlab que implementa esse algoritmo (veja abaixo). Para esta matriz de entrada, a sequência dos ângulos de rotação é:

48.1897   35.2644   45.0000

Desvios de componentes após cada etapa (em linhas):

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

A matriz de rotação final (produto de três matrizes de rotação 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

E a matriz final é:(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

Aqui está o 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

Aqui está o código em Python fornecido pelo @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

Observe que esse problema é completamente equivalente ao seguinte: considerando variáveis ​​não correlacionadas com variâncias , encontre uma rotação (isto é, uma nova base ortogonal) que produzirá variáveis ​​com variâncias iguais (mas é claro que não estão mais correlacionadas).kσi2k

ameba
fonte
Eu acho que, para quaisquer dois pares de componentes (suas pontuações), o ângulo de rotação seria de 45 graus, para igualar suas variações. No entanto, não consigo imaginar como executar toda a tarefa com mais de 3 componentes em pares.
ttnphns
11
@feilong, acho que equalizar a variação de um par de componentes por vez é um algoritmo muito abaixo do ideal. O que sugeri é escolher as rotações de modo que a variação de um componente se torne exatamente igual à variação média global. Então este componente está "pronto", e pode-se lidar com o resto. Isso garante a equalização de todas as variações em um número finito de etapas. Veja meu comentário anterior para um exemplo.
Ameba
11
@amoeba Você está certo, é uma solução melhor e deve terminar com as etapas n-1.
Feilong
11
@amoeba Adicionei minha implementação mínima usando Python. Modifiquei a peça multiplicando toda a matriz, pois isso pode levar tempo para matrizes grandes.
Feilong
11
@amoeba Especificamente para componentes principais, é possível economizar mais tempo removendo a peça que procura o máximo e o mínimo. Podemos simplesmente girar o 1º e o 2º componentes (para fazer com que o 1º componente tenha variação média), depois o 2º e o 3º, e assim por diante. Só precisamos garantir que a variação total de cada par seja maior que mu.
Feilong
2

Em sua resposta perspicaz e abrangente, @amoeba mostrou - como parte da resposta - como é possível girar duas variáveis ​​não correlacionadas (como componentes principais, por exemplo) para obter as variações desejadas para elas (embora às custas de perder a falta de correlação, é claro) . Permita que as variáveis ​​ortogonais e tenham variações (um maior) e (um menor), respectivamente. Gire-os para que obtenha uma variação arbitrária e reduzida (enquanto , consequentemente, se tornará na variação ).XYσmax2σmin2Xμ2Yσmax2+σmin2μ2

@amoeba mostra a fórmula a partir da qual podemos calcular o ângulo dessa rotação, :cosθ

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

mas não demonstrou de onde vem essa equação; provavelmente pensando que é óbvio sem explicação. Óbvio ou não, acredito que vale a pena elucidar - de alguma forma. Minha resposta apresenta uma maneira.

E assim, temos um elipsoidais, dados a nuvem centrada no espaço de variáveis não correlacionadas e . Temos que girar os eixos em ângulo . Um ponto de dados na nuvem (como mostrado como ponto verde na imagem) com a coordenada terá essa coordenada como após a rotação.XYθXxx

ilustração da rotação

Observe que a projeção da coordenada entalhe no eixo rotacionado é dada por (cateto como hipotenusa e ângulo entre eles). Observe também que é menor que pelo corte do comprimento calculável a partir da coordenada : (outro cateto e hipotenusa). E entao,x Xx=xcosθxxxxyysinθ

x=x(xx)=xcosθysinθ

Conhecemos (veja o início) as variações (ou soma de quadrados) das duas variáveis ​​e a variação (soma de quadrados) de . Então segue:μ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)

A partir da qual você estima , como @amoeba mostrou, e executa a rotação.cosθ

ttnphns
fonte
2
+1. Não achei que fosse óbvio (não é), mas achei que é fácil verificar :-) Também é possível mostrá-lo por álgebra direta, escrevendo (como na minha resposta) e calculando o elemento superior esquerdo do produto. É claro que esse é o mesmo raciocínio, apenas expresso de maneira diferente. Obrigado!
(cosθsinθsinθcosθ)(σmax200σmin2)(cosθsinθsinθcosθ),
Ameba
E eu acho que sua explicação geométrica e computação "direta" (sem matrizes) são mais fáceis de entender e muito úteis para desenvolver as intuições corretas.
Ameba
0

Se eu interpreto as coisas corretamente, você quer dizer que o primeiro componente do princípio (valor próprio) explica a maior parte da variação nos dados. Isso pode acontecer quando seu método de compactação é linear. No entanto, pode haver dependências não lineares no espaço de recursos.

TL / DR: PCA é um método linear. Use Autoencoders (pca não linear) para redução de dimensionalidade. Se a parte do aprendizado de máquina for supervisionada, basta monitorar sua função de perda enquanto ajusta os (hiper) parâmetros para o autoencoder. Dessa forma, você terá uma versão compactada muito melhor dos seus dados originais.

Aqui está um exemplo de scikit em que eles pesquisam em grade para encontrar o número ideal de componentes principais a serem mantidos (hiperparâmetro) usando o PCA. Finalmente, eles aplicam a regressão logística no espaço dimensional inferior: http://scikit-learn.org/stable/auto_examples/plot_digits_pipe.html#example-plot-digits-pipe-py

Protip: os codificadores automáticos não têm uma solução de formulário fechado (afaik); portanto, se o seu contexto estiver transmitindo dados, isso significa que você pode atualizar continuamente seu codificador automático (representação compactada) e, assim, compensar itens como desvio de conceito. Com o pca, você precisa treinar novamente o modo em lote de vez em quando à medida que novos dados são recebidos.

Quanto a dar a alguns recursos mais "peso", consulte a regularização (eu começaria a partir das normas https://en.wikipedia.org/wiki/Norm_(mathematics) ). Você também pode se surpreender com a regressão logística semelhante ao perceptron.

shuriken x blue
fonte
Não vejo como isso responde à pergunta do OP; sua resposta parece não ter relação com a pergunta.
Ameba
Por isso, fiquei pensando: existe uma maneira simples de dividir sua variação e compartilhá-la com os PCs com menos variações? O OP quer fazer redução de dimensionalidade. Ofereci uma alternativa para resolver o problema dele, pois, em última análise, o que o OP quer não garante um melhor desempenho, a menos que o desempenho seja medido. Trabalhar em espaços hilbert / espaços normatizados não garante melhores resultados. Medir o desempenho leva a melhores resultados.
shuriken x blue