web-dev-qa-db-fra.com

Scikit Grid Recherche sur plusieurs classificateurs

Je voulais savoir s'il existe une meilleure façon plus intégrée de faire une recherche de grille et de tester plusieurs modèles dans un seul pipeline. Bien sûr, les paramètres des modèles seraient différents, ce qui est fait est compliqué pour que cela puisse comprendre cela. Voici ce que j'ai fait:

from sklearn.pipeline import Pipeline
from sklearn.ensemble import RandomForestClassifier
from sklearn.neighbors import KNeighborsClassifier
from sklearn.svm import SVC
from sklearn.naive_bayes import MultinomialNB
from sklearn.grid_search import GridSearchCV


def grid_search():
    pipeline1 = Pipeline((
    ('clf', RandomForestClassifier()),
    ('vec2', TfidfTransformer())
    ))

    pipeline2 = Pipeline((
    ('clf', KNeighborsClassifier()),
    ))

    pipeline3 = Pipeline((
    ('clf', SVC()),
    ))

    pipeline4 = Pipeline((
    ('clf', MultinomialNB()),
    ))

    parameters1 = {
    'clf__n_estimators': [10, 20, 30],
    'clf__criterion': ['gini', 'entropy'],
    'clf__max_features': [5, 10, 15],
    'clf__max_depth': ['auto', 'log2', 'sqrt', None]
    }

    parameters2 = {
    'clf__n_neighbors': [3, 7, 10],
    'clf__weights': ['uniform', 'distance']
    }

    parameters3 = {
    'clf__C': [0.01, 0.1, 1.0],
    'clf__kernel': ['rbf', 'poly'],
    'clf__gamma': [0.01, 0.1, 1.0],

    }
    parameters4 = {
    'clf__alpha': [0.01, 0.1, 1.0]
    }

    pars = [parameters1, parameters2, parameters3, parameters4]
    pips = [pipeline1, pipeline2, pipeline3, pipeline4]

    print "starting Gridsearch"
    for i in range(len(pars)):
        gs = GridSearchCV(pips[i], pars[i], verbose=2, refit=False, n_jobs=-1)
        gs = gs.fit(X_train, y_train)
        print "finished Gridsearch"
        print gs.best_score_

Cependant, cette approche donne toujours le meilleur modèle au sein de chaque classificateur et ne comparant pas les classificateurs.

30
Anuj

Bien que le sujet soit un peu vieux, je pose la réponse au cas où elle aide toute personne à l'avenir.

Au lieu d'utiliser la recherche de la grille de sélection hyperparameter, vous pouvez utiliser la bibliothèque "hyperopt" .

Veuillez consulter la section 2.2 de cette page . Dans le cas susmentionné, vous pouvez utiliser une expression "HP.CHOICE" pour sélectionner entre les différents pipelines, puis définissez les expressions de paramètres pour chacune séparément.

Dans votre fonction objectif, vous devez avoir un chèque en fonction du pipeline choisi et de renvoyer le score CV pour le pipeline et les paramètres sélectionnés (éventuellement via cross_cal_score ).

L'objet d'essais à la fin de l'exécution indiquera le meilleur pipeline et paramètres dans l'ensemble.

6
Stergios

Le post Hyperparameter Grid Recherche sur plusieurs modèles de Scikit-apprendre (par David S. Batista) propose une mise en œuvre mise à jour d'un estimateur EstimatorSelectionHelper pouvant exécuter des estimateurs différents, chacun avec sa propre grille. des paramètres.

18
dubek

Bien que la solution de Dubek soit plus simple, cela n'aide pas aux interactions entre les paramètres d'éléments de pipeline qui arrivent avant le classfier. Par conséquent, j'ai écrit A Classe d'assistance pour y faire face et peut être incluse dans le réglage du pipeline par défaut de Scikit. Un exemple minimal:

from sklearn.pipeline import Pipeline
from sklearn.model_selection import GridSearchCV
from sklearn.preprocessing import StandardScaler, MaxAbsScaler
from sklearn.svm import LinearSVC
from sklearn.ensemble import RandomForestClassifier
from sklearn import datasets
from pipelinehelper import PipelineHelper

iris = datasets.load_iris()
X_iris = iris.data
y_iris = iris.target
pipe = Pipeline([
    ('scaler', PipelineHelper([
        ('std', StandardScaler()),
        ('max', MaxAbsScaler()),
    ])),
    ('classifier', PipelineHelper([
        ('svm', LinearSVC()),
        ('rf', RandomForestClassifier()),
    ])),
])

params = {
    'scaler__selected_model': pipe.named_steps['scaler'].generate({
        'std__with_mean': [True, False],
        'std__with_std': [True, False],
        'max__copy': [True],  # just for displaying
    }),
    'classifier__selected_model': pipe.named_steps['classifier'].generate({
        'svm__C': [0.1, 1.0],
        'rf__n_estimators': [100, 20],
    })
}
grid = GridSearchCV(pipe, params, scoring='accuracy', verbose=1)
grid.fit(X_iris, y_iris)
print(grid.best_params_)
print(grid.best_score_)

Il peut également être utilisé pour d'autres éléments du pipeline, pas seulement le classificateur. Le code est sur github si quelqu'un veut vérifier.

8
bmurauer