R语言 将栅格文件(4维)转换为允许进行随机森林分类的结构

mkshixfv  于 2023-01-28  发布在  其他
关注(0)|答案(1)|浏览(127)

我的目标是对农业土地利用形式进行随机森林分类(作物分类)。我对所有类别都有几个地面真值点。此外,我有27个栅格文件(.tif),每个文件都有相同的10个波段和相同的范围,一个文件代表时间序列中的一个日期。时间序列不是恒定的。
下面显示了使用terra读取的文件和第一个文件:

files <- list.files("C:/temp/final",full.names = T,pattern = ".tif$",recursive = T)  

> head(files)
[1] "C:/temp/final/20190324T095029_20190324T095522_T33UXP.tif" "C:/temp/final/20190401T100031_20190401T100512_T33UXP.tif" "C:/temp/final/20190416T100029_20190416T100607_T33UXP.tif"
[4] "C:/temp/final/20190418T095031_20190418T095032_T33UXP.tif" "C:/temp/final/20190421T100031_20190421T100030_T33UXP.tif" "C:/temp/final/20190501T100031_20190501T100424_T33UXP.tif"  

 > rast(files[1])
class       : SpatRaster 
dimensions  : 386, 695, 10  (nrow, ncol, nlyr)
resolution  : 10, 10  (x, y)
extent      : 634500, 641450, 5342460, 5346320  (xmin, xmax, ymin, ymax)
coord. ref. : WGS 84 / UTM zone 33N (EPSG:32633) 
source      : 20190324T095029_20190324T095522_T33UXP.tif 
names       : B2, B3, B4, B5, B8, B11, ...

我想提取每个日期和波段的值。这将产生一个 Dataframe ,其中包含观测变量和每个点的相应类别(见下文)。使用此 Dataframe ,我想训练一个随机森林模型,以便预测立方体中每个栅格单元的作物类别(产生一个以类别为值的单个栅格层)。
下面的结构(从https://gdalcubes.github.io/source/tutorials/vignettes/gc03_ML_training_data.html复制而来)是我需要的观测值,用作rf模型的训练数据。

##    FID       time    B2  ... more bands ... and class of respective FID
## 1   16 2018-01-01 13.33 
## 2   17 2018-01-01 13.63
## 3   18 2018-01-01 13.33
## 4   19 2018-01-01 12.15
## 5   20 2018-01-01 14.73
## 6   21 2018-01-01 15.91
## 7   16 2018-01-09 12.23
## 8   17 2018-01-09 12.15
## 9   18 2018-01-09 12.07
## 10  19 2018-01-09 10.19
## 11  20 2018-01-09  9.83

创建数据立方体结构最简单的方法可能是使用gdalcubes,不幸的是,它在我的例子中不起作用(R Sessipn Abort)(https://github.com/appelmar/gdalcubes_R/issues/78).这个包的教程显示了我所需要的(https://gdalcubes.github.io/source/tutorials/vignettes/gc03_ML_training_data.html).我不知道如何解决这个关于gdalcubes的问题,因此我正在寻找一种方法来绕过这个包与其他包.
因此,我开始使用。我希望能够使用以下代码直接从文件创建一个4维星对象:

library(stars)

> s2_cube <- read_stars(files,along = 4)
> s2_cube  

stars object with 4 dimensions and 1 attribute
attribute(s), summary of first 1e+05 cells:
                                     Min. 1st Qu. Median      Mean 3rd Qu.  Max.  NA's
20190324T095029_20190324T09552...  0.0537  0.0744 0.0855 0.0878417  0.0986 0.387 41975
dimension(s):
        from  to  offset delta                refsys point                                                    values x/y
x          1 695  634500    10 WGS 84 / UTM zone 33N FALSE                                                      NULL [x]
y          1 386 5346320   -10 WGS 84 / UTM zone 33N FALSE                                                      NULL [y]
band       1  10      NA    NA                    NA    NA                                               B2,...,SAVI    
new_dim    1  27      NA    NA                    NA    NA 324T095029_20190324T095522,...,920T095029_20190920T095354

这一个没有创建我需要的结构,让我怀疑这是否可行的是,在我阅读的所有恒星教程(例如https://r-spatial.github.io/stars/articles/stars1.html)中,阅读光栅时间序列对象假定存在NetCDF文件。

  • 是否可以使用read_stars创建这样的结构?*

现在我正在寻找创建NetCFD文件的方法。这是我会采取的路径:
1.为每个TIF创建一个spatRaster(terra)。每个spatRaster有10个图层,时间段包含10个相同的日期(因为图层不代表不同的时间步长,而是代表相同时间戳的不同波段)。
1.从所有27个spatRaster对象创建一个spatRasterDataset
1.将飞溅栅格数据集写入NetCDF文件
1.打开带有星号的NetCDF文件
1.行为分类

  • 此工作流对您有意义吗?或者您已经发现问题了吗?*

不幸的是,在步骤1中已经出现了一个问题:

library(terra)  

all_images <- list()
for(file in files){
  date <- rep(as.Date(substr(basename(file),1,8),"%Y%m%d"),10)
  ra <- rast(file,time=date)
  all_images[[file]] <- ra
}  

Error in .local(x, ...) : 
  unused argument (time = c(17979, 17979, 17979, 17979, 17979, 17979, 17979, 17979, 17979, 17979))
  • 我不能在每一层都加上相同的日期吗 *

正如你所看到的,我真的很困惑与现有的软件包,以及如何合并他们。正如我所说,gdalcube将是伟大的,但我没有知识和时间来找出为什么它导致一个R会话中止。我真的很感激各种帮助。谢谢!

ctehm74n

ctehm74n1#

您提到您想要一个具有四维的数据集。但您将如何训练模型并进行预测(只能使用二维)?因此,在我看来,您需要的是一个可以使用创建的三维SpatRaster

cube <- rast(files)

除非你想为每个文件运行一个单独的模型---但是你应该循环遍历这些文件。
下面是一个示例(摘自?terra::predict),显示了如何运行RandomForest或任何其他回归或分类模型。

library(terra)
logo1 <- rast(system.file("ex/logo.tif", package="terra"))   
logo2 <- sqrt(logo1)
cube <- c(logo1, logo2)

names(cube) <- c("red1", "green1", "blue1", "red2", "green2", "blue2")

p <- matrix(c(48, 48, 48, 53, 50, 46, 54, 70, 84, 85, 74, 84, 95, 85, 
   66, 42, 26, 4, 19, 17, 7, 14, 26, 29, 39, 45, 51, 56, 46, 38, 31, 
   22, 34, 60, 70, 73, 63, 46, 43, 28), ncol=2)
a <- matrix(c(22, 33, 64, 85, 92, 94, 59, 27, 30, 64, 60, 33, 31, 9,
   99, 67, 15, 5, 4, 30, 8, 37, 42, 27, 19, 69, 60, 73, 3, 5, 21,
   37, 52, 70, 74, 9, 13, 4, 17, 47), ncol=2)

xy <- rbind(cbind(1, p), cbind(0, a))
e <- extract(cube, xy[,2:3])
v <- data.frame(cbind(pa=xy[,1], e))

library(randomForest)
rfm <- randomForest(formula=pa~., data=v)
p <- predict(cube, rfm)

也许你可以编辑你的问题,解释为什么这对你不起作用。并包括一个玩具的例子,你打算如何拟合你的模型。我假设栅格是你的预测,但你预测什么(你的y变量)?它是常数还是每个时间步不同(栅格文件)?
如果要写入单个netCDF文件,可以执行以下操作

sds <- rast(files)
writeCDF(sds, "test.nc")

相关问题