J'essaie de comprendre comment reproduire en Python certains travaux que j'ai faits en SAS. En utilisant cet ensemble de données , où la multicollinéarité est un problème, je voudrais effectuer une analyse des composants principaux en Python. J'ai regardé scikit-learn et les modèles de statistiques, mais je ne sais pas comment prendre leur sortie et la convertir dans la même structure de résultats que SAS. D'une part, SAS semble exécuter PCA sur la matrice de corrélation lorsque vous utilisez PROC PRINCOMP
, mais la plupart (toutes?) Des bibliothèques Python semblent utiliser SVD.
Dans l'ensemble de données , la première colonne est la variable de réponse et les 5 suivantes sont des variables prédictives, appelées pred1-pred5.
Dans SAS, le workflow général est le suivant:
/* Get the PCs */
proc princomp data=indata out=pcdata;
var pred1 pred2 pred3 pred4 pred5;
run;
/* Standardize the response variable */
proc standard data=pcdata mean=0 std=1 out=pcdata2;
var response;
run;
/* Compare some models */
proc reg data=pcdata2;
Reg: model response = pred1 pred2 pred3 pred4 pred5 / vif;
PCa: model response = prin1-prin5 / vif;
PCfinal: model response = prin1 prin2 / vif;
run;
quit;
/* Use Proc PLS to to PCR Replacement - dropping pred5 */
/* This gets me my parameter estimates for the original data */
proc pls data=indata method=pcr nfac=2;
model response = pred1 pred2 pred3 pred4 / solution;
run;
quit;
Je sais que la dernière étape ne fonctionne que parce que je ne choisis que PC1 et PC2, dans l'ordre.
Donc, en Python, c'est à peu près autant que j'ai obtenu:
import pandas as pd
import numpy as np
from sklearn.decomposition.pca import PCA
source = pd.read_csv('C:/sourcedata.csv')
# Create a pandas DataFrame object
frame = pd.DataFrame(source)
# Make sure we are working with the proper data -- drop the response variable
cols = [col for col in frame.columns if col not in ['response']]
frame2 = frame[cols]
pca = PCA(n_components=5)
pca.fit(frame2)
La quantité d'écart que chaque PC explique?
print pca.explained_variance_ratio_
Out[190]:
array([ 9.99997603e-01, 2.01265023e-06, 2.70712663e-07,
1.11512302e-07, 2.40310191e-09])
Qu'est-ce que c'est? Vecteurs propres?
print pca.components_
Out[179]:
array([[ -4.32840645e-04, -7.18123771e-04, -9.99989955e-01,
-4.40303223e-03, -2.46115129e-05],
[ 1.00991662e-01, 8.75383248e-02, -4.46418880e-03,
9.89353169e-01, 5.74291257e-02],
[ -1.04223303e-02, 9.96159390e-01, -3.28435046e-04,
-8.68305757e-02, -4.26467920e-03],
[ -7.04377522e-03, 7.60168675e-04, -2.30933755e-04,
5.85966587e-02, -9.98256573e-01],
[ -9.94807648e-01, -1.55477793e-03, -1.30274879e-05,
1.00934650e-01, 1.29430210e-02]])
S'agit-il des valeurs propres?
print pca.explained_variance_
Out[180]:
array([ 8.07640319e+09, 1.62550137e+04, 2.18638986e+03,
9.00620474e+02, 1.94084664e+01])
Je ne sais pas trop comment passer des résultats Python à la régression effective des composants principaux (en Python). L'une des bibliothèques Python remplit-elle les espaces de manière similaire à SAS?
Tous les conseils sont appréciés. Je suis un peu gâté par l'utilisation d'étiquettes dans la sortie SAS et je ne connais pas très bien les pandas, numpy, scipy ou scikit-learn.
Éditer:
Il semble donc que sklearn ne fonctionnera pas directement sur une trame de données pandas. Disons que je le convertis en un tableau numpy:
npa = frame2.values
npa
Voici ce que j'obtiens:
Out[52]:
array([[ 8.45300000e+01, 4.20730000e+02, 1.99443000e+05,
7.94000000e+02, 1.21100000e+02],
[ 2.12500000e+01, 2.73810000e+02, 4.31180000e+04,
1.69000000e+02, 6.28500000e+01],
[ 3.38200000e+01, 3.73870000e+02, 7.07290000e+04,
2.79000000e+02, 3.53600000e+01],
...,
[ 4.71400000e+01, 3.55890000e+02, 1.02597000e+05,
4.07000000e+02, 3.25200000e+01],
[ 1.40100000e+01, 3.04970000e+02, 2.56270000e+04,
9.90000000e+01, 7.32200000e+01],
[ 3.85300000e+01, 3.73230000e+02, 8.02200000e+04,
3.17000000e+02, 4.32300000e+01]])
Si je change ensuite le copy
paramètre du PCA de sklearn pour False,
qu'il opère directement sur le tableau, selon le commentaire ci-dessous.
pca = PCA(n_components=5,copy=False)
pca.fit(npa)
npa
Par la sortie, il semble avoir remplacé toutes les valeurs au npa
lieu d'ajouter quoi que ce soit au tableau. Quelles sont les valeurs npa
actuelles? Les scores des composants principaux pour le tableau d'origine?
Out[64]:
array([[ 3.91846649e+01, 5.32456568e+01, 1.03614689e+05,
4.06726542e+02, 6.59830027e+01],
[ -2.40953351e+01, -9.36743432e+01, -5.27103110e+04,
-2.18273458e+02, 7.73300268e+00],
[ -1.15253351e+01, 6.38565684e+00, -2.50993110e+04,
-1.08273458e+02, -1.97569973e+01],
...,
[ 1.79466488e+00, -1.15943432e+01, 6.76868901e+03,
1.97265416e+01, -2.25969973e+01],
[ -3.13353351e+01, -6.25143432e+01, -7.02013110e+04,
-2.88273458e+02, 1.81030027e+01],
[ -6.81533512e+00, 5.74565684e+00, -1.56083110e+04,
-7.02734584e+01, -1.18869973e+01]])
copy=False
, j'obtiens de nouvelles valeurs. S'agit-il des scores des composantes principales?