首页 > 解决方案 > 如何调试此代码计算两个 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 列表的元素,但似乎我的代码无法转置列表并计算余弦相似度。

标签: pythonpython-2.7

解决方案


对于第一个例外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()返回一个列表而不是一个字符串。请确保您知道您在那里收到的数据。


推荐阅读