how to use different distance formula other than euclidean distance in k means
我正在处理纬度经度数据。我必须根据两点之间的距离进行聚类。现在两个不同点之间的距离是
我想在R中使用k均值。在此过程中,有什么方法可以覆盖距离计算?
K均值不是基于距离的
它基于方差最小化。方差之和公式等于欧几里德距离的平方和,但对于其他距离,反之则不成立。
如果您想对其他距离使用类似k均值的算法(均值不是适当的估计量),请使用k-medoids(PAM)。与k-means相比,k-medoids将与任意距离函数收敛!
对于曼哈顿距离,您还可以使用K中值。中位数是L1范数的适当估计量(中位数使差异之和最小;均值使平方和之差最小)。
对于您的特定用例,您还可以将数据转换为3D空间,然后使用(平方)欧几里得距离,从而使用k-均值。但是您的群集中心将位于地下!
使用以下函数来计算地球距离,不需要现有的R函数。我在Stackoverflow上发现了此功能,只是不记得这篇文章的链接。但是,我已经通过GPS累积距离计算对其进行了验证,并且它可以对齐。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 | 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) } |
使用以下函数调用该函数:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 | 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]之间循环,直到计算出所有成对组合。然后将此数据转置为矩阵,您应该有一个距离矩阵。
希望这能回答您的问题
如果您有一个数据框
1 2 3 4 5 | 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(...)。