Python 使用MLFlow执行GridSearchCV

Python 使用MLFlow执行GridSearchCV,python,scikit-learn,mlflow,Python,Scikit Learn,Mlflow,我刚开始使用MLFlow,我对它的功能很满意。但是,我无法从scikit learn中找到一种在GridSearchCV中记录不同运行的方法 例如,我可以手动执行此操作 params = ['l1', 'l2'] for param in params: with mlflow.start_run(experiment_id=1): clf = LogisticRegression(penalty = param).fit(X_train, y_train)

我刚开始使用MLFlow,我对它的功能很满意。但是,我无法从scikit learn中找到一种在
GridSearchCV
中记录不同运行的方法

例如,我可以手动执行此操作

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测试的所有单个模型。有什么方法可以做到这一点,或者我必须继续使用手动过程吗?

我建议不要使用scikit learn的
GridSearchCV
。Hyperopt可以使用
Hyperopt.tpe.suggest
使用贝叶斯优化搜索空间。它将比网格搜索更快地得到好的参数,并且无论空间大小如何,您都可以限制迭代次数,因此对于大空间来说,它肯定更好。因为您对单个运行的工件感兴趣,所以您可能更喜欢hyperopt的随机搜索,它仍然具有能够选择执行多少次运行的优势

您可以使用
hyperopt.SparkTrials
(这是一个更完整的示例)非常轻松地使用Spark并行化搜索。请注意,您可以继续使用scikit的交叉验证,只需将其放入目标函数中(您甚至可以使用跟踪交叉验证的方差)

现在,为了真正回答这个问题,我相信您可以在传递给
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)