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 Answers 2

3

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

##input_file=file
##output_file =output file
0
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.

4
  • 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
    Commented Feb 14, 2018 at 8:21
  • @mike89 ok, I updated my answer
    – aldo_tapia
    Commented Feb 14, 2018 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
    Commented Feb 14, 2018 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
    Commented Feb 14, 2018 at 13:46

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

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