如何使用除k中的欧氏距离以外的不同距离公式

时间:2013-12-18 10:04:06

标签: r machine-learning cluster-analysis data-mining k-means

我正在使用纬度经度数据。我必须根据两点之间的距离制作聚类。现在,两个不同点之间的距离为=ACOS(SIN(lat1)*SIN(lat2)+COS(lat1)*COS(lat2)*COS(lon2-lon1))*6371

我想在R中使用k均值。有什么方法可以在该过程中覆盖距离计算?

3 个答案:

答案 0 :(得分:3)

K-means不是基于距离的

它基于方差最小化。方差和公式等于欧氏距离平方和,但相反,对于其他距离,保持

如果你想为其他距离(其中均值不是一个合适的估算器)使用k-means算法,请使用 k-medoids (PAM)。与k-means相比,k-medoids将与任意距离函数收敛!

对于曼哈顿距离,您也可以使用K-medians。中位数是L1范数的合适估计(中位数最小化差异和;平均值最小化平方距离和平均值)。

对于您的特定用例,您还可以将数据转换为3D空间,然后使用(平方)欧几里德距离,从而使用k均值。但是您的集群中心将位于地下!

答案 1 :(得分:0)

如果您有一个data.frame df,其中包含latlong的列,那么您应该可以使用earth.dist(...)函数fossil 1}}包计算距离矩阵,并将其传递给pam(...)包中的cluster进行聚类。

library(fossil)
library(cluster)
df    <- data.frame(long=<longituces>, lat=<latitudes>))
dist  <- earth.dist(df, dist=T)
clust <- pam(dist, k, diss=T)

请参阅earth.dist(...)pam(...)了解文档

答案 2 :(得分:0)

使用以下函数来计算地球距离,不需要现有的R函数。我在Stackoverflow上发现了此功能,只是不记得这篇文章的链接。但是,我已经通过GPS累积距离计算对其进行了验证,并且它可以对齐。

earthDist <- function (lon1, lat1, lon2, lat2){
  rad <- pi/180
  a1 <- lat1 * rad
  a2 <- lon1 * rad
  b1 <- lat2 * rad
  b2 <- lon2 * rad
  dlon <- b2 - a2
  dlat <- b1 - a1
  a <- (sin(dlat/2))^2 + cos(a1) * cos(b1) * (sin(dlon/2))^2
  c <- 2 * atan2(sqrt(a), sqrt(1 - a))
  R <- 6378.145
  d <- R * c
  return(d)
}

使用以下函数调用该函数:

CalculateCumaltiveDist <- function(x,y,id) {

    # #Initiate a vectro P
    km <- vector()
    # #Starting Value is 0, because its home
    km[1] <- 0

    #Loop through the earthly distance function between the first and Nth Row
    for(i in 2:NROW(df)){


      t <-  earthDist(  x[i-1], y[i-1] ,x[i], y[i])
      km[i] <- t

      if( i == 2 ) {

       tmp_All <- data.frame(id[i],x[i], y[i],km[i])

              } else if(i > 2) {

        tmp_All <- rbind(tmp_All, data.frame(id[i],x[i], y[i],km[i]))

        }

    }


    return(sum(tmp_All$km.i., na.rm = T))
}

如果要使用数据框,请删除最终的返回和函数。

这将允许您计算数据框中每个obs-1与obs之间的距离。

如果要成对计算距离,请使用地球距离函数并在obs [1]:[200000]和obs [1:200000]之间循环,直到计算出所有成对组合。然后将此数据转置为矩阵,您应该有一个距离矩阵。

希望这可以回答您的问题