15

我正在尝试使用 TF-IDF将文档分类。我已经计算了一些文档的 tf_idf,但是现在当我尝试计算其中两个文档之间的余弦相似度时,我得到一个回溯说:

#len(u)==201, len(v)==246

cosine_distance(u, v)
ValueError: objects are not aligned

#this works though:
cosine_distance(u[:200], v[:200])
>> 0.52230249969265641

切片向量以便 len(u)==len(v) 是正确的方法吗?我认为余弦相似性适用于不同长度的向量。

我正在使用这个功能

def cosine_distance(u, v):
    """
    Returns the cosine of the angle between vectors v and u. This is equal to
    u.v / |u||v|.
    """
    return numpy.dot(u, v) / (math.sqrt(numpy.dot(u, u)) * math.sqrt(numpy.dot(v, v))) 

另外——向量中 tf_idf 值的顺序重要吗?是否应该对它们进行排序——或者它对这个计算不重要?

4

3 回答 3

10

您需要将向量中相应单词的条目相乘,因此单词应该有一个全局顺序。这意味着理论上你的向量应该是相同的长度。

在实践中,如果一个文档先于另一个文档出现,则第二个文档中的单词可能在看到第一个文档之后被添加到全局顺序中,因此即使向量具有相同的顺序,第一个文档也可能更短,因为它没有不在该向量中的单词的条目。

文件 1:敏捷的棕狐跳过了懒惰的狗。

Global order:     The quick brown fox jumped over the lazy dog
Vector for Doc 1:  1    1     1    1     1     1    1   1   1

文件2:跑步者很快。

Global order:     The quick brown fox jumped over the lazy dog runner was
Vector for Doc 1:  1    1     1    1     1     1    1   1   1
Vector for Doc 2:  1    1     0    0     0     0    0   0   0    1     1

在这种情况下,理论上您需要在 Document 1 向量的末尾填充零。实际上,在计算点积时,只需将元素相乘到向量 1 的末尾(因为省略向量 2 的额外元素并将它们乘以零完全一样,但访问额外元素会更慢)。

然后您可以分别计算每个向量的大小,为此向量不需要具有相同的长度。

于 2010-06-30T01:00:22.093 回答
6

你在计算词向量的余弦相似度吗?词向量应该是相同的长度。如果文档中不存在单词,则该术语的值应为 0。

我不确定您将余弦相似度应用于哪些向量,但是在进行余弦相似度时,您的向量应该始终具有相同的长度,并且顺序非常重要。

例子:

Term | Doc1 | Doc2
Foo     .3     .7
Bar  |  0   |  8
Baz  |  1   |  1

这里有两个向量 (.3,0,1) 和 (.7,8,1),可以计算它们之间的余弦相似度。如果您比较 (.3,1) 和 (.7,8),您会将 Baz 的 Doc1 分数与 Bar 的 Doc2 分数进行比较,这是没有意义的。

于 2010-06-25T20:40:32.113 回答
4

在将向量输入 cosine_distance 函数之前尝试构建向量:

import math
from collections import Counter
from nltk import cluster

def buildVector(iterable1, iterable2):
    counter1 = Counter(iterable1)
    counter2= Counter(iterable2)
    all_items = set(counter1.keys()).union( set(counter2.keys()) )
    vector1 = [counter1[k] for k in all_items]
    vector2 = [counter2[k] for k in all_items]
    return vector1, vector2


l1 = "Julie loves me more than Linda loves me".split()
l2 = "Jane likes me more than Julie loves me or".split()


v1,v2= buildVector(l1, l2)
print(cluster.util.cosine_distance(v1,v2))
于 2013-02-19T06:36:12.447 回答