2017-09-18 68 views
0

我試圖計算所有值之間的餘弦相似度。如何加速在python中使用嵌套循環計算餘弦相似度的時間

1000 * 20000的計算時間花了我10多分鐘。

代碼:

from gensim import matutils 
# array_A contains 1,000 TF-IDF values 
# array_B contains 20,000 TF-IDF values 
for x in array_A: 
    for y in array_B: 
     matutils.cossim(x,y) 

因此,有必要使用gensim包拿到TF-IDF值和相似度計算。

有人可以給我一些建議和指導,以加快時間?

+0

是否有可能擺脫for循環之一? Cython會加快速度嗎? –

回答

0

使用memoize的,也可能使用元組(可能更快)的陣列:

def memoize(f): 
    memo = {} 

    def helper(a, b): 
     if (b, a) in memo: return memo[b, a] 
     elif (a, b) in memo: return memo[a, b] 
     else: 
      memo[(a, b)] = f(a, b) 
      return memo[a, b] 

    return helper 


@memoize 
def myfunc(a, b): 
    matutils.cossim(x,y) 

編輯 也使用上面的代碼,以防萬一你做其他事情有可能添加此之後數據

cossim_responses = [myfunc(a, b) for a in array_A for b in array_B] 
# you could also do (myfunc(a, b) for a in array_A for b in array_B) 
+0

結果顯示「TypeError:unhashable type:'list'」 – Scoota

+0

哪個代碼?我更新了它,以便它現在說a,b而不是a –

0

你可以看看源gensim的matutils.cossim()

https://github.com/RaRe-Technologies/gensim/blob/2e58a1c899af05ee6a39a1dd1c49dd6641501a9c/gensim/matutils.py#L436

你會看到它在它的兩個(稀疏數組)參數上做了一些工作,將它們的非零維移動到臨時的字典中,然後計算它們的長度 - 每當同一個向量被重複時在您的循環中提供。

通過在每個向量上僅執行一次這些步驟,並記住在每次最終成對計算中重複使用的長度,可能會得到合理的加速。 (也就是記錄臨時值,而不僅僅是最終值。)