Scikit-learn ha un algoritmo di selezione diretta / regressione graduale?


37

Sto lavorando al problema con troppe funzioni e la formazione dei miei modelli richiede troppo tempo. Ho implementato l'algoritmo di selezione diretta per scegliere le funzionalità.

Tuttavia, mi chiedevo scikit-learn ha algoritmo di selezione in avanti / regressione graduale?


Ho creato la mia classe per questo, ma sono molto sorpreso che sklearn non lo abbia.
Maksud,

1
L'uso dei test di ipotesi è un terribile metodo di selezione delle caratteristiche. Dovrai farne molti e, ovviamente, otterrai molti falsi positivi e negativi.
Ricardo Cruz,

Risposte:


21

No, sklearn non sembra avere un algoritmo di selezione diretta. Tuttavia, fornisce l'eliminazione delle funzioni ricorsive, che è un avido algoritmo di eliminazione delle funzioni simile alla selezione all'indietro sequenziale. Vedi la documentazione qui:

http://scikit-learn.org/stable/modules/generated/sklearn.feature_selection.RFE.html


3
Un buon suggerimento, ma il problema con l'implementazione di sci-kit è che l'importanza della funzione è quantificata dai coefficienti del modello, ovvero se il modello ha coef_un'interfaccia. Questo escluderebbe il metodo basato su alberi, ecc. Tuttavia, penso che ciò che @Maksud ha chiesto sia quello che è descritto in "Un'introduzione all'apprendimento statistico" di James in cui le caratteristiche sono aggiunte / rimosse ricorsivamente dalla loro importanza che la sua quantificata dalla validazione imposta l'accuratezza . Ciò consente la selezione delle caratteristiche tra tutti i tipi di modelli, non solo quelli parametrici lineari.
eggie5,

9

Sklearn DOES ha un algoritmo di selezione diretta, sebbene non sia chiamato così in scikit-learn. Il metodo di selezione delle funzioni chiamato F_regression in scikit-learn includerà sequenzialmente funzioni che migliorano maggiormente il modello, fino a quando non ci sono Kcaratteristiche nel modello (K è un input).

Inizia con la regressione delle etichette su ciascuna caratteristica singolarmente, quindi osservando quale caratteristica ha migliorato maggiormente il modello usando la statistica F. Quindi incorpora la funzione vincente nel modello. Quindi scorre le restanti funzionalità per trovare la funzionalità successiva che migliora maggiormente il modello, sempre utilizzando la statistica F o il test F. Lo fa fino a quando non ci sono funzioni K nel modello.

Si noti che le restanti funzioni correlate alle funzioni incorporate nel modello probabilmente non verranno selezionate, poiché non sono correlate ai residui (sebbene possano essere correlate bene con le etichette). Questo aiuta a proteggersi dalla multi-collinearità.



1
Intendi Select K-best ?
Nitro,

sì. Inoltre, dovresti leggere questo: stats.stackexchange.com/questions/204141/… .
Candic3,

2
È una sorta di selezione diretta. Ma non è generico: è specifico per un modello di regressione lineare, mentre la selezione diretta in avanti può funzionare con qualsiasi modello (agnostico del modello) come lo è la RFE e può gestire problemi di classificazione o regressione. Ma sospetto che la maggior parte delle persone stia cercando questo caso d'uso ed è sicuramente bello menzionarlo qui.
Simon,

2
Questa non è una selezione STEPWISE, poiché ogni valore p viene calcolato per una regressione univariata, indipendentemente da tutte le altre covariate.
David Dale,

9

Scikit-learn infatti non supporta la regressione graduale. Questo perché ciò che è comunemente noto come "regressione graduale" è un algoritmo basato su valori p di coefficienti di regressione lineare, e scikit-learning evita deliberatamente un approccio inferenziale all'apprendimento del modello (test di significatività, ecc.). Inoltre, l'OLS puro è solo uno dei numerosi algoritmi di regressione e dal punto di vista dello scikit-learning non è né molto importante, né uno dei migliori.

Vi sono, tuttavia, alcuni consigli per coloro che hanno ancora bisogno di un buon modo per la selezione delle funzionalità con modelli lineari:

  1. Usa modelli intrinsecamente sparsi come ElasticNeto Lasso.
  2. Normalizza le tue funzionalità con StandardScaler, quindi ordina le funzionalità semplicemente per model.coef_. Per le covariate perfettamente indipendenti è equivalente all'ordinamento per valori di p. La classe sklearn.feature_selection.RFElo farà per te e RFECVvaluterà anche il numero ottimale di funzionalità.
  3. R2statsmodels
  4. Esegui la selezione in avanti o all'indietro della forza bruta per massimizzare la metrica preferita sulla convalida incrociata (il numero di covariate potrebbe richiedere circa il tempo quadratico). Un mlxtendpacchetto compatibile con scikit-learn supporta questo approccio per qualsiasi stimatore e metrica.
  5. Se vuoi ancora una regressione graduale alla vaniglia, è più facile basarla statsmodels, poiché questo pacchetto calcola i valori p per te. Una selezione di base avanti-indietro potrebbe apparire così:

