Question

Mon code:

from numpy import *

def pca(orig_data):
    data = array(orig_data)
    data = (data - data.mean(axis=0)) / data.std(axis=0)
    u, s, v = linalg.svd(data)
    print s #should be s**2 instead!
    print v

def load_iris(path):
    lines = []
    with open(path) as input_file:
        lines = input_file.readlines()
    data = []
    for line in lines:
        cur_line = line.rstrip().split(',')
        cur_line = cur_line[:-1]
        cur_line = [float(elem) for elem in cur_line]
        data.append(array(cur_line))
    return array(data)

if __name__ == '__main__':
    data = load_iris('iris.data')
    pca(data)

Le jeu de données de l'iris: http: // archive. ics.uci.edu/ml/machine-learning-databases/iris/iris.data

Sortie:

[ 20.89551896  11.75513248   4.7013819    1.75816839]
[[ 0.52237162 -0.26335492  0.58125401  0.56561105]
 [-0.37231836 -0.92555649 -0.02109478 -0.06541577]
 [ 0.72101681 -0.24203288 -0.14089226 -0.6338014 ]
 [ 0.26199559 -0.12413481 -0.80115427  0.52354627]]

souhaité Sortie:
Les valeurs propres - [2.9108 0.9212 0.1474 0.0206]
Composants principaux - Same as I got but transposed donc je imagine bien I

En outre, ce qui est à la sortie de la fonction linalg.eig? Selon la description de l'APC sur wikipedia, je suis censé ceci:

cov_mat = cov(orig_data)
val, vec = linalg.eig(cov_mat)
print val

Mais il ne correspond pas vraiment à la sortie dans les didacticiels en ligne je trouve. De plus, si j'ai 4 dimensions, je pensais que je devrais avoir 4 valeurs propres et non 150 comme le EIG me donne. Ai-je fait quelque chose de mal?

modifier : Je l'ai remarqué que les valeurs diffèrent par 150, ce qui est le nombre d'éléments dans l'ensemble de données. En outre, les valeurs propres sont censés ajouter être égal au nombre de dimensions, dans ce cas, 4. Ce que je ne comprends pas pourquoi cette différence se passe. Si je simplement divisé par les valeurs propres len(data) je pouvais obtenir le résultat que je veux, mais je ne comprends pas pourquoi. De toute façon, la proportion des valeurs propres ne sont pas modifiés, mais ils sont importants pour moi, donc je voudrais comprendre ce qui se passe.

Était-ce utile?

La solution

Vous décomposé la mauvaise matrice.

analyse en composantes principales nécessite la manipulation des vecteurs propres / valeurs propres du matrice de covariance , et non les données elles-mêmes. La matrice de covariance, créé à partir d'un m x n matrice de données, sera une matrice m x m avec ceux le long de la diagonale principale.

Vous pouvez en effet utiliser le cov fonction, mais vous avez besoin de manipulation de vos données. Il est probablement un peu plus facile d'utiliser une fonction similaire, corrcoef :

import numpy as NP
import numpy.linalg as LA

# a simulated data set with 8 data points, each point having five features
data = NP.random.randint(0, 10, 40).reshape(8, 5)

# usually a good idea to mean center your data first:
data -= NP.mean(data, axis=0)

# calculate the covariance matrix 
C = NP.corrcoef(data, rowvar=0)
# returns an m x m matrix, or here a 5 x 5 matrix)

# now get the eigenvalues/eigenvectors of C:
eval, evec = LA.eig(C)

Pour obtenir les vecteurs propres / valeurs propres, je ne l'ai pas décomposons la matrice de covariance en utilisant SVD, cependant, vous pouvez certainement. Ma préférence est de les calculer en utilisant EIG (ou de SciPy) de NumPy Module LA - il est un peu plus facile à travailler que SVD , les valeurs de retour sont les vecteurs propres et eux-mêmes, et les valeurs propres rien d'autre. En revanche, comme vous le savez, SVD ne retourne pas ces ceux-ci directement.

Certes la fonction SVD se décompose une matrice quelconque, et pas seulement les carrés (auquel le EIG fonction est limitée); Mais lorsque vous faites PCA, vous aurez toujours une matrice carrée à se décomposer, quelle que soit la forme que vos données sont. Cela est évident parce que la matrice vous se décomposent en PCA est une covariance matrice , qui par définition est toujours carré (À savoir, les colonnes sont des points de données individuels de la matrice d'origine, de même pour les lignes, et chaque cellule est la covariance de ces deux points, comme le montre par les bas de la diagonale principale - un point de données donné a covariance parfaite avec lui-même)

.

Autres conseils

Les valeurs singulières SVD gauche renvoyées par (A) sont les vecteurs propres de AA ^ T.

La matrice de covariance d'un jeu de données A est: 1 / (N-1) * AA ^ T

Maintenant, quand vous faites PCA en utilisant le SVD, vous devez diviser chaque entrée dans votre matrice A par (N-1) de sorte que vous obtenez les valeurs propres de la covariance avec l'échelle.

Dans votre cas, N = 150 et vous n'avez pas fait cette division, d'où l'écart.

Ceci est expliqué en détail

(Pouvez-vous poser une question, s'il vous plaît? Ou au moins la liste à vos questions séparément. Votre message se lit comme un flux de conscience parce que vous ne demandez pas une seule question.)

  1. Vous avez probablement utilisé de manière incorrecte cov en ne transposant pas la matrice première. Si cov_mat est de 4 par 4, puis eig produira quatre et quatre valeurs propres vecteurs propres.

  2. Notez comment SVD et PCA, bien que liées, ne sont pas exactement les mêmes. Soit X une matrice 4 par 150 des observations où chaque colonne 4-élément est une simple observation. Ensuite, les suivantes sont équivalentes:

    a. les vecteurs singuliers gauche de X,

    b. les principales composantes de X,

    c. les vecteurs propres de X X ^ T.

    En outre, les valeurs propres de X X ^ T sont égaux au carré des valeurs singulières de X. Pour voir tout cela, laissez-X ont la SVD X = QSV ^ T, où S est une matrice diagonale de valeurs singulières. Puis examiner le eigendecomposition D = Q ^ T ^ T X X Q, où D est une matrice diagonale de valeurs propres. Remplacez X par son SVD, et voir ce qui se passe.

Licencié sous: CC-BY-SA avec attribution
Non affilié à StackOverflow
scroll top