Генерация растра прогноза из модели Random Forest с использованием R? - PullRequest
0 голосов
/ 27 июня 2019

Я подгоняю модель случайного леса к табличным данным с тестовых участков в R, и теперь хотел бы сгенерировать растр, показывающий прогнозируемые значения вероятности, используя растровые данные, соответствующие тем же предикторам (например, наклону, высоте, pH), которые находятся вмодель.

Модель RF построена для прогнозирования двоичной переменной 0/1 SITE_NONSITE с использованием различных экологических и геофизических данных.

#random forest model
set.seed(321)
rf1 <- randomForest(formula=SITE_NONSITE ~., data=dcc.s.dummy, ntree=500, mtry=10)

dcc.s.dummy включает следующие данные:

str(dcc.s.dummy)
'data.frame':   7899 obs. of  25 variables:
 $ COST_DIST_ECOTONE        : num  -0.232 0.176 -0.443 -0.478 -0.305 ...
 $ COST_DIST_HEA            : num  -0.233 -0.659 -1.055 -0.999 -0.455 ...
 $ COST_DIST_MEDSTR         : num  0.74388 0.63933 0.55964 0.50768 0.00993 ...
 $ COST_DIST_RIV_COAST      : num  0.59 0.63 0.621 0.639 0.617 ...
 $ DEM30_ASP_RE_2           : num  0 0 0 0 1 0 0 0 0 0 ...
 $ DEM30_ASP_RE_3           : num  0 1 0 0 0 0 0 0 1 0 ...
 $ DEM30_ASP_RE_4           : num  1 0 0 0 0 0 0 1 0 0 ...
 $ DEM30_ASP_RE_5           : num  0 0 1 1 0 1 1 0 0 1 ...
 $ DEM30_M                  : num  0.916 0.72 0.499 0.54 1.114 ...
 $ DEM30_SLOPE              : num  0.2063 0.4631 -0.6445 -0.0512 -0.8235 ...
 $ LOC_REL_RE               : num  -0.489 -0.476 -0.476 -0.459 -0.661 ...
 $ LOC_SD_SLOPE             : num  -0.118 -0.135 -0.316 -0.367 -0.57 ...
 $ SSURGO_ESRI_DRAINAGE_RE_2: num  0 0 0 0 0 0 0 0 0 0 ...
 $ SSURGO_ESRI_DRAINAGE_RE_3: num  1 1 1 1 1 1 1 1 1 1 ...
 $ SSURGO_ESRI_DRAINAGE_RE_4: num  0 0 0 0 0 0 0 0 0 0 ...
 $ SSURGO_ESRI_DRAINAGE_RE_5: num  0 0 0 0 0 0 0 0 0 0 ...
 $ SSURGO_ESRI_DRAINAGE_RE_6: num  0 0 0 0 0 0 0 0 0 0 ...
 $ SSURGO_ESRI_EROSION_RE_2 : num  0 0 0 0 0 1 1 0 0 1 ...
 $ SSURGO_ESRI_EROSION_RE_3 : num  1 1 1 0 1 0 0 1 1 0 ...
 $ SSURGO_ESRI_EROSION_RE_4 : num  0 0 0 0 0 0 0 0 0 0 ...
 $ SSURGO_ESRI_LOC_DIV      : num  -0.328 -0.188 -0.157 -0.213 -0.652 ...
 $ SSURGO_ESRI_NATIVEVEG_2  : num  1 1 1 0 1 0 0 1 1 1 ...
 $ SSURGO_ESRI_NATIVEVEG_3  : num  0 0 0 0 0 1 1 0 0 0 ...
 $ SSURGO_PH                : num  0.813 0.059 1.529 2.32 -1.298 ...
 $ SITE_NONSITE             : Factor w/ 2 levels "0","1": 2 2 2 2 2 1 1 2 2 2

Затем я беру растры, соответствующие этим же предикторам, по всей моей области исследования и объединяю их в стек растров:

