O scikit-learn possui algoritmo de seleção direta / regressão gradual?


37

Estou trabalhando no problema com muitos recursos e o treinamento dos meus modelos leva muito tempo. Eu implementei o algoritmo de seleção direta para escolher os recursos.

No entanto, eu queria saber se o scikit-learn tem seleção direta / algoritmo de regressão gradual?


Eu criei minha própria classe para isso, mas fiquei muito surpreso que o sklearn não tenha isso.
Maksud

11
O uso de testes de hipóteses é um método terrível de seleção de recursos. Você terá que fazer muitos deles e, é claro, obterá muitos falsos positivos e negativos.
Ricardo Cruz

Respostas:


21

Não, o sklearn parece não ter um algoritmo de seleção direta. No entanto, ele fornece eliminação de recurso recursivo, que é um algoritmo de eliminação de recurso ganancioso semelhante à seleção sequencial para trás. Veja a documentação aqui:

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


3
Boa sugestão, mas o problema com a implementação do sci-kit é que a importância do recurso é quantificada pelos coeficientes do modelo, ou seja, se o modelo tiver coef_interface. Isso excluiria o método baseado em árvore, etc. No entanto, acho que o que o @Maksud pediu é o que é descrito em "Uma introdução ao aprendizado estatístico" de James, no qual os recursos são recursivamente adicionados / removidos por sua importância, que é quantificada pela validação. . Isso permite a seleção de recursos em todos os tipos de modelos, não apenas nos paramétricos lineares.
precisa saber é o seguinte

9

O Sklearn TEM um algoritmo de seleção direta, embora não seja chamado assim no scikit-learn. O método de seleção de recurso chamado F_regression no scikit -learn sequencialmente incluirá recursos que melhoram o modelo, até que haja Krecursos no modelo (K é uma entrada).

Começa por regressão dos rótulos de cada recurso individualmente e depois observando qual recurso melhorou o modelo ao máximo usando a estatística-F. Em seguida, incorpora o recurso vencedor no modelo. Em seguida, ele percorre os recursos restantes para encontrar o próximo recurso que melhor aprimora o modelo, novamente usando a estatística F ou o teste F. Isso é feito até que haja recursos K no modelo.

Observe que os recursos restantes correlacionados aos recursos incorporados ao modelo provavelmente não serão selecionados, pois não se correlacionam com os resíduos (embora possam se correlacionar bem com os rótulos). Isso ajuda a proteger contra a multicolinearidade.



11
Você quer dizer Select K-best ?
Nitro

sim. Além disso, você deve ler o seguinte: stats.stackexchange.com/questions/204141/… .
Candic3

2
Esse é o tipo de seleção direta. Mas não é genérico - é específico para um modelo de regressão linear, enquanto que a seleção direta pode funcionar com qualquer modelo (independente de modelo) como é o RFE e pode lidar com problemas de classificação ou regressão. Mas suspeito que a maioria das pessoas esteja procurando esse caso de uso e certamente é bom mencioná-lo aqui.
Simon

2
Esta não é uma seleção STEPWISE, porque cada valor p é calculado para uma regressão univariada, independentemente de todas as outras covariáveis.
David Dale

9

O Scikit-learn de fato não suporta regressão gradual. Isso porque o que é comumente conhecido como 'regressão stepwise' é um algoritmo baseado em valores-p dos coeficientes de regressão linear, e o scikit-learn evita deliberadamente a abordagem inferencial do modelo de aprendizagem (teste de significância, etc.). Além disso, o OLS puro é apenas um dos numerosos algoritmos de regressão e, do ponto de vista do aprendizado do scikit, não é muito importante nem um dos melhores.

No entanto, existem alguns conselhos para quem ainda precisa de um bom caminho para a seleção de recursos com modelos lineares:

  1. Use modelos inerentemente esparsos como ElasticNetou Lasso.
  2. Normalize seus recursos com StandardScalere, em seguida, encomende-os apenas por model.coef_. Para covariáveis ​​perfeitamente independentes, é equivalente à classificação por valores-p. A turma sklearn.feature_selection.RFEfará isso por você e RFECVaté avaliará o número ideal de recursos.
  3. R2statsmodels
  4. Faça a seleção de força bruta para frente ou para trás para maximizar sua métrica favorita na validação cruzada (isso pode levar aproximadamente tempo quadrático no número de covariáveis). Um mlxtendpacote compatível com o scikit-learn suporta essa abordagem para qualquer estimador e qualquer métrica.
  5. Se você ainda deseja a regressão passo a passo de baunilha, é mais fácil basear isso statsmodels, pois este pacote calcula valores de p para você. Uma seleção básica para frente e para trás pode ser assim:

`` ``

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)

Este exemplo imprimiria a seguinte saída:

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

O código de regressão passo a passo publicado adiante não funciona corretamente. Ele deve fornecer resultados idênticos à regressão passo a passo para trás, mas não fornece. Ele está retornando fatores com valores-p superiores ao limite quando você executa novamente a regressão. Também executei o mesmo conjunto de dados com STATA e os mesmos limites usando retrocedendo passo a passo e obtendo resultados materialmente diferentes. Basicamente, não use. Vou escrever meu próprio código de regressão passo a passo usando seu modelo.
Michael Corley MBA LSSBB

As regressões passo a passo para frente e para trás não são de forma alguma garantidas para convergir para a mesma solução. E se você notou um bug na minha solução, anexe o código para reproduzi-lo.
David Dale

1

De fato, existe um bom algoritmo chamado "Forward_Select" que usa modelos Stats e permite que você defina sua própria métrica (AIC, BIC, Adjusted-R-Squared ou o que você quiser) para adicionar progressivamente uma variável ao modelo. O algoritmo pode ser encontrado na seção de comentários desta página - role para baixo e você o verá próximo à parte inferior da página.

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

Eu acrescentaria que o algoritmo também possui um recurso interessante: você pode aplicá-lo a problemas de classificação ou regressão! Você apenas tem que contar.

Experimente e veja por si mesmo.


0

Na verdade, o sklearn não possui um algoritmo de seleção direta, embora uma solicitação pull com uma implementação de seleção direta de recursos aguarde no repositório Scikit-Learn desde abril de 2017.

Como alternativa, há uma seleção anterior e um passo à frente no mlxtend . Você pode encontrar o documento no Seletor de recursos sequenciais

Ao utilizar nosso site, você reconhece que leu e compreendeu nossa Política de Cookies e nossa Política de Privacidade.
Licensed under cc by-sa 3.0 with attribution required.