<p>并非所有这些观察结果都与您所表达的问题直接相关,但是….:</p>
<p>a.如图所示,为什么在prefs中的键是long?除非你有几十亿的用户,简单的INT就可以了,而且可以节省一点内存。在</p>
<p>b.您的代码:</p>
<pre><code>centroids = [prefs[random.choice(users)] for i in range(k)]
</code></pre>
<p>可以给你重复(两个相同的质心),这反过来又不会使K-means算法满意。用更快更结实的</p>
^{pr2}$
<p>c.在你发布的代码中,你调用了一个函数<code>simple_pearson</code>,你从来没有在任何地方定义过这个函数;我假设你的意思是调用<code>sim_func</code>,但同时又不得不猜测你发布的代码与任何实际运行的代码有何不同,这确实很难帮助解决不同的问题</p>
<p>还有一个迹象表明,这个发布的代码可能不同于任何实际工作的代码:您设置了<code>bestmatch=(0,0)</code>,但是使用<code>if d < bestmatch[1]:</code>进行测试,测试怎么会成功?距离函数是否返回负值?在</p>
<p>e.defaultdict的意义在于,仅仅访问<code>row[m]</code>就神奇地在索引<code>m</code>的<code>row</code>中添加一个项(通过调用defaultdict的工厂获得的值,这里是0.0)。那个项目将永远占据记忆。您绝对不需要这种行为,因此您的代码:</p>
<pre><code> row = prefs[user_id]
for m in items:
if row[m] > 0.0: centroids[i][m]+=(row[m]/len_best)
</code></pre>
<p>正在浪费大量内存,使<code>prefs</code>从原来的稀疏矩阵变成一个密集矩阵(大部分都是0.0值)。如果你改为编码</p>
<pre><code> row = prefs[user_id]
for m in row:
centroids[i][m]+=(row[m]/len_best)
</code></pre>
<p>在<code>row</code>中没有增长,因此在{<cd8>}中没有增长,因为您正在循环<code>row</code>已经拥有的键。在</p>
<p>可能还有许多其他类似的问题,主要类似于最后一个问题,或者以次要问题为例</p>
<p>f.不要用<code>len_best</code>:在循环外计算它的逆1,然后乘以这个逆数。你不需要在循环内做乘法运算,你可以在一个单独的末尾做,因为它是相同的值乘以每一项,这既不节省内存,又避免了肆意浪费CPU时间;-)。好吧,我想这是两个小问题,而不仅仅是一个;-)。在</p>
<p>正如我所提到的,可能还有很多其他问题,但是由于这六个(或七个)已经显示出问题的密度,再加上S.Lott已经提出的单独建议(我认为这不会解决您的主要内存不足问题,因为他的代码仍然通过太多不包含的键来处理<code>row</code>defaultdict),我认为继续寻找更多的可能不是很有成效的,也许从解决这些问题开始,如果问题仍然存在,就单独提出一个关于这些问题的问题。。。?在</p>