2012-10-02 10 views
15

Ho un grande dataset di dati multidimensionali (132 dimensioni).Matlab - Analisi PCA e ricostruzione di dati multidimensionali

Sono un principiante nello sviluppo di data mining e voglio applicare Principal Components Analysis usando Matlab. Tuttavia, ho visto che ci sono molte funzioni spiegate sul web ma non capisco come dovrebbero essere applicate.

Fondamentalmente, voglio applicare PCA e ottenere gli autovettori ei relativi autovalori dai miei dati.

Dopo questo passaggio, vorrei essere in grado di eseguire una ricostruzione dei miei dati sulla base di una selezione degli autovettori ottenuti.

Posso farlo manualmente, ma mi chiedevo se ci sono funzioni predefinite che possono farlo perché dovrebbero già essere ottimizzate.

I miei dati iniziali sono qualcosa come: size(x) = [33800 132]. Quindi in pratica ho le caratteristiche (dimensioni) di 132 e i punti di dati 33800. E voglio eseguire PCA su questo set di dati.

Qualsiasi aiuto o suggerimento farebbe.

risposta

41

Ecco una breve panoramica. Per prima cosa creiamo una matrice delle tue variabili nascoste (o "fattori"). Ha 100 osservazioni e ci sono due fattori indipendenti.

>> factors = randn(100, 2); 

Ora creare una matrice di caricamenti. Questo sta per mappare le variabili nascoste sulle tue variabili osservate. Supponi che le tue variabili osservate abbiano quattro caratteristiche. Allora la vostra matrice carichi deve essere 4 x 2

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

che ti dice che i primi carichi variabili osservato sul primo fattore, il secondo carichi sul secondo fattore, il terzo carichi variabili sulla somma di fattori e la quarta variabile carichi sulla differenza dei fattori.

Ora creare le tue osservazioni:

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

ho aggiunto una piccola quantità di rumore casuale per simulare errore sperimentale. Ora eseguiamo l'APC utilizzando la funzione di pca dal statistiche strumenti:

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

La variabile score è la matrice di punteggi principali componenti. Questi saranno ortogonali da costruzione, che è possibile controllare -

>> 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 combinazione score * coeff' riprodurrà la versione centrato delle vostre osservazioni. La media mu viene sottratta prima di eseguire PCA. Per riprodurre le vostre osservazioni originali è necessario aggiungere di nuovo in,

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

per ottenere un'approssimazione i dati originali, è possibile avviare l'eliminazione di colonne dai componenti principali calcolate.Per avere un'idea di quali colonne a goccia, esaminiamo i explained variabili

>> explained 
explained = 
    58.0639 
    41.6302 
    0.1693 
    0.1366 

Le voci indicano la percentuale di varianza si spiega con ciascuno dei componenti principali. Possiamo vedere chiaramente che le prime due componenti sono più significative delle seconde due (spiegano oltre il 99% della varianza tra loro). Utilizzando le prime due componenti di ricostruire le osservazioni dà il rango-2 approssimazione,

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

Ora possiamo provare tracciando:

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

otteniamo una riproduzione quasi perfetta dell'originale osservazioni. Se volessimo un'approssimazione grossolana, potremmo utilizzare la prima componente principale:

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

e tracciare esso,

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

Questa volta la ricostruzione non è così buono. Questo perché abbiamo deliberatamente costruito i nostri dati per avere due fattori, e lo stiamo solo ricostruendo da uno di essi.

nota che, nonostante la suggestiva somiglianza tra il modo abbiamo costruito i dati originali e la sua riproduzione,

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

non v'è necessariamente una corrispondenza tra factors e score, o tra loadings e coeff. L'algoritmo PCA non sa nulla del modo in cui i dati sono costruiti: cerca semplicemente di spiegare la varianza totale che può con ogni componente successivo.


utente @Mari chiesto nei commenti come poteva tracciare l'errore di ricostruzione in funzione del numero di componenti principali. Utilizzando la variabile explained sopra questo è abbastanza facile. Io generare un po 'di dati con una struttura fattore più interessante per illustrare l'effetto -

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

Ora tutte le osservazioni carico su un significativo fattore comune, con altri fattori di importanza decrescente. Siamo in grado di ottenere la decomposizione PCA come prima

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

e tracciare la percentuale di varianza spiegata come segue,

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

enter image description here

+0

davvero grande risposta, volevo solo ringraziarvi. –

+0

Risposta stupenda. Grazie Chris! – rayryeng

+0

Ottimo da imparare. Grazie mille. Però, ho un piccolo dubbio, perché abbiamo bisogno di creare variabili nascoste in un primo momento? Posso iniziare con '[w pc ev] = princomp (X);' per analizzare i miei dati originali? Grazie ancora. – Mari

Problemi correlati