3

我想为我的数据尝试几种不同的模型并交叉验证它们,因此结果有些可靠。

对于我的交叉验证,我调用:

cross_val_score(model, X, y, scoring = 'mean_squared_error', cv=kf, n_jobs = -1)

它并行执行了我的 10 倍交叉验证。由于我正在运行的机器有 40 个内核和足够的内存,我想并行尝试四个不同的“模型”值,每个值都进行 10 倍交叉验证。

但是,当我尝试以下列方式使用 joblib 时,出现错误:

results = Parallel(n_jobs = num_jobs)(delayed(crossVal)(model) for model in models)

/usr/local/lib/python2.7/dist-packages/sklearn/cross_validation.py:1433: UserWarning: Multiprocessing-backed parallel loops cannot be nested, setting n_jobs=1 for train, test in cv)

其中crossVal是我定义的一个方法,主要是调用cross_val_score。

有没有一种优雅的方法可以在不手动启动几个不同的 python 文件的情况下做到这一点?

4

1 回答 1

1

Joblib 可以使用多处理和线程后端,默认情况下它使用多处理(这是因为 CPython 实现,线程仅在某些特定情况下会更快,我不想在这里详细介绍,你可以找到大量关于CPython 和 Python GIL)。

这不是错误,它只是一个警告,告诉您您尝试从进程创建进程。即通过这一行:

results = Parallel(n_jobs = num_jobs)(delayed(crossVal)(model) for model in models)

您已经生成了一些进程(n_jobs),然后cross_val_score您内部的每个进程都crossVal尝试做同样的事情(生成一些进程),因为默认情况下 cross_val_score 使用多处理。Joblib 不允许使用多处理后端执行此类操作。因此 AFAIK 它给出了这个警告并在单个进程中运行嵌套的并行循环,即cross_val_score内部现在在单线程中运行,但您的crossVal函数仍然在多处理模式下运行。

如果你摆脱了这两个多处理周期中的任何一个,你可以避免这个警告,即你可以通过调用来摆脱嵌套的多处理:

cross_val_score(..., n_jobs=1)

在您的函数中,或者您可以在简单循环中多次crossVal调用默认值,无需多处理,然后聚合结果,例如:cross_val_score

results = [cross_val_score(estimator = est, ...) for est in estimators]

在第一种情况下,您可以min(n_models, n_jobs)同时运行(在原始情况下,当 joblib 发出警告时,您已经隐式执行此操作),在第二种情况下 - min(n_folds, n_cores)。如果你想运行min(n_jobs, n_models*n_folds),你应该使用GridSearchCV,因为它在内部以这种方式产生作业:

    out = Parallel(
        n_jobs=self.n_jobs, verbose=self.verbose,
        pre_dispatch=pre_dispatch
    )(
        delayed(_fit_and_score)(clone(base_estimator), X, y, self.scorer_,
                                train, test, self.verbose, parameters,
                                self.fit_params, return_parameters=True,
                                error_score=self.error_score)
            for parameters in parameter_iterable
            for train, test in cv)
于 2015-12-01T03:09:36.517 回答