R에서 kmeans로 감독되지 않은 분류


10

나는 일련의 위성 이미지 (5 밴드)를 가지고 있으며 R에서 kmeans로 분류하고 싶습니다. 내 스크립트가 정상적으로 작동합니다 (이미지를 반복하고 이미지를 data.frame으로 변환하고 클러스터링 한 다음 다시 래스터) :

for (n in files) {
image <- stack(n)    
image <- clip(image,subset)

###classify raster
image.df <- as.data.frame(image)  
cluster.image <- kmeans(na.omit(image.df), 10, iter.max = 10, nstart = 25) ### kmeans, with 10 clusters

#add back NAs using the NAs in band 1 (identic NA positions in all bands), see http://stackoverflow.com/questions/12006366/add-back-nas-after-removing-them/12006502#12006502
image.df.factor <- rep(NA, length(image.df[,1]))
image.df.factor[!is.na(image.df[,1])] <- cluster.image$cluster

#create raster output
clusters <- raster(image)   ## create an empty raster with same extent than "image"  
clusters <- setValues(clusters, image.df.factor) ## fill the empty raster with the class results  
plot(clusters)
}

내 문제는 : 클러스터 할당자가 이미지마다 다르기 때문에 분류 결과를 서로 비교할 수 없습니다. 예를 들어, "물"은 첫 번째 이미지 클러스터 번호 1, 다음 2 및 세 번째 10에 있으므로 날짜 간의 물 결과를 비교할 수 없습니다.

클러스터 할당을 어떻게 수정합니까?

모든 이미지에 대해 고정 된 시작점을 지정할 수 있습니까 (물이 항상 먼저 감지되어 1로 분류 됨).

그리고 만약 그렇다면 어떻게?

답변:


6

할 수 없다고 생각합니다 ... 먼저 각 클래스에 레이블을 지정하여 비교해야합니다. Kmean은 사전 정보없이 감독없이 분류하므로 어떤 종류의 클래스도 정의 할 수 없습니다.

참조 레이어가있는 경우 다수 투표로 레이블을 지정할 수 있습니다. 다음은 '래스터'패키지 함수를 사용하는 것보다 과반수의 투표에 훨씬 효율적인 코드입니다 zonal.

require (data.table)
fun <- match.fun(modal)
vals <- getValues(ref) 
zones <- round(getValues(class_file), digits = 0) 
rDT <- data.table(vals, z=zones) 
setkey(rDT, z) 
zr<-rDT[, lapply(.SD, modal,na.rm=T), by=z]

ref래스터 클래스 참조 파일은 어디에 있으며, class_filekmeans 결과입니다.

zr 첫 번째 열에는 '영역'번호가 있고 두 번째 열에는 클래스의 레이블이 있습니다.


나는 그것이 불가능하다는 것을 두려워했다. 과반수 투표 코드에 감사드립니다!
Iris

4

이미지 스택에서 클러스터링을 구현하려면 밴드 단위로 수행하지 않고 전체 이미지 스택에서 동시에 클러스터링을 수행하십시오. 그렇지 않으면 @nmatton이 지적한 것처럼 통계는 의미가 없습니다.

그러나 나는 이것이 불가능하고 메모리 집약적이라는 것에 동의하지 않습니다. 실제 위성 데이터에서는 큰 문제가 될 수 있으며 고해상도 데이터에서는 불가능할 수 있지만 래스터를 클러스터링 함수에 전달할 수있는 단일 객체로 강제 변환하여 메모리에서 처리 할 수 ​​있습니다. 클러스터링 중 래스터 값이 제거되므로 래스터에서 NA 값을 추적해야하며 클러스터 값을 올바른 셀에 할당 할 수 있도록 래스터의 위치를 ​​알아야합니다.

여기서 하나의 접근 방식을 단계별로 진행할 수 있습니다. 필요한 라이브러리와 예제 데이터 (RGB R 로고를 추가하여 작업 할 3 개의 밴드를 제공)를 추가 할 수 있습니다.

library(raster)
library(cluster)
r <- stack(system.file("external/rlogo.grd", package="raster")) 
  plot(r)

