Analyse des composantes principales pondérées

17

Après quelques recherches, je trouve très peu sur l'incorporation de poids d'observation / erreurs de mesure dans l'analyse des composants principaux. Ce que je trouve a tendance à s'appuyer sur des approches itératives pour inclure des pondérations (par exemple, ici ). Ma question est pourquoi cette approche est-elle nécessaire? Pourquoi ne pouvons-nous pas utiliser les vecteurs propres de la matrice de covariance pondérée?

sans nom
la source
1
En plus des réponses ci-dessous, veuillez consulter le fil stats.stackexchange.com/q/141754/3277 , où l'ACP pondérée (avec des pondérations sur les colonnes et / ou les lignes) est expliquée comme étant principalement équivalente à svd / pondérée (généralisée) biplot.
ttnphns

Réponses:

33

Cela dépend à quoi s'appliquent exactement vos poids.

Poids des rangées

Soit la matrice de données avec des variables dans les colonnes et n observations x i dans les lignes. Si chaque observation a un poids associé w i , il est en effet simple d'incorporer ces poids dans l'ACP.Xnxiwi

Tout d'abord, il faut calculer la moyenne pondérée et soustrayez-le des données afin de lecentrer.μ=1wiwixi

Ensuite, nous calculons la matrice de covariance pondérée , oùW=diag(wi)est la matrice diagonale des poids, et appliquer l'APC standard pour l'analyser.1wiXWXW=diag(wi)

Poids des cellules

L'article de Tamuz et al., 2013 , que vous avez trouvé, considère un cas plus compliqué lorsque différents poids sont appliqués à chaque élément de la matrice de données. Alors en effet il n'y a pas de solution analytique et il faut utiliser une méthode itérative. Notez que, comme l'ont reconnu les auteurs, ils ont réinventé la roue, car de tels poids généraux ont certainement été pris en compte auparavant, par exemple dans Gabriel et Zamir, 1979, Lower Rank Approximation of Matrices by Least Squares With Any Choice of Weights . Cela a également été discuté ici .wij

Comme remarque supplémentaire: si les poids varient à la fois avec les variables et les observations, mais sont symétriques, de sorte que w i j = w j i , alors la solution analytique est à nouveau possible, voir Koren et Carmel, 2004, Robust Linear Dimensionality Reduction Reduction .wjejwjej=wjje

amibe dit réintégrer Monica
la source
Merci pour la clarification. Pouvez-vous expliquer pourquoi aucune solution analytique n'est possible avec des poids hors diagonale? C'est ce qui me manque à la fois dans Tamuz et al 2013 et Gabriel et Zamir 1979.
noname
@noname: Je ne suis pas au courant d'une telle preuve, et d'ailleurs je ne serais pas surpris si elle n'était pas connue. Il est généralement assez difficile de prouver que quelque chose n'est pas possible , en particulier que quelque chose n'est pas possible analytiquement. L'impossibilité de la trisection d'angle a attendu sa preuve pendant plus de 2000 ans ... (suite)
amibe dit Reinstate Monica
3
@noname: (suite) Ce que vous demandez, c'est de montrer que le problème de la minimisation de par rapport à A contraint d'avoir un rang q faible . n'est pas réductible à un problème de vecteur propre. Je crains que vous n'ayez besoin d'un autre forum pour cela (peut-être mathoverflow?). Mais notez que la recherche de vecteurs propres n'est pas non plus exactement une solution analytique : c'est juste que les itérations sont généralement effectuées en silence par une fonction de bibliothèque standard. je,jwjej(Xjej-UNEjej)2UNEq
amoeba dit Réintègre Monica
2
+1. La première section de la réponse peut également être conceptualisée en termes de Biplot pondéré (généralisé) comme décrit ici . Gardant à l'esprit que l'APC est un "cas spécifique de" Biplot (également concerné dans la réponse lignée).
ttnphns
@ttnphns: Après que votre commentaire et un autre fil ont été fermés en double, j'ai relu ma réponse et développé l'explication de la façon de gérer les épaisseurs de ligne. Je pense qu'auparavant, ce n'était pas complètement correct ou du moins n'était pas complet parce que je n'ai pas mentionné le centrage avec une moyenne pondérée. J'espère que cela a plus de sens maintenant!
amibe dit Réintégrer Monica
5

Merci beaucoup amibe pour la compréhension des poids des rangées. Je sais que ce n'est pas un stackoverflow, mais j'ai eu quelques difficultés à trouver une implémentation de PCA pondérée par ligne avec explication et, puisque c'est l'un des premiers résultats lors de la recherche de PCA pondéré, j'ai pensé qu'il serait bon d'attacher ma solution , cela peut peut-être aider d'autres personnes dans la même situation. Dans cet extrait de code Python2, une PCA pondérée avec un noyau RBF comme celui décrit ci-dessus est utilisée pour calculer les tangentes d'un ensemble de données 2D. Je serai très heureux d'entendre des commentaires!

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()

Et un exemple de sortie (il fait de même pour chaque point): entrez la description de l'image ici

Santé,
Andres

fr_andres SupportsMonicaCellio
la source