Czy scikit-learn ma algorytm selekcji do przodu / regresji krokowej?

37

Pracuję nad problemem ze zbyt wieloma funkcjami, a szkolenie moich modeli trwa zdecydowanie za długo. Zaimplementowałem algorytm wybierania do przodu, aby wybrać funkcje.

Zastanawiałem się jednak, czy scikit-learn ma algorytm selekcji do przodu / regresji krokowej?

Maksud
źródło
Stworzyłem własną klasę do tego, ale jestem bardzo zaskoczony, że sklearn tego nie ma.
Maksud
1
Korzystanie z testów hipotez jest straszną metodą wyboru cech. Będziesz musiał zrobić wiele z nich i oczywiście dostaniesz wiele fałszywych pozytywów i negatywów.
Ricardo Cruz,

Odpowiedzi:

21

Nie, sklearn nie wydaje się mieć algorytmu selekcji do przodu. Jednak zapewnia rekurencyjną eliminację cech, która jest chciwym algorytmem eliminacji cech podobnym do sekwencyjnego wybierania wstecznego. Zobacz dokumentację tutaj:

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

brentlance
źródło
3
Dobra sugestia, ale problem z implementacją sci-kit polega na tym, że ważność funkcji jest kwantyfikowana przez współczynniki modelu, tj. Jeśli model ma coef_interfejs. Wykluczałoby to metodę opartą na drzewach itp. Myślę jednak, że o co prosił @Maksud, jest to, co opisano w „An Introduction to statystycznego uczenia się” Jamesa, w którym cechy są rekurencyjnie dodawane / usuwane według ich ważności, którą określa ilościowo przez dokładność zestawu walidacyjnego . Umożliwia to wybór funkcji we wszystkich typach modeli, a nie tylko liniowych parametrycznych.
eggie5
9

Sklearn ma algorytm selekcji do przodu, chociaż nie jest tak nazywany w scikit-learn. Metoda wyboru funkcji o nazwie F_regresja w scikit-learn będzie sekwencyjnie obejmować funkcje, które najbardziej poprawią model, dopóki nie pojawią się Kfunkcje w modelu (K jest wejściem).

Zaczyna się od regresji etykiet każdego elementu osobno, a następnie obserwując, która cecha najbardziej poprawiła model przy użyciu statystyki F. Następnie włącza zwycięską funkcję do modelu. Następnie iteruje pozostałe funkcje, aby znaleźć kolejną cechę, która najbardziej ulepsza model, ponownie za pomocą statystyki F lub testu F. Robi to, dopóki w modelu nie będzie funkcji K.

Zauważ, że pozostałe funkcje, które są skorelowane z elementami włączonymi do modelu, prawdopodobnie nie zostaną wybrane, ponieważ nie korelują z resztami (chociaż mogą dobrze korelować z etykietami). Pomaga to chronić przed wielokolinearnością.

Candic3
źródło
1
Masz na myśli Select K-best ?
Nitro
tak. Ponadto powinieneś przeczytać to: stats.stackexchange.com/questions/204141/… .
Candic3
2
To rodzaj selekcji do przodu. Ale to nie jest ogólne - jest specyficzne dla modelu regresji liniowej, podczas gdy typowa selekcja do przodu może działać z dowolnym modelem (model agnostyczny), podobnie jak RFE i może obsługiwać problemy z klasyfikacją lub regresją. Ale podejrzewam, że większość ludzi szuka tego przypadku użycia i na pewno warto o tym wspomnieć tutaj.
Simon
2
Nie jest to wybór STEPWISE, ponieważ każda wartość p jest obliczana dla regresji jednowymiarowej, niezależnie od wszystkich innych zmiennych towarzyszących.
David Dale,
9

Scikit-learn rzeczywiście nie obsługuje regresji stopniowej. Jest tak, ponieważ to, co jest powszechnie znane jako „regresja krokowa”, jest algorytmem opartym na wartościach p współczynników regresji liniowej, a scikit-learning celowo unika inferencyjnego podejścia do uczenia się modelu (testowanie istotności itp.). Co więcej, czysty OLS jest tylko jednym z wielu algorytmów regresji, a z punktu widzenia scikit-learning nie jest ani bardzo ważny, ani jeden z najlepszych.

Istnieją jednak porady dla tych, którzy nadal potrzebują dobrego sposobu wyboru funkcji za pomocą modeli liniowych:

  1. Używaj z natury rzadkich modeli, takich jak ElasticNetlub Lasso.
  2. Normalizuj swoje funkcje za pomocą StandardScaler, a następnie zamawiaj je po prostu model.coef_. Dla idealnie niezależnych zmiennych towarzyszących jest to równoważne sortowaniu według wartości p. Klasa sklearn.feature_selection.RFEzrobi to za Ciebie, a RFECVnawet oceni optymalną liczbę funkcji.
  3. R2statsmodels
  4. Wybierz opcję brutalnej siły do ​​przodu lub do tyłu, aby zmaksymalizować swoją ulubioną metrykę podczas krzyżowej weryfikacji (może to zająć około kwadratu czasu w wielu współzmiennych). mlxtendPakiet kompatybilny z scikit-learn obsługuje to podejście dla każdego estymatora i każdej metryki.
  5. Jeśli nadal chcesz krokową regresję waniliową, łatwiej jest ją oprzeć statsmodels, ponieważ ten pakiet oblicza dla ciebie wartości p. Podstawowy wybór do przodu i do tyłu może wyglądać następująco:

``

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)

W tym przykładzie zostaną wydrukowane następujące dane wyjściowe:

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']
David Dale
źródło
Przesłany kod regresji krokowej do przodu nie działa poprawnie. Powinno dawać identyczne wyniki wstecznej regresji, ale nie daje. Powracają czynniki o wartościach p, które są wyższe niż próg po ponownym uruchomieniu regresji. Uruchomiłem również ten sam zestaw danych ze STATA i te same progi, stosując krok po kroku wstecz i uzyskuję istotnie różne wyniki. Zasadniczo nie używaj go. Zamierzam napisać własny kod regresji wstecznej za pomocą jego szablonu.
Michael Corley MBA LSSBB
Regresje stopniowe do przodu i do tyłu w żadnym wypadku nie gwarantują zbieżności z tym samym rozwiązaniem. A jeśli zauważyłeś błąd w moim rozwiązaniu, dołącz kod, aby go odtworzyć.
David Dale
1

W rzeczywistości istnieje przyjemny algorytm o nazwie „Forward_Select”, który używa Statsmodels i pozwala ustawić własną metrykę (AIC, BIC, skorygowane R-kwadrat lub cokolwiek zechcesz), aby stopniowo dodawać zmienną do modelu. Algorytm można znaleźć w sekcji komentarzy na tej stronie - przewiń w dół, a zobaczysz go u dołu strony.

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

Dodałbym, że algorytm ma również jedną fajną cechę: możesz zastosować go do problemów klasyfikacji lub regresji! Musisz tylko to powiedzieć.

Wypróbuj i przekonaj się sam.

Ram Seshadri
źródło