减少语料库中计算词频的计算时间(python)
我的函数基本上返回单词列表,如果一个单词出现在至少n个句子中,那么它就在列表中。我要做的是遍历self.all句子是一个单词列表(句子),遍历self.wordSet(语料库中所有唯一的单词),并将每个单词的频率添加到字典(wordFreqDict) 然后循环遍历单词freqdict并将频率>=n的单词添加到结果列表中 我假设这会起作用,但检查结果要花太长时间 有没有一种方法可以提高效率并缩短计算时间 编辑: 下面是self.all句子的计算方法减少语料库中计算词频的计算时间(python),python,nlp,Python,Nlp,我的函数基本上返回单词列表,如果一个单词出现在至少n个句子中,那么它就在列表中。我要做的是遍历self.all句子是一个单词列表(句子),遍历self.wordSet(语料库中所有唯一的单词),并将每个单词的频率添加到字典(wordFreqDict) 然后循环遍历单词freqdict并将频率>=n的单词添加到结果列表中 我假设这会起作用,但检查结果要花太长时间 有没有一种方法可以提高效率并缩短计算时间 编辑: 下面是self.all句子的计算方法 def foo(self, n): wo
def foo(self, n):
wordFreqDict = defaultdict(int)
resultList = []
for sentence in self.allSentences:
for word in self.wordSet:
if word in sentence:
wordFreqDict[word] += 1
for candidateWord in wordFreqDict:
if wordFreqDict[candidateWord] >= n:
resultList.append(candidateWord)
return resultList
以及self.wordSet:
def storeAllSentences(self, corpus):
for sentence in corpus:
self.allSentences.append(sentence)
这里的一个假设是,如果一个词在至少
n
个句子中唯一出现,则选择该词。所以,即使它在一个句子中出现10次,那仍然是一次
两个突出的问题是嵌套循环和对字符串的
in
检查。这实际上是立方复杂性。应该可以使用设置
+计数器
来大幅减少这种情况
def getUniqueWordSet(self, corpus):
for sentence in self.allSentences:
for word in sentence:
self.wordSet.append(word)
self.wordSet = set(self.wordSet)
在这里,我使用正则表达式删除特殊字符和标点符号,然后拆分并检索句子中所有唯一的单词。然后更新计数器
最后,使用itertools.takewhile
提取所需频率(或更多)的所有单词并返回
如果
sent
是一个字符串句子,您可以使用基于re
的过滤删除标点符号,然后拆分:
from collections import Counter
from itertools import takewhile
def foo(self, n):
c = Counter()
for sent in self.allSentences:
c.update(set(sent))
resultSet = list(itertools.takewhile(lambda x: x[1] >= n, c.most_common()))
return resultSet
这并不考虑单词是否属于self.wordSet
。因此,如果您也想这样做,您可以稍微修改第一个循环,以包含过滤器步骤:
import re
tempWordSet = set(re.sub('[^\w\s]+', '', sent).split())
c.update(tempWordSet)
或者,使用第二种技术:
c.update(set(filter(lambda x: x in self.wordSet, sent)))
另一方面,您是否正在尝试执行文本挖掘?您可能有兴趣研究。这里的一个假设是,如果一个词在至少n
个句子中唯一出现,则选择该词。所以,即使它在一个句子中出现10次,那仍然是一次
两个突出的问题是嵌套循环和对字符串的in
检查。这实际上是立方复杂性。应该可以使用设置
+计数器
来大幅减少这种情况
def getUniqueWordSet(self, corpus):
for sentence in self.allSentences:
for word in sentence:
self.wordSet.append(word)
self.wordSet = set(self.wordSet)
在这里,我使用正则表达式删除特殊字符和标点符号,然后拆分并检索句子中所有唯一的单词。然后更新计数器
最后,使用itertools.takewhile
提取所需频率(或更多)的所有单词并返回
如果sent
是一个字符串句子,您可以使用基于re
的过滤删除标点符号,然后拆分:
from collections import Counter
from itertools import takewhile
def foo(self, n):
c = Counter()
for sent in self.allSentences:
c.update(set(sent))
resultSet = list(itertools.takewhile(lambda x: x[1] >= n, c.most_common()))
return resultSet
这并不考虑单词是否属于self.wordSet
。因此,如果您也想这样做,您可以稍微修改第一个循环,以包含过滤器步骤:
import re
tempWordSet = set(re.sub('[^\w\s]+', '', sent).split())
c.update(tempWordSet)
或者,使用第二种技术:
c.update(set(filter(lambda x: x in self.wordSet, sent)))
另一方面,您是否正在尝试执行文本挖掘?您可能有兴趣研究。集合词集可能比单个句子中的词至少大两个数量级。因此,在一个句子中通过单词循环是有意义的。然而,这要求拆分一个句子并不是一个真正缓慢的操作。如果是,您应该在getUniqueWordSet中完成整个过程。这里仅更改了第一个for循环:
tempWordSet = set(filter(lambda x: x in self.wordSet,
re.sub('[^\w\s]+', '', sent).split()))
集合词集可能比单个句子中的词至少大两个数量级。因此,在一个句子中通过单词循环是有意义的。然而,这要求拆分一个句子并不是一个真正缓慢的操作。如果是,您应该在getUniqueWordSet中完成整个过程。这里仅更改了第一个for循环:
tempWordSet = set(filter(lambda x: x in self.wordSet,
re.sub('[^\w\s]+', '', sent).split()))
使用线程怎么样?设置
+计数器
应该能真正提高这一点。@堆栈,不。如果算法在单个处理环境中不能很好地工作,那么将其并行化是没有意义的。@cᴏʟᴅsᴘᴇᴇᴅ 你能详细说明一下吗?@user6792790在做这件事之前,我需要一些信息。您的函数的输入是什么?文档在哪里,如何标记句子?使用线程如何?set
+Counter
应该能真正提高这一点。@Stack,不是。如果算法在单个处理环境中不能很好地工作,那么并行化它就没有意义了。@cᴏʟᴅsᴘᴇᴇᴅ 你能详细说明一下吗?@user6792790在做这件事之前,我需要一些信息。您的函数的输入是什么?文档在哪里?您如何标记句子?谢谢,但它在以下行上给了我一个“TypeError:预期的字符串或类似字节的对象”:tempWordSet=set(re.sub('[^\w\s]+','',sent).split()@user6792790噢,sent
不是字符串吗?这是一张字表吗?是的。snet是一个单词列表。对不起,我应该clarified@user6792790没问题,我已经编辑了我的答案。现在应该可以工作了。还可以使用filter
查看选项,并在需要时使用它。@user6792790没问题!现在的表演怎么样?我打赌现在应该好多了。谢谢,但它在以下行上给了我一个“TypeError:预期的字符串或类似字节的对象”:tempWordSet=set(re.sub('[^\w\s]+','',sent).split()@user6792790噢,sent
不是字符串吗?这是一张字表吗?是的。snet是一个单词列表。对不起,我应该clarified@user6792790没问题,我已经编辑了我的答案。现在应该可以工作了。还可以使用filter
查看选项,并在需要时使用它。@user6792790没问题!现在的表演怎么样?我敢打赌现在应该好多了。