¿Scikit-learn tiene un algoritmo de selección hacia adelante / regresión escalonada?


37

Estoy trabajando en el problema con demasiadas funciones y la capacitación de mis modelos lleva demasiado tiempo. Implementé el algoritmo de selección directa para elegir características.

Sin embargo, me preguntaba si scikit-learn tiene un algoritmo de selección progresiva / regresión gradual.


Creé mi propia clase para eso, pero estoy muy sorprendido de que Sklearn no tenga eso.
Maksud

1
El uso de pruebas de hipótesis es un método terrible de selección de características. Tendrás que hacer muchos de ellos y, por supuesto, obtendrás muchos falsos positivos y negativos.
Ricardo Cruz

Respuestas:


21

No, sklearn no parece tener un algoritmo de selección hacia adelante. Sin embargo, proporciona la eliminación de características recursivas, que es un algoritmo de eliminación de características codicioso similar a la selección secuencial hacia atrás. Vea la documentación aquí:

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


3
Buena sugerencia, pero el problema con la implementación del kit de ciencia ficción es que la importancia de la característica se cuantifica por los coeficientes del modelo, es decir, si el modelo tiene coef_interfaz. Esto descartaría el método basado en árbol, etc. Sin embargo, creo que lo que pidió @Maksud es lo que se describe en "Introducción al aprendizaje estadístico" de James en el que las características se agregan / eliminan recursivamente por su importancia que cuantificó mediante la precisión del conjunto de validación . Esto permite la selección de características en todos los tipos de modelos, no solo los paramétricos lineales.
eggie5

9

Sklearn TIENE un algoritmo de selección hacia adelante, aunque no se llama así en scikit-learn. El método de selección de características llamado F_regression en scikit-learn incluirá secuencialmente características que mejoren más el modelo, hasta que haya Kcaracterísticas en el modelo (K es una entrada).

Comienza por la regresión de las etiquetas en cada característica individualmente, y luego observando qué característica mejoró más el modelo usando la estadística F. Luego incorpora la característica ganadora en el modelo. Luego, itera a través de las características restantes para encontrar la siguiente característica que mejora más el modelo, nuevamente utilizando la estadística F o la prueba F. Hace esto hasta que haya K características en el modelo.

Tenga en cuenta que las características restantes que están correlacionadas con las características incorporadas en el modelo probablemente no se seleccionarán, ya que no se correlacionan con los residuos (aunque podrían correlacionarse bien con las etiquetas). Esto ayuda a proteger contra la multicolinealidad.



1
¿Te refieres a Select K-best ?
Nitro

sí. Además, debe leer esto: stats.stackexchange.com/questions/204141/… .
Candic3

2
Eso es una especie de selección hacia adelante. Pero no es genérico: es específico de un modelo de regresión lineal, mientras que la selección directa puede funcionar con cualquier modelo (modelo agnóstico) como lo es el RFE y puede manejar problemas de clasificación o regresión. Pero sospecho que la mayoría de las personas está buscando este caso de uso y ciertamente es bueno mencionarlo aquí.
Simon

2
Esta no es una selección de STEPWISE, porque cada valor p se calcula para una regresión univariada, independientemente de todas las demás covariables.
David Dale

9

Scikit-learn de hecho no es compatible con la regresión gradual. Esto se debe a que lo que comúnmente se conoce como 'regresión por pasos' es un algoritmo basado en valores p de coeficientes de regresión lineal, y scikit-learn evita deliberadamente el enfoque inferencial para el aprendizaje de modelos (pruebas de significación, etc.). Además, OLS puro es solo uno de los numerosos algoritmos de regresión, y desde el punto de vista de scikit-learn no es muy importante ni uno de los mejores.

Sin embargo, hay algunos consejos para aquellos que todavía necesitan una buena forma de selección de características con modelos lineales:

  1. Utilice modelos intrínsecamente escasos como ElasticNeto Lasso.
  2. Normalice sus funciones con StandardScaler, y luego ordene sus funciones solo por model.coef_. Para covariables perfectamente independientes es equivalente a ordenar por valores p. La clase sklearn.feature_selection.RFElo hará por usted e RFECVincluso evaluará la cantidad óptima de características.
  3. Utilice una implementación de selección hacia adelante mediante ajustado que funcione .R2statsmodels
  4. Haga una selección de fuerza bruta hacia adelante o hacia atrás para maximizar su métrica favorita en la validación cruzada (podría tomar aproximadamente un tiempo cuadrático en número de covariables). Un mlxtendpaquete compatible con scikit-learn admite este enfoque para cualquier estimador y cualquier métrica.
  5. Si aún desea una regresión gradual vainilla, es más fácil basarla statsmodels, ya que este paquete calcula los valores p por usted. Una selección básica hacia adelante y hacia atrás podría verse así:

`` `

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 ejemplo imprimiría el siguiente resultado:

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

El código de regresión escalonada hacia adelante publicado no funciona correctamente. Debería dar resultados idénticos a la regresión gradual hacia atrás, pero no lo hace. Son factores de retorno con valores p que son más altos que el umbral cuando se vuelve a ejecutar la regresión. También ejecuté el mismo conjunto de datos con STATA y los mismos umbrales usando paso a paso hacia atrás y obtuve resultados significativamente diferentes. Básicamente, no lo uses. Voy a escribir mi propio código de regresión gradual utilizando su plantilla.
Michael Corley MBA LSSBB

Las regresiones escalonadas hacia adelante y hacia atrás de ninguna manera están garantizadas para converger en la misma solución. Y si notó un error en mi solución, adjunte el código para reproducirlo.
David Dale

1

De hecho, hay un buen algoritmo llamado "Forward_Select" que utiliza modelos de estadísticas y le permite establecer su propia métrica (AIC, BIC, Adjusted-R-Squared, o lo que quiera) para agregar progresivamente una variable al modelo. El algoritmo se puede encontrar en la sección de comentarios de esta página: desplácese hacia abajo y lo verá cerca de la parte inferior de la página.

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

Yo agregaría que el algoritmo también tiene una buena característica: ¡puede aplicarlo a problemas de clasificación o regresión! Solo tienes que contarlo.

Pruébalo y compruébalo por ti mismo.


Al usar nuestro sitio, usted reconoce que ha leído y comprende nuestra Política de Cookies y Política de Privacidad.
Licensed under cc by-sa 3.0 with attribution required.