我在循环中使用sklearn的OneVsRest
类进行内存使用时出现问题(我们不能使用sklearns交叉验证方法,原因与此问题无关)。
分类器的设置可能如下所示:
clf = make_pipeline(TfidfVectorizer(), OneVsRestClassifier(SGDClassifier(loss='log', n_iter=5, penalty=None, alpha=1e-7, average=True))
使用memory_profiler模块,内存使用情况如下所示:
Line # Mem usage Increment Line Contents
================================================
(...)
231 1092.8 MiB 911.7 MiB clf.fit(X_train, Y_train)
(...)
next loop:
231 2001.8 MiB 897.4 MiB clf.fit(X_train, Y_train)
next loop:
231 2892.5 MiB 890.5 MiB clf.fit(X_train, Y_train)
next loop:
231 2928.1 MiB 35.6 MiB clf.fit(X_train, Y_train)
next loop:
231 2977.6 MiB 49.5 MiB clf.fit(X_train, Y_train)
next loop:
231 3009.2 MiB 31.6 MiB clf.fit(X_train, Y_train)
next loop:
231 3014.6 MiB 5.4 MiB clf.fit(X_train, Y_train)
next loop:
231 3019.4 MiB 4.8 MiB clf.fit(X_train, Y_train)
next loop:
231 3031.0 MiB 11.6 MiB clf.fit(X_train, Y_train)
next loop:
231 3041.4 MiB 10.4 MiB clf.fit(X_train, Y_train)
如您所见,内存使用率在开始时急剧增加,然后更慢。
使用不使用OneVsRest
的分类器,内存使用率或多或少保持不变,因为分类器会在每个循环中重新适应新的训练数据。这显然是我期望的行为。
为什么会这样?我该怎样预防呢?它是一个sklearn bug还是更低级别的东西?请注意,重新初始化分类器对我们当前的代码来说是不好的。
更新
我更改为代码以重新初始化分类器,并在获得预测后使用clf键将其删除并且问题仍然存在。此外,使用pympler.summary
分配的内存不会出现,因此它似乎不是python对象而是numpy数组(如预期的那样)。使用.sparsify()
不会改变任何内容。
当运行到内存限制时,交换正在填充,因此操作系统似乎无法重用内存。
请注意,上面的示例仅占数据集的一小部分。