2015-10-27 32 views
6

ho utilizzato pipeline e grid_search per selezionare i parametri migliori e quindi ho utilizzato questi parametri per adattarli alla pipeline migliore ("best_pipe"). Tuttavia, dal momento che la feature_selection (SelectKBest) si trova nella pipeline non è stato applicato alcun criterio a SelectKBest.selezione della funzione python nella pipeline: come determinare i nomi delle funzionalità?

Ho bisogno di conoscere i nomi delle funzionalità delle funzioni selezionate "k". Qualche idea su come recuperarli? Grazie in anticipo

from sklearn import (cross_validation, feature_selection, pipeline, 
        preprocessing, linear_model, grid_search) 
folds = 5 
split = cross_validation.StratifiedKFold(target, n_folds=folds, shuffle = False, random_state = 0) 

scores = [] 
for k, (train, test) in enumerate(split): 

    X_train, X_test, y_train, y_test = X.ix[train], X.ix[test], y.ix[train], y.ix[test] 

    top_feat = feature_selection.SelectKBest() 

    pipe = pipeline.Pipeline([('scaler', preprocessing.StandardScaler()), 
           ('feat', top_feat), 
           ('clf', linear_model.LogisticRegression())]) 

    K = [40, 60, 80, 100] 
    C = [1.0, 0.1, 0.01, 0.001, 0.0001, 0.00001] 
    penalty = ['l1', 'l2'] 

    param_grid = [{'feat__k': K, 
        'clf__C': C, 
        'clf__penalty': penalty}] 

    scoring = 'precision' 

    gs = grid_search.GridSearchCV(estimator=pipe, param_grid = param_grid, scoring = scoring) 
    gs.fit(X_train, y_train) 

    best_score = gs.best_score_ 
    scores.append(best_score) 

    print "Fold: {} {} {:.4f}".format(k+1, scoring, best_score) 
    print gs.best_params_ 

best_pipe = pipeline.Pipeline([('scale', preprocessing.StandardScaler()), 
          ('feat', feature_selection.SelectKBest(k=80)), 
          ('clf', linear_model.LogisticRegression(C=.0001, penalty='l2'))]) 

best_pipe.fit(X_train, y_train) 
best_pipe.predict(X_test) 

risposta

5

È possibile accedere al selettore di funzione per nome in best_pipe:

features = best_pipe.named_steps['feat'] 

Poi si può chiamare transform() su un array di indice per ottenere i nomi dei colonne selezionate:

X.columns[features.transform(np.arange(len(X.columns)))] 

L'output qui sarà gli 80 nomi di colonna selezionati nella pipeline.

+0

Un vero regalo per ricevere la soluzione da te Jake, in realtà mi hai aiutato a imparare Python con i tuoi video tutorial di Pyramid. Tuttavia, ottengo l'errore "Impossibile convertire la stringa in float: punteggio_575-600" (punteggio_575-600 è il nome di una delle colonne) come può essere risolto? – figgy

+0

Ah - Ho dimenticato che il selettore di funzioni non funziona sulle stringhe. Prova la versione aggiornata qui sopra. Sono contento di sentire i video sono stati utili! – jakevdp

+0

non sono ancora sicuro su come evitare l'errore sopra, ma questa soluzione a doppio passo mi ha almeno ottenuto i nomi delle colonne per le migliori caratteristiche k: features = best_pipe.named_steps ['feat']. Get_support() x_cols = X.colonne .values ​​[features == True] x_cols – figgy

3

Questa potrebbe essere un'alternativa istruttiva: ho riscontrato un'esigenza simile a quella richiesta da OP. Se si vuole ottenere indici k migliori caratteristiche direttamente da GridSearchCV:

finalFeatureIndices = gs.best_estimator_.named_steps["feat"].get_support(indices=True) 

E via index manipulation, può ottenere la vostra finalFeatureList: risposta

finalFeatureList = [initialFeatureList[i] for i in finalFeatureIndices] 
3

di Jake funziona completamente. Ma a seconda del selettore di funzioni che usi, c'è un'altra opzione che penso sia più pulita. Questo ha funzionato per me:

X.columns[features.get_support()] 

Mi ha dato una risposta identica alla risposta di Jake. E potete vederne di più in the docs, ma get_support restituisce un array di valori vero/falso per stabilire se la colonna è stata usata o meno. Inoltre, vale la pena notare che lo X deve avere la stessa forma dei dati di allenamento utilizzati nel selettore di funzioni.

+0

Preferibilmente preferisco questa risposta, 'features.transform (np.arange (len (X.columns)))' è fondamentalmente longhand per 'features.get_support()'. – andrew