使用多处理生成单个dict

2024-04-27 17:32:47 发布

您现在位置:Python中文网/ 问答频道 /正文

我正在使用Python构建一个Markov链生成器。链式模型是从训练数据中构造出来的,它提供了查找一系列单词以找出下一个单词最有可能是什么的能力。你知道吗

链模型是一个字典,具有元组键(“states”,表示一个单词序列)和dict值(表示可以在该序列之后选择的单词)。选项dict有字符串键(表示每个单词)和int值(表示该单词的频率)。例如:

>>> make_model("I went to the shop then I went home then I went to bed")
{ (BEGIN, BEGIN): {"I", 1},
  (BEGIN, "I"): {"went", 1},
  ("I", "went"): {"to": 2, "home": 1},
  ("went", "to"): {"the": 1, "bed": 1},
  ("to", "the"): {"shop": 1},
  ... }

但是,我正在尝试尽可能快地生成模型。为了做到这一点,我尝试使用multiprocessing包。我的尝试可以归结为三个步骤:

  1. 将句子语料库分成n段,其中n是可用处理器的数量。你知道吗
  2. 使用multiprocessing.Pool().map为每个处理器创建部分模型。你知道吗
  3. 将模型合并回单个模型。你知道吗

1和2的速度非常快。但是,我正在努力完成第三步。我能想到的唯一方法是使用3个嵌套的for循环(部分模型->;状态->;选择)在一个处理器上生成一个包含所有部分模型的状态和所有单词选择频率正确相加的dict。但总的来说,这种方法比在单个处理器上执行整个过程要慢(然后根本不需要步骤3)。你知道吗

我试过让最后一个模型dict amultiprocessing.Manager().dict(),但那要慢得多(我怀疑是因为它被传递了太多,并且被锁定/解锁了)。我试过创建multiprocessing.Manager().dict()multiprocessing.Value()的内部dicts实例,但是multiprocessing不允许在程序流在多个处理器之间分配时创建这些对象-我必须事先创建它们。你知道吗

如何在形成一个dict时实现多重处理?你知道吗


Tags: theto模型home序列处理器shop单词
1条回答
网友
1楼 · 发布于 2024-04-27 17:32:47

您可以使用collections.Counters作为键,使其稍微更快:

from collections import Counter
d1 = {("a", "b"): Counter({"c": 3, "d": 4})}
d2 = {("a", "b"): Counter({"c": 5, "e": 6})}
d1['a','b'] += d2['a','b']
# d1 is now {('a', 'b'): Counter({'c': 8, 'e': 6, 'd': 4})}

Counter会自然合并,所以它们可能会更快一些。就代码长度而言,这无疑要好得多:

final = collections.defaultdict(Counter)
for d in results:
    for key in d:
        final[key] += d[key]

但如果有大量数据需要合并,则实际速度可能不会明显加快。你知道吗

相关问题 更多 >