我正在构建我的单词 n-gram 训练向量,稍后供
SVM
使用。我运行了我的代码,但是花了我太多时间,超过 10 个小时。有什么方法可以让它更快吗
def wordNgrams(s,n):
"""Calculate word n-grams and return a dictionary"""
input = s.split(' ')
output = {}
for i in xrange(len(input)-n+1):
g = " ".join(input[i:i+n]).lower()
output.setdefault(g,0)
output[g] += 1
return output
res
是 10000 个字符串的 list
,而每个字符串平均包含 300 个单词。 global_vector
是 200000 个 2 克的排序 list
。
X = []
for i in xrange(10000):
word_dic = wordNgrams(res[i], 2)
vector1 = {key : 1 if key in word_dic else 0 for key in global_vector}
od = OrderedDict(sorted(vector1.items(), key = lambda t : t[0]))
X.append(od.values())
说实话,2、3个小时是很常见的。但我花了10多个小时。我真的没有做我应该做的事。请帮助我。
我认为您在循环中运行的
sorted
调用是唯一可以优化的事情。其他一切似乎都是渐近最优的(可能可以通过不同地方的小因素来改善事物,但不能大量改善)。
如果您的
global_vector
已经排序,您可以通过直接创建结果列表来避免对结果进行排序,而不是先通过无序字典。这是使用列表理解的快速版本:
X = []
for text in res:
word_dic = wordNgrams(text, 2)
X.append([1 if bigram in word_dic else 0 for bigram in global_vector])
这应该是
O(M*N) + O(M*P)
,其中M
是res
的长度,N
是global_vector
的长度,P
是文本的平均长度。由于额外的排序,您的原始代码在第一项中包含了额外的 log(N)
因素。