余弦相似度结果高于1

时间:2013-06-03 18:08:32

标签: php information-retrieval cosine-similarity

我在PHP中编码余弦相似度。有时formula会给出高于一的结果。为了使用逆cos从该数字导出一个度数,它需要在1和0之间。

我知道我不需要学位,因为它越接近1,它们越相似,越接近0就越不相似。

但是,我不知道如何制作一个高于1的数字。它只是意味着它完全不同吗? 2比0更不相似吗?

你能否说出相似的顺序:

最接近1从下到下0 - 最相似,从0变为1。 从上到下最接近1 - 越远越不相似。

谢谢!

我的代码,请求是:

$norm1 = 0;
foreach ($dict1 as $value) {
    $valuesq = $value * $value;
    $norm1 = $norm1 + $valuesq;
}
$norm1 = sqrt($norm1);
$dot_product = array_sum(array_map('bcmul', $dict1, $dict2));
$cospheta = ($dot_product)/($norm1*$norm2);

让您了解我所获得的各种价值观:

0.9076645291077

2.0680991116095

1.4015600717928

1.0377360186767

1.8563586243689

1.0349674872379

1.2083865384822

2.3000034036913

0.84280491429133 

3 个答案:

答案 0 :(得分:1)

你的数学很好,但我认为你错过了计算规范的东西。如果您将数学运算到其自己的函数,它的工作原理如下:

<?php
function calc_norm($arr) {
    $norm = 0;
    foreach ($arr as $value) {
        $valuesq = $value * $value;
        $norm = $norm + $valuesq;
    }
    return(sqrt($norm));
}

$dict1 = array(5,0,97);
$dict2 = array(300,2,124);

$dot_product = array_sum(array_map('bcmul', $dict1, $dict2));
$cospheta = ($dot_product)/(calc_norm($dict1)*calc_norm($dict2));

print_r($cospheta);

&GT;

答案 1 :(得分:0)

我不知道我是否遗漏了一些东西,但我认为你没有将和和平方根应用于dict2中的值(我假设的查询)。

如果未对每个查询进行规范化,则可以获得大于1的结果。但是,这样做了一些时间,因为它与正确的结果等效(成比例)并且计算速度更快。

我希望这会有所帮助。

答案 2 :(得分:-1)

由于floating point arithmetic的变幻莫测,您可以进行计算,当以计算机使用的二进制形式表示时,这些计算并不精确。也许你可以向下舍入。同样,对于略小于零的数字。