我正在尝试将经/纬度坐标聚类为指定数量的密集创建的聚类,但需要考虑线段边界-如果任意两个数据点之间的线段与指定线段列表相交(例如4个线段- ->以开始/结束纬度/经度标识),则不应将这些点聚类在一起。由于这是地理空间数据,因此我希望围绕特定的“地理区域”进行聚类,而这些“地理区域”无法从当前使用的聚类算法中轻松地进行解释。最初的想法是修改输入到聚类算法中的距离矩阵的上三角,遍历该三角的每个条目,针对“边界”检查线段,并在发现相交的情况下将其替换为较大的值。但是,这在计算上难以置信(或者至少是我已经设置的配置),并且我无法在合理的时间内操纵数据。
为表示比例,这些数据集可能包含1000-50,000个纬度/经度对的任何地方。
我试图通过利用Python中的“ kneighbors_graph”来开发数据结构,以基于KNN算法开发连接矩阵,但并不能解决问题(k的值不同)。示例如下:{{ 3}} 最终使用了聚集聚类方法,但没有得到我希望的结果(聚类仍然跨越不同的地理位置,并且聚类大小不均匀-占数据集的大多数)。
在RI中,尝试了上述线段方法来调整输入到k-means算法中的距离矩阵,但在大约一个小时的计算后(并且几乎未处理上三角),停止了代码执行。我认为这与我的实施有关。我将在下面粘贴我的方法(将线段作为带有start_lat,start_long,end_lat,end_long的数据帧从csv文件读入,因此调用了“ barrier [k,...]”)
无论是关于如何解决问题的一般意识形态,还是可以加速我提到的处理思想的特定代码实现,都可以得到任何帮助。我还研究了扫描线算法,但是无法将有效的方法包罗万象,以将其实现到整个脚本中。
#Load CSV of barrier line segments
barrier <- read.csv("LineSegments.csv")
#Create distance matrix from Lat/Long Dataframe
distMatrix <- as.matrix(dist(LatLongDf))
q <- nrow(distMatrix)
#Loop through upper triangle of matrix without diagonal
for (i in 1:(q-1)){
for (j in (i+1):q) {
#Grab row/column index of matrix (point IDs) and remap to original DF for point lat/longs
c1 <- c(LatLongDf[rownames(distMatrix)[i][1],LatLongDf[rownames(distMatrix)[i][2])
c2 <- c(LatLongDf[rownames(distMatrix)[j][1],LatLongDf[rownames(distMatrix)[j][2])
#Loop through inputted line segments
for (k in 1:nrow(barrier)) {
#Get point of intersection between two segments
dp <- line.line.intersection(c1,c2,c(barrier[k,2],barrier[k,3]),c(barrier[k,4],barrier[k,5]),interior.only = TRUE)
#If the lines do not intersect then set distance to max
if (is.na(dp[1])) {
distMatrix[i,j] <- max(distMatrix)
break
}
}
}
}
答案 0 :(得分:0)
您不能使用行先分割数据,然后仅对部分进行聚类吗?那肯定是最简单的解决方案。
K-means不使用距离矩阵,因此您的方法无效。它需要计算向量的均值,仅最小化平方的欧几里得距离,因为算术平均值是L2最佳中心。您不能仅对k均值使用不同的距离。 如果要在地理数据上使用k均值,最好将数据投影到合适的Kartesian坐标上,例如UTM区域。
R解释器是 slow 。太慢了。如果您希望代码快速,请避免使用任何未经“向量化”的方法,甚至最好不要调用某些快速的Fortran或C库。