<p><strong>在进一步编辑包含的代码时</strong>如果您能够在内存中保存<code>arrayOfTrigrams</code>,请参阅底部的原始解决方案。但是,如果您还不能创建<code>arrayOfTrigrams</code>(鉴于数据大小,我有点怀疑您是否已经做到了这一点),您仍然可以创建一个包含重复三元组的字典。重复的双元组总是包含重复的单词,重复的三元组包含重复的双元组。分阶段处理500 MB的数据。首先创建一组重复的单词。使用这个,创建一个重复的双元组字典。首先对包含一个重复单词的双元组进行原始频率计数,然后丢弃计数仅为1的任何双元组。然后对数据进行第三次处理,创建重复三元组字典。同样,对包含重复的二元曲线(应该是所有可能的三元曲线的一小部分)进行原始频率计数,然后从字典中丢弃最终计数为1的那些。这样你就可以建立字典,而不需要一次将所有的三元组保存在内存中。在</p>
<p>概念证明:</p>
<pre><code>from collections import defaultdict
chars = set('ABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789')
def cleanWord(s):
return ''.join(c for c in s if c in chars)
f = open('moby dick.txt') #downloaded from Project Gutenberg: http://www.gutenberg.org/ebooks/2701 Thanks!
words = f.read().split()
f.close()
words = [cleanWord(w.upper()) for w in words]
words = [w for w in words if len(w) > 1 and not(w in set('AIOY'))]
repeatedWords = defaultdict(int)
for w in words:
repeatedWords[w] += 1
repeatedWords = set(w for w in repeatedWords if repeatedWords[w] > 1)
repeatedBigrams = defaultdict(int)
for i in range(len(words) - 1):
x,y = words[i:i+2]
if x in repeatedWords or y in repeatedWords:
repeatedBigrams[x + ' ' + y] +=1
repeatedBigrams = set(b for b in repeatedBigrams if repeatedBigrams[b] > 1)
repeatedTrigrams = defaultdict(int)
for i in range(len(words) - 2):
x,y,z = words[i:i+3]
if x + ' ' + y in repeatedBigrams and y + ' ' + z in repeatedBigrams:
repeatedTrigrams[x + ' ' + y + ' ' + z] +=1
repeatedTrigrams = {t:c for t,c in repeatedTrigrams.items() if c > 1}
</code></pre>
<p>这段代码显示10016个多次出现的三元组。相反,当我评估</p>
^{pr2}$
<p>我得到了188285,所以在这个有点大的自然语言例子中,只有10016/188285=5.3%的可能的三元组是重复的。假设您的数据也有类似的比率,我估计用于重复三角函数的频率字典的大小大约为100MB。在</p>
<hr/>
<p>原液:</p>
<hr/>
<p>您的代码和问题表明您可以在内存中保存<code>arrayOfTrigrams</code>,但无法创建字典。一个潜在的解决方法是首先对这个数组进行排序,然后创建一个<em>重复</em>三元组的频率计数:</p>
<pre><code>arrayOfTrigrams.sort()
repeatedTrigrams = {}
for i,t in enumerate(arrayOfTrigrams):
if i > 0 and arrayOfTrigrams[i-1] == t:
if t in repeatedTrigrams:
repeatedTrigrams[t] += 1
else:
repeatedTrigrams[t] = 2
</code></pre>
<p>在构造<code>repeatedTrigrams</code>之后,您可以使用集合理解:</p>
<pre><code>uniques = {t for t in arrayOfTrigrams if not t in repeatedTrigrams}
</code></pre>
<p>然后<code>t in uniques</code>将传递<code>t</code>的计数为1的信息,我怀疑这对于绝大多数的三元曲线都是正确的。在这一阶段,您拥有所有相关频率信息,并可以放弃trigrams列表,以释放一些已消耗的内存:</p>
<pre><code>arrayOfTrigrams = None
</code></pre>