使用Python和Doc2Vec的MemoryError

时间:2018-08-27 12:14:02

标签: python machine-learning doc2vec

我正在尝试训练Doc2vec来处理海量数据。我总共有一个 20k 个文件,总计 72GB ,并编写以下代码:

def train():
    onlyfiles = [f for f in listdir(mypath) if isfile(join(mypath, f))]
    data = []
    random.shuffle(onlyfiles)
    tagged_data = []
    t = 0
    try:
        for file_name in onlyfiles:
            with open(mypath+"/"+file_name, 'r', encoding="utf-8") as file:
                txt = file.read()
                tagged_data.append([word_tokenize(txt.lower()), [str(t)]])
                t+=1
    except Exception as e:
        print(t)
        return 
    print("Files Loaded")
    max_epochs = 1000
    vec_size = 500
    alpha = 0.025

    model = Doc2Vec(vector_size=vec_size,
                    alpha=alpha, workers=1,
                    min_alpha=0.00025,
                    min_count=1,
                    dm=1)

    print("Model Works")
    print("Building vocabulary")

    model.build_vocab(tagged_data)
    print("Trainning")
    for epoch in range(max_epochs):
        print("Iteration {0}".format(epoch))
        model.train(tagged_data,
                    total_examples=model.corpus_count,
                    epochs=model.iter)
        model.alpha -= 0.0002
        model.min_alpha = model.alpha

    model.save(model_name)
    print("Model Saved")

但是当我运行此方法时,会出现此错误: 追溯(最近一次通话):

File "doc2vec.py", line 20, in train
    tagged_data.append([word_tokenize(txt.lower()), [str(t)]])
MemoryError

仅会处理 3k 文件。但是在查看内存时,python过程显示仅使用了内存的 1.7%。 我可以通知python解决任何参数吗? 我该如何解决?

1 个答案:

答案 0 :(得分:0)

您甚至在尝试Doc2Vec之前就已经收到错误消息,因此,这实际上不是一个Doc2Vec问题-这是Python数据处理问题。您是否有足够的RAM将72GB的磁盘数据(当以Python字符串对象表示时可能会扩展一点)加载到RAM中?

但是,您通常不必通过将庞大的语料表附加到一个庞大的列表中来完成所有这些任务。一次读取一个东西,然后从一个迭代器/迭代器进行处理,也许将临时结果(如标记化文本)写回到IO源。本文可能会有所帮助:

https://rare-technologies.com/data-streaming-in-python-generators-iterators-iterables/

最后,如果您的代码 did 进入Doc2Vec部分,您将遇到其他问题。无论您要作为模型参考的任何在线示例都有许多不良做法。例如:

  • 典型的交互次数是10-20;您当然不会在72GB的数据集中使用1000

  • min_count=1导致了更大的模型;通常,丢弃低频词是必要的,甚至可能会改善所得的矢量质量,并且较大的数据集(72GB非常大)倾向于使用更大而不是最小的min_count设置

  • 大多数人不应该使用非默认的alpha / min_alpha值,也不应该尝试通过自己的计算来管理它们,甚至不应该多次调用train()train()有自己的epochs参数,如果使用该参数,它将为您顺利地处理学习率alpha。据我所知,在自己的循环中多次调用train()的人中有100%做错了,我不知道他们在哪里继续得到这些例子。

  • workers=1的训练要慢得多;尤其是对于大型数据集,您将需要尝试更大的workers值,而在3.5.0之前的gensim版本中,用于训练吞吐量的最佳值通常在3到12之间(假设您至少有那么多的CPU核心)。

因此,您当前的代码可能会导致模型大于RAM,缓慢地训练单线程,并且比必要的时间多1000倍,并且许多训练都是在无意义的负α情况下进行的,这会使模型在每个循环中变得更糟。如果奇迹般地没有在模型初始化期间MemoryError,则它将运行数月或数年,并最终导致无意义的结果。