ディスクからファイルを読み取って作成された大きな辞書に対して分析を行おうとしています。読み取り操作により、安定したメモリ フットプリントが得られます。次に、その辞書から一時的な辞書にコピーしたデータに基づいて計算を実行するメソッドがあります。これにより、すべてのコピーとデータの使用がメソッド内でスコープされ、メソッド呼び出しの最後に消えることを望んでいました。
悲しいことに、私は何か間違ったことをしています。customerdict の定義は次のとおりです (.py 変数の先頭で定義)。
customerdict = collections.defaultdict(dict)
オブジェクトの形式は {customerid: dictionary{id: 0||1}} です。
同様に定義された allids という辞書もあります。
以下の sim_pearson 距離を計算する方法があります (Programming Collective Intelligence のコードを変更したもの)。
def sim_pearson(custID1, custID2):
si = []
smallcustdict = {}
smallcustdict[custID1] = customerdict[custID1]
smallcustdict[custID2] = customerdict[custID2]
#a loop to round out the remaining allids object to fill in 0 values
for customerID, catalog in smallcustdict.iteritems():
for id in allids:
if id not in catalog:
smallcustdict[customerID][asin] = 0.0
#get the list of mutually rated items
for id in smallcustdict[custID1]:
if id in smallcustdict[custID2]:
si.append(id) # = 1
#return 0 if there are no matches
if len(si) == 0: return 0
#add up all the preferences
sum1 = sum([smallcustdict[custID1][id] for id in si])
sum2 = sum([smallcustdict[custID2][id] for id in si])
#sum up the squares
sum1sq = sum([pow(smallcustdict[custID1][id],2) for id in si])
sum2sq = sum([pow(smallcustdict[custID2][id],2) for id in si])
#sum up the products
psum = sum([smallcustdict[custID1][id] * smallcustdict[custID2][id] for id in si])
#calc Pearson score
num = psum - (sum1*sum2/len(si))
den = sqrt((sum1sq - pow(sum1,2)/len(si)) * (sum2sq - pow(sum2,2)/len(si)))
del smallcustdict
del si
del sum1
del sum2
del sum1sq
del sum2sq
del psum
if den == 0:
return 0
return num/den
sim_pearson メソッドをループするたびに、python.exe のメモリ フットプリントが無制限に増加します。「del」メソッドを使用して、ローカルスコープ変数を明示的に削除しようとしました。
タスクマネージャーを見ると、メモリが 6 ~ 10Mb ずつ増加しています。最初の customerdict がセットアップされると、フットプリントは 137Mb になります。
このようにしてメモリが不足している理由はありますか?