在R中的空间聚类(简单示例)

11

我有这个简单的数据框(data.frame)

 lat<-c(1,2,3,10,11,12,20,21,22,23)
 lon<-c(5,6,7,30,31,32,50,51,52,53)
 data=data.frame(lat,lon)

该想法是基于距离找到空间聚类。

首先,我绘制地图(经度,纬度):

plot(data$lon,data$lat)

图片描述

因此,根据点的位置之间的距离,我明显有三个聚类。

为了达到这个目的,我在R中尝试了以下代码:

d= as.matrix(dist(cbind(data$lon,data$lat))) #Creat distance matrix
d=ifelse(d<5,d,0) #keep only distance < 5
d=as.dist(d)
hc<-hclust(d) # hierarchical clustering
plot(hc)
data$clust <- cutree(hc,k=3) # cut the dendrogram to generate 3 clusters

这给出了:

这里输入图片描述

现在我尝试绘制相同的点,但使用聚类的颜色。

plot(data$x,data$y, col=c("red","blue","green")[data$clust],pch=19)

这是结果:

enter image description here

但这不是我要找的。

事实上,我想要找类似于这张图的绘图:

enter image description here

感谢您的帮助。


我尝试遵循以下链接:https://dev59.com/K2Ei5IYBdhLWcg3wpdjJ - Math
2
我不太确定你为什么要以那种方式对距离进行聚类……如果您使用hc <- hclust(dist(data)); clust <- cutree(hc, 3),它将按预期工作。 - nico
3个回答

12

这个怎么样:

lat<-c(1,2,3,10,11,12,20,21,22,23)
lon<-c(5,6,7,30,31,32,50,51,52,53)

km <- kmeans(cbind(lat, lon), centers = 3)
plot(lon, lat, col = km$cluster, pch = 20)

输入图片说明


10

这里有一个不同的方法。首先,它假设坐标是WGS-84而不是UTM(平面)。然后,使用分层聚类(方法为single,采用“朋友的朋友”聚类策略)将给定半径内的所有邻居聚集到同一个簇中。

为了计算距离矩阵,我正在使用包fields中的rdist.earth方法。该包的默认地球半径为6378.388(赤道半径),可能不是大家想要的,因此我已将其更改为6371。请参见此文章获取更多信息。

library(fields)
lon = c(31.621785, 31.641773, 31.617269, 31.583895, 31.603284)
lat = c(30.901118, 31.245008, 31.163886, 30.25058, 30.262378)
threshold.in.km <- 40
coors <- data.frame(lon,lat)

#distance matrix
dist.in.km.matrix <- rdist.earth(coors,miles = F,R=6371)

#clustering
fit <- hclust(as.dist(dist.in.km.matrix), method = "single")
clusters <- cutree(fit,h = threshold.in.km)

plot(lon, lat, col = clusters, pch = 20)
这可能是一个不错的解决方案,如果你不知道聚类数目(例如k-means选项),并且与minPts = 1的dbscan选项有些相关。
---编辑---
使用原始数据:
lat<-c(1,2,3,10,11,12,20,21,22,23)
lon<-c(5,6,7,30,31,32,50,51,52,53)
data=data.frame(lat,lon)

dist <- rdist.earth(data,miles = F,R=6371) #dist <- dist(data) if data is UTM
fit <- hclust(as.dist(dist), method = "single")
clusters <- cutree(fit,h = 1000) #h = 2 if data is UTM
plot(lon, lat, col = clusters, pch = 20)

我发现你的答案非常有帮助,你能否也加上k-means方法的解释? - Anubhav Dikshit
1
@user3875610 转换到k-means不是很直观,因为无法将距离矩阵用作k-means的输入(仅使用距离无法计算平均值)。此外,在这种情况下,您通常不知道要聚类的簇数,并且更喜欢使用基于密度的方法,例如hclust或dbscan。话虽如此,如果您想使用类似于kmeans的k-medoids,请查看此答案:https://stats.stackexchange.com/questions/32925/perform-k-means-or-its-close-kin-clustering-with-only-a-distance-matrix-not-p - Omri374

6

由于您有一些空间数据需要聚类,因此最适合您的数据是 DBSCAN

您可以使用由fpc提供的dbscan()函数进行聚类,这是一个R软件包。

library(fpc)

lat<-c(1,2,3,10,11,12,20,21,22,23)
lon<-c(5,6,7,30,31,32,50,51,52,53)

DBSCAN <- dbscan(cbind(lat, lon), eps = 1.5, MinPts = 3)
plot(lon, lat, col = DBSCAN$cluster, pch = 20)

Plot of DBSCAN Clustering


你如何获得/猜测eps参数? - radek

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接