【发布时间】:2021-06-02 08:03:05
【问题描述】:
我目前在 python 中实现 TFIDF,在测试余弦距离函数时,我得到了相当令人费解的结果。它看起来像这样:
def cosSim(self, doc1,doc2):
docList = [doc1, doc2]
count_vector = self.cv.transform(docList)
tf_idf_vector = self.tfidfTrans.transform(count_vector)
cos_sim = cosine_similarity(tf_idf_vector)
return cos_sim[0][1]
问题是 self.cv.transform(docList) 会返回不同的结果,有时看起来像这样
(0, 720) 1
(0, 824) 1
(0, 864) 1
(0, 1456) 1
(0, 1762) 1
(0, 1890) 1
(0, 2406) 1
(0, 2593) 1
(0, 3244) 1
(0, 4258) 1
(0, 4414) 1
(1, 969) 1
(1, 2416) 1
(1, 2661) 1
(1, 4075) 1
(1, 4258) 1
and sometimes (wrong) like this
(0, 720) 1
(0, 824) 1
(0, 864) 1
(0, 1456) 1
(0, 1762) 1
(0, 1890) 1
(0, 2406) 1
(0, 2593) 1
(0, 3244) 1
(0, 4258) 1
(0, 4414) 1
所以它似乎在“吃掉”第二份文件。这在程序执行之间甚至不一致,在循环中调用函数,同时看似随机返回两个结果。知道是什么原因造成的吗?
编辑: 我像这样构建我的模型:
def build_tfidf(self, docList):
self.cv = CountVectorizer(stop_words=self.stop_words, strip_accents='ascii', tokenizer=tokenize)
word_count_vector = self.cv.fit_transform(docList)
self.tfidfTrans = TfidfTransformer(use_idf=True)
self.tfidfTrans.fit(word_count_vector)
self.vocab = self.cv.get_feature_names()
我调用了类似的函数,但仍然得到奇怪的结果:
tfidf = TFIDF()
tfidf.build_tfidf(data)
doc1 = "However, a few cooperative transaction models have been proposed to facilitate collaboration, usually while maintaining some guarantees of consistency."
doc2 = "Transaction Management in Multidatabase Systems Databases."
for i in range(0,10):
sim = tfidf.cosSim(doc1, doc2)
print(sim)
Edit2:经过一番修修补补,我找到了一个解决方案,但没有找到解决方案:如果我不通过 CountVectorizer() 一个标记器,我就会开始工作。问题是我需要那个标记器,但这仍然不能解释为什么它不能用它。这是标记化代码以防万一,尽管它可能无关:
def tokenize(doc):
tokens = regex_tokenize(doc)
stemmed = porter_stem(tokens)
return stemmed
def regex_tokenize(doc, reg=u'(?u)\\b\\w\\w+\\b'):
words = []
token_pattern = re.compile(reg)
lan = ""
try:
lan = detect(doc)
except :
pass
if lan == "en":
words = token_pattern.findall(doc)
return words
def porter_stem(doc):
porter_stemmer = PorterStemmer()
stemmed_words = []
for word in doc:
match = re.match("[0-9]+", word)
if match is None: #& match.group() != word:
stemmed_words.append(porter_stemmer.stem(word))
return stemmed_words
在我的cosSim函数中,也尝试过拆分
count_vector = cv.transform([doc1, doc2])
进入
count_vector1 = cv.transform([doc1])
count_vector2 = cv.transform([doc2])
print(f"vec1: {count_vector1}")
print(f"vec2: {count_vector2}")
但即使在那之后它有时仍然不计算第二个向量:
vec1: (0, 266) 1
(0, 294) 1
(0, 527) 1
(0, 603) 1
(0, 743) 2
(0, 1022) 1
vec2: (0, 266) 1
(0, 656) 1
(0, 709) 1
(0, 1068) 1
(0, 1122) 1
0.09454412899652256
vec1: (0, 266) 1
(0, 294) 1
(0, 527) 1
(0, 603) 1
(0, 743) 2
(0, 1022) 1
vec2:
【问题讨论】:
-
这里最可能的情况是由于调用
cosSim()的代码中的错误,输入实际上并不相同。请发布该代码。 -
将代码添加到问题中
标签: python scikit-learn countvectorizer