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

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

欧氏距离

d = ( x i − y i ) 2 d = \sqrt{(x_i-y_i)^2} d=(xiyi)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 = ∑ r = 1 n ∣ x i − y i ∣ d = \sum_{r=1}^n|x_i-y_i| d=r=1nxiyi
曼哈顿距离(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 = m a x ( ∣ x i − y i ∣ ) d= max(|x_i-y_i|) d=max(xiyi)
是向量空间中的一种度量,二个点之间的距离定义是其各坐标数值差绝对值的最大值:

 /**
    *
    * @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 = ∑ r = 1 n ∣ x i − y i ∣ p p d = \sqrt[p]{ \sum_{r=1}^n|x_i-y_i|^p } d=pr=1nxiyip

/**
    *
    * @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 T Y ∣ ∣ x ∣ ∣ 2 + ∣ ∣ y ∣ ∣ 2 + X T Y d = {X^TY\over ||x||^2+||y||^2+X^TY} d=x2+y2+XTYXTY

  /**
    *
    * @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 T Y ∣ ∣ x ∣ ∣   ∣ ∣ y ∣ ∣ d = {X^TY\over ||x|| \ ||y||} d=x yXTY

 /**
    *
    * @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

  • 1
    点赞
  • 3
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值