Попробуйте выполнить несколько оценок в одном сетевом поиске

Есть ли способ, с помощью которого можно выполнить поиск по сетке по нескольким оценкам за один раз в Sklearn или любой другой библиотеке. Например, мы можем передавать SVM и Random Forest в один сетевой поиск?.

Ответ 1

Да. Пример:

pipeline = Pipeline([
    ('vect', CountVectorizer()),
    ('clf', SGDClassifier()),
])
parameters = [
    {
        'vect__max_df': (0.5, 0.75, 1.0),
        'clf': (SGDClassifier(),),
        'clf__alpha': (0.00001, 0.000001),
        'clf__penalty': ('l2', 'elasticnet'),
        'clf__n_iter': (10, 50, 80),
    }, {
        'vect__max_df': (0.5, 0.75, 1.0),
        'clf': (LinearSVC(),),
        'clf__C': (0.01, 0.5, 1.0)
    }
]
grid_search = GridSearchCV(pipeline, parameters)

Ответ 2

from sklearn.base import BaseEstimator
from sklearn.model_selection import GridSearchCV

class DummyEstimator(BaseEstimator):
    def fit(self): pass
    def score(self): pass

# Create a pipeline
pipe = Pipeline([('clf', DummyEstimator())]) # Placeholder Estimator

# Candidate learning algorithms and their hyperparameters
search_space = [{'clf': [LogisticRegression()], # Actual Estimator
                 'clf__penalty': ['l1', 'l2'],
                 'clf__C': np.logspace(0, 4, 10)},

                {'clf': [DecisionTreeClassifier()],  # Actual Estimator
                 'clf__criterion': ['gini', 'entropy']}]


# Create grid search 
gs = GridSearchCV(pipe, search_space)

Ответ 3

Я думаю, что вы искали:

from sklearn.svm import LinearSVC
from sklearn.linear_model import LogisticRegression
from sklearn.ensemble import RandomForestClassifier
from sklearn.neural_network import MLPClassifier
from sklearn.model_selection import GridSearchCV
from sklearn.model_selection import train_test_split

X_train, X_test, y_train, y_test = train_test_split(X, y, test_size=0.2, random_state=42)

names = [
         "Naive Bayes",
         "Linear SVM",
         "Logistic Regression",
         "Random Forest",
         "Multilayer Perceptron"
        ]

classifiers = [
    MultinomialNB(),
    LinearSVC(),
    LogisticRegression(),
    RandomForestClassifier(),
    MLPClassifier()
]

parameters = [
              {'vect__ngram_range': [(1, 1), (1, 2)],
              'clf__alpha': (1e-2, 1e-3)},
              {'vect__ngram_range': [(1, 1), (1, 2)],
              'clf__C': (np.logspace(-5, 1, 5))},
              {'vect__ngram_range': [(1, 1), (1, 2)],
              'clf__C': (np.logspace(-5, 1, 5))},
              {'vect__ngram_range': [(1, 1), (1, 2)],
              'clf__max_depth': (1, 2)},
              {'vect__ngram_range': [(1, 1), (1, 2)],
              'clf__alpha': (1e-2, 1e-3)}
             ]

for name, classifier, params in zip(names, classifiers, parameters):
    clf_pipe = Pipeline([
        ('vect', TfidfVectorizer(stop_words='english')),
        ('clf', classifier),
    ])
    gs_clf = GridSearchCV(clf_pipe, param_grid=params, n_jobs=-1)
    clf = gs_clf.fit(X_train, y_train)
    score = clf.score(X_test, y_test)
    print("{} score: {}".format(name, score))

Ответ 4

Вы можете использовать TransformedTargetRegressor. Этот класс предназначен для преобразования целевой переменной перед установкой, принимая в качестве параметров регрессор и набор трансформаторов. Но вы можете не давать преобразователь, тогда применяется преобразователь идентификатора (т.е. без преобразования). Поскольку регрессор является параметром класса, мы можем изменить его с помощью сетки поиска объектов.

