使用Python在大文本中计算多词术语的频率

问题描述 投票:0回答:1

我有一本字典,包含近一百万个多字词(包含空格的词条)。看起来像

[..., 
'multilayer ceramic', 
'multilayer ceramic capacitor', 
'multilayer optical disk', 
'multilayer perceptron', 
...]

我想用几千兆字节的文本来计算它们的出现频率。

作为一个小示例,请考虑在Wikipedia页面中对这四个多词表达式进行计数:

payload = {'action': 'query', 'titles': 'Ceramic_capacitor', 'explaintext':1, 'prop':'extracts', 'format': 'json'}
r = requests.get('https://en.wikipedia.org/w/api.php', params=payload)
sampletext = r.json()['query']['pages']['9221221']['extract'].lower()
sampledict = ['multilayer ceramic', 'multilayer ceramic capacitor', 'multilayer optical disk', 'multilayer perceptron']

termfreqdic = {}
for term in sampledict:
    termfreqdic[term] = sampletext.count(term)
print(termfreqdic)

这类似于{'multilayer ceramic': 7, 'multilayer ceramic capacitor': 2, 'multilayer optical disk': 0, 'multilayer perceptron': 0},但如果词典中包含一百万个条目,则似乎不是最佳选择。

我尝试使用非常大的正则表达式:

termlist = [re.escape(w) for w in open('termlistfile.txt').read().strip().split('\n')]
termregex = re.compile(r'\b'+r'\b|\b'.join(termlist), re.I)
termfreqdic = {}
for i,li in enumerate(open(f)):
    for m in termregex.finditer(li):
        termfreqdic[m.group(0)]=termfreqdic.get(m.group(0),0)+1
open('counted.tsv','w').write('\n'.join([a+'\t'+v for a,v in termfreqdic.items()]))

这太慢了(最近的i7上1000行文本需要6分钟)。但是,如果我通过替换前两行使用regex而不是re,则每1000行文本它会减少到大约12s,这对于我的需求而言仍然很慢:

termlist = open(termlistfile).read().strip().split('\n')
termregex = regex.compile(r"\L<options>", options=termlist)
...

[注意,这并不能完全满足我的要求,因为一个术语可能是另一个术语的子术语,例如示例“多层陶瓷”和“多层陶瓷电容器”(也排除了Find multi-word terms in a tokenized text in Python中的第一次标记化方法)。

这似乎是文本语料库或遗传字符串中序列匹配的常见问题,必须具有众所周知的解决方案。也许可以用一些trie的单词解决(我不介意术语表的初始编译很慢)? las,我似乎并没有在寻找正确的条件。也许有人可以指出正确的方向?

python nlp corpus word-frequency
1个回答
0
投票

如果您确定只有一个字/索引,您可以这样做吗?

list1 = ['a b c', 'b c', 'a c']
a = 0
word = 'a'
for x in list1:
    if word in x:
        a += 1
print(a)
© www.soinside.com 2019 - 2024. All rights reserved.