Выполнить GridSearchCV с MLFlow - PullRequest
       14

Выполнить GridSearchCV с MLFlow

0 голосов
/ 02 апреля 2020

Я только начал использовать MLFlow, и я доволен тем, что он может сделать. Тем не менее, я не могу найти способ регистрировать различные прогоны в GridSearchCV из scikit learn.

Например, я могу сделать это вручную

params = ['l1', 'l2']
for param in params:
    with mlflow.start_run(experiment_id=1):
        clf = LogisticRegression(penalty = param).fit(X_train, y_train)
        y_predictions = clf.predict(X_test)

        precision = precision_score(y_test, y_predictions)
        recall = recall_score(y_test, y_predictions)
        f1 = f1_score(y_test, y_predictions)

        mlflow.log_param("penalty", param)
        mlflow.log_metric("Precision", precision)
        mlflow.log_metric("Recall", recall)
        mlflow.log_metric("F1", f1)

        mlflow.sklearn.log_model(clf, "model")

Но когда я хочу использовать GridSearchCV вот так

pipe = Pipeline([('classifier' , RandomForestClassifier())])

param_grid = [
    {'classifier' : [LogisticRegression()],
     'classifier__penalty' : ['l1', 'l2'],
    'classifier__C' : np.logspace(-4, 4, 20),
    'classifier__solver' : ['liblinear']},
    {'classifier' : [RandomForestClassifier()],
    'classifier__n_estimators' : list(range(10,101,10)),
    'classifier__max_features' : list(range(6,32,5))}
]


clf = GridSearchCV(pipe, param_grid = param_grid, cv = 5, verbose=True, n_jobs=-1)

best_clf = clf.fit(X_train, y_train)

Я не могу придумать, как записать все отдельные модели, которые тестирует GridSearch. Есть ли способ сделать это, или я должен продолжать использовать ручной процесс?

1 Ответ

0 голосов
/ 03 апреля 2020

Я бы рекомендовал hyperopt вместо scikit-learn's GridSearchCV. Hyperopt может искать пространство с помощью байесовской оптимизации, используя hyperopt.tpe.suggest. Он получит хорошие параметры быстрее, чем поиск по сетке, и вы можете ограничить число итераций независимо от размера пространства, поэтому это определенно лучше для больших пространств. Поскольку вас интересуют артефакты из отдельных прогонов, вы можете предпочесть случайный поиск в hyperopt, который по-прежнему имеет преимущество в выборе того, сколько прогонов вы выполняете.

Вы можете очень легко распараллелить поиск с помощью Spark, используя hyperopt.SparkTrials ( здесь - более полный пример). Обратите внимание, что вы можете продолжать использовать перекрестную проверку Scikit, просто поместив ее в целевую функцию (вы даже можете отслеживать дисперсию перекрестной проверки, используя loss_variance ).

Теперь, чтобы на самом деле Отвечая на вопрос, я полагаю, что вы можете записать модель, параметры, метрики или что-то еще внутри целевой функции, которую вы передаете hyperopt.fmin. MLFlow будет хранить каждый прогон как дочерний элемент основного прогона, и каждый прогон может иметь свои собственные артефакты.

Итак, вы хотите что-то вроде этого:

def objective(params):
    metrics = ...
    classifier = SomeClassifier(**params)
    cv = cross_validate(classifier, X_train, y_train, scoring = metrics)
    scores = {metric: cv[f'test_{metric}'] for metric in metrics}
    # log all the stuff here
    mlflow.log_metric('...', scores[...])
    mlflow.sklearn.log_model(classifier.fit(X_train, y_train))
    return scores['some_loss'].mean()

space = hp.choice(...)
trials = SparkTrials(parallelism = ...)
with mlflow.start_run() as run:
    best_result = fmin(fn = objective, space = space, algo = tpe.suggest, max_evals = 100, trials = trials)
...