【发布时间】:2018-03-26 18:05:51
【问题描述】:
我运行以下 sn-p 来训练文本分类模型。我对它进行了相当多的优化,它运行得非常顺利,但是它仍然使用了大量的 RAM。我们的数据集非常庞大(1300 万个文档 + 1800 万个词汇表),但在我看来,执行时抛出错误的点非常奇怪。脚本:
encoder = LabelEncoder()
y = encoder.fit_transform(categories)
classes = list(range(0, len(encoder.classes_)))
vectorizer = CountVectorizer(vocabulary=vocabulary,
binary=True,
dtype=numpy.int8)
classifier = SGDClassifier(loss='modified_huber',
n_jobs=-1,
average=True,
random_state=1)
tokenpath = modelpath.joinpath("tokens")
for i in range(0, len(batches)):
token_matrix = joblib.load(
tokenpath.joinpath("{}.pickle".format(i)))
batchsize = len(token_matrix)
classifier.partial_fit(
vectorizer.transform(token_matrix),
y[i * batchsize:(i + 1) * batchsize],
classes=classes
)
joblib.dump(classifier, modelpath.joinpath('classifier.pickle'))
joblib.dump(vectorizer, modelpath.joinpath('vectorizer.pickle'))
joblib.dump(encoder, modelpath.joinpath('category_encoder.pickle'))
joblib.dump(options, modelpath.joinpath('extraction_options.pickle'))
我在这一行得到了 MemoryError:
joblib.dump(vectorizer, modelpath.joinpath('vectorizer.pickle'))
在执行的这一点上,训练完成并且分类器已经被转储。它应该由垃圾收集器收集,以防需要更多内存。除此之外,如果它甚至不是compressing the data,为什么joblib要分配这么多内存。
我对 python 垃圾收集器的内部工作没有深入的了解。我应该强制 gc.collect() 还是使用 'del' 语句来释放那些不再需要的对象?
更新:
我尝试使用 HashingVectorizer,尽管它大大减少了内存使用量,但矢量化速度较慢,因此不是一个很好的选择。
我必须腌制矢量化器,以便稍后在分类过程中使用它,这样我就可以生成提交给分类器的稀疏矩阵。我将在这里发布我的分类代码:
extracted_features = joblib.Parallel(n_jobs=-1)(
joblib.delayed(features.extractor) (d, extraction_options) for d in documents)
probabilities = classifier.predict_proba(
vectorizer.transform(extracted_features))
predictions = category_encoder.inverse_transform(
probabilities.argmax(axis=1))
trust = probabilities.max(axis=1)
【问题讨论】:
-
你能用
HashingVectorizer代替吗?你的vocabulary是什么类型的?为什么首先需要腌制矢量化器? -
@krassowski 我更新了我的问题以包含有关分类过程的更多详细信息。此外,词汇表是一组字符串,包含从文档中提取的所有特征
标签: python-3.x scikit-learn out-of-memory joblib