我正在尝试使用以下代码进行特征选择:
from sklearn.feature_selection import SequentialFeatureSelector
from sklearn.discriminant_analysis import LinearDiscriminantAnalysis
model = LinearDiscriminantAnalysis(solver='svd')
sfs = SequentialFeatureSelector(model, n_features_to_select=3, direction='forward', n_jobs=-2, cv=3, scoring='accuracy')
sfs.fit(X, y)
其中 X 的形状为 (213661, 354)
但是,无论我设置
n_jobs
参数什么,sklearn 似乎从不使用超过 1 个线程进行计算。当我运行终端命令htop
时,这一点立即显而易见。下面的屏幕截图显示了在上述htop
运行期间SequentialFeatureSelector
的输出(这是一个共享服务器,所以其他人也在使用RAM)。
我正在运行一台有 80 个线程的 Linux 机器(每个内核 2 个线程,每个插槽 20 个内核,2 个插槽)。将 n_jobs 更改为对运行时的边际影响,如下代码所示:
from sklearn.feature_selection import SequentialFeatureSelector
from sklearn.discriminant_analysis import LinearDiscriminantAnalysis
model = LinearDiscriminantAnalysis(solver='svd')
for j in [-2, 20, 40]:
start = time.time()
sfs = SequentialFeatureSelector(model, n_features_to_select=3, direction='forward', n_jobs=j, cv=3, scoring='accuracy')
sfs.fit(X, y)
stop = time.time()
print(stop-start)
产生以下输出:
341.53
289.15
303.93
看起来所有线程都可用,从这个命令可以看出:
import multiprocessing
n_cpus = multiprocessing.cpu_count()
print(n_cpus)
输出
80
此外,像 polars 这样的包在同一个 jupyter notebook 中成功地利用了并行化。
我知道 sklearn 利用 joblib 进行并行化,所以我尝试在 joblib 后端运行一些测试:
from joblib import Parallel, delayed
from math import sqrt
import time
for j in [-1, -2, 1, 10, 20, 40]:
start = time.time()
Parallel(n_jobs=j)(delayed(sqrt)(i ** 2) for i in range(400000))
stop = time.time()
print(stop-start)
取得成果
73.6
4.9
133.8
11.8
20.5
37.8
这表明 joblib 工作正常? (忽略从 10 到 40 的增加,这可能是由于并行化开销比计算本身成本更高)
为什么
n_jobs
参数输入没有反映在htop
输出中,也不影响运行时?我错过了什么,或者这种行为是预期的吗?任何帮助将不胜感激!
n_jobs
仅用于交叉验证,您只有 cv=3
这意味着只能同时训练 3 个分类器,因此只有 3 个核心被完全使用,如您的 htop
屏幕截图所示,其余逻辑是顺序的,并且不会被并行化。