Phân loại không giám sát với kmeans trong R


10

Tôi có một chuỗi thời gian hình ảnh vệ tinh (5 băng tần) và muốn phân loại chúng theo kmeans trong R. Kịch bản của tôi hoạt động tốt (lặp qua hình ảnh của tôi, chuyển đổi hình ảnh thành data.frame, phân cụm chúng và chuyển đổi lại thành raster):

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)
}

Vấn đề của tôi là: Tôi không thể so sánh các kết quả phân loại với nhau vì các hàm gán cụm khác nhau từ hình ảnh này sang hình ảnh khác. Ví dụ: "nước" nằm trong cụm ảnh đầu tiên số 1, trong 2 tiếp theo và trong 10 thứ ba, khiến cho không thể so sánh kết quả nước giữa các ngày.

Làm thế nào tôi có thể sửa chữa phân công cụm?

Tôi có thể chỉ định điểm bắt đầu cố định cho tất cả hình ảnh không (hy vọng rằng nước luôn được phát hiện đầu tiên và do đó được phân loại là 1)?

Và nếu có, làm thế nào?

Câu trả lời:


6

Tôi nghĩ bạn không thể ... Trước tiên bạn phải dán nhãn cho mỗi lớp để so sánh chúng. Kmean phân loại không giám sát nên không có bất kỳ thông tin nào trước đó và do đó không thể định nghĩa bất kỳ loại lớp nào.

Nếu bạn có một lớp tham chiếu, bạn có thể tạo nhãn bằng cách bỏ phiếu đa số. Đây là một mã khá hiệu quả để bỏ phiếu đa số hơn là sử dụng chức năng gói 'raster' 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]

reftệp tham chiếu lớp raster của bạn ở đâu , class_filelà kết quả kmeans của bạn.

zr cung cấp cho bạn trong col đầu tiên số 'vùng' và trong col thứ hai, nhãn cho lớp.


Tôi sợ rằng điều đó là không thể. Cảm ơn bạn đã mã cho đa số bỏ phiếu!
Iris

4

Để thực hiện phân cụm trên một ngăn xếp hình ảnh, bạn không thực hiện đồng thời theo từng dải mà thay vào đó trên toàn bộ ngăn xếp hình ảnh. Mặt khác, như được chỉ ra bởi @nmatton, thống kê không có nhiều ý nghĩa.

Tuy nhiên, tôi không đồng ý rằng điều này là không thể, chỉ cần nhiều bộ nhớ. Trên dữ liệu vệ tinh thực, đây sẽ là một vấn đề lớn và có lẽ là không thể đối với dữ liệu có độ phân giải cao, nhưng bạn có thể xử lý trong bộ nhớ bằng cách ép (các) raster của bạn vào một đối tượng có thể được truyền cho một chức năng phân cụm. Bạn sẽ cần theo dõi các giá trị NA trên các raster vì chúng sẽ bị xóa trong khi phân cụm và bạn sẽ cần biết các vị trí trong raster để bạn có thể gán các giá trị cụm cho các ô chính xác.

Chúng ta có thể bước qua một cách tiếp cận ở đây. Cho phép thêm các thư viện cần thiết và một số dữ liệu mẫu (logo RGB R để cung cấp cho chúng tôi 3 băng tần để làm việc).

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

Đầu tiên, chúng ta có thể ép buộc đối tượng ngăn xếp raster nhiều băng tần của mình vào data.frame bằng cách sử dụng getValues. Lưu ý rằng tôi đang thêm một giá trị NA ở hàng 1, cột 3 để tôi có thể minh họa cách xử lý không có dữ liệu.

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

Tại đây, chúng ta có thể bắt tay vào kinh doanh và tạo một chỉ mục ô của các giá trị không phải NA sẽ được sử dụng để gán kết quả cụm.

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

Bây giờ, chúng ta tạo một đối tượng cụm từ các giá trị RGB 3 băng tần với k = 4. Tôi đang sử dụng phương pháp clara K-Medoids vì nó tốt với dữ liệu lớn và tốt hơn với các phân phối lẻ. Nó rất giống với K-Means.

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

Để đơn giản, chúng ta có thể tạo một raster trống bằng cách kéo một trong các dải raster từ đối tượng ngăn xếp raster ban đầu của chúng ta và gán cho nó các giá trị NA.

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

Cuối cùng, bằng cách sử dụng chỉ mục, chúng tôi gán các giá trị cụm cho ô thích hợp trong raster trống và vẽ kết quả.

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

Đối với các trình quét lớn, bạn có thể muốn xem xét gói bigmemory ghi ma trận vào đĩa và hoạt động trên các khối và có sẵn hàm k-mean. Ngoài ra, hãy nhớ rằng đây không chính xác là những gì R được thiết kế cho và phần mềm xử lý hình ảnh hoặc phần mềm GIS có thể phù hợp hơn. Tôi biết rằng SAGA và hộp công cụ Orfeo đều là phần mềm miễn phí có phân cụm k-mean có sẵn cho ngăn xếp hình ảnh. Thậm chí còn có một thư viện RSAGA cho phép phần mềm được gọi từ R.


Nếu tất cả các hình ảnh được xếp chồng lên nhau và phân cụm cùng một lúc, thì kết quả là một hình ảnh được phân cụm, phải không?
Iris

@Iris, vâng, đây là cách thức phân cụm hình ảnh này hoạt động và tuân theo các triển khai trong phần mềm viễn thám. Một ví dụ rõ ràng và có liên quan sẽ là việc triển khai isocluster trong ArcGIS ( desktop.arcgis.com/en/arcmap/10.3/tools/spatial-analyst-toolbox/iêu )
Jeffrey Evans

Sau đó, anwer này không giúp đỡ gì cả. Vấn đề của tôi là tôi đã cố gắng thực hiện phát hiện thay đổi theo thời gian dựa trên một số phân loại hình ảnh không được giám sát, nhưng tôi có thể so sánh các kết quả khác nhau vì các lớp được chỉ định khác nhau.
Iris

Phân loại không giám sát không phải là một cách khả thi để thực hiện phát hiện thay đổi. Ngay cả sự thay đổi nhỏ trong một hình ảnh nhất định cũng có thể kết thúc bằng việc pixel được gán vào một lớp khác. Đây sẽ là trường hợp ngay cả khi bạn cung cấp các trung tâm cụm cho K-Means. Tôi có một hàm entropy trong gói spatialEco rất hữu ích để phát hiện thay đổi. Bạn tính toán entropy trong một cửa sổ NxN và sau đó lấy delta ở mỗi bước thời gian. Entropy âm biểu thị sự mất mát và tích cực là mức tăng của các thành phần cảnh quan trong một cường độ nhất định dưới entropy tối đa.
Jeffrey Evans

Đó là một câu hỏi cũ và tôi đã loại bỏ ý tưởng sử dụng k-nghĩa từ lâu. Nhưng thật tốt khi biết gói spatialEco cho lần tiếp theo;)
Iris
Khi sử dụng trang web của chúng tôi, bạn xác nhận rằng bạn đã đọc và hiểu Chính sách cookieChính sách bảo mật của chúng tôi.
Licensed under cc by-sa 3.0 with attribution required.