#plot model predictions
COST_DIST_ECOTONE <- raster("cost_dist_ecotone_s.tif.tif")
COST_DIST_HEA <- raster("cost_dist_hea_s.tif.tif")
COST_DIST_MEDSTR <- raster("cost_dist_medstr_s.tif.tif")
COST_DIST_RIV_COAST <- raster("cost_dist_riv_coast_s.tif.tif")
DEM30_ASP_RE_2 <- raster("dem30_asp_rel_2.tif.tif")
DEM30_ASP_RE_3 <- raster("dem30_asp_rel_3.tif.tif")
DEM30_ASP_RE_4 <- raster("dem30_asp_rel_4.tif.tif")
DEM30_ASP_RE_5 <- raster("dem30_asp_rel_5.tif.tif")
DEM30_M <- raster("dem30_m_s.tif.tif")
DEM30_SLOPE <- raster("dem30_slope_s.tif.tif")
LOC_REL_RE <- raster("loc_rel_re_s.tif.tif")
LOC_SD_SLOPE <- raster("loc_sd_slope_s.tif.tif")
SSURGO_ESRI_DRAINAGE_RE_2 <- raster("SSURGO_ESRI_drainage_reclass_nulfill_2.tif.tif")
SSURGO_ESRI_DRAINAGE_RE_3 <- raster("SSURGO_ESRI_drainage_reclass_nulfill_3.tif.tif")
SSURGO_ESRI_DRAINAGE_RE_4 <- raster("SSURGO_ESRI_drainage_reclass_nulfill_4.tif.tif")
SSURGO_ESRI_DRAINAGE_RE_5 <- raster("SSURGO_ESRI_drainage_reclass_nulfill_5.tif.tif")
SSURGO_ESRI_DRAINAGE_RE_6 <- raster("SSURGO_ESRI_drainage_reclass_nulfill_6.tif.tif")
SSURGO_ESRI_EROSION_RE_2 <- raster("SSURGO_ESRI_erosion_reclass_nulfilll_2.tif.tif")
SSURGO_ESRI_EROSION_RE_3 <- raster("SSURGO_ESRI_erosion_reclass_nulfilll_3.tif.tif")
SSURGO_ESRI_EROSION_RE_4 <- raster("SSURGO_ESRI_erosion_reclass_nulfilll_4.tif.tif")
SSURGO_ESRI_LOC_DIV <- raster("SSURGO_ESRI_loc_div_s.tif.tif")
SSURGO_ESRI_NATIVEVEG_2 <- raster("SSURGO_ESRI_nativeveg_nullfill_2.tif.tif")
SSURGO_ESRI_NATIVEVEG_3 <- raster("SSURGO_ESRI_nativeveg_nullfill_3.tif.tif")
SSURGO_PH <- raster("SSURGO_pH_nullfill_s.tif.tif")

ApPl_stack <- stack(COST_DIST_ECOTONE, COST_DIST_HEA, COST_DIST_MEDSTR, COST_DIST_RIV_COAST, DEM30_ASP_RE_2, DEM30_ASP_RE_3, DEM30_ASP_RE_4, DEM30_ASP_RE_5, DEM30_M, DEM30_SLOPE, LOC_REL_RE, LOC_SD_SLOPE, SSURGO_ESRI_DRAINAGE_RE_2, SSURGO_ESRI_DRAINAGE_RE_3, SSURGO_ESRI_DRAINAGE_RE_4, SSURGO_ESRI_DRAINAGE_RE_5, SSURGO_ESRI_DRAINAGE_RE_6, SSURGO_ESRI_EROSION_RE_2, SSURGO_ESRI_EROSION_RE_3, SSURGO_ESRI_EROSION_RE_4, SSURGO_ESRI_LOC_DIV, SSURGO_ESRI_NATIVEVEG_2, SSURGO_ESRI_NATIVEVEG_3, SSURGO_PH)

Однако попытка использовать этот растровый стек ApPl_stack в raster::predict() завершается неудачно со следующей ошибкой:

ApPl_prob <- raster::predict(rf1, newdata=ApPl_stack, type="prob")

