2014-01-13 32 views
11

我想将一些基本聚类技术应用于某些纬度和经度坐标。沿着聚类线(或某些无监督学习)的坐标,可以通过它们的距离或其距离来确定坐标。 注意:这可能是一个非常差的方法,所以请指教。用测地线或大圆距离测量R中空间测地纬度经度聚类的方法

理想情况下,我想在R解决这个问题。

我已经做了一些搜索,但也许我错过了一个坚实的方法?我所遇到的包:flexclustpam - 但是,我还没有碰到过一个明确的例子(S)相对于得出如下:

  1. 定义我自己的距离函数。
  2. 要么flexclut(通过kccacclust)或pam考虑到随机重启?
  3. 蛋糕上的结冰=是否有人知道方法/软件包,可以指定每个集群中元素的最少数量?

回答

16

关于你提到的第一个问题:由于数据是经度/纬度,一种方法是在包fossil使用earth.dist(...)(计算大圆DIST):

library(fossil) 
d = earth.dist(df) # distance object 

另一种方法在geosphere包使用distHaversine(...)

geo.dist = function(df) { 
    require(geosphere) 
    d <- function(i,z){   # z[1:2] contain long, lat 
    dist <- rep(0,nrow(z)) 
    dist[i:nrow(z)] <- distHaversine(z[i:nrow(z),1:2],z[i,1:2]) 
    return(dist) 
    } 
    dm <- do.call(cbind,lapply(1:nrow(df),d,df)) 
    return(as.dist(dm)) 
} 

这里的好处是,你可以使用任何的其他距离算法geosphere,或者你可以定义你自己的距离函数并用它代替distHaversine(...)。然后应用任何的基础R聚类技术(例如,k均值,hclust):

km <- kmeans(geo.dist(df),centers=3) # k-means, 3 clusters 
hc <- hclust(geo.dist(df))   # hierarchical clustering, dendrogram 
clust <- cutree(hc, k=3)    # cut the dendrogram to generate 3 clusters 

最后,一个真实的例子:

setwd("<directory with all files...>") 
cities <- read.csv("GeoLiteCity-Location.csv",header=T,skip=1) 
set.seed(123) 
CA  <- cities[cities$country=="US" & cities$region=="CA",] 
CA  <- CA[sample(1:nrow(CA),100),] # 100 random cities in California 
df  <- data.frame(long=CA$long, lat=CA$lat, city=CA$city) 

d  <- geo.dist(df) # distance matrix 
hc  <- hclust(d)  # hierarchical clustering 
plot(hc)     # dendrogram suggests 4 clusters 
df$clust <- cutree(hc,k=4) 

library(ggplot2) 
library(rgdal) 
map.US <- readOGR(dsn=".", layer="tl_2013_us_state") 
map.CA <- map.US[map.US$NAME=="California",] 
map.df <- fortify(map.CA) 
ggplot(map.df)+ 
    geom_path(aes(x=long, y=lat, group=group))+ 
    geom_point(data=df, aes(x=long, y=lat, color=factor(clust)), size=4)+ 
    scale_color_discrete("Cluster")+ 
    coord_fixed() 

城市数据是从GeoLite。美国国家shapefile来自Census Bureau

编辑响应@ Anony-慕斯评论:

它可能看起来奇怪,“LA”是两个集群之间的分歧,但是,扩大地图显示,对于城市的这种随机选择,有是第3组和第4组之间的差距。第4组基本上是圣莫尼卡和伯班克;第3组是帕萨迪纳,南洛杉矶,长滩以及南部的所有地方。

K-means聚类(4簇)确实将LA/Santa Monica/Burbank/Long Beach周围的区域保存在一个簇中(见下文)。这只是归结于kmeans(...)hclust(...)所使用的不同算法。

km <- kmeans(d, centers=4) 
df$clust <- km$cluster 

值得一提的是,这些方法都需要所有的点都必须进入一些集群。如果你只是问哪些点靠得很近,并且允许一些城市没有进入任何聚类,你会得到非常不同的结果。

+0

嗯......洛杉矶分为两个聚类算法?看起来有什么问题。 –

+0

如果您运行的数据大小超过200万条记录,这不会造成问题 –

0

我偶尔会使用ELKI对空间数据进行聚类。

这不是R(我不喜欢R,并发现它在许多情况下很慢。事实上,任何超越了简单的矩阵乘法和简单的调用到C或Fortran代码很慢。)

无论如何,ELKI支持大地测量距离,甚至对这些距离的索引加速(通过M树和R *树;批量加载的R *树最适合我,并且产生大规模的加速);许多聚类算法如DBSCAN和OPTICS都可以与这些距离函数一起使用。

这里是我与ELKI集群得到了一个例子:https://stackoverflow.com/a/14702758/1060350

我没有保持代码虽然。不知道我是否将Python用于KML输出,或者是否实现了ELKI输出模块。