무 방향 회선 클러스터링


16

방향에 관계없이 라인을 클러스터링하는 효율적인 방법을 찾고 있습니다. 즉, 뉴욕과 로스 앤젤레스 사이의 노선은 로스 앤젤레스와 뉴욕 사이의 다른 방향의 노선과 동일한 클러스터에 있어야합니다. 시작 / 종료 지점 위치는 유사해야합니다 (즉, 샌디에고에서 롱 아일랜드는 LA-NY와 동일한 클러스터에 있어야하지만 샌프란시스코에서 보스턴은 아닐 것입니다). 중간 지점이 없습니다. 입력 데이터는 다음 예제와 유사합니다.

여기에 이미지 설명을 입력하십시오 (일본 위키 백과 GFDL 또는 CC-BY-SA-3.0 에서 카시오페아 스위트로 Wikimedia Commons를 통해)

이전에 선을 미리 정렬하려고 시도했습니다. 예를 들어, 선을 모두 서쪽에서 동쪽으로 이동 시키려고했지만 북쪽에서 남쪽으로 또는 다른 방향으로가는 선의 문제는 해결되지 않았습니다.

이 문제를 다루는 알고리즘을 알고 있습니까? 나는 방향이 지정되지 않은 세그먼트의 평균 방향을 계산하기 위해 알고리즘 외에 찾고 있지만 원격으로 도움이되는 것을 찾지 못했기 때문에 잘못된 검색어를 사용해야합니다.


1
양쪽 끝 좌표를 계산하고 STR (set ([x1, y1, x2, y2]))을 사용하여 문자열 필드를 채 웁니다. 이 필드를 요약하여 고유 한 값을 찾을 수 있습니다.
FelixIP

답변:


10

내가 당신을 올바르게 이해한다면 방향에 관계없이 거의 같은 줄을 묶고 싶습니다.

내가 생각할 수있는 아이디어는 다음과 같습니다.

  1. 시작점과 끝점에서 선을 분할

  2. 포인트를 클러스터링하고 클러스터 ID를 얻습니다.

  3. 동일한 클러스터 ID 조합을 가진 행을 찾으십시오. 그것들은 클러스터입니다

이것은 PostGIS (물론 :-) 버전 2.3에서 가능해야합니다.

ST_ClusterDBSCAN 함수를 테스트하지는 않았지만 작동해야합니다.

다음과 같은 라인 테이블이있는 경우 :

CREATE TABLE the_lines
(
   geom geometry(linestring),
   id integer primary key
)

시작점과 끝 점이 최대 10km 떨어진 곳에 클러스터를 생성하려고합니다. 그리고 클러스터가 되려면 적어도 2 개의 포인트가 있어야합니다. 그러면 쿼리는 다음과 같습니다.

WITH point_id AS
   (SELECT (ST_DumpPoints(geom)).geom, id FROM the_lines),
point_clusters as
   (SELECT ST_ClusterDBSCAN(geom, 10000, 2) cluster_id, id line_id FROM point_id) 
SELECT array_agg(a.line_id), a.cluster_id, b.cluster_id 
FROM point_clusters a 
     INNER JOIN point_clusters b 
     ON a.line_id = b.line_id AND a.cluster_id < b.cluster_id
GROUP BY a.cluster_id, b.cluster_id

참여 a.cluster_id<b.cluster_id하면 방향에 관계없이 비슷한 클러스터 ID를 얻을 수 있습니다.


니클라스 감사합니다! 클러스터링 중에 다른 단위 (예 : 각도 및 거리)를 강제로 혼합하지 않기 때문에이 방법이 마음에 듭니다.
underdark

5

출발지 또는 목적지를 고려하지 않고 방향별로 만 클러스터하고 싶습니까? 그렇다면 매우 간단한 방법이 있습니다. 아마도 가장 쉬운 방법은 각 선의 방위를 계산하여 두 배로 늘리고 원의 점으로 표시하는 것입니다. 전진 후진 베어링은 180도 다르므로 배가 된 후 360도 차이가 나므로 정확히 같은 위치에 플롯합니다. 이제 원하는 방법을 사용하여 평면의 점을 클러스터합니다.

