【问题标题】:Cosine similarity result above one余弦相似度结果大于一
【发布时间】:2013-05-29 23:25:53
【问题描述】:

我在 PHP 中编码余弦相似度。有时formula 给出的结果高于一个。为了使用反 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 

【问题讨论】:

  • 你是如何计算点积的?你能展示你的代码吗?
  • @Tap 我已经添加了代码。
  • 你能举个例子说明 $dict1 和 $dict2 值导致 cospheta 大于一吗?

标签: php information-retrieval cosine-similarity


【解决方案1】:

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

【讨论】:

    【解决方案2】:

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

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

    我希望这会有所帮助。

    【讨论】:

      【解决方案3】:

      你的数学很好,但我认为你在计算规范时遗漏了一些东西。如果您将数学移到它自己的函数中,效果会很好,如下所示:

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

      ?>

      【讨论】:

        猜你喜欢
        • 2011-02-08
        • 1970-01-01
        • 2011-02-21
        • 2020-08-12
        • 2011-01-01
        • 2016-01-26
        • 1970-01-01
        • 2017-12-12
        相关资源
        最近更新 更多