python - 如何调试此代码计算两个 unicode 文件的余弦相似度?
问题描述
我已经修改了我在 NLTK 教程中找到的一些代码,用于计算文档的余弦相似度,以应用于两个 unicode 文件。我实际上有 5 个文件要处理,但我从可以处理两个小示例文件的代码开始。但是,我无法实际计算余弦相似度。此代码产生以下错误:AttributeError: 'list' object has no attribute 'lower'
。
我试过这个:
tfidf = TfidfVectorizer(
tokenizer=tokenize, stop_words='english',
encoding='utf-8', decode_error='ignore',
strip_accents='unicode',lowercase='false', norm='l1')
def cosine_sim(token_dict):
tfs = [tfidf.fit_transform(w) for w in token_dict]
return ((tfs[0] * tfs0[0].T).A)[0,1]
但这会返回以下错误:IndexError: index 1 is out of bounds for axis 1 with size 1
.
我还尝试将 tfs 列表转换为 numpy 数组,手动转置它,然后进行余弦计算,但出现错误:TypeError: can't multiply sequence by non-int of type 'list'
.
import nltk
import string
import os
from sklearn.feature_extraction.text import TfidfVectorizer
from nltk.stem.porter import PorterStemmer
import codecs
path = 'C:/Users/Me/Dropbox/DocumentSimilarityTesting'
token_dict = {}
stemmer = PorterStemmer()
def stem_tokens(tokens, stemmer):
stemmed = []
for item in tokens:
stemmed.append(stemmer.stem(item))
return stemmed
def tokenize(text):
tokens = nltk.word_tokenize(text)
stems = stem_tokens(tokens, stemmer)
return stems
for subdir, dirs, files in os.walk(path):
for file in files:
shakes = codecs.open(os.path.join(path,file), "r",encoding='utf-8',
errors='ignore')
text = shakes.read()
lowers = text.lower()
remove_punctuation_map = dict((ord(char), None) for char in
string.punctuation)
no_punctuation = [lowers.translate(remove_punctuation_map)]
token_dict[file] = no_punctuation
tfidf = TfidfVectorizer(tokenizer=tokenize, stop_words='english',
encoding='utf-8', decode_error='ignore',
strip_accents='unicode',lowercase='false', norm='l1')
def cosine_sim(token_dict):
tfs = tfidf.fit_transform(token_dict.values())
return ((tfs * tfs.T).A)[0,1]
我期待一个值是两个文档的余弦相似度,但我收到一条错误消息。我可以打印此代码生成的 tfs 列表的元素,但似乎我的代码无法转置列表并计算余弦相似度。
解决方案
对于第一个例外IndexError: index 1 is out of bounds for axis 1 with size 1
,我假设这((tfs[0] * tfs0[0].T).A)[0,1]
是罪魁祸首。尝试探索它的内容,(tfs[0] * tfs0[0].T).A
看看它包含多少维度和元素。这应该让您了解为什么您可能超出该矩阵的范围。
对于例外的换位,TypeError: can't multiply sequence by non-int of type 'list'
恐怕只有代码才能说出真相。(我们在问题中没有看到)
至于最后一个例外TypeError: can't multiply sequence by non-int of type 'list'
,我假设:
text = shakes.read()
lowers = text.lower()
导致问题,并且可能shakes.read()
返回一个列表而不是一个字符串。请确保您知道您在那里收到的数据。
推荐阅读
- javascript - 如何将对象数组传递给 Query?
- python - 将元组从函数“导出”到全局变量
- typescript - 从组件获取数据
- azure - 端点 webhook url 上的事件网格订阅的 ARM 部署失败
- hdf5 - 如何将 HDF5 数据集作为 Snakemake 输入/输出?
- ios - 我希望打印的值太长,无法打印 firebase 中的所有值
- excel - 如何从工作表中读取值并检查它们是否存在于 .txt 文件中
- project-reactor - Reactor 项目中的 Fuseable 接口有什么用?
- javascript - 如何在 React 中调用注入到 ReactNative 的 WebView 中的 JavaScript 代码?
- c# - 如何使用 Angular 7 保持 AngularCLIServer 在 asp.net 核心上的构建之间运行