web-dev-qa-db-fra.com

Matlab - Analyse PCA et reconstruction de données multidimensionnelles

J'ai un grand ensemble de données de données multidimensionnelles (132 dimensions).

Je suis un débutant dans l'exploration de données et je souhaite appliquer l'analyse des composants principaux en utilisant Matlab. Cependant, j'ai vu qu'il y a beaucoup de fonctions expliquées sur le web mais je ne comprends pas comment les appliquer.

Fondamentalement, je souhaite appliquer l'ACP et obtenir les vecteurs propres et leurs valeurs propres correspondantes à partir de mes données.

Après cette étape, je veux pouvoir faire une reconstruction de mes données basée sur une sélection des vecteurs propres obtenus.

Je peux le faire manuellement, mais je me demandais s'il existe des fonctions prédéfinies qui peuvent le faire car elles devraient déjà être optimisées.

Mes données initiales sont quelque chose comme: size(x) = [33800 132]. Donc, fondamentalement, j'ai 132 caractéristiques (dimensions) et 33800 points de données. Et je veux effectuer PCA sur cet ensemble de données.

Toute aide ou indice ferait l'affaire.

19
Simon

Voici une procédure pas à pas rapide. Nous créons d'abord une matrice de vos variables cachées (ou "facteurs"). Il compte 100 observations et il existe deux facteurs indépendants.

>> factors = randn(100, 2);

Créez maintenant une matrice de charges. Cela va mapper les variables cachées sur vos variables observées. Disons que vos variables observées ont quatre caractéristiques. Votre matrice de charges doit alors être 4 x 2

>> loadings = [
      1   0
      0   1
      1   1
      1  -1   ];

Cela vous indique que les premières charges variables observées sur le premier facteur, les secondes charges sur le deuxième facteur, les troisièmes charges variables sur la somme des facteurs et les quatrièmes charges variables sur la différence des facteurs.

Créez maintenant vos observations:

>> observations = factors * loadings' + 0.1 * randn(100,4);

J'ai ajouté une petite quantité de bruit aléatoire pour simuler une erreur expérimentale. Maintenant, nous effectuons le PCA en utilisant la fonction pca de la boîte à outils stats:

>> [coeff, score, latent, tsquared, explained, mu] = pca(observations);

La variable score est le tableau des scores des composants principaux. Celles-ci seront orthogonales par construction, que vous pouvez vérifier -

>> corr(score)
ans =
    1.0000    0.0000    0.0000    0.0000
    0.0000    1.0000    0.0000    0.0000
    0.0000    0.0000    1.0000    0.0000
    0.0000    0.0000    0.0000    1.0000

La combinaison score * coeff' reproduira la version centrée de vos observations. La moyenne mu est soustraite avant d'effectuer l'ACP. Pour reproduire vos observations originales, vous devez les rajouter,

>> reconstructed = score * coeff' + repmat(mu, 100, 1);
>> sum((observations - reconstructed).^2)
ans =
   1.0e-27 *
    0.0311    0.0104    0.0440    0.3378

Pour obtenir une approximation de vos données d'origine, vous pouvez commencer à supprimer des colonnes des composants principaux calculés. Pour avoir une idée des colonnes à supprimer, nous examinons la variable explained

>> explained
explained =
   58.0639
   41.6302
    0.1693
    0.1366

Les entrées vous indiquent quel pourcentage de la variance est expliqué par chacune des principales composantes. On voit bien que les deux premières composantes sont plus significatives que les deux secondes (elles expliquent plus de 99% de la variance entre elles). L'utilisation des deux premières composantes pour reconstruire les observations donne l'approximation de rang 2,

>> approximationRank2 = score(:,1:2) * coeff(:,1:2)' + repmat(mu, 100, 1);

Nous pouvons maintenant essayer de tracer:

>> for k = 1:4
       subplot(2, 2, k);
       hold on;
       grid on
       plot(approximationRank2(:, k), observations(:, k), 'x');
       plot([-4 4], [-4 4]);
       xlim([-4 4]);
       ylim([-4 4]);
       title(sprintf('Variable %d', k));
   end

enter image description here

Nous obtenons une reproduction presque parfaite des observations originales. Si nous voulions une approximation plus grossière, nous pourrions simplement utiliser le premier composant principal:

>> approximationRank1 = score(:,1) * coeff(:,1)' + repmat(mu, 100, 1);

et l'intrigue,

>> for k = 1:4
       subplot(2, 2, k);
       hold on;
       grid on
       plot(approximationRank1(:, k), observations(:, k), 'x');
       plot([-4 4], [-4 4]);
       xlim([-4 4]);
       ylim([-4 4]);
       title(sprintf('Variable %d', k));
   end

enter image description here

Cette fois, la reconstruction n'est pas si bonne. C'est parce que nous avons délibérément construit nos données pour avoir deux facteurs, et nous ne les reconstruisons qu'à partir de l'un d'eux.

Notez que malgré la similitude suggestive entre la façon dont nous avons construit les données originales et leur reproduction,

>> observations  = factors * loadings'  +  0.1 * randn(100,4);
>> reconstructed = score   * coeff'     +  repmat(mu, 100, 1);

il n'y a pas nécessairement de correspondance entre factors et score, ou entre loadings et coeff. L'algorithme PCA ne sait rien de la façon dont vos données sont construites - il essaie simplement d'expliquer autant de la variance totale que possible avec chaque composant successif.


L'utilisateur @Mari a demandé dans les commentaires comment elle pouvait tracer l'erreur de reconstruction en fonction du nombre de composants principaux. L'utilisation de la variable explained ci-dessus est assez simple. Je vais générer des données avec une structure factorielle plus intéressante pour illustrer l'effet -

>> factors = randn(100, 20);
>> loadings = chol(corr(factors * triu(ones(20))))';
>> observations = factors * loadings' + 0.1 * randn(100, 20);

Maintenant, toutes les observations se chargent d'un facteur commun significatif, avec d'autres facteurs d'importance décroissante. On peut obtenir la décomposition PCA comme avant

>> [coeff, score, latent, tsquared, explained, mu] = pca(observations);

et tracer le pourcentage de la variance expliquée comme suit,

>> cumexplained = cumsum(explained);
   cumunexplained = 100 - cumexplained;
   plot(1:20, cumunexplained, 'x-');
   grid on;
   xlabel('Number of factors');
   ylabel('Unexplained variance')

enter image description here

48
Chris Taylor

Vous avez une assez bonne boîte à outils de réduction de dimensionnalité sur http://homepage.tudelft.nl/19j49/Matlab_Toolbox_for_Dimensionality_Reduction.html Outre PCA, cette boîte à outils possède de nombreux autres algorithmes pour la réduction de dimensionnalité.

Exemple de réalisation de PCA:

Reduced = compute_mapping(Features, 'PCA', NumberOfDimension);
6
Luka