Ошибка в as.data.frame.по умолчанию (x [[i]], необязательный = TRUE): невозможно привести структуру класса («RasterLayer», package = «растр») к data.frame

Преобразование во фрейм данныхи использование этого вместо этого генерирует эту ошибку вместо:

ApPl_df <- as.data.frame(ApPl_stack, xy=TRUE)
ApPl_prob <- raster::predict(rf1, newdata=ApPl_df, type="prob")

Ошибка в model.frame.default (Условия, новые данные, na.action = na.omit):
объект не является матрицейКроме того: Предупреждающее сообщение: «newdata» содержит 658242 строки, но найденные переменные имеют 754 строки

Не может быть совпадением, что в каждом из моих растров-предикторов есть 658242 ячейки и 754 строки.Что мне здесь не хватает?Я чувствую, что одна из функций ожидает тип данных, который не получает.

Ответы [ 2 ]

1 голос
/ 28 июня 2019

«Имена объектов» не имеют ничего общего с именами слоев, поэтому вам необходимо установить их так, чтобы они соответствовали именам в data.frame, используемом для соответствия модели.В большинстве рабочих процессов вы делаете что-то вроде

f <- c("cost_dist_ecotone_s.tif.tif", "cost_dist_hea_s.tif.tif", "cost_dist_medstr_s.tif.tif")
s <- stack(f)
names(s) <- gsub(".tif.tif", "", f)

, а затем извлекаете значения из RasterStack, чтобы соответствовать вашей модели - в этом случае имена уже совпадают.

Но главная ошибка, которую вы сделали, была здесь

ApPl_prob <- raster::predict(rf1, newdata=ApPl_stack, type="prob")

Первым аргументом должен быть RasterStack:

ApPl_prob <- raster::predict(ApPl_stack, rf1, type="prob")

Или используйте именованные параметры, как вы сделали в своем ответе

raster::predict(model=rf1, object=ApPl_stack, type="prob")
0 голосов
/ 27 июня 2019

После более тщательного изучения структуры всех объектов, сгенерированных приведенным выше кодом, я обнаружил проблему. По какой-то причине stack() менял имена растровых слоев обратно на их исходные имена файлов, а не на имена объектов, которые я назначил. Сначала я не заметил этой проблемы, поскольку plot(ApPl_stack) показывал имена, которые я ожидал увидеть там, даже если они не были отражены в структуре стека растров. В результате имена растров из стека, предоставленного raster::predict(), не совпадали с именами в модели Random Forest.

Добавление дополнительного шага для назначения совпадающих имен решило проблему:

names(ApPl_stack) <- c("COST_DIST_ECOTONE", "COST_DIST_HEA", "COST_DIST_MEDSTR", "COST_DIST_RIV_COAST", "DEM30_ASP_RE_2", "DEM30_ASP_RE_3", "DEM30_ASP_RE_4", "DEM30_ASP_RE_5", "DEM30_M", "DEM30_SLOPE", "LOC_REL_RE", "LOC_SD_SLOPE", "SSURGO_ESRI_DRAINAGE_RE_2", "SSURGO_ESRI_DRAINAGE_RE_3", "SSURGO_ESRI_DRAINAGE_RE_4", "SSURGO_ESRI_DRAINAGE_RE_5", "SSURGO_ESRI_DRAINAGE_RE_6", "SSURGO_ESRI_EROSION_RE_2", "SSURGO_ESRI_EROSION_RE_3", "SSURGO_ESRI_EROSION_RE_4", "SSURGO_ESRI_LOC_DIV", "SSURGO_ESRI_NATIVEVEG_2", "SSURGO_ESRI_NATIVEVEG_3", "SSURGO_PH")

Тогда я смог без проблем генерировать и составлять прогнозы, используя следующий код:

#plot predictions and save raster to file
ApPl_prob <- 1- raster::predict(model=rf1, object=ApPl_stack, type="prob")
palette <- matlab.like(20)
plot(ApPl_prob, col=palette)
writeRaster(ApPl_prob, "ApPl_prob", format='GTiff')

enter image description here

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...