我正在使用纬度经度数据。我必须根据两点之间的距离制作聚类。现在,两个不同点之间的距离为=ACOS(SIN(lat1)*SIN(lat2)+COS(lat1)*COS(lat2)*COS(lon2-lon1))*6371
我想在R中使用k均值。有什么方法可以在该过程中覆盖距离计算?
答案 0 :(得分:3)
它基于方差最小化。方差和公式等于欧氏距离平方和,但相反,对于其他距离,不保持。
如果你想为其他距离(其中均值不是一个合适的估算器)使用k-means算法,请使用 k-medoids (PAM)。与k-means相比,k-medoids将与任意距离函数收敛!
对于曼哈顿距离,您也可以使用K-medians。中位数是L1范数的合适估计(中位数最小化差异和;平均值最小化平方距离和平均值)。
对于您的特定用例,您还可以将数据转换为3D空间,然后使用(平方)欧几里德距离,从而使用k均值。但是您的集群中心将位于地下!
答案 1 :(得分:0)
如果您有一个data.frame df
,其中包含lat
和long
的列,那么您应该可以使用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]之间循环,直到计算出所有成对组合。然后将此数据转置为矩阵,您应该有一个距离矩阵。
希望这可以回答您的问题