import numpy as np
from sklearn.compose import TransformedTargetRegressor
from sklearn.linear_model import LinearRegression
from sklearn.neural_network import MLPRegressor
from sklearn.model_selection import GridSearchCV

Y = np.array([1,2,3,4,5,6,7,8,9,10])
X = np.array([0,1,3,5,3,5,7,9,8,9]).reshape((-1, 1))

Для поиска по сетке мы должны указать param_grid в виде списка dict, каждый для разных оценок. Это связано с тем, что разные оценщики используют разный набор параметров (например, установка fit_intercept с MLPRegressor вызывает ошибку). Обратите внимание, что имя "регрессор" автоматически присваивается регрессору.

model = TransformedTargetRegressor()
params = [
    {
        "regressor": [LinearRegression()],
        "regressor__fit_intercept": [True, False]
    },
    {
        "regressor": [MLPRegressor()],
        "regressor__hidden_layer_sizes": [1, 5, 10]
    }
]

Мы можем соответствовать как обычно.

g = GridSearchCV(model, params)
g.fit(X, Y)

g.best_estimator_, g.best_score_, g.best_params_

# results in like
(TransformedTargetRegressor(check_inverse=True, func=None, inverse_func=None,
               regressor=LinearRegression(copy_X=True, fit_intercept=False, n_jobs=None,
          normalize=False),
               transformer=None),
 -0.419213380219391,
 {'regressor': LinearRegression(copy_X=True, fit_intercept=False, n_jobs=None,
           normalize=False), 'regressor__fit_intercept': False})

Ответ 5

Что вы можете сделать, это создать класс, который принимает любой классификатор и для каждого классификатора любые настройки параметров.

Создать класс переключателя, который работает для любого оценщика

from sklearn.base import BaseEstimator
class ClfSwitcher(BaseEstimator):

def __init__(
    self, 
    estimator = SGDClassifier(),
):
    """
    A Custom BaseEstimator that can switch between classifiers.
    :param estimator: sklearn object - The classifier
    """ 

    self.estimator = estimator


def fit(self, X, y=None, **kwargs):
    self.estimator.fit(X, y)
    return self


def predict(self, X, y=None):
    return self.estimator.predict(X)


def predict_proba(self, X):
    return self.estimator.predict_proba(X)


def score(self, X, y):
    return self.estimator.score(X, y)

Теперь вы можете предварительно тренировать свой tfidf так, как вам нравится.

from sklearn.feature_extraction.text import TfidfVectorizer
tfidf = TfidfVectorizer()
tfidf.fit(data, labels)

Теперь создайте конвейер с этим предварительно обученным tfidf.

from sklearn.pipeline import Pipeline

pipeline = Pipeline([
    ('tfidf',tfidf), # Already pretrained/fit
    ('clf', ClfSwitcher()),
])

Выполнить гиперпараметрическую оптимизацию

from sklearn.naive_bayes import MultinomialNB
from sklearn.linear_model import SGDClassifier
from sklearn.model_selection import GridSearchCV



parameters = [
    {
        'clf__estimator': [SGDClassifier()], # SVM if hinge loss / logreg if log loss
        'clf__estimator__penalty': ('l2', 'elasticnet', 'l1'),
        'clf__estimator__max_iter': [50, 80],
        'clf__estimator__tol': [1e-4],
        'clf__estimator__loss': ['hinge', 'log', 'modified_huber'],
    },
    {
        'clf__estimator': [MultinomialNB()],
        'clf__estimator__alpha': (1e-2, 1e-3, 1e-1),
    },
]

gscv = GridSearchCV(pipeline, parameters, cv=5, n_jobs=12, verbose=3)
# param optimization
gscv.fit(train_data, train_labels)

Как интерпретировать clf__estimator__loss

clf__estimator__loss интерпретируется как параметр loss для любого estimator, где estimator = SGDClassifier() в самом верхнем примере и сам является параметром clf который является объектом ClfSwitcher.