2015-09-30 37 views
5

Fase 0: Descrizione del problema

ho un problema di classificazione, cioè voglio prevedere un obiettivo binario sulla base di un insieme di caratteristiche numeriche, utilizzando la regressione logistica, e dopo l'esecuzione di un Principal Components Analysis (PCA).Classificazione: PCA e regressione logistica usando sklearn

Ho 2 set di dati: df_train e df_valid (set di allenamento e set di convalida rispettivamente) come frame dati panda, contenente le caratteristiche e il target. Come primo passo, ho usato la funzione panda di get_dummies per trasformare tutte le variabili categoriali come booleane. Ad esempio, vorrei avere:

n_train = 10 
np.random.seed(0) 
df_train = pd.DataFrame({"f1":np.random.random(n_train), \ 
         "f2": np.random.random(n_train), \ 
         "f3":np.random.randint(0,2,n_train).astype(bool),\ 
         "target":np.random.randint(0,2,n_train).astype(bool)}) 

In [36]: df_train 
Out[36]: 
     f1  f2  f3 target 
0 0.548814 0.791725 False False 
1 0.715189 0.528895 True True 
2 0.602763 0.568045 False True 
3 0.544883 0.925597 True True 
4 0.423655 0.071036 True True 
5 0.645894 0.087129 True False 
6 0.437587 0.020218 True True 
7 0.891773 0.832620 True False 
8 0.963663 0.778157 False False 
9 0.383442 0.870012 True True 

n_valid = 3 
np.random.seed(1) 
df_valid = pd.DataFrame({"f1":np.random.random(n_valid), \ 
         "f2": np.random.random(n_valid), \ 
         "f3":np.random.randint(0,2,n_valid).astype(bool),\ 
         "target":np.random.randint(0,2,n_valid).astype(bool)}) 

In [44]: df_valid 
Out[44]: 
     f1  f2  f3 target 
0 0.417022 0.302333 False False 
1 0.720324 0.146756 True False 
2 0.000114 0.092339 True True 

Vorrei ora di applicare un APC per ridurre la dimensionalità del mio problema, quindi utilizzare LogisticRegression da sklearn per la formazione e ottenere la previsione sul mio set di validazione, ma io non sono sicuro che la procedura che seguo sia corretta. Ecco quello che faccio:

Fase 1: PCA

L'idea è che ho bisogno di trasformare sia la mia formazione e validazione impostati allo stesso modo con PCA. In altre parole, posso non eseguire PCA separatamente. Altrimenti, saranno proiettati su diversi autovettori.

from sklearn.decomposition import PCA 

pca = PCA(n_components=2) #assume to keep 2 components, but doesn't matter 
newdf_train = pca.fit_transform(df_train.drop("target", axis=1)) 
newdf_valid = pca.transform(df_valid.drop("target", axis=1)) #not sure here if this is right 

Fase 2: Regressione logistica

Non è necessario, ma preferisco mantenere le cose come dataframe:

features_train = pd.DataFrame(newdf_train) 
features_valid = pd.DataFrame(newdf_valid) 

E ora eseguire la regressione logistica

from sklearn.linear_model import LogisticRegression 
cls = LogisticRegression() 
cls.fit(features_train, df_train["target"]) 
predictions = cls.predict(features_valid) 

I penso che il passo 2 sia corretto, ma ho più dubbi sul passo 1: è questo il modo in cui dovrei fare catena PCA, quindi un classificatore?

+0

Non vedo alcun problema con la procedura. E i tuoi risultati? Ti aspetti l'uscita prevista? – Riyaz

+0

Uno dei comportamenti imprevisti sui miei dati (diversi dall'esempio mostrato qui) è che mentre aumento il numero di componenti nella funzione PCA, la mia matrice di confusione peggiora! Inoltre, mi stavo chiedendo se "dummifying" troppe variabili categoriali non abbia alcun effetto sui risultati? Devo escludere la colonna "target" durante PCA? – ldocao

+3

Il target non fa parte dei tuoi dati. Quindi escludi le etichette target mentre usi PCA. Per i dati categoriali è necessario utilizzare una rappresentazione a caldo implementata in sklearn. – Riyaz

risposta

2

C'è uno pipeline in sklearn per questo scopo.

from sklearn.decomposition import PCA 
from sklearn.linear_model import LogisticRegression 
from sklearn.pipeline import Pipeline 

pca = PCA(n_components=2) 
cls = LogisticRegression() 

pipe = Pipeline([('pca', pca), ('logistic', clf)]) 
pipe.fit(features_train, df_train["target"]) 
predictions = pipe.predict(features_valid) 
+0

cos'è 'clf'? è un errore? – guy

+0

Sì, dovrebbe essere 'cls'. – Mooncrater