13

Given data points with longitude, latitude, and a third property value of this point. How can I cluster points into groups (geographical sub-regions) based on the property value? I searched by google and figured out that this problem seems to be called "spatial constrained clustering" or "regionalizing". However, I am not familiar with handling geographical data and haven't get an idea about what kind of algorithms are good, and which python/R packages are good for this task.

To give a more intuitive idea about what I want, let's say my data scatter plots are as following: enter image description here

So each dot is a point, x is longitude, y is latitude, and colormap shows whether the value is big or small. I want to divide those points into sub regions/groups/clusters based on location and similarity of values. Like the following (it is not exactly what I want, just to show a intuitive idea.): enter image description here

So how can I achieve this?

  • Your question is a bit broad as it stands. Have you tried any of the R or Python packages out? – John Powell May 25 '16 at 7:33
  • @JohnBarça Currently I think clusterPy package seems useful and rise-group.org/risem/clusterpy/clusterpy0_9_9/… shows how to use it. However, my data is three column points: latitude, longitude, and value. I wish to divide points into sub-region groups based on point value. The package input format seems like some polygon or grid, and I haven't figure out how to directly use it to handle spatial points. – Excalibur May 25 '16 at 7:38
  • 1
    check out the related questions to your question, e.g.: gis.stackexchange.com/questions/17638/… – Iris May 25 '16 at 9:55
  • @Iris Thanks! I have checked the webpage, but seems I still cannot find a way to handle such 3 column spatial points with property directly. – Excalibur May 25 '16 at 18:02
  • @Excalibur for any geographical clustering I would currently recommend HDBScan. In regards to your third value, this could be seen as some kind of weight, I guess. Without projecting all of the values into the same space, this could be a tricky task. Can you provide some background info regarding your objective? – Timothy Dalton May 28 '16 at 18:13
4

The rioja package provides functionality for constrained hierarchical clustering. For what your are thinking of as "spatially constrained" your would specify your cuts based on distance whereas for "regionalization" you could use k nearest neighbors. I would highly recommend projecting your data so it is in a distance based coordinate system.

require(sp)
require(rioja)

data(meuse)
  coordinates(meuse) <- ~x+y
  cdat <- data.frame(x=coordinates(meuse)[,1],y=coordinates(meuse)[,2])
  rownames(cdat) <- rownames(meuse@data)

# Constrained hierarchical clustering 
chc <- chclust(dist(cdat), method="conslink")

# Using kNN with 3 neighbors
chc.n3 <- cutree(chc, k=3) 

# Using distance 
chc.d200 <- cutree(chc, h=200) 

meuse@data <- data.frame(meuse@data, KNN=as.factor(chc.n3), DClust=chc.d200)

opar <- par
  par(mfcol=c(1,2))  
   cols <- topo.colors(length(unique(meuse@data$KNN)))  
    color <- rep("xx", nrow(meuse@data))
      for(i in 1:length(unique(meuse@data$KNN))) {
        v <- unique(meuse@data$KNN)[i] 
          color[(meuse@data$KNN == v)] <- cols[i]
        }
    plot(meuse, col=color, pch=19, main="kNN Clustering")
      box()

    cols <- topo.colors(length(unique(meuse@data$DClust)))  
    color <- rep("xx", nrow(meuse@data))
      for(i in 1:length(unique(meuse@data$DClust))) {
        v <- unique(meuse@data$DClust)[i] 
          color[(meuse@data$DClust == v)] <- cols[i]
        }
    plot(meuse, col=color, pch=19, main="Distance Clustering")
      box() 
par <- opar
  • 1
    Hi @JeffreyEvans, thanks for your reply! So you are suggesting that I project the third property value into another kind of coordinate right? However, I think there should be some existing algorithms that distinguish (lon, lat) with associated attributes, and then do clustering and make points into continuous regions, and points in the same regions shall have similar values (of course there are some outliers). Is there any package can achieve this? I updated my problem for a more intuitive example. Thanks. – Excalibur May 25 '16 at 21:37

protected by Community Apr 25 '17 at 20:28

Thank you for your interest in this question. Because it has attracted low-quality or spam answers that had to be removed, posting an answer now requires 10 reputation on this site (the association bonus does not count).

Would you like to answer one of these unanswered questions instead?

Not the answer you're looking for? Browse other questions tagged or ask your own question.