如何使用sklearn禁用ConvergenceWarning?

Boh*_* Xu 4 warnings scikit-learn

我正在使用GridSearchCV优化SVM的超参数。我设置了最大迭代次数,因为我迫不及待要几个小时才能得到结果。我知道会有收敛警告。我只想忽略这些警告,而不显示在终端中。

提前致谢。

Yah*_*hya 15

我会在这里做一个长镜头。

您没有提供足够的信息。您刚刚提到您正在使用SVM但没有提到哪种类型,SVM因为它有很多实现,例如SVC,NuSVCLinearSVC。这些不同的类型具有不同的属性。

为什么要关心?因为其中一些支持/接受并行执行作业,例如LinearSVC一个!

with warnings.catch_warnings():
    warnings.filterwarnings("ignore", category=ConvergenceWarning)
Run Code Online (Sandbox Code Playgroud)

上面的代码(或它的其他变体)应该可以完成这项工作,但如果它并行运行,它只会在第一次运行/迭代中完成(我不太确定为什么,但似乎每个工作都有自己的Pythonic 配置好像是一个新实例什么的!)


另外,您提到您正在使用GridSearchCVwhich 也有n_job参数。它的Scikit文档说:

要并行运行的作业数。None 意味着 1 除非在 joblib.parallel_backend 上下文中。-1 表示使用所有处理器

joblib.parallel_backend 表示在估算器或任何预先定义的配置中设置的作业数量。


概括

并行运行作业可能是不抑制警告的原因。需要来自 OP 的更多信息。


编辑

我又查了一下,确实,使用GridSearchCVscikit-learn版本0.20.3 max_iter ,同时抑制警告,导致以下结果:

  1. SVC or LinearSVC+ GridSearchCV(n_jobs=-1 or >1):无法抑制警告。
  2. SVC or LinearSVC+ GridSearchCV(n_jobs=None or 1):成功抑制警告。
  3. LogisticRegression(n_jobs=-1, solver='sag')+ GridSearchCV(n_jobs=None or 1 or >1 or -1):无法抑制警告。
  4. LogisticRegression(n_jobs=1, solver='sag')+ GridSearchCV(n_jobs=-1 or >1):无法抑制警告。
  5. LogisticRegression(n_jobs=1, solver='sag')+ GridSearchCV(n_jobs=None or 1):成功抑制警告。

如您所见,如果估算器支持多作业,n_jobs=-1 or >1则无论n_jobsGridSearchCV. 另一方面,如果 estimator 不支持 multi-jobs,设置n_jobs=-1 or >1inGridSearchCV不会使警告抑制工作,但是,设置n_jobs=None or 1会使它工作。

重要的提示

这就是我在0.20.3scikit-learn版本中发现的内容,但是,我在另一台0.19.2scikit-learn版本的笔记本电脑上尝试了它,并且无论如何抑制警告始终有效!我检查了scikit-learnGitHub 存储库并注意到joblib自 0.19.2 版以来的一些提交,但我不确定是否存在导致上述行为的真正更改/更新!你可能想在那里开一张票并参考上面的结果。


更新

我可以抑制所有Scikit-learn警告的唯一方法是在模块的开头发出以下代码。(但请注意,这将抑制包括您在内的所有警告 - 我需要它,因为我已将日志保存到数据库中):

if not sys.warnoptions:
    warnings.simplefilter("ignore")
    os.environ["PYTHONWARNINGS"] = "ignore" # Also affect subprocesses
Run Code Online (Sandbox Code Playgroud)

  • “n_jobs”和并行处理的出色发现让我难住了。 (4认同)
  • 很好的答案!这是唯一有助于抑制“RandomizedSearchCV”和“GridSearchCV”与“njobs>1”警告的答案!为了专门禁用警告,我将最后一行更改为: `os.environ["PYTHONWARNINGS"] = ('ignore::UserWarning,ignore::ConvergenceWarning,ignore::RuntimeWarning')`。指定要忽略警告的模块也是一个很好的补充:``os.environ["PYTHONWARNINGS"] = 'ignore::ConvergenceWarning:sklearn.model_selection.RandomizedSearchCV'` (2认同)
  • 我不再收到警告消息。很有帮助。谢谢@叶海亚!@JE_Muc 也感谢您的宝贵评论。 (2认同)

sim*_*ing 10

This was a pain to track down, as all suggested answers I've seen simply do not work. What finally worked for me was in the example code Early stopping of Stochastic Gradient Descent:

from sklearn.utils.testing import ignore_warnings
from sklearn.exceptions import ConvergenceWarning
Run Code Online (Sandbox Code Playgroud)

You can then annotate a function like so:

@ignore_warnings(category=ConvergenceWarning)
def my_function():
    # Code that triggers the warning
Run Code Online (Sandbox Code Playgroud)

Note that you need not directly import anything from warnings.

I think that's quite nice as it will only suppress warnings in the specific case where you need it, rather than globally.

  • 请注意,'sklearn.utils.testing' 自 0.22 起已弃用,并将在 0.24 中删除。看来“sklearn.utils._testing”(注意额外的下划线)是现在的方法 - 请参阅https://scikit-learn.org/stable/auto_examples/linear_model/plot_sgd_early_stopping.html#sphx-glr-auto-示例线性模型图 sgd-early-stopping-py (3认同)
  • 它只是有点在生产中导入“测试”代码的味道,但是......好吧...... (2认同)

Tho*_* G. 8

为了控制 Python 警告,您可以使用警告库。请参阅此处的详细文档。所以你可以使用warning.simplefilter()方法如下:

from warnings import simplefilter
from sklearn.exceptions import ConvergenceWarning
simplefilter("ignore", category=ConvergenceWarning)
Run Code Online (Sandbox Code Playgroud)


小智 7

尝试这个:

from warnings import filterwarnings
filterwarnings('ignore')
Run Code Online (Sandbox Code Playgroud)