Obtener valores propios y vectores de sklearn PCA

¿Cómo puedo obtener los valores propios y los vectores propios de la aplicación PCA?

from sklearn.decomposition import PCA clf=PCA(0.98,whiten=True) #converse 98% variance X_train=clf.fit_transform(X_train) X_test=clf.transform(X_test) 

No lo encuentro en los documentos .

1. No puedo “comprender” los diferentes resultados aquí.

Editar :

 def pca_code(data): #raw_implementation var_per=.98 data-=np.mean(data, axis=0) data/=np.std(data, axis=0) cov_mat=np.cov(data, rowvar=False) evals, evecs = np.linalg.eigh(cov_mat) idx = np.argsort(evals)[::-1] evecs = evecs[:,idx] evals = evals[idx] variance_retained=np.cumsum(evals)/np.sum(evals) index=np.argmax(variance_retained>=var_per) evecs = evecs[:,:index+1] reduced_data=np.dot(evecs.T, data.T).T print(evals) print("_"*30) print(evecs) print("_"*30) #using scipy package clf=PCA(var_per) X_train=data.T X_train=clf.fit_transform(X_train) print(clf.explained_variance_) print("_"*30) print(clf.components_) print("__"*30) 
  1. Deseo obtener todos los valores propios y vectores propios en lugar del conjunto reducido con la condición de convergencia.

Tu implementacion

Usted está calculando los vectores propios de la matriz de correlación , que es la matriz de covarianza de las variables normalizadas .
data/=np.std(data, axis=0) no es parte del PCA clásico, solo centramos las variables. Por lo tanto, la PCA de sklearn no ofrece escalar los datos de antemano .

Además, está en el camino correcto, si abstraemos el hecho de que el código que proporcionó no se ejecutó;). Sólo se confundió con los diseños de fila / columna. Sinceramente, creo que es mucho más fácil comenzar con X = data.T y trabajar solo con X a partir de ahí. Agregué tu código ‘arreglado’ al final de la publicación.

Obteniendo los valores propios

Ya clf.components_ que puedes obtener los vectores propios usando clf.components_ .

Así que tienes los componentes principales. Son vectores propios de la matriz de covarianza $ X ^ TX $.

Una forma de recuperar los valores propios desde allí es aplicar esta matriz a cada componente principal y proyectar los resultados en el componente. Sea v_1 el primer componente principal y lambda_1 el valor propio asociado. Tenemos:
eq y por lo tanto: eq2 ya que eq3 . (x, y) el producto escalar de los vectores x y y.

De vuelta en Python puedes hacer:

 n_samples = X.shape[0] # We center the data and compute the sample covariance matrix. X -= np.mean(X, axis=0) cov_matrix = np.dot(XT, X) / n_samples for eigenvector in pca.components_: print(np.dot(eigenvector.T, np.dot(cov_matrix, eigenvector))) 

Y obtienes el valor propio asociado con el vector propio. Bueno, en mis pruebas resultó que no funcionaba con los valores propios de la pareja, pero lo atribuyo a mi ausencia de habilidades en estabilidad numérica.

Ahora esa no es la mejor manera de obtener los valores propios, pero es bueno saber de dónde vienen.
Los valores propios representan la varianza en la dirección del vector propio. Así que puedes obtenerlos a través del atributo pca.explained_variance_ :

 eigenvalues = pca.explained_variance_ 

Aquí hay un ejemplo reproducible que imprime los valores propios que obtienes con cada método:

 import numpy as np from sklearn.decomposition import PCA from sklearn.datasets import make_classification X, y = make_classification(n_samples=1000) n_samples = X.shape[0] pca = PCA() X_transformed = pca.fit_transform(X) # We center the data and compute the sample covariance matrix. X_centered = X - np.mean(X, axis=0) cov_matrix = np.dot(X_centered.T, X_centered) / n_samples eigenvalues = pca.explained_variance_ for eigenvalue, eigenvector in zip(eigenvalues, pca.components_): print(np.dot(eigenvector.T, np.dot(cov_matrix, eigenvector))) print(eigenvalue) 

Su código original, fijo

Si lo ejecutas verás que los valores son consistentes. No son exactamente iguales porque numpy y scikit-learn no están utilizando el mismo algoritmo aquí.
Lo principal era que estaba usando una matriz de correlación en lugar de covarianza, como se mencionó anteriormente. También obtuviste los vectores propios transpuestos de numpy lo que lo hizo muy confuso.

 import numpy as np from scipy.stats.mstats import zscore from sklearn.decomposition import PCA def pca_code(data): #raw_implementation var_per=.98 data-=np.mean(data, axis=0) # data/=np.std(data, axis=0) cov_mat=np.cov(data, rowvar=False) evals, evecs = np.linalg.eigh(cov_mat) idx = np.argsort(evals)[::-1] evecs = evecs[:,idx] evals = evals[idx] variance_retained=np.cumsum(evals)/np.sum(evals) index=np.argmax(variance_retained>=var_per) evecs = evecs[:,:index+1] reduced_data=np.dot(evecs.T, data.T).T print("evals", evals) print("_"*30) print(evecs.T[1, :]) print("_"*30) #using scipy package clf=PCA(var_per) X_train=data X_train=clf.fit_transform(X_train) print(clf.explained_variance_) print("_"*30) print(clf.components_[1,:]) print("__"*30) 

Espero que esto ayude, no dude en pedir aclaraciones.