Análise ponderada de componentes principais

17

Após algumas pesquisas, encontro muito pouco sobre a incorporação de pesos de observação / erros de medição na análise de componentes principais. O que eu acho tende a depender de abordagens iterativas para incluir ponderações (por exemplo, aqui ). Minha pergunta é por que essa abordagem é necessária? Por que não podemos usar os autovetores da matriz de covariância ponderada?

noname
fonte
1
Além das respostas abaixo, consulte o tópico stats.stackexchange.com/q/141754/3277 , em que o PCA ponderado (com pesos nas colunas e / ou linhas) é explicado como equivalente principalmente ao svd (generalizado) ponderado / biplot.
ttnphns

Respostas:

33

Depende do que exatamente seus pesos se aplicam.

Pesos de linha

Deixe ser a matriz de dados com variáveis em colunas e n observações x i em fileiras. Se cada observação tiver um peso associado, w iXnxiwi , é realmente fácil incorporar esses pesos no PCA.

Primeiro, é preciso calcular a média ponderada e subtrai-lo a partir dos dados, a fim decentrar-lo.μ=1wiwixi

Em seguida, calculamos a matriz de covariância ponderada , ondeW=diag(wi)é a matriz diagonal de pesos, e aplica o PCA padrão para analisá-lo.1wiXWXW=diag(wi)

Pesos de células

O artigo de Tamuz et al., 2013 , que você encontrou, considera um caso mais complicado quando pesos diferentes são aplicados a cada elemento da matriz de dados. Então, de fato, não há solução analítica e é preciso usar um método iterativo. Observe que, como reconhecido pelos autores, eles reinventaram a roda, pois tais pesos gerais certamente já foram considerados antes, por exemplo, em Gabriel e Zamir, 1979, aproximação mais baixa de matrizes por mínimos quadrados com qualquer escolha de pesos . Isso também foi discutido aqui .WEuj

Como observação adicional: se os pesos variam com as variáveis ​​e as observações, mas são simétricos, de modo que w i j = w j i , a solução analítica é possível novamente, ver Koren e Carmel, 2004, Robust Linear Dimensionality Reduction .WEujWEuj=WjEu

ameba diz Restabelecer Monica
fonte
Obrigado pelo esclarecimento. Você pode explicar por que nenhuma solução analítica é possível com pesos fora da diagonal? I é isso que eu estou ausente de ambos Tamuz et al 2013 e Gabriel e Zamir 1979.
noname
@noname: Não conheço essa prova e, além disso, não ficaria surpreso se não fosse conhecido. Geralmente, é bastante complicado provar que algo não é possível , em particular que algo não é possível analiticamente. A impossibilidade de trissecção de ângulos esperou sua prova por mais de 2000 anos ... (cont.)
ameba diz Reinstate Monica
3
Eu,jWEuj(XEuj-UMAEuj)2UMAq
ameba diz Restabelecer Monica
2
+1. A primeira seção da resposta pode ser conceituada também em termos de Biplot ponderado (generalizado), conforme descrito aqui . Tendo em mente que o PCA é um "caso específico de" Biplot (também relacionado à resposta alinhada).
ttnphns
@ttnphns: Depois que seu comentário e outro tópico foram fechados como duplicado, reli minha resposta e expandi a explicação de como lidar com pesos de linha. Acho que anteriormente não estava completamente correto ou pelo menos não estava completo porque não mencionei a centralização com uma média ponderada. Espero que faça mais sentido agora!
Ameba diz Reinstate Monica
5

Muito obrigado ameba pela compreensão sobre pesos de linha. Sei que isso não é stackoverflow, mas tive algumas dificuldades para encontrar uma implementação do PCA ponderado por linha com explicação e, como esse é um dos primeiros resultados ao pesquisar no PCA ponderado, achei que seria bom anexar minha solução , talvez possa ajudar outras pessoas na mesma situação. Nesse snippet de código Python2, um PCA ponderado com um kernel RBF como o descrito acima é usado para calcular as tangentes de um conjunto de dados 2D. Ficarei muito feliz em ouvir alguns comentários!

def weighted_pca_regression(x_vec, y_vec, weights):
    """
    Given three real-valued vectors of same length, corresponding to the coordinates
    and weight of a 2-dimensional dataset, this function outputs the angle in radians
    of the line that aligns with the (weighted) average and main linear component of
    the data. For that, first a weighted mean and covariance matrix are computed.
    Then u,e,v=svd(cov) is performed, and u * f(x)=0 is solved.
    """
    input_mat = np.stack([x_vec, y_vec])
    weights_sum = weights.sum()
    # Subtract (weighted) mean and compute (weighted) covariance matrix:
    mean_x, mean_y =  weights.dot(x_vec)/weights_sum, weights.dot(y_vec)/weights_sum
    centered_x, centered_y = x_vec-mean_x, y_vec-mean_y
    matrix_centered = np.stack([centered_x, centered_y])
    weighted_cov = matrix_centered.dot(np.diag(weights).dot(matrix_centered.T)) / weights_sum
    # We know that v rotates the data's main component onto the y=0 axis, and
    # that u rotates it back. Solving u.dot([x,0])=[x*u[0,0], x*u[1,0]] gives
    # f(x)=(u[1,0]/u[0,0])x as the reconstructed function.
    u,e,v = np.linalg.svd(weighted_cov)
    return np.arctan2(u[1,0], u[0,0]) # arctan more stable than dividing


# USAGE EXAMPLE:
# Define the kernel and make an ellipse to perform regression on:
rbf = lambda vec, stddev: np.exp(-0.5*np.power(vec/stddev, 2))
x_span = np.linspace(0, 2*np.pi, 31)+0.1
data_x = np.cos(x_span)[:-1]*20-1000
data_y = np.sin(x_span)[:-1]*10+5000
data_xy = np.stack([data_x, data_y])
stddev = 1 # a stddev of 1 in this context is highly local
for center in data_xy.T:
    # weight the  points based on their euclidean distance to the current center
    euclidean_distances = np.linalg.norm(data_xy.T-center, axis=1)
    weights = rbf(euclidean_distances, stddev)
    # get the angle for the regression in radians
    p_grad = weighted_pca_regression(data_x, data_y, weights)
    # plot for illustration purposes
    line_x = np.linspace(-5,5,10)
    line_y = np.tan(p_grad)*line_x
    plt.plot(line_x+center[0], line_y+center[1], c="r")
    plt.scatter(*data_xy)
    plt.show()

E uma amostra de saída (faz o mesmo para cada ponto): insira a descrição da imagem aqui

Cheers,
Andres

fr_andres SupportsMonicaCellio
fonte