`` `

from sklearn.datasets import load_boston
import pandas as pd
import numpy as np
import statsmodels.api as sm

data = load_boston()
X = pd.DataFrame(data.data, columns=data.feature_names)
y = data.target


def stepwise_selection(X, y, 
                       initial_list=[], 
                       threshold_in=0.01, 
                       threshold_out = 0.05, 
                       verbose=True):
    """ Perform a forward-backward feature selection 
    based on p-value from statsmodels.api.OLS
    Arguments:
        X - pandas.DataFrame with candidate features
        y - list-like with the target
        initial_list - list of features to start with (column names of X)
        threshold_in - include a feature if its p-value < threshold_in
        threshold_out - exclude a feature if its p-value > threshold_out
        verbose - whether to print the sequence of inclusions and exclusions
    Returns: list of selected features 
    Always set threshold_in < threshold_out to avoid infinite looping.
    See https://en.wikipedia.org/wiki/Stepwise_regression for the details
    """
    included = list(initial_list)
    while True:
        changed=False
        # forward step
        excluded = list(set(X.columns)-set(included))
        new_pval = pd.Series(index=excluded)
        for new_column in excluded:
            model = sm.OLS(y, sm.add_constant(pd.DataFrame(X[included+[new_column]]))).fit()
            new_pval[new_column] = model.pvalues[new_column]
        best_pval = new_pval.min()
        if best_pval < threshold_in:
            best_feature = new_pval.argmin()
            included.append(best_feature)
            changed=True
            if verbose:
                print('Add  {:30} with p-value {:.6}'.format(best_feature, best_pval))

        # backward step
        model = sm.OLS(y, sm.add_constant(pd.DataFrame(X[included]))).fit()
        # use all coefs except intercept
        pvalues = model.pvalues.iloc[1:]
        worst_pval = pvalues.max() # null if pvalues is empty
        if worst_pval > threshold_out:
            changed=True
            worst_feature = pvalues.argmax()
            included.remove(worst_feature)
            if verbose:
                print('Drop {:30} with p-value {:.6}'.format(worst_feature, worst_pval))
        if not changed:
            break
    return included

result = stepwise_selection(X, y)

print('resulting features:')
print(result)

In questo esempio verrà stampato il seguente output:

Add  LSTAT                          with p-value 5.0811e-88
Add  RM                             with p-value 3.47226e-27
Add  PTRATIO                        with p-value 1.64466e-14
Add  DIS                            with p-value 1.66847e-05
Add  NOX                            with p-value 5.48815e-08
Add  CHAS                           with p-value 0.000265473
Add  B                              with p-value 0.000771946
Add  ZN                             with p-value 0.00465162
resulting features:
['LSTAT', 'RM', 'PTRATIO', 'DIS', 'NOX', 'CHAS', 'B', 'ZN']

Il codice di regressione graduale in avanti pubblicato non funziona correttamente. Dovrebbe dare risultati identici alla regressione graduale all'indietro, ma non lo è. Restituisce fattori con valori p superiori alla soglia quando si esegue nuovamente la regressione. Ho anche eseguito lo stesso set di dati con STATA e le stesse soglie usando all'indietro per gradi e ottenendo risultati sostanzialmente diversi. Fondamentalmente, non usarlo. Scriverò il mio codice di regressione graduale all'indietro usando il suo modello.
Michael Corley MBA LSSBB,

Le regressioni in avanti e all'indietro non sono affatto garantite per convergere alla stessa soluzione. E se hai notato un bug nella mia soluzione, allega il codice per riprodurlo.
David Dale,

1

In effetti esiste un simpatico algoritmo chiamato "Forward_Select" che utilizza Statsmodels e consente di impostare la propria metrica (AIC, BIC, Adjusted-R-Squared o qualsiasi altra cosa si desideri) per aggiungere progressivamente una variabile al modello. L'algoritmo è disponibile nella sezione commenti di questa pagina: scorri verso il basso e lo vedrai nella parte inferiore della pagina.

https://planspace.org/20150423-forward_selection_with_statsmodels/

Aggiungo che l'algoritmo ha anche una bella caratteristica: puoi applicarlo a problemi di classificazione o regressione! Devi solo dirlo.

Provalo e vedi di persona.


Utilizzando il nostro sito, riconosci di aver letto e compreso le nostre Informativa sui cookie e Informativa sulla privacy.
Licensed under cc by-sa 3.0 with attribution required.