【问题标题】:Clustering based on connectivity of points基于点连通性的聚类
【发布时间】:2016-10-05 19:09:26
【问题描述】:

我有 100 万条 lat long [5 位精度] 和 Route 的记录。我想对这些数据点进行聚类。

我不想使用标准的 k-means 聚类,因为我不确定有多少 clsuter [尝试过 Elbow 方法但不相信]。

这是我的逻辑 -

1) 我想将 lat long 的宽度从 5 位减少到 3 位。

2) 现在,在 +/- 0.001 范围内的经纬度将被聚集在一次集群中。计算簇的质心。

但是这样做我找不到好的算法和 R 脚本来执行我的思想代码。

谁能帮我解决上述问题。

谢谢,

【问题讨论】:

  • 请提供一个最小的工作示例。 R 中有很多方法可以生成随机数据或使用现有的 in-R-datasets。
  • 那是不是聚类,但您只是在降低数据集的精度。你不想“发现结构”。

标签: r cluster-analysis


【解决方案1】:

可以基于connected components进行聚类。

可以连接彼此距离为 +/-0.001 的所有点,因此我们将有一个包含子图的图,每个子图可以是单个点或一系列连接点(连接组件) 然后可以找到连接的组件并计算它们的中心点。 此任务需要两个包:

1.deldir 形成点的三角剖分并指定哪些点相互适应并计算它们之间的距离。

2 igraph 查找连接的组件。

library(deldir)
library(igraph)
coords <- data.frame(lat = runif(1000000),long=runif(1000000))

#round to 3 digits
coords.r <- round(coords,3)

#remove duplicates
coords.u <- unique(coords.r)

# create triangulation of points. depends on the data may take a while an consume more memory
triangulation <- deldir(coords.u$long,coords.u$lat)

#compute distance between adjacent points
distances <- abs(triangulation$delsgs$x1 - triangulation$delsgs$x2) +
            abs(triangulation$delsgs$y1 - triangulation$delsgs$y2)

#remove edges that are greater than .001
edge.list <- as.matrix(triangulation$delsgs[distances < .0011,5:6])
if (length(edge.list) == 0) { #there is no edge that its lenght is less than .0011
    coords.clustered <- coords.u
} else { # find connected components

    #reformat list of edges so that if the list is 
    #   9 5
    #   5 7
    #so reformatted to
    #   3 1
    #   1 2
    sorted <- sort(c(edge.list), index.return = TRUE)
    run.length <- rle(sorted$x)
    indices <- rep(1:length(run.length$lengths),times=run.length$lengths)
    edge.list.reformatted <- edge.list
    edge.list.reformatted[sorted$ix] <- indices

    #create graph from list of edges
    graph.struct <- graph_from_edgelist(edge.list.reformatted, directed = FALSE)

    # cluster based on connected components
    clust <- components(graph.struct)

    #computation of centroids
    coords.connected <- coords.u[run.length$values, ]
    centroids <- data.frame(lat = tapply(coords.connected$lat,factor(clust$membership),mean) ,
                           long = tapply(coords.connected$long,factor(clust$membership),mean))

    #combine clustered points with unclustered points
    coords.clustered <- rbind(coords.u[-run.length$values,], centroids)

    # round the data and remove possible duplicates
    coords.clustered <- round(coords.clustered, 3)
    coords.clustered <- unique(coords.clustered)
}

【讨论】:

  • Hi Buhtz , Hi Rahnema1, 所以在四舍五入到 3 位数之后。我想对彼此相差 +/- 0.001 的读数进行聚类。地理坐标差 0.001 相当于 150 m。因此,基本上彼此相距 150 m 范围内的读数将聚集在一个集群中。请参见下面的示例 -
猜你喜欢
  • 2015-10-06
  • 2018-02-02
  • 1970-01-01
  • 2020-07-12
  • 2021-11-28
  • 2018-02-13
  • 1970-01-01
  • 2020-11-28
  • 2018-11-29
相关资源
最近更新 更多