我正在尝试计算一系列福尔摩斯故事的逆文档频率。请看一下代码:
逆文档频率是衡量一个词在多个文档中出现的常见程度或稀有程度的指标。
因此,逆文档频率或简称idf
,衡量的是一个词在特定文档中的常见程度,而在其他文档中不那么常见。
idf的公式为:log x (总文档数/包含该词的文档数)
main.py
import mathimport nltkimport osimport sysdef main(): if len(sys.argv) != 2: sys.exit("Usage: python main.py corpus") print("Loading data...") corpus = load_data(sys.argv[1]) words = set() for filename in corpus: words.update(corpus[filename]) idfs = list() for word in words: f = sum(word in corpus[filename] for filename in corpus) idf = math.log(len(corpus) / f) idfs[word] = idf tfidfs = dict() for filename in corpus: tfidfs[filename] = [] for word in corpus[filename]: tf = corpus[filename][word] tfidfs[filename].append((word, tf * idfs[word])) for filename in corpus: tfidfs[filename].sort(key=lambda tfidf: tfidf[1], reverse=True) tfidfs[filename] = tfidfs[filename][:5] print() for filename in corpus: print(filename) for term, score in tfidfs[filename]: print(f" {term}: {score:.4f}")def load_data(directory): files = dict() for filename in os.listdir(directory): with open(os.path.join(directory, filename)) as f: contents = [ word.lower() for word in nltk.word_tokenize(f.read()) if word.isalpha() ] frequencies = dict() for word in contents: if word not in frequencies: frequencies[word] = 1 else: frequencies[word] += 1 files[filename] = frequencies return filesif __name__ == "__main__": main()
但当我在Powershell中运行python .\main.py .\shelock_holmes\
时,
我得到了这个令人困惑的错误:
Loading data...Traceback (most recent call last): File ".\main.py", line 65, in <module> main() File ".\main.py", line 22, in main idfs[word] = idfTypeError: list indices must be integers or slices, not str
谁能帮帮我吗?
回答:
您将idfs
定义为列表:
idfs = list()
如果idfs
是一个列表,那么在这一赋值中:
idfs[word] = idf
word
必须是一个整数,因为它指定了列表中的索引或位置。
但看起来words
是一个str
的列表,因此在迭代中:
for word in words:
word
是一个str
。由于str
不是整数,因此这一行
idfs[word] = idf
引起了您看到的错误,原因正是它所解释的。也许idfs
应该是一个dict
而不是列表,像这样定义:
idfs = dict()
然后这一行:
idfs[word] = idf
将word
解释为字典中的键,并将idf
作为该键的值赋给dict
。字典的键可以是任何对象,并且通常是字符串,所以这样做非常合理。