2

I have done a Random Forest classification model in R and I have implemented a script to work in QGIS. For the moment I specify the model's path into the script to apply it (image), but is it any form to choose the model as a input parameter? And in the same way, is it possible to save the model as output parameter?

Script to apply Random Forest model in a image

2

In addition of @gene answer... You should train your model inside R-Qgis script. Because if layer names are different, the script will raise an error.

Reproducible example (in R):

library(raster)
library(RStoolbox)
library(rgdal)

data("lsat")
writeRaster(lsat,'~/Landsat_image.tif',bylayer=F)

shp <- rgeos::readWKT("GEOMETRYCOLLECTION (POLYGON ((624911.3918305600527674 -415054.4364599100081250, 623877.2768532499903813 -414241.9175491699716076, 624246.6036308599868789 -413902.1369137699948624, 625221.6263237500097603 -414685.1096823000116274, 624911.3918305600527674 -415054.4364599100081250)), POLYGON ((619622.6323751900345087 -417979.5045385800185613, 619578.3131618800107390 -416782.8857791200280190, 620479.4704992399783805 -416738.5665658100042492, 620641.9742813899647444 -417935.1853252599830739, 619622.6323751900345087 -417979.5045385800185613)), POLYGON ((622385.1966717100003734 -419043.1656580899725668, 622702.8177004499593750 -418599.9735249599907547, 623086.9175491699716076 -418740.3177004500175826, 622976.1195158900227398 -419057.9387291999883018, 622385.1966717100003734 -419043.1656580899725668)))")
shp <- SpatialPolygonsDataFrame(shp, data.frame(ID = 1:3, Class = c('Water','Forest','Soil')))
crs(shp) <- crs(lsat)

writeOGR(obj = shp, dsn = '~/', layer = 'train_sites',driver = 'ESRI Shapefile')

Basic R-QGIS script:

##rst=raster
##shp=vector
##fld=Field shp
##output=output raster
library(raster)
library(randomForest)
lst = extract(rst, shp)
train_len = min(sapply(lst, function(x){dim(x)[1]}))
df = lapply(lst, function(x){
  x[sample(x = 1:dim(x)[1], size = train_len, replace = F),]
})
df = cbind(data.frame(ID = factor(rep(x = unique(shp@data[,fld]),
                                       each = train_len))),
            do.call(rbind.data.frame,df))
rf = randomForest(x = df[,2:dim(df)[2]], y = df[,1])
output = predict(rst,rf)

Test:

enter image description here

enter image description here

enter image description here


Save random forest model

Use path and string to create file:

##rst=raster
##shp=vector
##fld=Field shp
##output=output raster
##output_folder=folder
##filename=string
library(raster)
library(randomForest)
lst = extract(rst, shp)
train_len = min(sapply(lst, function(x){dim(x)[1]}))
df = lapply(lst, function(x){
  x[sample(x = 1:dim(x)[1], size = train_len, replace = F),]
})
df = cbind(data.frame(ID = factor(rep(x = unique(shp@data[,fld]),
                                       each = train_len))),
            do.call(rbind.data.frame,df))
rf = randomForest(x = df[,2:dim(df)[2]], y = df[,1])
saveRDS(object=rf,file=file.path(output_folder,paste0(filename,'.rds')))
output = predict(rst,rf)

enter image description here

Back in R:

library(randomForest)
model <- readRDS('/some/path/test.rds')
model
## 
## Call:
##  randomForest(x = df[, 2:dim(df)[2]], y = df[, 1]) 
##                Type of random forest: classification
##                      Number of trees: 500
## No. of variables tried at each split: 2
## 
##         OOB estimate of  error rate: 0%
## Confusion matrix:
##        Forest Soil Water class.error
## Forest    229    0     0           0
## Soil        0  229     0           0
## Water       0    0   229           0

You can make some test to know if output file is defined and so on, but that is out of your question.

  • With input_file I can import the random forest model. But I have a problem with the output file, because It is not a file It is the path where I want to save the file. So the question is: Can I specify the file's Path as a variable? Maybe as a folder? I know that I can establish the path as a string variable, but in this case the path have to be written and I don't want this – mike89 Feb 14 '18 at 8:21
  • @mike89 ok, I updated my answer – aldo_tapia Feb 14 '18 at 11:32
  • thanks @ aldo_tapia. I have done in this way. As output folder parameter is optional, I have written a conditional if sentence which allows not to fill the gap. PARAMETERS: ##model_name= string ##Path= folder CODE TO SAVE THE FILE: if ( Path !="" ) { name<-paste(Path, paste(model_name, "rds", sep="."),sep="/") saveRDS(fit.forest, file=name) } – mike89 Feb 14 '18 at 13:43
  • Yes, but be careful with python path's conversion. I would use name<-file.path(Path,paste0(model_name,'.rds')) – aldo_tapia Feb 14 '18 at 13:46
3

Look at Basic rules for writing Python scripts for Processing Toolbox in QGIS

##input_file=file
##output_file =output file

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.