Définition du problème: Avec un texte de longueur n
caractères et une liste de termes (qui peuvent être des expressions régulières) de longueur t
, trouvez et comptez toutes les occurrences de termes dans le texte.Optimisation de la correspondance d'expressions rationnelles pour une longue liste d'expressions
Voici une implémentation naïve pour que:
class WordFrequency(TextAnalysis):
"""Determines the frequency of words from a vocabulary in a given text"""
def __init__(self, vocabulary, text):
"""
:param vocabulary: contains the words (e.g. list)
:param text: the analysed text
"""
self.text = text
self.vocabulary = vocabulary
self.matches = {}
def run(self):
"""
:return: self for method chaining
"""
ltext = self.text.lower()
self.freq = {} # word -> absolute frequency
for word in self.vocabulary:
matches = re.findall(r'\b' + word + r'\b', ltext)
self.matches[word] = [match for match in matches] #.lstrip() for match in matches]
self.freq[word] = len(matches)
return self
Maintenant, cela prend environ 6 secondes pour un texte d'environ longueur 35000 caractères et une liste de ca. 5000 termes, ce qui est trop lent. Il semble que la complexité temporelle de ceci est O(t * n)
car pour chacun des termes t
le texte doit être scanné une fois. Y a-t-il un bug de performance évident ici? Quelles sont les optimisations possibles et/ou de meilleurs algorithmes?
Cette question doit être migrée vers http://codereview.stackexchange.com – danidee
Pourquoi joignez-vous une copie de la liste des correspondances à votre collection? Vous connaissez la fréquence, et vous connaissez le mot ... À moins que vous ne vouliez compter de manière insensible à la casse (ce que vous ne faites pas actuellement) et conserver les correspondances d'origine. Et même pour cela, vous n'avez pas besoin de faire une copie supplémentaire - 'self.matches [word] = matches' serait beaucoup plus rapide. –