Как использовать GridSearchCV вместе с конвейером и гиперпараметром в python - PullRequest
2 голосов
/ 08 мая 2020

Я использую два оценщика, Randomforest и SVM

random_forest_pipeline=Pipeline([   
    ('vectorizer',CountVectorizer(stop_words='english')),
    ('random_forest',RandomForestClassifier())
])
svm_pipeline=Pipeline([
    ('vectorizer',CountVectorizer(stop_words='english')),
    ('svm',LinearSVC())
])

Я хочу сначала векторизовать данные, а затем использовать оценщик, я просматривал этот онлайн учебник . затем я использую гиперпараметр следующим образом:

parameters=[
    {
        'vectorizer__max_features':[500,1000,1500],
        'random_forest__min_samples_split':[50,100,250,500]
    },
    {
        'vectorizer__max_features':[500,1000,1500],
        'svm__C':[1,3,5]
    }
]

и передаю в GridSearchCV

pipelines=[random_forest_pipeline,svm_pipeline]
grid_search=GridSearchCV(pipelines,param_grid=parameters,cv=3,n_jobs=-1)
grid_search.fit(x_train,y_train)

, но когда я запускаю код, я получаю сообщение об ошибке

TypeError: оценщик должен быть оценщиком, реализующим метод «подгонки»

Не знаю, почему я получаю эту ошибку

Ответы [ 2 ]

2 голосов
/ 08 мая 2020

Проблема в том, что pipelines=[random_forest_pipeline,svm_pipeline] - это список, не имеющий метода fit.

Даже если бы вы могли заставить его работать таким образом, в какой-то момент 'random_forest__min_samples_split':[50,100,250,500] будет передан в svm_pipeline, и это вызовет ошибку.

ValueError: Недопустимый параметр svm для конвейера оценки

Вы не можете смешать таким образом 2 конвейера, потому что в какой-то момент вы запрашиваете svm_pipeline оценивается с использованием значений random_forest__min_samples_split, и это НЕВЕРНО.


Решение: Fit a GridSearch object for the Random forest model and another GridSearch object for the SVC model

pipelines=[random_forest_pipeline,svm_pipeline]

grid_search_1=GridSearchCV(pipelines[0],param_grid=parameters[0],cv=3,n_jobs=-1)
grid_search_1.fit(X,y)

grid_search_2=GridSearchCV(pipelines[1],param_grid=parameters[1],cv=3,n_jobs=-1)
grid_search_2.fit(X,y)

Полный код:

random_forest_pipeline=Pipeline([   
    ('vectorizer',CountVectorizer(stop_words='english')),
    ('random_forest',RandomForestClassifier())
])
svm_pipeline=Pipeline([
    ('vectorizer',CountVectorizer(stop_words='english')),
    ('svm',LinearSVC())
])

parameters=[
    {
        'vectorizer__max_features':[500,1000,1500],
        'random_forest__min_samples_split':[50,100,250,500]
    },
    {
        'vectorizer__max_features':[500,1000,1500],
        'svm__C':[1,3,5]
    }
]

pipelines=[random_forest_pipeline,svm_pipeline]

# gridsearch only for the Random Forest model
grid_search_1 =GridSearchCV(pipelines[0],param_grid=parameters[0],cv=3,n_jobs=-1)
grid_search_1.fit(X,y)

# gridsearch only for the SVC model
grid_search_2 =GridSearchCV(pipelines[1],param_grid=parameters[1],cv=3,n_jobs=-1)
grid_search_2.fit(X,y)

EDIT

Если вы явно определяете модели в списке param_grid, то это возможно на основе документации.

Ссылка: https://scikit-learn.org/stable/auto_examples/compose/plot_compare_reduction.html?highlight=pipeline%20gridsearch

Код из do c:

import numpy as np
import matplotlib.pyplot as plt
from sklearn.datasets import load_digits
from sklearn.model_selection import GridSearchCV
from sklearn.pipeline import Pipeline
from sklearn.svm import LinearSVC
from sklearn.decomposition import PCA, NMF
from sklearn.feature_selection import SelectKBest, chi2

print(__doc__)

pipe = Pipeline([
    # the reduce_dim stage is populated by the param_grid
    ('reduce_dim', 'passthrough'),
    ('classify', LinearSVC(dual=False, max_iter=10000))
])

N_FEATURES_OPTIONS = [2, 4, 8]
C_OPTIONS = [1, 10, 100, 1000]
param_grid = [
    {
        'reduce_dim': [PCA(iterated_power=7), NMF()],
        'reduce_dim__n_components': N_FEATURES_OPTIONS,
        'classify__C': C_OPTIONS
    },
    {
        'reduce_dim': [SelectKBest(chi2)],
        'reduce_dim__k': N_FEATURES_OPTIONS,
        'classify__C': C_OPTIONS
    },
]
reducer_labels = ['PCA', 'NMF', 'KBest(chi2)']

grid = GridSearchCV(pipe, n_jobs=1, param_grid=param_grid)
X, y = load_digits(return_X_y=True)
grid.fit(X, y)
1 голос
/ 08 мая 2020

Вполне возможно сделать это за один Pipeline / GridSearchCV, основываясь на примере здесь .

Вам просто нужно явно указать метод scoring для конвейера, поскольку мы не объявляем окончательную оценку изначально.

Пример:

from sklearn.feature_extraction.text import CountVectorizer
from sklearn.pipeline import Pipeline
from sklearn.ensemble import RandomForestClassifier
from sklearn.svm import LinearSVC


my_pipeline = Pipeline([
    ('vectorizer', CountVectorizer(stop_words='english')),
    ('clf', 'passthrough')
])


parameters = [
    {
        'vectorizer__max_features': [500, 1000],
        'clf':[RandomForestClassifier()],
        'clf__min_samples_split':[50, 100,]
    },
    {
        'vectorizer__max_features': [500, 1000],
        'clf':[LinearSVC()],
        'clf__C':[1, 3]
    }
]

grid_search = GridSearchCV(my_pipeline, param_grid=parameters, cv=3, n_jobs=-1, scoring='accuracy')
grid_search.fit(X, y)

grid_search.best_params_

# {'clf': RandomForestClassifier(bootstrap=True, ccp_alpha=0.0, class_weight=None,
#                         criterion='gini', max_depth=None, max_features='auto',
#                         max_leaf_nodes=None, max_samples=None,
#                         min_impurity_decrease=0.0, min_impurity_split=None,
#                         min_samples_leaf=1, min_samples_split=100,
#                         min_weight_fraction_leaf=0.0, n_estimators=100,
#                         n_jobs=None, oob_score=False, random_state=None,
#                         verbose=0, warm_start=False),
#  'clf__min_samples_split': 100,
#  'vectorizer__max_features': 1000}



pd.options.display.max_colwidth =-1
pd.DataFrame(grid_search.cv_results_)[['param_vectorizer__max_features',
                                       'param_clf__min_samples_split',
                                       'param_clf__C','mean_test_score',
                                       'rank_test_score']]

введите описание изображения здесь

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...