提高python算法的速度

Dmi*_*lov 2 python algorithm nlp machine-learning word2vec

我使用 Twitter 的 Sentiment140 数据集进行情感分析

代码:

从推文中获取文字:

tweet_tokens = []
[tweet_tokens.append(dev.get_tweet_tokens(idx)) for idx, item in enumerate(dev)]
Run Code Online (Sandbox Code Playgroud)

从 token 中获取未知单词

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)
Run Code Online (Sandbox Code Playgroud)

代码的最后一部分,计算向量作为左右单词(上下文)的平均值

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
Run Code Online (Sandbox Code Playgroud)

有 1058532 个单词,该代码的最后部分运行速度非常慢,大约每分钟 250 个单词。

如何提高该算法的速度?

OmG*_*OmG 6

代码缓慢的主要原因之一是检查tweet_tokens. 因此,您的实现的时间复杂度为1e6 * |tweet_tokens|

1)第一个改进(减少搜索和比较)

tweet但是,您可以通过首先对每个单词进行标记,然后查找单词的索引来做得更好。如果你在现有的单词上建立了一本字典,你最多可以log(1e6) ~ 25从单词字典中找到与该单词标记进行比较的索引。因此,在这种情况下,时间复杂度最多为25 * |tweet_tokens|。因此,您可以更快地提高代码的性能1e6/25 = 40000

2)第二个改进(减少Word2Vec计算量)

此外,您总是在计算不同推文中相同单词的向量。因此,每个单词的向量将被计算为该单词在推文中出现的频率的f倍。f一种合理的解决方案是一次性计算所有单词的向量words_without_embs(可以是离线过程)。然后,例如,根据单词词典中单词的索引存储所有这些向量(以某种方式根据单词查询快速找到它们)。最终,只需从准备好的数据结构中读取它即可进行平均计算。在这种情况下,除了 40000 倍的改进之外,您还可以通过推文中所有单词的频率总和来提高代码的性能。