字符串"double"时欧几里得距离会改变吗?



问题我试图回答这个问题:考虑两个文档A和B,它们的欧几里得距离为d,余弦相似性为c(除了原始项频率之外,不使用任何归一化(。如果我们通过将a附加到自身来创建新文档a',并通过将B附加到自身创建另一个文档B',则:

a.a'和B'之间的欧几里得距离是多少(使用原始项频率(?

我的解决方案

doc1 = "the quicker brown dogs easily jumps over the lazy dogs" 
doc2 = "the quicker dogs pose a serious problem for lazy dogs"
def calc_term_frequency(doc : list):
dic = {}
for word in doc.split():
if word in dic:
dic[word] = dic[word] + 1
else:
dic[word]= 1
for word, frequency in dic.items():
dic[word]= frequency / len(doc.split())
return dic
tfs_doc1 = calc_term_frequency(doc1)
tfs_doc2 = calc_term_frequency(doc2)
print(tfs_doc1)

将tfs_doc1输出为:{":0.2,"更快":0.1,"棕色":0.1这似乎起到了应有的作用。然后,我继续计算欧几里得距离,首先是在doc1和doc1之间,然后是doc1和doc2之间,如下所示。

import math
math.sqrt(sum((tfs_doc1.get(k, 0) - tfs_doc1.get(k, 0))**2 for k in set(tfs_doc1.keys()).union(set(tfs_doc1.keys())))) # output: 0
math.sqrt(sum((tfs_doc1.get(k, 0) - tfs_doc2.get(k, 0))**2 for k in set(tfs_doc1.keys()).union(set(tfs_doc2.keys())))) # output: 0.316227766016838

这给了我0.316227766016838的分数。当我尝试使用sklearn验证这是正确的时,如下所示:

from sklearn.feature_extraction.text import CountVectorizer
from sklearn.metrics.pairwise import euclidean_distances
corpus_vect = CountVectorizer().fit_transform(corpus).todense() 
print(euclidean_distances(corpus_vect[0], corpus_vect[0])) # output: 0
print(euclidean_distances(corpus_vect[0], corpus_vect[1] )) # output: 3.

我得到的输出为[[0.]][[3.]],这转换为我的"手动"结果的四舍五入(,1(。

问题:当我试图回答最初的问题并"加倍"字符串时,例如

doc1 = "the quicker brown dogs easily jumps over the lazy dogs the quicker brown dogs easily jumps over the lazy dogs" 
doc2 = "the quicker dogs pose a serious problem for lazy dogs the quicker dogs pose a serious problem for lazy dogs"

使用"sklearn方法"/矢量器时,我得到了与手动技术相同的输出(0.316227766016838(,但[[0.]][[6.]]。因此,使用一种方法ED保持不变,使用另一种方法则加倍!

什么是正确的解决方案,是什么导致了差异?真的被困在这里了。提前谢谢。

当您将字符串加倍时,所有术语(包括原始术语(的频率都将重复。因此,如果在复制之前,文档a和B分别有一个(a1, a2, ..., ad)(b1, b2, ..., bd)频率矢量,则欧氏距离将为sqrt((a1-b1)^2 + (a2-b2)^2 + ... + (ad - bd)^2)。现在,经过复制,我们有了(2 * a1, 2 * a2, ..., 2 * ad)(2 * b1,2 * b2, ...,2 * bd),距离是:

dist(A', B') = sqrt((2 * a1- 2 * b1)^2 + (2 * a2 - 2 *b2)^2 + ... + (2 * ad - 2 * bd)^2) = 
2 * sqrt((a1-b1)^2 + (a2-b2)^2 + ... + (ad - bd)^2) = 2 * dist(A,B)

注意,在手动解决方案中,您将频率除以文档的长度,这样可以防止重复术语频率。

最新更新