Python 为什么GridSearchCV在';thread.lock';对象的{method';acquire';上花费了50%以上的时间?

Python 为什么GridSearchCV在';thread.lock';对象的{method';acquire';上花费了50%以上的时间?,python,scikit-learn,Python,Scikit Learn,最近,我正在调整我的一些机器学习管道。我决定利用我的多核处理器。我用paramn_jobs=-1运行了交叉验证。我还介绍了它,让我惊讶的是:最重要的功能是: {method 'acquire' of 'thread.lock' objects} 我不确定这是否是由于我在管道中执行的操作造成的。所以我决定做一个小实验: pp = Pipeline([('svc', SVC())]) cv = GridSearchCV(pp, {'svc__C' : [1, 100, 200]}, jobs=-1

最近,我正在调整我的一些机器学习管道。我决定利用我的多核处理器。我用param
n_jobs=-1
运行了交叉验证。我还介绍了它,让我惊讶的是:最重要的功能是:

{method 'acquire' of 'thread.lock' objects}
我不确定这是否是由于我在
管道中执行的操作造成的。所以我决定做一个小实验:

pp = Pipeline([('svc', SVC())])
cv = GridSearchCV(pp, {'svc__C' : [1, 100, 200]}, jobs=-1, cv=2, refit=True)
%prun cv.fit(np.random.rand(1e4, 100), np.random.randint(0, 5, 1e4))
输出为:

2691 function calls (2655 primitive calls) in 74.005 seconds
Ordered by: internal time

ncalls  tottime  percall  cumtime  percall filename:lineno(function)
   83   43.819    0.528   43.819    0.528 {method 'acquire' of 'thread.lock' objects}
    1   30.112   30.112   30.112   30.112 {sklearn.svm.libsvm.fit}

我想知道这种行为的原因是什么。如果可能的话,可以稍微加快一点。

探查器只告诉您主进程正在做什么,而它的子进程正在做所有的工作。在这种情况下,在GridSearchCV上设置
verbose=2
可能会比
%prun
提供更好的输出。

实际的挂钟时间下降了吗?是的。从:
1个循环,每个循环最好3:2min 7s
使用一个作业到
1个循环,每个循环最好3:1min 20s
使用四个。然后,分析器可能只是告诉您主进程在做什么,而它的子进程正在做所有的工作。事实上,处理实际上是由多处理子进程完成的。您需要一种方法将探查器插入其中一个。但是,它不认为可以用
%prun
魔法来分析子进程。@larsmans你的评论应该是答案。我不太明白这个答案。在一个实际大小的数据集上尝试您的建议,详细程度将不会向您显示时间花费在哪里。在我的例子中,详细程度显示了~30秒的计算时间,即计算单个交叉验证分数所需的时间,但没有显示两个交叉验证分数之间>4分钟的时间间隔,无论详细程度如何,都不会打印任何内容。