I'm trying to use 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)正确的方法?我认为余弦相似性适用于不同长度的矢量。
我正在使用this function:
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值的顺序是否重要?它们应该被排序 - 或者这个计算不重要吗?
答案 0 :(得分:9)
您需要将向量中相应单词的条目相乘,因此应该有单词的全局顺序。这意味着理论上你的向量应该是相同的长度。
实际上,如果在另一个文档之前看到一个文档,则在看到第一个文档后,第二个文档中的单词可能已添加到全局顺序中,因此即使向量具有相同的顺序,第一个文档也可能是更短,因为它没有不在该向量中的单词的条目。
文件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的额外元素并将它们乘以零完全相同,但访问额外元素的速度较慢)。
然后你可以分别计算每个向量的大小,为此,向量不需要具有相同的长度。
答案 1 :(得分: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分数,这是没有意义的。
答案 2 :(得分:2)
尝试构建向量,然后将它们提供给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))