여기에 실제 예제가 있으며 R4 개의 클러스터 각각에 따라 선이 색상으로 표시됩니다. 물론 베어링을 계산하기 위해 GIS를 사용할 것입니다. 저는 단순성을 위해 유클리드 베어링을 사용했습니다.

그림

cluster.undirected <- function(x, ...) {
  #
  # Compute the bearing and double it.
  #
  theta <- atan2(x[, 4] - x[, 2], x[, 3] - x[, 1]) * 2
  #
  # Convert to a point on the unit circle.
  #
  z <- cbind(cos(theta), sin(theta))
  #
  # Cluster those points.
  #
  kmeans(z, ...)
}
#
# Create some data.
#
n <- 100
set.seed(17)
pts <- matrix(rnorm(4*n, c(-2,0,2,0), sd=1), ncol=4, byrow=TRUE)
colnames(pts) <- c("x.O", "y.O", "x.D", "y.D")
#
# Plot them.
#
plot(rbind(pts[1:n,1:2], pts[1:n,3:4]), pch=19, col="Gray", xlab="X", ylab="Y")
#
# Plot the clustering solution.
#
n.centers <- 4
s <- cluster.undirected(pts, centers=n.centers)
colors <- hsv(seq(1/6, 5/6, length.out=n.centers), 0.8, 0.6, 0.25)
invisible(sapply(1:n, function(i) 
  lines(pts[i, c(1,3)], pts[i, c(2,4)], col=colors[s$cluster[i]], lwd=2))
)

감사합니다! 출발지와 목적지 (O & D)도 중요합니다. "시작 / 종료점 위치가 비슷해야 함"으로 힌트를 주려고했지만 O와 D는 상관하지 않습니다. 그래도 귀하의 설명이 내가 찾고 있던 솔루션에 더 가까이 갈 수 있다고 생각합니다. KMeans를 실행하기 전에 단위 원 값을 점 좌표로 스케일하는 방법을 알아낼 수 있습니다.
underdark

나는 당신이 그것을 염두에두고 있다고 의심했다. 그래서 반 방향을 한 쌍의 좌표 (점)에 매핑하는 것이 좋습니다. 두 번째 변수로 해당 점의 크기를 조정 (극좌표 생각)하거나 원점 또는 목적지에 대한 추가 좌표를 도입 할 수 있습니다. 클러스터링의 궁극적 인 목적을 알지 못하면 추가 좌표의 상대적 크기 (원 좌표와 비교)가 클러스터링 솔루션을 결정하므로 더 많은 조언을 제공하기가 어렵습니다. 또 다른 해결책은 Hough 변환 을 이용하는 것 입니다.
whuber

4

질문을 명확하게 설명 하면 두 출발지와 목적지가 모두 가까울 때 두 원점 목적지 (OD) 쌍을 "닫기"로 간주해야한다는 점에서 클러스터링이 실제 선분을 기반으로하고 싶다는 것을 나타냅니다. , 상관없이 포인트는 원점 또는 목적지 여겨진다 .

이 공식은 두 점 사이 의 거리 d 를 이미 알고 있음을 나타 냅니다. 비행기가 날아가는 거리,지도상의 거리, 왕복 이동 시간 또는 O와 D가 변경 될 때 변하지 않는 다른 메트릭 일 수 있습니다. 전환. 유일한 합병증은 세그먼트가 고유 한 표현을 갖지 않는다는 것입니다. 세그먼트는 비 순차 쌍 {O, D}에 해당하지만 (O, D) 또는 (D, O) 로 정렬 된 쌍 으로 표시되어야합니다 . 따라서 우리는 두 개의 순서 쌍 (O1, D1)과 (O2, D2) 사이의 거리를 합하여 거리 d (O1, O2)와 d (D1, D2)의 대칭 조합으로합니다. 그들의 제곱의 합. 이 조합을 다음과 같이 작성하십시오

distance((O1,D1), (O2,D2)) = f(d(O1,O2), d(D1,D2)).

정렬되지 않은 쌍 사이의 거리를 두 가능한 거리 중 더 작게 정의하면됩니다.

distance({O1,D1}, {O2,D2}) = min(f(d(O1,O2)), d(D1,D2)), f(d(O1,D2), d(D1,O2))).

