我有两个文本文件,每个文件大约有70万行。
第二个文件包含对应行的第一个文件中语句的响应。
我需要计算在匹配行中出现的每个词对的Fisher精确得分。
例如,如果文件中的第n行是
how are you
并且
fine thanx
接下来我需要为(how,fine), (how,thanx), (are,fine), (are,thanx), (you,fine), (you,thanx)计算Fisher的分数。
为了计算Fisher的精确分数,我使用了collections模块的Counter方法,统计了每个单词出现的次数以及它们在两个文件中的共同出现情况,如下所示:
with open("finalsrc.txt") as f1, open("finaltgt.txt") as f2:
for line1, line2 in itertools.izip(f1, f2):
words1 = list(set(list(find_words(line1))))
words2 = list(set(list(find_words(line2))))
counts1.update(words1)
counts2.update(words2)
counts_pair.update(list(set(list(itertools.product(words1, words2)))))
然后我使用scipy模块计算每对数据的Fisher精确分数
from scipy import stats
def calculateFisher(s, t):
sa = counts1[s]
ta = counts2[t]
st = counts_pair[s, t]
snt = sa - st
nst = ta - st
nsnt = n - sa - ta + st
oddsratio, pvalue = stats.fisher_exact([[st, snt], [nst, nsnt]])
return pvalue
这对于小型文本文件而言是快速而有效的,但由于我的文件每个都包含700,000行,因此我认为计数器会变得过大,以至于无法快速检索值,从而导致速度变得非常缓慢。 (假设每个句子有10个单词,则counts_pair将具有(10^2)* 700,000 = 70,000,000个条目。)
这需要数十天的时间才能完成文件中所有单词对的计算。您有什么明智的解决方案吗?
非常感谢您的帮助。
list(set(list(...
可以简化为list(set(...
。 - Erik Kaplunfind_words()
返回什么? - martineaucProfile
。检查在Counter.__getitem__
中花费了多少时间(如果它们不同,则需要cumtime
而不是tottime
)。检查随着行数的增加,所花费的时间比例是否增加。如果是这样,那么计数器变慢了。如果不是,那么就没有变慢。 - Steve Jessop