【问题标题】:Approaches for spatial geodesic latitude longitude clustering in R with geodesic or great circle distancesR中具有测地线或大圆距离的空间测地纬度经度聚类的方法
【发布时间】:2014-02-01 10:56:27
【问题描述】:

我想将一些基本的聚类技术应用于一些经纬度坐标。类似于聚类(或一些无监督学习)的东西,将坐标分成由它们的great circle 距离或geodesic 距离确定的组。 注意:这可能是一个非常糟糕的方法,所以请提出建议。

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

我进行了一些搜索,但也许我错过了一个可靠的方法?我遇到过这些软件包:flexclustpam——但是,我还没有遇到关于以下内容的明确示例:

  1. 定义我自己的距离函数。
  2. flexclut(通过kccacclust)或pam 是否考虑随机重启?
  3. 锦上添花 = 有谁知道允许指定每个集群中最小元素数量的方法/包?

【问题讨论】:

    标签: r cluster-analysis


    【解决方案1】:

    关于您的第一个问题:由于数据是长/纬度,一种方法是在包fossil 中使用earth.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 聚类技术(例如,kmeans、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-Mousse 评论:

    “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
    

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

    【讨论】:

    • 嗯...LA被聚类算法一分为二?好像有什么问题。
    • 如果您在数据大小 > 200 万条记录上运行,这不会导致问题
    猜你喜欢
    • 2014-07-19
    • 1970-01-01
    • 1970-01-01
    • 2019-12-09
    • 2015-11-28
    • 2017-11-05
    相关资源
    最近更新 更多