이 시점에서 거리 매트릭스를 기반으로 한 클러스터링 기술을 적용 할 수 있습니다.


예를 들어, 미국에서 가장 인구가 많은 20 개 도시의지도에서 190 개의 지점 간 거리를 모두 계산하고 계층 적 방법을 사용하여 8 개의 클러스터를 요청했습니다. (간단하게하기 위해 유클리드 거리 계산을 사용하고 내가 사용하고있는 소프트웨어에서 기본 방법을 적용했습니다. 실제로 문제에 적합한 거리와 클러스터링 방법을 선택하고 싶을 것입니다). 다음은 각 선분의 색상으로 클러스터가 표시된 솔루션입니다. (색상은 클러스터에 무작위로 할당되었습니다.)

그림

다음은 R이 예제를 생성 한 코드입니다. 입력은 도시의 "위도"및 "위도"필드가있는 텍스트 파일입니다. (그림에서 도시에 레이블을 지정하기 위해 "키"필드도 포함합니다.)

#
# Obtain an array of point pairs.
#
X <- read.csv("F:/Research/R/Projects/US_cities.txt", stringsAsFactors=FALSE)
pts <- cbind(X$Longitude, X$Latitude)

# -- This emulates arbitrary choices of origin and destination in each pair
XX <- t(combn(nrow(X), 2, function(i) c(pts[i[1],], pts[i[2],])))
k <- runif(nrow(XX)) < 1/2
XX <- rbind(XX[k, ], XX[!k, c(3,4,1,2)])
#
# Construct 4-D points for clustering.
# This is the combined array of O-D and D-O pairs, one per row.
#
Pairs <- rbind(XX, XX[, c(3,4,1,2)])
#
# Compute a distance matrix for the combined array.
#
D <- dist(Pairs)
#
# Select the smaller of each pair of possible distances and construct a new
# distance matrix for the original {O,D} pairs.
#
m <- attr(D, "Size")
delta <- matrix(NA, m, m)
delta[lower.tri(delta)] <- D
f <- matrix(NA, m/2, m/2)
block <- 1:(m/2)
f <- pmin(delta[block, block], delta[block+m/2, block])
D <- structure(f[lower.tri(f)], Size=nrow(f), Diag=FALSE, Upper=FALSE, 
               method="Euclidean", call=attr(D, "call"), class="dist")
#
# Cluster according to these distances.
#
H <- hclust(D)
n.groups <- 8
members <- cutree(H, k=2*n.groups)
#
# Display the clusters with colors.
#
plot(c(-131, -66), c(28, 44), xlab="Longitude", ylab="Latitude", type="n")
g <- max(members)
colors <- hsv(seq(1/6, 5/6, length.out=g), seq(1, 0.25, length.out=g), 0.6, 0.45)
colors <- colors[sample.int(g)]
invisible(sapply(1:nrow(Pairs), function(i) 
  lines(Pairs[i, c(1,3)], Pairs[i, c(2,4)], col=colors[members[i]], lwd=1))
)
#
# Show the points for reference
#
positions <- round(apply(t(pts) - colMeans(pts), 2, 
                         function(x) atan2(x[2], x[1])) / (pi/2)) %% 4
positions <- c(4, 3, 2, 1)[positions+1]
points(pts, pch=19, col="Gray", xlab="X", ylab="Y")
text(pts, labels=X$Key, pos=positions, cex=0.6)

감사! 대형 OD 데이터 세트의 경우 페어 단위 거리 계산이 문제가됩니까?
underdark

예, n 개의 선분으로 n (n-1) / 2 거리 계산이 있기 때문입니다 . 그러나 고유 한 문제는 없습니다. 모든 군집 알고리즘은 점 (또는 점과 군집 중심) 사이의 거리 또는 비 유사성을 찾아야합니다. 이것은 많은 알고리즘이 커스텀 거리 기능으로 작동하는 일반적인 문제입니다.
whuber
당사 사이트를 사용함과 동시에 당사의 쿠키 정책개인정보 보호정책을 읽고 이해하였음을 인정하는 것으로 간주합니다.
Licensed under cc by-sa 3.0 with attribution required.