Scikit-learn a-t-il un algorithme de sélection directe / régression pas à pas?


37

Je travaille sur le problème avec trop de fonctionnalités et la formation de mes modèles prend beaucoup trop de temps. J'ai mis en œuvre un algorithme de sélection directe pour choisir les fonctionnalités.

Cependant, je me demandais si scikit-learn avait un algorithme de sélection en aval / de régression pas à pas?


J'ai créé ma propre classe pour cela, mais très surpris que Sklearn ne l'ait pas.
Maksud

1
L'utilisation de tests d'hypothèses est une méthode terrible de sélection de fonctionnalités. Vous devrez en faire beaucoup et, bien sûr, vous obtiendrez beaucoup de faux positifs et négatifs.
Ricardo Cruz

Réponses:


21

Non, sklearn ne semble pas avoir d'algorithme de sélection en aval. Cependant, il fournit une élimination des fonctionnalités récursive, qui est un algorithme d'élimination des fonctionnalités glouton similaire à la sélection arrière séquentielle. Voir la documentation ici:

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


3
Bonne suggestion, mais le problème avec l'implémentation de sci-kit est que l'importance des fonctionnalités est quantifiée par les coefficients du modèle, c'est-à-dire si le modèle a une coef_interface. Ceci exclurait la méthode basée sur l’arbre, etc. Cependant, je pense que ce que @Maksud a demandé est ce qui est décrit dans "Une introduction à l’apprentissage statistique" de James, dans lequel les fonctionnalités sont ajoutées / supprimées de manière récursive par leur importance, qui est quantifiée par la précision de la validation. . Cela permet de sélectionner les caractéristiques de tous les types de modèles, et non des modèles paramétriques linéaires.
eggie5

9

Sklearn a un algorithme de sélection directe, bien qu'il ne s'appelle pas cela dans scikit-learn. La méthode de sélection des fonctionnalités appelée F_regression dans scikit-learn inclura séquentiellement les fonctionnalités qui améliorent le plus le modèle, jusqu'à ce qu'il y ait des Kfonctionnalités dans le modèle (K est une entrée).

Il commence par régresser individuellement les étiquettes de chaque entité, puis en observant laquelle améliore le modèle le plus à l'aide de la statistique F. Ensuite, il intègre la fonctionnalité gagnante dans le modèle. Il parcourt ensuite les fonctionnalités restantes pour rechercher la fonctionnalité suivante qui améliore le plus le modèle, en utilisant à nouveau la statistique F ou le test F. Cela jusqu’à ce qu’il y ait K caractéristiques dans le modèle.

Notez que les entités restantes qui sont en corrélation avec les entités incorporées dans le modèle ne seront probablement pas sélectionnées, car elles ne sont pas en corrélation avec les résidus (bien qu'elles puissent être en corrélation avec les étiquettes). Cela aide à se protéger contre la multi-colinéarité.



1
Voulez-vous dire Select K-best ?
Nitro

Oui. Vous devriez également lire ceci: stats.stackexchange.com/questions/204141/… .
Candic3

2
C'est une sorte de sélection en avant. Mais ce n'est pas générique - il est spécifique à un modèle de régression linéaire, alors que la sélection en aval peut fonctionner avec n'importe quel modèle (agnostique), comme le RFE et peut gérer des problèmes de classification ou de régression. Mais je soupçonne que la plupart des gens recherchent ce cas d'utilisation et il est certainement bon de le mentionner ici.
Simon

2
Ce n'est pas une sélection STEPWISE, car chaque p-valeur est calculée pour une régression univariée, indépendamment de toutes les autres covariables.
David Dale

9

Scikit-learn ne prend effectivement pas en charge la régression par étapes. En effet, ce qu'on appelle communément la «régression par étapes» est un algorithme basé sur les valeurs p des coefficients de régression linéaire, et scikit-learn évite délibérément l'approche par inférence de l'apprentissage par modèle (test de signification, etc.). De plus, la pure méthode MLS n'est que l'un des nombreux algorithmes de régression et, du point de vue de l'acquisition de connaissances scientifiques, ce n'est ni très important, ni l'un des meilleurs.

Il y a cependant quelques conseils à donner à ceux qui ont encore besoin d'un bon moyen de sélectionner des fonctionnalités avec des modèles linéaires:

  1. Utilisez des modèles intrinsèquement clairs comme ElasticNetou Lasso.
  2. Normalisez vos fonctionnalités avec StandardScaler, puis commandez-les simplement par model.coef_. Pour des covariables parfaitement indépendantes, cela équivaut à un tri par valeurs p. La classe le sklearn.feature_selection.RFEfera pour vous et RFECVévaluera même le nombre optimal de fonctionnalités.
  3. R2statsmodels
  4. Effectuez une sélection en avant ou en arrière par force brute afin de maximiser votre métrique préférée lors de la validation croisée (cela peut prendre un temps approximativement quadratique en nombre de covariables). Un mlxtendpackage compatible avec scikit-learn prend en charge cette approche pour tout estimateur et toute métrique.
  5. Si vous souhaitez toujours une régression progressive vanille, il est plus facile de la baser statsmodels, car ce package calcule les valeurs p pour vous. Une sélection de base en avant-arrière pourrait ressembler à ceci:

`` `

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)

Cet exemple afficherait le résultat suivant:

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

Le code de régression pas à pas publié ne fonctionne pas correctement. La régression pas à pas inverse devrait donner des résultats identiques, mais ce n’est pas le cas. Il renvoie les facteurs avec des valeurs p supérieures au seuil lorsque vous réexécutez la régression. J'ai également exécuté le même jeu de données avec STATA et les mêmes seuils en utilisant la méthode inverse, pas à pas, pour obtenir des résultats sensiblement différents. Fondamentalement, ne l'utilisez pas. Je vais écrire mon propre code de régression pas à pas arrière en utilisant son modèle.
Michael Corley MBA LSSBB Le

Les régressions par étapes en avant et en arrière ne sont en aucun cas garanties de converger vers la même solution. Et si vous avez remarqué un bogue dans ma solution, veuillez joindre le code pour le reproduire.
David Dale

1

En fait, il existe un algorithme appelé "Forward_Select" qui utilise Statsmodels et vous permet de définir votre propre métrique (AIC, BIC, Adjusted-R-Squared ou ce que vous préférez) pour ajouter progressivement une variable au modèle. L'algorithme peut être trouvé dans la section commentaires de cette page - faites défiler vers le bas et vous le verrez au bas de la page.

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

J'ajouterais que l'algorithme a aussi une fonctionnalité intéressante: vous pouvez l'appliquer à des problèmes de classification ou de régression! Vous devez juste le dire.

Essayez-le et voyez par vous-même.


0

En réalité, sklearn ne dispose pas d'algorithme de sélection directe, pensait une demande d'extraction avec une implémentation de la sélection des fonctionnalités avancées attend dans le référentiel Scikit-Learn depuis avril 2017.

Comme alternative, il y a une sélection en avant et une étape en avant dans mlxtend . Vous pouvez trouver son document dans le sélecteur de fonctions séquentiel

En utilisant notre site, vous reconnaissez avoir lu et compris notre politique liée aux cookies et notre politique de confidentialité.
Licensed under cc by-sa 3.0 with attribution required.