美文网首页
Scala实现机器学习中常用的相识度和距离计算

Scala实现机器学习中常用的相识度和距离计算

作者: k_wzzc | 来源:发表于2019-07-13 16:04 被阅读0次

    在机器学习和人工智能领域,距离(distance)、相似度(similarity)是经常出现的基本概念,关于距离和相似度度量的方法也多种多样,本文将总结一些常用的距离计算方法:

    欧氏距离

    d = \sqrt{(x_i-y_i)^2}
    在二维平面即是两点间的直线距离,是最常用的距离度量的方法之一:

      /**
        *
        * @param p1
        * @param p2
        * @return Euclidean Distance
        */
     def euclidean(p1: Seq[Double], p2: Seq[Double]) = {
     
        require(p1.size == p2.size)
    
        val d = p1.zip(p2)
          .map(tp => pow(tp._1 - tp._2, 2))
          .sum
    
        sqrt(d)
      }
    

    曼哈顿距离

    d = \sum_{r=1}^n|x_i-y_i|
    曼哈顿距离(Manhattan Distance)是由十九世纪的赫尔曼·闵可夫斯基所创词汇 ,是种使用在几何度量空间的几何学用语,用以标明两个点在标准坐标系上的绝对轴距总和。

      /**
        *
        * @param p1
        * @param p2
        * @return Manhattan Distance    
        */
      def manhattan(p1: Seq[Double], p2: Seq[Double]) = {
       
        require(p1.size == p2.size)
    
        p1.zip(p2).map(tp => abs(tp._1 - tp._2)).sum
    
      }
    

    欧式距离和曼哈顿距离在二维平面空间的图示:


    欧式距离与曼哈顿距离

    切比雪夫距离

    d= max(|x_i-y_i|)
    是向量空间中的一种度量,二个点之间的距离定义是其各坐标数值差绝对值的最大值:

     /**
        *
        * @param p1
        * @param p2
        * @return Chebyshev Distance
        */
      def chebyshev(p1: Seq[Double], p2: Seq[Double]) = {
    
        require(p1.size == p2.size)
    
        p1.zip(p2).map(tp => abs(tp._1 - tp._2)).max
    
      }
    
    国际象棋棋盘

    闵氏距离

    闵氏距离不是一种距离,而是一组距离的定义,上面提到的欧氏距离、曼哈顿距离、切比雪夫距离都是属于闵氏距离。
    闵氏距离的定义如下:

    d = \sqrt[p]{ \sum_{r=1}^n|x_i-y_i|^p }

    /**
        *
        * @param p1
        * @param p2
        * @param p
        * @return Minkowski Distance
        */
      def minkowski(p1: Seq[Double], p2: Seq[Double], p: Int) = {
        require(p1.size == p2.size)
        val d = p1
          .zip(p2)
          .map(tp => pow(abs(tp._1 - tp._2), p))
          .sum
    
        pow(d, 1 / p)
      }
    

    当 p=1 时,就是曼哈顿距离
    当 p=2 时,就是欧式距离
    当 p趋于无穷 时,就是闵氏距离


    杰卡德距离

    杰卡德距离(Jaccard Distance) 是用来衡量两个集合差异性的一种指标。

    
      /**
        *
        * @param p1
        * @param p2
        * @return Jaccard Distance  d(A,B) = 1-J(A,B) 表示Jaccard相似系数
        */
      
      def jaccard(p1: Seq[Any], p2: Seq[Any]) = {
    
        val anb = p1.intersect(p2).distinct
        val aub = p1.union(p2).distinct
    
        val jaccardcoefficient = anb.length.toDouble / aub.length
    
        1 - jaccardcoefficient
    
      }
    
    

    Tanimoto 距离

    Tanimoto系数是Jaccard系数的扩展

    d = {X^TY\over ||x||^2+||y||^2+X^TY}

      /**
        *
        * @param p1
        * @param p2
        * @return Tanimoto Distance
        */
      def tanimoto(p1: Seq[Double], p2: Seq[Double]) = {
        require(p1.size == p2.size)
    
        val v1 = new DenseVector(p1.toArray)
        val v2 = new DenseVector(p2.toArray)
    
        val a: Double = p1.map(pow(_, 2)).sum
        val b: Double = p2.map(pow(_, 2)).sum
        val pq = v1.dot(v2)
     
        pq / (a + b - pq)
      }
    
    

    余弦距离

    余弦相似度是计算两个向量夹角的余弦值来度量两个向量的相似度,取值在0-1之间,越大则表示两个向量相似度越高:

    d = {X^TY\over ||x|| \ ||y||}

     /**
        *
        * @param p1
        * @param p2
        */
      def cos(p1: Seq[Double], p2: Seq[Double]) = {
        require(p1.size == p2.size)
    
        val v1 = new DenseVector(p1.toArray)
        val v2 = new DenseVector(p2.toArray)
    
        val a = sqrt(p1.map(pow(_, 2)).sum)
        val b = sqrt(p2.map(pow(_, 2)).sum)
    
        val ab =  v1.t * v2
    
        ab / (a * b)
      }
    

    余弦距离图示:


    余弦距离 图片来源百度百科

    参考资料:

    1.百度百科
    2.https://www.biaodianfu.com/jaccard-tanimoto.html

    相关文章

      网友评论

          本文标题:Scala实现机器学习中常用的相识度和距离计算

          本文链接:https://www.haomeiwen.com/subject/crlmkctx.html