0

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

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

但是,我不知道 1 以上的数字是什么意思。这是否意味着它完全不同?2 比 0 更相似吗?

你能说相似的顺序是这样的吗:

从下方到 0 最接近 1 - 从 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 
4

3 回答 3

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);

?>

于 2013-06-03T20:08:26.073 回答
0

我不知道我是否遗漏了什么,但我认为您没有将总和和平方根应用于 dict2 中的值(我假设的查询)。

如果您没有对每个查询进行标准化,您可以获得大于 1 的结果。但是,有时会这样做,因为它与正确结果的排名等价(成比例)并且计算速度更快。

我希望这有帮助。

于 2013-06-03T19:43:15.723 回答
-1

由于浮点运算的变幻莫测,当以计算机使用的二进制形式表示时,您的计算可能并不精确。也许你可以四舍五入。对于略小于零的数字也是如此。

于 2013-06-03T18:38:50.557 回答