【问题标题】:Find euclidean distance of two array of different length查找两个不同长度数组的欧几里得距离
【发布时间】:2020-02-20 15:26:40
【问题描述】:

我想找到欧几里得距离来检查字符串的相似性。

从上面的绘画对象字段中的图像,数据库中有许多图像类型。使用此 paining_object 字段显示图像。现在我想通过比较来自paining_object 字段的字符串来显示一个选定图像的相关图像。所以我使用欧几里得距离方法来查找字符串的相似性。

但我面临长度问题。例如。在数据库的第一行中,paining_object 字段中有四种图像类型,第二行中有四种以上的图像类型。那么,我如何用这种方法测量长度不等的数组的距离。

【问题讨论】:

  • 欧几里得不是几何距离吗?也许您正在搜索levenshtein distance?
  • 但您实际上不想要字符串的相似性而是数组的相似性,对吧?而且您更不希望数组的相似性而是集合的相似性(因为顺序无关紧要:hellsing,katana==katana,hellsing ?)
  • @MarkusZeller 数组元素的顺序对 Levenshtein 算法很重要。但我不想考虑有序数组。
  • 我们首先需要澄清你真正想要什么,因为我不太明白。您想知道数组中的字符串是否彼此相似,或者数组本身是否相似?如何使用欧几里得距离(坐标系中两点之间的距离)来衡量字符串的相似度?
  • 我想检查两个字符串数组的相似性。 @TobiasBrösamle

标签: php ios algorithm similarity euclidean-distance


【解决方案1】:

非欧式距离

两个无序数组之间的距离可以改写为集合之间的距离。

快速查找显示存在多个表示集合之间相似性的距离,例如

  • Jaccard 距离

    d(a,b) = |a 间 b| / |a 联合 b|

  • 最大差异度量

    d(a,b) = 1 - |a 中间 b| / 最大值(|a|, |b|)

纸上有更多的距离(例如)Distances between sets on set commonality

还是欧式距离

你仍然可以强制它:

将所有漫画作为词汇表V,比如大小n。 考虑集合R^n

表格的一行可以表示为vR^n 的向量: 如果该行包含单词i,则输入v[i] = 1,否则输入v[i]=0

最后欧几里得距离可以简单地应用于相同长度的向量。

距离就这样

d(a,b) = || v_b - v_a ||_2 = sqrt( (v_b[0] - v_a[0])^2 + ... + (v_b[n-1] - v_a[n-1)^2)

每个正方形都等于1 iff v_b[i]!=v_a[i] 即您要计算a 中的元素而不是b U b not in a 同上ab 的对称差异。

因此你可以重写你的距离:

d(a,b) = sqrt(|a Δ b|)

【讨论】:

    【解决方案2】:

    我通过使用 Jaccard 距离来做到这一点,如下所示。首先为唯一对象创建了两个表,我们可以从其中收集来自 id 的对象,其次是所有对象聚集在一起,与 (,) 分开

    1) image_sub_main 表格

    2) image_main 表格

    3) PHP 文件作为 Wordpress 方式

    global $wpdb;
    $post_id = $wpdb->get_results("SELECT * FROM `image_main`");
    
    $i=1;
    $finimgarray = array();
    $aa = array();
    $bb = array();
    $firstarray = array('similarity' =>100 , 'id' => $post_id[0]->id );
    
    foreach($post_id as $key => $post){
        if($i < count($post_id)){
        $arraya =$post_id[0]->image_types;
        $a = explode(",",$arraya);
        $arrayb =$post_id[$i]->image_types;
        $b = explode(",",$arrayb);
        $array = array_unique (array_merge ($a, $b));
        $result=array_intersect($a,$b);
        $finalres = count($result) / count($array)*100 ;
        $finimgarray[] = array('similarity' =>round($finalres, 2) , 'id' => $post_id[$i]->id );
     }
        $i++;
    }
    
    array_push($finimgarray, $firstarray);
    arsort($finimgarray);
    
    foreach($finimgarray as $findimgarr){
      $id = $findimgarr['id'];
      $image = $wpdb->get_row("SELECT * FROM `image_main` WHERE `id` = $id ");
      echo "<img src='$image->image'/>";
    }
    

    您的输出会将图像与第一张图像进行比较,并根据相似度百分比显示

    【讨论】:

      【解决方案3】:

      我们不能在这里申请Euclidean Distance,因为:

      • 数组长度可以不同
      • 不应考虑字符串的顺序。例如,地狱 可以在数组中的任何索引处。所以,我们不应该只比较第一个数组的第一个元素和第二个数组的第一个元素。

      相反,我们可以定义一个相似度函数来处理上述两个问题——我们可以使用字符串匹配数与组合总数的比率作为相似度分数。

      // Assuming $firstArr and $secondArr are sets, i.e., don't contain duplicates
      function similarityScore($firstArr, $secondArr) {
          $matchCount = 0;
          foreach ($firstArr as $first) {
              foreach($secondArr as $second) {
                  if ($first == $second) {
                      $matchCount++;
                  }
              }
          }
          return $matchCount/(count($firstArr)*count($secondArr));
      }
      

      此函数返回 [0,1] 范围内的实数,值越大表示相似度越大。

      【讨论】:

      • 我想你还不清楚我的问题。我想使用距离查找算法来检查相似性。 @hsin1.att214
      • @KomalGoyani 我已经更新了我的答案,如果您需要更多帮助,请告诉我。
      • @hsin1.att214 虽然它以某种方式提供了相似性的概念,但您没有定义距离。例如 (firstArr,firstArr) 距离应该是 0。
      • @user753642,感谢您指出这一点,也许我们应该使用Jaccard Index 来查找集合的相似性。
      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 2013-03-02
      • 1970-01-01
      • 2017-03-12
      • 2014-06-08
      • 2020-06-10
      相关资源
      最近更新 更多