Hat scikit-learn einen Vorwärtsauswahl- / schrittweisen Regressionsalgorithmus?


37

Ich arbeite an dem Problem mit zu vielen Funktionen und das Training meiner Modelle dauert viel zu lange. Ich habe einen Vorwärtsauswahlalgorithmus implementiert, um Features auszuwählen.

Allerdings habe ich mich gefragt, ob Scikit-Learn einen Vorwärtsauswahl- / schrittweisen Regressionsalgorithmus hat.


Ich habe meine eigene Klasse dafür erstellt, aber sehr überrascht, dass sklearn das nicht hat.
Maksud

1
Die Verwendung von Hypothesentests ist eine schreckliche Methode zur Merkmalsauswahl. Sie müssen eine Menge davon machen und natürlich erhalten Sie eine Menge falsch positiver und negativer Ergebnisse.
Ricardo Cruz

Antworten:


21

Nein, sklearn scheint keinen Algorithmus für die Vorauswahl zu haben. Es wird jedoch eine rekursive Merkmaleliminierung bereitgestellt, bei der es sich um einen gierigen Merkmaleliminierungsalgorithmus handelt, der der sequentiellen Rückwärtsauswahl ähnelt. Siehe die Dokumentation hier:

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


3
Guter Vorschlag, aber das Problem bei der Implementierung des Sci-Kits ist, dass die Merkmalsbedeutung durch die Modellkoeffizienten quantifiziert wird, dh wenn das Modell eine coef_Schnittstelle hat. Dies würde eine baumbasierte Methode usw. ausschließen. Ich denke jedoch, dass @Maksud nach einer Beschreibung in "Eine Einführung in das statistische Lernen" von James gefragt hat, in der Features aufgrund ihrer Wichtigkeit rekursiv hinzugefügt / entfernt werden, was durch die Genauigkeit der Validierungsmenge quantifiziert wird . Dies ermöglicht die Auswahl von Funktionen für alle Modelltypen, nicht nur für lineare Parameter.
eggie5

9

Sklearn DOES hat einen Vorwärtsauswahlalgorithmus, obwohl er in Scikit-Learn nicht so genannt wird. Die Feature-Auswahlmethode mit dem Namen F_regression in scikit-learn enthält nacheinander Features, die das Modell am meisten verbessern, bis Kdas Modell Features enthält (K ist eine Eingabe).

Zunächst werden die Beschriftungen für jedes Feature einzeln zurückgeführt und anschließend anhand der F-Statistik überprüft, welches Feature das Modell am meisten verbessert hat. Anschließend wird die Gewinnfunktion in das Modell integriert. Anschließend werden die verbleibenden Features durchlaufen, um das nächste Feature zu finden, das das Modell am besten verbessert, und zwar wiederum mithilfe der F-Statistik oder des F-Tests. Dies geschieht so lange, bis das Modell K Merkmale enthält.

Beachten Sie, dass die verbleibenden Features, die mit im Modell enthaltenen Features korrelieren, wahrscheinlich nicht ausgewählt werden, da sie nicht mit den Residuen korrelieren (obwohl sie möglicherweise gut mit den Beschriftungen korrelieren). Dies schützt vor Multi-Kollinearität.



1
Meinen Sie damit Select K-best ?
Nitro


2
Das ist eine Art Vorauswahl. Es ist jedoch nicht generisch - es ist spezifisch für ein lineares Regressionsmodell, wohingegen die Vorauswahl in der Regel mit jedem Modell (modellunabhängig) wie der RFE funktionieren kann und mit Klassifizierungs- oder Regressionsproblemen umgehen kann. Aber ich vermute, die meisten Leute suchen nach diesem Anwendungsfall und es ist auf jeden Fall gut, ihn hier zu erwähnen.
Simon

2
Dies ist keine STEPWISE-Auswahl, da jeder p-Wert unabhängig von allen anderen Kovariaten für eine univariate Regression berechnet wird.
David Dale

9

