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?
2 Answers
Look at Basic rules for writing Python scripts for Processing Toolbox in QGIS
##input_file=file
##output_file =output file
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:
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)
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– mike89Commented Feb 14, 2018 at 8:21
-
-
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) }
– mike89Commented 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'))
Commented Feb 14, 2018 at 13:46