Scipy PCA Ergebnisse identisch zu Matlab PCA

Wenn du dir nicht sicher bist, in welchem der anderen Foren du die Frage stellen sollst, dann bist du hier im Forum für allgemeine Fragen sicher richtig.
Antworten
thomas15
User
Beiträge: 98
Registriert: Montag 7. April 2008, 19:07

Hallo Pythonianer,

ich habe eine Frage die eventuell sehr speziell ist, aber lasst euch nicht abschrecken das hier durchzulesen.
Ich will herausfinden wie ich die PCA in scipy benutzen kann so dass ich identische Ergebnisse zu der Matlab PCA bekomme.
Wenn es irgendwo ein einfaches Beispiel gibt bitte weitergeben.

Hat da wer Erfahrungen?

Danke und ciao,
Thomas
Benutzeravatar
DrFaust
User
Beiträge: 21
Registriert: Freitag 15. Oktober 2010, 23:10

Die PCA beruht ja im wesentlich auf der Eigenwert-Analyse. Jetzt ist das Problem, dass Eigenvektoren eindeutig sind BIS AUF einen linearen Faktor. Folglich musst du die Eigenvektoren der CoVar-Matrix, die das Ergebnis der PCA sind, irgendwie in scipy und matlab normieren. Ich habe das letztens so gemacht, dass ich in beiden Sprachen jeden Eigenvektor auf Länge 1 normiert habe und dann noch dafür gesorgt, dass die erste Komponente des Vektors positiv ist.
Dann wäre es noch hilfreich in beiden Sprachen die Vektoren gleich zu sortieren. Anbietet tut sich hier die Größe des zugehörigen Eigenwertes zu verwenden. Genau genommen, sollten die schon nach Größe der Eigenwerte sortiert sein, du musst nur sicherstellen, dass die Richtung (aufsteigend/absteigend) die selbe ist.
thomas15
User
Beiträge: 98
Registriert: Montag 7. April 2008, 19:07

Hallo,
ich habe endlich wieder Zeit gefunden mich mit dem obigen Thema zu beschaeftigen.

Mittlerweile habe ich die pcacov funktion aus matlab in python nachgecoded.
Ich bin daran interessiert den code noch ein wenig zu 'optimieren'.

Kennt wer ein paar high level numpy befehle damit ich meine schleifen sparen kann? Der code ist der pcacov funktion aus Matlab nachempfunden und steht ebenfalls in dem funktions kommentar.

Jemand ideen wie man es schlanker machen koennte, sonst laufts konsitent zu den ergebnissen von matlab...

Danke!

Code: Alles auswählen

def pcacov(matrix):
    """
    function [coeff,latent,explained] = pcacov(v)
    [~,latent,coeff] = svd(v);
    latent = diag(latent);
    
    totalvar = sum(latent);
    explained = 100*latent/totalvar;
    
    % Enforce a sign convention on the coefficients -- the largest element in each
    % column will have a positive sign.
    [p,d] = size(coeff);
    
    [~,maxind] = max(abs(coeff),[],1);
    colsign = sign(coeff(maxind + (0:p:(d-1)*p)));
    coeff = bsxfun(@times,coeff,colsign);
    
    """
    from numpy import sum,max,diag
    from scipy.linalg import svd
    
    [x,latent,coeff] = svd(matrix)
    
    totalvar = sum(latent)
    
    explained = 100*latent / totalvar
    
    [p,d] = coeff.shape
    
    abscoeff = abs(coeff)
    
    for cols in xrange(p):
        abscoef = abscoeff[:,cols]
        coef = coeff[:,cols]

        index = 0
        currentValue = -1
        
        for i in xrange(d):
            if currentValue < abscoef[i]:
                index = i
                currentValue = currentValue
                
        if coef[index] >= 1:
            sign = 1 
        else:
            sign = -1
            
        coeff[:,cols] = coeff[:,cols] * sign
    
    return [coeff,latent,explained]
Antworten