Scikit-Learn unterstützt in der Tat keine schrittweise Regression. Das liegt daran, dass das, was gemeinhin als "schrittweise Regression" bezeichnet wird, ein Algorithmus ist, der auf p-Werten von linearen Regressionskoeffizienten basiert, und das Lernen mit Hilfe von Scikits den inferentiellen Ansatz für das Lernen von Modellen (Signifikanztests usw.) bewusst vermeidet. Darüber hinaus ist reines OLS nur einer von zahlreichen Regressionsalgorithmen und aus der Sicht des Scikit-Learn weder sehr wichtig noch einer der besten.

Es gibt jedoch einige Ratschläge für diejenigen, die noch eine gute Möglichkeit für die Feature-Auswahl mit linearen Modellen benötigen:

  1. Verwenden Sie von Natur aus spärliche Modelle wie ElasticNetoder Lasso.
  2. Normalisieren Sie Ihre Funktionen mit StandardScalerund ordnen Sie Ihre Funktionen dann einfach nach model.coef_. Für vollkommen unabhängige Kovariaten entspricht dies der Sortierung nach p-Werten. Die Klasse sklearn.feature_selection.RFEerledigt dies für Sie und RFECVbewertet sogar die optimale Anzahl von Funktionen.
  3. R2statsmodels
  4. Führen Sie eine vorwärts- oder rückwärtsgerichtete Brute-Force-Auswahl durch, um Ihre bevorzugte Metrik bei der Kreuzvalidierung zu maximieren (die Anzahl der Kovariaten kann ungefähr quadratisch sein). Ein mit Scikit Learn kompatibles mlxtendPaket unterstützt diesen Ansatz für jeden Schätzer und jede Metrik.
  5. Wenn Sie immer noch eine schrittweise Vanille-Regression wünschen, ist es einfacher, sie zu verwenden statsmodels, da dieses Paket p-Werte für Sie berechnet. Eine grundlegende Vorwärts-Rückwärts-Auswahl könnte folgendermaßen aussehen:

`` `

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 diesem Beispiel wird die folgende Ausgabe gedruckt:

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']

Der vorwärts gepostete schrittweise Regressionscode funktioniert nicht richtig. Es sollte zu identischen Ergebnissen bei schrittweiser Rückwärtsregression führen, tut dies jedoch nicht. Es werden Faktoren mit p-Werten zurückgegeben, die höher als der Schwellenwert sind, wenn Sie die Regression wiederholen. Ich habe den gleichen Datensatz auch mit STATA und den gleichen Schwellenwerten schrittweise rückwärts ausgeführt und dabei erheblich unterschiedliche Ergebnisse erzielt. Grundsätzlich nicht verwenden. Ich werde meinen eigenen schrittweisen Regressionscode mit seiner Vorlage rückwärts schreiben.
Michael Corley MBA LSSBB

Es ist keineswegs garantiert, dass vorwärts und rückwärts schrittweise Regressionen zur gleichen Lösung konvergieren. Und wenn Sie einen Fehler in meiner Lösung bemerkt haben, fügen Sie bitte den Code hinzu, um ihn zu reproduzieren.
David Dale

1

Tatsächlich gibt es einen netten Algorithmus namens "Forward_Select", der Statsmodels verwendet und es Ihnen ermöglicht, Ihre eigene Metrik (AIC, BIC, Adjusted-R-Squared oder was auch immer Sie möchten) festzulegen, um dem Modell schrittweise eine Variable hinzuzufügen. Der Algorithmus befindet sich im Kommentarbereich dieser Seite - scrollen Sie nach unten und Sie sehen ihn am unteren Rand der Seite.

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

Ich würde hinzufügen, dass der Algorithmus auch eine nette Funktion hat: Sie können ihn entweder auf Klassifizierungs- oder auf Regressionsprobleme anwenden! Du musst es nur sagen.

Probieren Sie es aus und überzeugen Sie sich.


0

Eigentlich hat sklearn keinen Forward-Auswahlalgorithmus, dachte eine Pull-Anfrage mit einer Implementierung der Forward-Feature-Auswahl wartet seit April 2017 im Scikit-Learn-Repository.

Alternativ können Sie in mlxtend vorwärts und rückwärts vorwärts wählen . Sie finden das Dokument in Sequential Feature Selector

Durch die Nutzung unserer Website bestätigen Sie, dass Sie unsere Cookie-Richtlinie und Datenschutzrichtlinie gelesen und verstanden haben.
Licensed under cc by-sa 3.0 with attribution required.