[英]Improve speed of python algorithm
我已將 Sentiment140 數據集用於 twitter 進行情感分析
代碼:
從推文中獲取單詞:
tweet_tokens = []
[tweet_tokens.append(dev.get_tweet_tokens(idx)) for idx, item in enumerate(dev)]
從令牌中獲取未知單詞
words_without_embs = []
[[words_without_embs.append(w) for w in tweet if w not in word2vec] for tweet in tweet_tokens]
len(words_without_embs)
代碼的最后一部分,計算向量作為左右詞(上下文)的平均值
vectors = {} # alg
for word in words_without_embs:
mean_vectors = []
for tweet in tweet_tokens:
if word in tweet:
idx = tweet.index(word)
try:
mean_vector = np.mean([word2vec.get_vector(tweet[idx-1]), word2vec.get_vector(tweet[idx+1])], axis=0)
mean_vectors.append(mean_vector)
except:
pass
if tweet == tweet_tokens[-1]: # last iteration
mean_vector_all_tweets = np.mean(mean_vectors, axis=0)
vectors[word] = mean_vector_all_tweets
有 1058532 個字,這段代碼的最后一部分工作很慢,大約每分鍾 250 個字。
你如何提高這個算法的速度?
代碼緩慢的主要原因之一是檢查tweet_tokens
每條推文的所有單詞(接近 100 萬個單詞)是否tweet_tokens
。 因此,您的實現的時間復雜度是1e6 * |tweet_tokens|
.
但是,您可以通過先標記每條tweet
,然后找到單詞的索引來做得更好。 如果您在現有單詞上構建了一本字典,您可以從單詞字典中找到最多log(1e6) ~ 25
比較的單詞標記的索引。 因此,在這種情況下,時間復雜度最多為25 * |tweet_tokens|
. 因此,您可以將代碼的性能提高1e6/25 = 40000
倍!
此外,你總是在計算不同推文中同一個詞的向量。 因此,每個單詞的向量將被計算f
倍, f
是單詞在推文中的頻率。 一種合理的解決方案是將words_without_embs
中所有單詞的向量計算一次(它可以是一個離線過程)。 然后,例如,根據單詞詞典中單詞的索引存儲所有這些向量(以某種方式根據單詞查詢快速找到它們)。 最終,只需從准備好的數據結構中讀取它以進行平均計算。 在這種情況下,除了 40000 倍的改進之外,您還可以通過推文中所有單詞頻率之和的系數來提高代碼的性能。
這看起來可以很好地與一些小的編輯並行。
if tweet == tweet_tokens[-1]:
阻塞一個級別並刪除它的“if”語句,你能移動最后一個嗎? 這本身只會帶來輕微的速度提升,但是有了它,您可以更有效地並行化代碼。[tweet_tokens.append(dev.get_tweet_tokens(idx)) for idx, item in enumerate(dev)]
更改為tweet_tokens = [dev.get_tweet_tokens(idx) for idx, item in enumerate(dev)]
。處理未知單詞的更常見(並且可能更好)的策略包括:
您似乎決定通過對所有直接鄰居求平均值來為 OOV 詞合成新向量。 我不認為這會特別有效。 在詞向量的多種下游使用中,它只是傾向於過重詞的上下文中的鄰居——這也可以通過完全忽略未知詞來非常簡單/廉價地實現。
但考慮到您想要做什么,最好的方法是在標識words_without_embs
的同一遍期間收集相鄰的單詞。
例如,使words_without_embs
成為一個dict
(或者可能是一個DefaultDict
),其中每個鍵是一個需要向量的詞,每個值是您迄今為止找到的所有相鄰詞的list
。
然后, tweet_tokens
一個循環將用需要向量的詞的鍵填充words_without_embs
,同時用目前看到的所有相鄰詞填充這些值。
然后,對words_without_embs
鍵的最后一次循環將簡單地獲取現有的相鄰詞列表進行平均。 (不再多次通過tweet_tokens
。)
但同樣:所有這些工作可能不會勝過簡單地刪除未知單詞的基線做法。
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.