PCA de la projection et de la reconstruction en scikit-learn
Je peux effectuer l'ACP, scikit par le code ci-dessous:
X_train a 279180 lignes et 104 colonnes.
from sklearn.decomposition import PCA
pca = PCA(n_components=30)
X_train_pca = pca.fit_transform(X_train)
Maintenant, quand je veux projeter les vecteurs propres sur la fonctionnalité de l'espace, je doit effectuer les opérations suivantes:
""" Projection """
comp = pca.components_ #30x104
com_tr = np.transpose(pca.components_) #104x30
proj = np.dot(X_train,com_tr) #279180x104 * 104x30 = 297180x30
Mais je suis hésitant à cette étape, parce que Scikit la documentation dit:
components_: array [n_components, n_features]
Axes principaux dans l'espace de la fonctionnalité, représentant les directions du maximum de la variance dans les données.
Il me semble que c'est déjà prévu, mais quand j'ai regardé le code source, il ne retourne que les vecteurs propres.
Quelle est la bonne façon de comment la projeter?
En fin de compte, je suis visant à calculer le MSE de la reconstruction.
""" Reconstruct """
recon = np.dot(proj,comp) #297180x30 * 30x104 = 279180x104
""" MSE Error """
print "MSE = %.6G" %(np.mean((X_train - recon)**2))
Vous devez vous connecter pour publier un commentaire.
Vous pouvez faire
De cette façon, vous n'avez pas à vous soucier de la façon de faire les multiplications.
Ce que vous obtenez après
pca.fit_transform
oupca.transform
sont ce qu'on appelle habituellement les "charges" pour chaque échantillon, signifiant la quantité de chaque composant dont vous avez besoin pour le mieux pour le décrire à l'aide d'une combinaison linéaire de lacomponents_
(les axes principaux en fonction de l'espace).La projection que vous visez est de retour dans le signal d'origine de l'espace. Cela signifie que vous devez aller dans le signal de l'espace en utilisant les composants et les chargements.
Donc, il y a trois étapes pour lever l'ambiguïté ici. Vous avez ici, étape par étape, ce que vous pouvez faire à l'aide de l'APC objet et comment il est effectivement calculé:
pca.fit
estimations les composants (à l'aide d'un SVD sur l'centrée Xtrain):pca.transform
calcule les charges que vous la décrivezpca.inverse_transform
obtient la projection sur les composantes du signal de l'espace qui vous intéresseVous pouvez maintenant évaluer la projection perte
pca.fit
pour calculer les composants, puis la projection peut être calculée parpca.fit_transform
(c'est aussi quand je veux continuer à travailler avec les données récupérer leur de certains, car la dimension est réduite). Et pour la reconstruction, j'appellepca.invert_transform
pour calculer MSE. Est-ce exact?pca.fit_transform(X)
donne le même résultat quepca.fit(X).transform(X)
(c'est une optimisation du raccourci). Deuxièmement, une projection est généralement quelque chose qui va d'un espace dans le même espace, alors voici ce que donnerait le signal de l'espace de signal de l'espace, avec la propriété que de l'appliquer deux fois, c'est comme de l'appliquer une fois. Ici, il seraitf= lambda X: pca.inverse_transform(pca.transform(X))
. Vous pouvez le vérifierf(f(X)) == f(X).
Donc, je dirais que la projection.pca.transform
est l'obtention de l'chargements. En fin de compte c'est juste terminolgypca.transform(X)
n'est la matrice de Mxk, où M est le nombre de lignes et de k nombre de composants sélectionnés. Je vais l'utiliser comme entrée pour les modèles (et je devrais attendre de meilleurs résultats que l'utilisation d'ensembles de données d'origine)from sklearn.pipeline import make_pipeline
puispipeline = make_pipeline(PCA(n_components=30), your_classifier)
et vous pouvez l'utiliser comme votre propre classificateur. Toutefois, notez qu'une projection est une opération définie mathématiquement et il peut être préférable de l'utiliser de cette façon pour éviter tout malentendu: en.wikipedia.org/wiki/Projection_%28linear_algebra%29assert_array_almost_equal(VT[:30], pca.components_)
n'est pas toujours vrai. Dans la mise en œuvre de l'APC, les signes sont bousculés entre U et V. Pour imiter ce brassage remplacerU, S, VT = np.linalg.svd(Xtrain - Xtrain.mean(0))
parU, S, VT = np.linalg.svd(Xtrain - Xtrain.mean(0), full_matrices=False)
et insérezfrom sklearn.utils.extmath import svd_flip
suivie parU, VT = svd_flip(U, VT)
.X_train
dansloss = ((X_train - X_projected) ** 2).mean()
remplacerXtrain
variable définie plus haut dans le code?Ajout sur @eickenberg post, voici comment faire de l'apc de reconstruction des chiffres' images: