我正在尝试编写一个函数,它将获取单词(字符串)列表,计算每个特定单词出现的次数,并返回一个字典,其中单词出现在列表中的次数除以总数列表中的单词(术语频率向量)。
def makeTermFrequencyVector(wordList):
'''
makeTermFrequencyVector Takes a list of words as parameter and returns a dictionary representing the term frequency
vector of the word list, where words are keys and values are the frequency of occurrence of
each word in the document.
'''
tfDict = {}
for word in wordList:
for i in range(len(wordList)):
state = 0
if wordList[i] == word:
state += 1
tfv = state / (len(wordList))
tfDict[word] = tfv
return tfDict
如果我输入:
makeTermFrequencyVector(['cat', 'dog']):
输出应为:
{'cat': 0.5, 'dog': 0.5}
因为每个单词在总长度为2的列表中出现一次。
但是,此代码返回一个字典,其中只有输入列表中的最后一个单词具有正确的tf值,所有其他单词的值为0.因此,如果我尝试在当前代码中输入上面的列表,则返回:
{'dog': 0.5, 'cat': 0.0}
这是不正确的。
如何解决这个问题,以便迭代列表中每个单词的值,而不仅仅是最后一个单词?我想让固定代码尽可能接近我当前的代码。
答案 0 :(得分:0)
如果我们制作单独的传球而不是嵌套传球,这会更简单。在第一遍,我们采用字数。在第二遍,我们用频率替换字数:
def makeTermFrequencyVector(wordList):
'''
Takes a list of words and returns a dictionary representing
the term frequency vector of the word list, where words are
keys and values are the frequency of occurrence.
'''
tfDict = dict()
for word in wordList:
tfDict[word] = tfDict.get(word, 0) + 1
word_count = len(wordList)
for word in tfDict:
tfDict[word] /= word_count
return tfDict
print(makeTermFrequencyVector(['cat', 'dog']))
word_list = [ \
'Takes', 'a', 'list', 'of', 'words', 'as', 'its', 'sole', 'parameter', \
'and', 'returns', 'a', 'dictionary', 'representing', 'the', 'term', \
'frequency', 'vector', 'of', 'the', 'word', 'list,', 'where', 'words', \
'are', 'keys', 'and', 'values', 'are', 'the', 'frequency', 'of', \
'occurrence', 'of', 'each', 'word', 'in', 'the', 'source', 'document', \
]
print(makeTermFrequencyVector(word_list))
<强>输出强>
> python3 test.py
{'cat': 0.5, 'dog': 0.5}
{'Takes': 0.025, 'a': 0.05, 'list': 0.025, 'of': 0.1, 'words': 0.05, 'as': 0.025, 'its': 0.025, 'sole': 0.025, 'parameter': 0.025, 'and': 0.05, 'returns': 0.025, 'dictionary': 0.025, 'representing': 0.025, 'the': 0.1, 'term': 0.025, 'frequency': 0.05, 'vector': 0.025, 'word': 0.05, 'list,': 0.025, 'where': 0.025, 'are': 0.05, 'keys': 0.025, 'values': 0.025, 'occurrence': 0.025, 'each': 0.025, 'in': 0.025, 'source': 0.025, 'document': 0.025}
>
答案 1 :(得分:0)
cdlane使用2遍方法是使用嵌套for循环的方法。原因是每次传递将花费O(n)时间,其中n是列表的长度。通过两次传递,它将是O(n)+ O(n)= O(2n)时间,但是常数被丢弃以产生O(n)渐近运行时间。
您的代码无法工作的部分原因是因为state
被置于内部循环中,因此对于该循环的每次迭代,状态将重置为0,而不是每次都递增。如果你采用行state = 0
并将其从内部for循环中删除,我认为逻辑应该可行。