相似的

时间:2009-12-31 20:13:08

标签: java text similarity tf-idf

我正在使用TF / IDF来计算相似度。例如,如果我有以下两个文档。

Doc A => cat dog
Doc B => dog sparrow

这是正常的,它的相似性是50%,但是当我计算它的TF / IDF时。如下

Doc A的Tf值

dog tf = 0.5
cat tf = 0.5

Doc B的Tf值

dog tf = 0.5
sparrow tf = 0.5

Doc A的IDF值

dog idf = -0.4055
cat idf = 0

Doc B的IDF值

dog idf = -0.4055 ( without +1 formula 0.6931)
sparrow idf = 0

Doc A的TF / IDF值

0.5x-0.4055 + 0.5x0 = -0.20275

Doc B的TF / IDF值

0.5x-0.4055 + 0.5x0 = -0.20275

现在看起来有-0.20275的相似性。是吗? 或者我错过了什么? 或者也是下一步呢?请告诉我,我也可以计算一下。

我使用了维基百科提到的tf / idf公式

3 个答案:

答案 0 :(得分:17)

让我们看看我是否收到你的问题: 您想要计算两个文档之间的TF / IDF相似性:

Doc A: cat dog

Doc B: dog sparrow

我认为这是你的整个语料库。因此|D| = 2 对于所有单词,Tfs确实是0.5。 要计算'狗'的IDF,请log(|D|/|d:dog in d| = log(2/2) = 0 同样,'cat'和'sparrow'的IDF是log(2/1) = log(2) =1 (我使用2作为日志基础来使这更容易)。

因此,'dog'的TF / IDF值将为0.5 * 0 = 0 'cat'和'sparrow'的TF / IDF值将为0.5 * 1 = 0.5

要测量两个文档之间的相似性,您应该计算余弦 (猫,麻雀,狗)空间中的向量之间: (0.5,0,0)和(0,0.5,0)并得到结果0。

总结一下:

  1. 您在IDF计算中出错。
  2. 此错误会导致错误的TF / IDF值。
  3. 维基百科文章没有充分解释TF / IDF对相似性的使用。我更喜欢Manning, Raghavan & Schütze's explanation

答案 1 :(得分:0)

我认为你必须使用ln而不是log。

答案 2 :(得分:0)

def calctfidfvec(tfvec, withidf):
    tfidfvec = {}
    veclen = 0.0

    for token in tfvec:
        if withidf:
            tfidf = (1+log10(tfvec[token])) * getidf(token)
        else:
            tfidf = (1+log10(tfvec[token]))
        tfidfvec[token] = tfidf 
        veclen += pow(tfidf,2)

    if veclen > 0:
        for token in tfvec: 
            tfidfvec[token] /= sqrt(veclen)

    return tfidfvec

def cosinesim(vec1, vec2):
    commonterms = set(vec1).intersection(vec2)
    sim = 0.0
    for token in commonterms:
        sim += vec1[token]*vec2[token]

    return sim