R - 使用点数据集(GPS 数据)进行网络分析

问题描述 投票:0回答:1

我是网络分析新手,但我正在为我正在进行的研究探索这个选项。

我想做的是检测点簇(来自 GPS 数据)。我知道有多种方法可以做到这一点,可以使用多个 R 包(例如

GPSeqClus
)。然而,似乎大多数都需要建立一个半径(然后对数据进行分组,这对我来说很有意义)。

这是我的输入数据集的样子:

id   datetime          lat    lon
A1   12/05/2018 12:00  47.369 17.326
A1   12/05/2018 17:00  47.371 17.328
A1   12/05/2018 21:00  47.373 17.331
A1   12/05/2018 23:00  47.381 17.385
A1   13/05/2018 02:00  47.392 17.391

绘制时,红色圆圈将是一个簇:

但是,我想知道是否有一种方法可以做到同样的事情,但是不需要指定集群半径。在尝试回答这个问题时,我想出了网络分析,这似乎就是我一直在寻找的东西 - 例如,从我在本教程中看到的内容来看,有些组是明确定义的,无需指定任何缓冲区。

但通过使用

make_graph

 包(
source
)中的 
igraph 函数,输入数据看起来像是某种矩阵。所以 (1) 我想知道是否可以使用其他数据(GPS 数据,如上所示的示例)来完成此操作?

当我将

make_graph

 函数应用于上面提供的示例(纬度和经度值)时,我得到以下结果:

这基本上只是关联每个点的

x

y
 坐标...有什么想法吗?

而且,

(2)如果网络分析不适用于这种特殊情况(GPS 数据),是否有人知道无需建立半径即可对数据进行分组的另一种选择?预先感谢!

编辑:更加关注问题,并添加了我的数据的示例,以及集群的示例(以及当我将 make_graph

 函数应用于我的数据时会发生什么)

r gps cluster-analysis igraph
1个回答
0
投票
这个问题主要是指定您的设计和所需输出的问题,而不是代码技术问题,但我将编写一些代码来帮助您指导所需的输出。

有大量的聚类或分类算法可以应用于您的坐标,并且您不需要任何图论。我想说,只有当网络轨道对于可以在你的点之间假设超过一级的联系的位置有意义时,你才应该追求网络轨道。

但是,由于您专门询问了网络,因此您应该知道您的图形输出是这样的,因为我认为您以无意的方式生成了它。

让我们始终使用此数据:

library(igraph) df <- data.frame( name = paste0('N',1:5), ts = as.POSIXlt(c('2018-05-12 12:00:00', '2018-05-12 17:00:00', '2018-05-12 21:00:00', '2018-05-12 23:00:00', '2018-05-13 02:00:00')), x = c(47.369,47.371,47.373,47.381,47.392), y = c(17.326,17.328,17.331,17.385,17.391) ) # You should build the graph using NETWORK data, not a list of data-points. # This is wrong: g <- graph_from_data_frame(df) plot(g) # This is right: g <- make_empty_graph() %>% add_vertices(nrow(df), attr=list('name'=df$name)) plot(g)

graph_from_data_frame()

所需的输入格式是边列表。由于您的数据仅隐式包含相关网络数据,我们将首先创建完整图的边列表(所有节点都连接的图),然后计算它们之间的距离,以用作 cummunity 检测算法的基础它的聚类。

# Build an edgelist using the combinations between all nodes el <- combn(df$name, 2, simplify = TRUE) %>% t() %>% as.data.frame() %>% rename(i=V1, j=V2) # This function calculates the pythagorean distance between points pyth_dist <- function(node_1, node_2){ x1 <- df$x[df$name == node_1] y1 <- df$y[df$name == node_1] x2 <- df$x[df$name == node_2] y2 <- df$y[df$name == node_2] # Pythagoras is our friend! sqrt((abs(x1-x2)^2) + (abs(y1-y2)^2)) } # Apply to get distance between all nodes el$dist <- apply(el[, c("i", "j")], 1, function(row) { pyth_dist(row[1], row[2]) }) * 100 # Your graph recieves the third column as a weight. Each point is now connected # with a weight equal to the pythagorean distance between it and its connected # node. g <- graph_from_data_frame(el, directed=F) plot(g, edge.width=E(g)$dist) # Community-detection with weights as inverted distance: between_point_weights <- max(E(g)$dist)-E(g)$dist comm <- cluster_spinglass(g, spins=2, weights=between_point_weights) plot(g, vertex.color=comm$membership, edge.width=E(g)$dist, layout = layout_nicely) # Communities are here comm
在输出图中,您会看到所有点都与所有其他点都有关系(因为每个点到其他点都有距离)。如果距离较大,则该距离会显示为粗线。彼此靠近的三个点被正确地聚类到同一组中。查找 

comm

 对象中的分组。另请注意 igrpah 如何处理权重,以及出于算法和可视化目的我反转权重。如果您愿意,可以使用我们发送到 
cluster_spinglass()
 的相同权重来可视化距离,该权重需要高值来表示接近度(与关系距离相反)。

您可以使用此处使用的算法在

spins

 中进行截断实验,以获得“所需”的社区数量,但是对于聚类如何工作并没有绝对的定义;由您来定义合理的边界。

回到总体问题,与其他分类算法相比,这种网络方法可能没有多大意义。

© www.soinside.com 2019 - 2024. All rights reserved.