如何序列化大型随机森林分类器

Posted

技术标签:

【中文标题】如何序列化大型随机森林分类器【英文标题】:How to serialize a large randomforest classifier 【发布时间】:2019-02-25 16:59:27 【问题描述】:

我正在使用 sklearn 的随机森林分类器来预测一组类。我有超过 26000 个类,因此分类器的大小超过 30 GB。我在具有 64 GB RAM 和 20 GB 存储空间的 Linux 上运行它。

我正在尝试使用 joblib 来腌制我的模型,但它无法正常工作,因为我没有足够的辅助存储(我猜)。有什么办法可以做到这一点??也许是某种压缩技术或其他什么?

【问题讨论】:

【参考方案1】:

你可以尝试 gzip 泡菜

compressed_pickle = StringIO.StringIO()
with gzip.GzipFile(fileobj=compressed_pickle, mode='w') as f:
    f.write(pickle.dumps(classifier))

然后您可以将compressed_pickle 写入文件。

回读:

with open('rf_classifier.pickle', 'rb') as f:
    compressed_pickle  = f.read()
rf_classifier = pickle.loads(zlib.decompress(compressed_pickle, 16 + zlib.MAX_WBITS))

编辑

3.4 之前的 Python 版本似乎对序列化对象大小有 4GB 的硬限制。最新版本的pickle协议(4.0版)没有这个限制,只需指定协议版本即可:

pickle.dumps(obj, protocol=4)

对于旧版本的 Python,请参考以下答案: _pickle in python3 doesn't work for large data saving

【讨论】:

我试过这个,但我得到了同样的错误:溢出:无法序列化大于 4 GiB 的字节对象 @Shiv 似乎 3.4 之前的 Python 版本对腌制对象的硬编码限制为 4 GB。如果您使用的是更高版本的 Python,请在调用转储时指定协议 = 4。对于旧版本的 python,我在我的答案中链接了另一个答案。【参考方案2】:

一种可能的解决方法是将单个树转储到一个文件夹中:

path = '/folder/tree_'
import _pickle as cPickle
i = 0
for tree in model.estimators_:
    with open(path.format(i), 'wb') as f:
        cPickle.dump(tree, f)
    i+=1
   

在 sklearn 的随机森林实现中,属性“estimators_”是一个包含各个树的列表。您可以考虑将所有树单独序列化到一个文件夹中。

要生成预测,您可以平均树的预测

# load the trees
path = '/folder/tree_'
import _pickle as cPickle
trees = []
i = 0
for i in range(num_trees):
    with open(path.format(i), 'rb') as f:
        trees.append(cPickle.load(f))
    i+=1
# generate predictions
predictions = []
for tree in trees:
    predictions.append(tree.predict(X))
predictions = np.asarray(predictions).T

# average predictions as in a RF
y_pred = predictions.mean(axis=0)

【讨论】:

以上是关于如何序列化大型随机森林分类器的主要内容,如果未能解决你的问题,请参考以下文章

如何测量随机森林分类器的准确性?

随机森林分类 weka

如何使用随机森林分类器确定用于预测类别的特征值范围

随机森林

如何调整管道内随机森林分类器中的参数?

如何在 python 中的大型数据集上训练随机森林?