먼저 getValues를 사용하여 다중 대역 래스터 스택 객체를 data.frame으로 강제 변환 할 수 있습니다. 행 1, 열 3에 NA 값을 추가하여 데이터를 처리하지 않는 방법을 설명 할 수 있습니다.

r.vals <- getValues(r[[1:3]])
  r.vals[1,][3] <- NA

여기서 비즈니스에 착수하여 클러스터 결과를 할당하는 데 사용될 비 NA 값의 셀 인덱스를 만들 수 있습니다.

idx <- 1:ncell(r)
idx <- idx[-unique(which(is.na(r.vals), arr.ind=TRUE)[,1])]  

이제 k = 4 인 3 대역 RGB 값에서 클러스터 객체를 만듭니다. 나는 clara K-Medoids 방법을 사용하고 있습니다. 큰 데이터에는 좋고 홀수 분포에 더 좋습니다. K-Means와 매우 유사합니다.

clus <- cluster::clara(na.omit(scale(r.vals)), k=4)

편의상 원본 래스터 스택 객체에서 래스터 밴드 중 하나를 가져 와서 NA 값을 할당하여 빈 래스터를 만들 수 있습니다.

r.clust <- r[[1]]
r.clust[] <- NA

마지막으로 인덱스를 사용하여 빈 래스터의 해당 셀에 클러스터 값을 할당하고 결과를 플로팅합니다.

r.clust[idx] <- clus$clustering
plot(r.clust) 

거대한 래스터의 경우 디스크에 행렬을 기록하고 블록에서 작동하는 k-means 기능이있는 bigmemory 패키지를 살펴볼 수 있습니다. 또한 이것이 R이 의도 한 것과 정확히 일치하지 않으며 이미지 처리 또는 GIS 소프트웨어가 더 적합 할 수 있습니다. SAGA와 Orfeo 툴박스는 이미지 스택에 k- 평균 클러스터링을 사용할 수있는 무료 소프트웨어라는 것을 알고 있습니다. R에서 소프트웨어를 호출 할 수있는 RSAGA 라이브러리도 있습니다.


모든 이미지가 한 번에 쌓이고 클러스터되면 결과는 하나의 클러스터 된 이미지입니다.
아이리스

@Iris, 그렇습니다.이 유형의 이미지 클러스터링이 작동하는 방식이며 원격 감지 소프트웨어의 구현을 따릅니다. 분명하고 관련 예제 (는 ArcGIS에서 isocluster 구현 될 desktop.arcgis.com/en/arcmap/10.3/tools/spatial-analyst-toolbox/...가 )
제프리 에반스

그런 다음이 anwer는 전혀 도움이되지 않습니다. 내 문제는 감독되지 않은 여러 이미지 분류를 기반으로 시간이 지남에 따라 변경 감지를 시도했지만 클래스가 다르게 할당되었으므로 다른 결과를 비교할 수 있다는 것입니다.
아이리스

감독되지 않은 분류는 변경 감지를 수행하기위한 실용적인 방법이 아닙니다. 주어진 이미지의 약간의 변화조차도 픽셀이 다른 클래스에 할당 될 수 있습니다. K-Means에 클러스터 센터를 제공 한 경우에도 마찬가지입니다. 공간 감지 패키지에 변경 감지에 유용한 엔트로피 기능이 있습니다. NxN 창 내에서 엔트로피를 계산 한 다음 각 시간 단계에서 델타를 도출합니다. 음의 엔트로피는 손실을 나타내고 양의 엔트로피는 주어진 크기 내에서 가로 성분의 이득입니다.
Jeffrey Evans

그것은 오래된 질문이며 나는 오래 전 k- 평균을 사용한다는 생각을 무시했습니다. 그러나 다음 시간에 공간적 공간 패키지를 아는 것이 좋습니다;)
Iris
당사 사이트를 사용함과 동시에 당사의 쿠키 정책개인정보 보호정책을 읽고 이해하였음을 인정하는 것으로 간주합니다.
Licensed under cc by-sa 3.0 with attribution required.