[GRASS-SVN] r68575 - grass-addons/grass7/vector/v.class.mlR
svn_grass at osgeo.org
svn_grass at osgeo.org
Thu Jun 2 03:40:29 PDT 2016
Author: mlennert
Date: 2016-06-02 03:40:29 -0700 (Thu, 02 Jun 2016)
New Revision: 68575
Modified:
grass-addons/grass7/vector/v.class.mlR/v.class.mlR.html
grass-addons/grass7/vector/v.class.mlR/v.class.mlR.py
Log:
v.class.mlR: complete rewrite, using the caret package, with several classifiers and majority voting scheme
Modified: grass-addons/grass7/vector/v.class.mlR/v.class.mlR.html
===================================================================
--- grass-addons/grass7/vector/v.class.mlR/v.class.mlR.html 2016-06-02 09:11:01 UTC (rev 68574)
+++ grass-addons/grass7/vector/v.class.mlR/v.class.mlR.html 2016-06-02 10:40:29 UTC (rev 68575)
@@ -1,64 +1,71 @@
<h2>DESCRIPTION</h2>
<p>
-<em>v.class.mlR</em> uses machine learning functions in R to classify
-features in a vector map using training features in a second map for
-supervised learning.
+<em>v.class.mlR</em> is a wrapper script that uses the R caret package
+for machine learning in R to classify features using training features
+by supervised learning.
-<p>
-At the current stage it is just a quick and dirty hack to allow students to
-do such classification in the framework of a course. It is meant as a very
-simplistic alternative to v.class.ml which can be a bit overwhelming for
-newbies.
+<p>The user can provide input either as vector maps, or as csv files, or
+a combination of both. Output can consist of either additional columns in
+the vector input map of features, a text file or reclassed raster maps.
-<p>
-Currently, only support vector machine classification is implemented, using
-the e1071 CRAN contrib package (which is automatically installed if necessary).
-The user has to chose between different kernel types. The module then goes
-through tuning across a range of possible parameters using 10-fold cross-
-validation. Optionally, the user can determine fixed values for certain
-parameters so that they will be excluded from tuning. This speeds up the tuning
-process.
+<p>Different classifiers are proposed: k-nearest neighbor (knn and knn1
+for k=1), support vector machine with a radial kernel (svmRadial), random
+forest (rf) and recursive partitioning (rpart). Each of these classifiers
+is tuned automatically throught repeated cross-validation. See the
+<a href="https://topepo.github.io/caret/index.html">caret webpage</a> for
+more information about the tuning parameters for each classifier, and
+more generally for the information about how caret works.
-<p>
-For the details of the parameters see the <a href="http://www.inside-r.org/node/57517">
-manual of the svm function</a> in the e1071 package.
+<p>The user can chose to include the individual classifiers results in
+the output using the <em>i</em> flag, but by default the output will be
+the result of a voting scheme merging the results of the different
+classifiers. The voting schemes available are: simple majority vote without
+weighting (smv), simple weighted majority vote (swv), best-worst weighted
+vote (bwwv) and quadratic best-worst weighted vote (qbwwv). For more details
+about these voting schemes see [TODO: include reference].
-<h2>NOTES</h2>
+<p>In the output (as attribute columns or text file) each weighting schemes
+result is provided accompanied by an estimation of the probability of the
+classification, based on the equation used in [TODO: include reference].
-<p>
-The module automatically excludes columns that contain empty values in the map
-of all features.
+<p>Optional output of the module include a box-and-whisker plot indicating
+the variance of the cross-validation results for each classifier
+(<em>bw_plot_file</em>) and a csv file containing accuracy measures (overall
+accuracy and kappa) for each classifier (<em>accuracy_file</em>). The user
+can also chose to write the R script constructed and used internally to a text
+file for study or further modification.
-<p>
-Running the same model with exactly the same specifications generally leads
-to differing classification errors. This is due to the cross-validation for
-which training and validation sets are drawn randomly. The user can run the
-same model call several times to get an idea of the variances of the error.
+<h2>NOTES</h2>
<p>
The module can be used in a tool chain together with <a href="i.segment.html">i.segment</a>
and the addon <em>i.segment.stats</em> for object-based classification of
satellite imagery.
+<h2>DEPENDENCIES</h2>
+
+<p>This modules uses R. The following R-packages have to be installed to be able to use this
+module: 'caret', 'kernlab', 'randomForest', 'rpart', 'ggplot2', 'lattice'.
+
<h2>TODO</h2>
-<p>
-If the module is deemed to deserve a longer life-span, than it should possibly
-be recoded to use rpy2 instead of simple text batch files for R (although this
-latter solution is quite useful in a computer lab where rpy2 is not installed).
+Add automagic installation of missing R packages.
-<p>
-Other classifiers should be included. One option would be to use the 'caret'
-R package but this would mean handling the different dependency packages for
-the different methods.
-
<h2>EXAMPLE</h2>
+<p>
+Using existing vector maps as input and writing the output to the attribute table of the segments map, including the individual classifier results:
<div class="code"><pre>
-v.class.mlR segments training=training_areas classcol=class outcol=class_linear kernel=linear
+v.class.mlR segments_map=seg training_map=training train_class_column=class weighting_mode=smv,swv,qbwwv -i
</pre></div>
+<p>
+Using text files with segment characteristics as input and writing output to raster files and a csv file
+<div class="code"><pre>
+v.class.mlR segments_file=segstats.csv training_file=training.csv train_class_column=class weighting_mode=smv,swv,qbwwv raster_segments_map=seg classified_map=vote classification_results=class_results.csv
+</pre></div>
+
<h2>SEE ALSO</h2>
<em>
@@ -66,6 +73,8 @@
</em>
<h2>AUTHOR</h2>
-Moritz Lennert
+Moritz Lennert, Université Libre de Bruxelles (ULB)
+based on an initial R-script by Ruben Van de Kerckove, also ULB at the time
+
<p><i>Last changed: $Date$</i>
Modified: grass-addons/grass7/vector/v.class.mlR/v.class.mlR.py
===================================================================
--- grass-addons/grass7/vector/v.class.mlR/v.class.mlR.py 2016-06-02 09:11:01 UTC (rev 68574)
+++ grass-addons/grass7/vector/v.class.mlR/v.class.mlR.py 2016-06-02 10:40:29 UTC (rev 68575)
@@ -18,268 +18,410 @@
#% keyword: classification
#% keyword: machine learning
#% keyword: R
-#% keyword: svm
+#% keyword: classifiers
#%end
#%option G_OPT_V_MAP
+#% key: segments_map
#% label: Vector map with areas to be classified
#% description: Vector map containing all areas and relevant attributes
-#% required: yes
+#% required: no
+#% guisection: Vector input
#%end
#%option G_OPT_V_INPUT
-#% key: training
+#% key: training_map
#% label: Vector map with training areas
#% description: Vector map with training areas and relevant attributes
-#% required: yes
+#% required: no
+#% guisection: Vector input
#%end
+#%option G_OPT_F_INPUT
+#% key: segments_file
+#% label: File containing statistics of all segments
+#% description: File containing relevant attributes for all areas
+#% required: no
+#% guisection: Text input
+#%end
+#%option G_OPT_F_INPUT
+#% key: training_file
+#% label: File containing statistics of training segments
+#% description: File containing relevant attributes for training areas
+#% required: no
+#% guisection: Text input
+#%end
+#%option G_OPT_R_INPUT
+#% key: raster_segments_map
+#% label: Raster map with segments
+#% description: Input raster map containing all segments
+#% required: no
+#% guisection: Raster maps
+#%end
+#%option G_OPT_R_OUTPUT
+#% key: classified_map
+#% label: Prefix for raster maps (one per weighting mode) with classes attributed to pixels
+#% description: Output raster maps (one per weighting mode) in which all pixels are reclassed to the class attributed to the segment they belong to
+#% required: no
+#% guisection: Raster maps
+#%end
#%option
-#% key: class_column
+#% key: train_class_column
#% type: string
#% description: Name of attribute column containing training classification
#% required: yes
#%end
#%option
-#% key: output_column
+#% key: output_class_column
#% type: string
-#% description: Name of column to create with final classification
+#% description: Prefix of column with final classification
#% required: yes
+#% answer: vote
#%end
#%option
-#% key: classifier
+#% key: output_prob_column
#% type: string
-#% description: Classifier to use
+#% description: Prefix of column with probability of classification
#% required: yes
-#% options: svm
-#% answer: svm
-#% end
+#% answer: prob
+#%end
#%option
-#% key: kernel
+#% key: classifiers
#% type: string
-#% description: Kernel to use
+#% description: Classifiers to use
#% required: yes
-#% options: linear,polynomial,radial,sigmoid
-#% answer: linear
-#% guisection: SVM
+#% multiple: yes
+#% options: svmRadial,rf,rpart,knn,knn1
+#% answer: svmRadial,rf,rpart,knn,knn1
#%end
#%option
-#% key: cost
-#% type: double
-#% description: Cost value
+#% key: weighting_modes
+#% type: string
+#% description: Type of weighting to use
+#% required: yes
+#% multiple: yes
+#% options: smv,swv,bwwv,qbwwv
+#% answer: smv
+#%end
+#%option G_OPT_F_OUTPUT
+#% key: classification_results
+#% description: File for saving results of all classifiers
#% required: no
-#% guisection: SVM
+#% guisection: Optional output
#%end
-#%option
-#% key: degree
-#% type: integer
-#% description: Degree value (for polynomial kernel)
+#%option G_OPT_F_OUTPUT
+#% key: accuracy_file
+#% description: File for saving accuracy measures of classifiers
#% required: no
-#% guisection: SVM
+#% guisection: Optional output
#%end
-#%option
-#% key: gamma
-#% type: double
-#% description: Gamma value (for all kernels except linear)
+#%option G_OPT_F_OUTPUT
+#% key: bw_plot_file
+#% description: PNG file for saving box-whisker plot of classifier performance
#% required: no
-#% guisection: SVM
+#% guisection: Optional output
#%end
-#%option
-#% key: coeff0
-#% type: double
-#% description: Coeff0 value (for polynomial and sigmoid kernels)
+#%option G_OPT_F_OUTPUT
+#% key: r_script_file
+#% description: File containing R script
#% required: no
-#% guisection: SVM
+#% guisection: Optional output
#%end
#%flag
-#% key: t
-#% description: Only tune model, do not update attribute table
+#% key: f
+#% description: Only write results to text file, do not update vector map
#%end
+#%flag
+#% key: i
+#% description: Include individual classifier results in output
+#%end
+#
+#%rules
+#% required: segments_map,segments_file
+#% required: training_map,training_file
+#% requires: classified_map,raster_segments_map
+#%end
import atexit
import subprocess
-import os
-import grass.script as grass
+import os, shutil
+import grass.script as gscript
def cleanup():
- os.remove(feature_vars)
- os.remove(training_vars)
- os.remove(model_output)
- os.remove(model_output_desc)
- os.remove(r_commands)
- if not flags['t']:
- grass.run_command('db.droptable', table=temptable, flags='f', quiet=True)
+ if allmap:
+ gscript.try_remove(feature_vars)
+ if trainmap:
+ gscript.try_remove(training_vars)
+ gscript.try_remove(model_output)
+ gscript.try_remove(model_output_desc)
+ gscript.try_remove(r_commands)
+ if reclass_files:
+ for reclass_file in reclass_files.itervalues():
+ gscript.try_remove(reclass_file)
+ if temptable:
+ gscript.run_command('db.droptable',
+ table=temptable,
+ flags='f',
+ quiet=True)
def main():
- allfeatures = options['map']
- training = options['training']
- classcol = options['class_column']
- output_classcol = options['output_column']
- #output_classcol = classcol + '_model'
- kernel = options['kernel']
- cost = options['cost']
- gamma = options['gamma']
- degree = options['degree']
- coeff0 = options['coeff0']
-
+ global allmap
+ global trainmap
global feature_vars
global training_vars
global model_output
global model_output_desc
global temptable
global r_commands
- feature_vars = grass.tempfile()
- training_vars = grass.tempfile()
- model_output = '.grass_tmp_model_output_%d.csv' % os.getpid()
- model_output_desc = model_output + 't'
- temptable = 'classif_tmp_table_%d' % os.getpid()
+ global reclass_files
- feature_vars_file = open(feature_vars, 'w')
- training_vars_file = open(training_vars, 'w')
+ allmap = trainmap = feature_vars = training_vars = None
+ model_output = model_output_desc = temptable = r_commands = None
+ reclass_files = None
- grass.run_command('v.db.select', map_=allfeatures, file_=feature_vars,
- quiet=True, overwrite=True)
- grass.run_command('v.db.select', map_=training, file_=training_vars,
- quiet=True, overwrite=True)
+ voting_function = "voting <- function (x, w) {\n"
+ voting_function += "res <- tapply(w, x, sum, simplify = TRUE)\n"
+ voting_function += "maj_class <- as.numeric(names(res)[which.max(res)])\n"
+ voting_function += "prob <- as.numeric(res[which.max(res)])\n"
+ voting_function += "return(list(maj_class=maj_class, prob=prob))\n}"
- feature_vars_file.close()
- training_vars_file.close()
+ weighting_functions = {}
+ weighting_functions['smv'] = "weights <- rep(1/length(accuracy_means), length(accuracy_means))"
+ weighting_functions['swv'] = "weights <- accuracy_means/sum(accuracy_means)"
+ weighting_functions['bwwv'] = "weights <- 1-(max(accuracy_means) - accuracy_means)/(max(accuracy_means) - min(accuracy_means))"
+ weighting_functions['qbwwv'] = "weights <- ((min(accuracy_means) - accuracy_means)/(max(accuracy_means) - min(accuracy_means)))**2"
- r_commands = grass.tempfile()
+ if options['segments_map']:
+ allfeatures = options['segments_map']
+ allmap = True
+ else:
+ allfeatures = options['segments_file']
+ allmap = False
+
+ if options['training_map']:
+ training = options['training_map']
+ trainmap = True
+ else:
+ training = options['training_file']
+ trainmap = False
+
+ classcol = options['train_class_column']
+ output_classcol = options['output_class_column']
+ output_probcol = None
+ if options['output_prob_column']:
+ output_probcol = options['output_prob_column']
+ classifiers = options['classifiers'].split(',')
+ weighting_modes = options['weighting_modes'].split(',')
+ classification_results = None
+ if options['classification_results']:
+ classification_results = options['classification_results']
+ if flags['f'] and not classification_results:
+ gscript.fatal("A classification_results file is necessary for flag 'f'")
+
+ raster_segments_map = None
+ if options['raster_segments_map']:
+ raster_segments_map = options['raster_segments_map']
+
+ classified_map = None
+ if options['classified_map']:
+ classified_map = options['classified_map']
+
+ r_script_file = None
+ if options['r_script_file']:
+ r_script_file = options['r_script_file']
+
+ accuracy_file = None
+ if options['accuracy_file']:
+ accuracy_file = options['accuracy_file']
+
+ bw_plot_file = None
+ if options['bw_plot_file']:
+ bw_plot_file = options['bw_plot_file']
+
+ if allmap:
+ feature_vars = gscript.tempfile()
+ gscript.run_command('v.db.select',
+ map_=allfeatures,
+ file_=feature_vars,
+ quiet=True,
+ overwrite=True)
+ else:
+ feature_vars = allfeatures
+
+ if trainmap:
+ training_vars = gscript.tempfile()
+ gscript.run_command('v.db.select',
+ map_=training,
+ file_=training_vars,
+ quiet=True,
+ overwrite=True)
+ else:
+ training_vars = training
+
+ r_commands = gscript.tempfile()
+
r_file = open(r_commands, 'w')
- install = "if(!is.element('e1071', installed.packages()[,1])){\n"
- install += "cat('\\n\\nInstalling e1071 package from CRAN\n')\n"
+ install = "if(!is.element('caret', installed.packages()[,1])){\n"
+ install += "cat('\\n\\nInstalling caret package from CRAN\n')\n"
install += "if(!file.exists(Sys.getenv('R_LIBS_USER'))){\n"
install += "dir.create(Sys.getenv('R_LIBS_USER'), recursive=TRUE)\n"
install += ".libPaths(Sys.getenv('R_LIBS_USER'))}\n"
install += "chooseCRANmirror(ind=1)\n"
- install += "install.packages('e1071')}"
+ install += "install.packages('caret')}"
r_file.write(install)
r_file.write("\n")
- r_file.write('library(e1071)')
r_file.write("\n")
- r_file.write("cat('\\nRunning R to tune and apply model...\\n')")
+ r_file.write('require(caret)')
r_file.write("\n")
- r_file.write('features<-read.csv("%s", sep="|", header=TRUE)' % feature_vars)
+ r_file.write("cat('\\nRunning R...\\n')")
r_file.write("\n")
- r_file.write("features<-features[sapply(features, function(x) !any(is.na(x)))]")
+ r_file.write('features <- read.csv("%s", sep="|", header=TRUE, row.names=1)' % feature_vars)
r_file.write("\n")
- r_file.write('training<-read.csv("%s", sep="|", header=TRUE)' % training_vars)
+ r_file.write('training <- read.csv("%s", sep="|", header=TRUE, row.names=1)' % training_vars)
r_file.write("\n")
- data_string = "training = data.frame(training[names(training)[names(training)"
- data_string += "%%in%% names(features)]], trainingclass=training$%s)" % classcol
- r_file.write(data_string)
+ r_file.write("training$%s <- as.factor(training$%s)" % (classcol, classcol))
r_file.write("\n")
- r_file.write("training$trainingclass <- as.factor(training$trainingclass)")
+ r_file.write("MyFolds.cv <- createMultiFolds(training$%s, k=5, times=10)" % classcol)
r_file.write("\n")
- model_string = "model=svm(trainingclass~., data=training[-1], "
- model_string += "kernel = '%s', " % kernel
- tune = True
- if kernel == 'linear' and cost:
- model_string += "cost = %s)" % cost
- tune = False
- if kernel == 'polynomial' and cost and degree and gamma and coeff0:
- model_string += "cost = %s, " % cost
- model_string += "degree = %s, " % degree
- model_string += "gamma = %s, " % gamma
- model_string += "coeff0 = %s)" % coeff0
- tune = False
- if kernel == 'radial' and cost and gamma:
- model_string += "cost = %s, " % cost
- model_string += "gamma = %s)" % gamma
- tune = False
- if kernel == 'sigmoid' and cost and gamma and coeff0:
- model_string += "cost = %s, " % cost
- model_string += "gamma = %s, " % gamma
- model_string += "coeff0 = %s)" % coeff0
- tune = False
- if tune:
- model_string = "model=tune(svm, trainingclass~., data=training[-1], "
- model_string += "nrepeat=10, "
- model_string += "sampling='cross', cross=10"
- model_string += ", kernel='%s'" % kernel
- if cost:
- model_string += ", cost = %s, " % cost
- if gamma:
- model_string += ", gamma = %s, " % gamma
- if degree:
- model_string += ", degree = %s, " % degree
- if coeff0:
- model_string += ", coeff0 = %s, " % coeff0
- if not cost or not gamma or not degree or not coeff0:
- model_string += ", ranges=list("
- first = True
-
- if not cost:
- model_string += "cost=c(0.01, 0.1, 1, 5, 10)"
- first = False
-
- if not gamma and not kernel == 'linear':
- if first:
- model_string += "gamma=seq(0,0.5,0.1)"
- first = False
- else:
- model_string += ", gamma=seq(0,0.5,0.1)"
-
- if not degree and kernel == 'polynomial':
- if first:
- model_string += "degree=seq(2,4,1)"
- first = False
- else:
- model_string += ", degree=seq(2,4,1)"
-
- if not coeff0 and (kernel == 'polynomial' or kernel == 'sigmoid'):
- if first:
- model_string += "coeff0=seq(0,0.5,0.1)"
- else:
- model_string += ", coeff0=seq(0,0.5,0.1)"
-
- model_string += "))"
-
- r_file.write(model_string)
+ r_file.write("MyControl.cv <- trainControl(method='repeatedCV', index=MyFolds.cv)")
r_file.write("\n")
- r_file.write("cat('\\nTuning (or model) summary: \\n\\n')")
+ r_file.write("fmla <- %s ~ ." % classcol)
r_file.write("\n")
- r_file.write("cat('Kernel used: ')")
+ r_file.write("models.cv <- list()")
r_file.write("\n")
- r_file.write("cat('%s\\n')" % kernel)
+ for classifier in classifiers:
+ if classifier == 'knn1':
+ r_file.write("Grid <- expand.grid(k=1)")
+ r_file.write("\n")
+ r_file.write("knn1Model.cv <- train(fmla, training, method='knn', trControl=MyControl.cv, tuneGrid=Grid)")
+ r_file.write("\n")
+ r_file.write("models.cv$knn1 <- knn1Model.cv")
+ r_file.write("\n")
+ else:
+ r_file.write("%sModel.cv <- train(fmla,training,method='%s', trControl=MyControl.cv,tuneLength=10)" % (classifier, classifier))
+ r_file.write("\n")
+ r_file.write("models.cv$%s <- %sModel.cv" % (classifier, classifier))
+ r_file.write("\n")
+
+ r_file.write("resamps.cv <- resamples(models.cv)")
r_file.write("\n")
- install += "cat('\\n')"
+ r_file.write("accuracy_means <- as.vector(apply(resamps.cv$values[seq(2,length(resamps.cv$values), by=2)], 2, mean))")
r_file.write("\n")
- r_file.write("summary(model)")
+ r_file.write("kappa_means <- as.vector(apply(resamps.cv$values[seq(3,length(resamps.cv$values), by=2)], 2, mean))")
r_file.write("\n")
- if tune:
- r_file.write("%s=predict(model$best.model, features[-1])" % output_classcol)
+ r_file.write("predicted <- data.frame(predict(models.cv, features))")
+ r_file.write("\n")
+ if flags['i']:
+ r_file.write("resultsdf <- data.frame(id=rownames(features), predicted)")
else:
- r_file.write("%s=predict(model, features[-1])" % output_classcol)
-
+ r_file.write("resultsdf <- data.frame(id=rownames(features))")
r_file.write("\n")
- write_string = "write.csv(data.frame(cat=features$cat, %s), " % output_classcol
- write_string += "'%s', row.names=FALSE, quote=FALSE)" % model_output
- r_file.write(write_string)
+ r_file.write(voting_function)
r_file.write("\n")
+
+ for weighting_mode in weighting_modes:
+ r_file.write(weighting_functions[weighting_mode])
+ r_file.write("\n")
+ r_file.write("weights <- weights / sum(weights)")
+ r_file.write("\n")
+ r_file.write("vote <- apply(predicted, 1, voting, w=weights)")
+ r_file.write("\n")
+ r_file.write("vote <- as.data.frame(matrix(unlist(vote), ncol=2, byrow=TRUE))")
+ r_file.write("\n")
+ r_file.write("resultsdf$%s_%s <- vote$V1" % (output_classcol, weighting_mode))
+ r_file.write("\n")
+ r_file.write("resultsdf$%s_%s <- vote$V2" % (output_probcol, weighting_mode))
+ r_file.write("\n")
+
+ if allmap and not flags['f']:
+ model_output = '.gscript_tmp_model_output_%d.csv' % os.getpid()
+ write_string = "write.csv(resultsdf, '%s'," % model_output
+ write_string += " row.names=FALSE, quote=FALSE)"
+ r_file.write(write_string)
+ r_file.write("\n")
+ if classified_map:
+ reclass_files = {}
+ for weighting_mode in weighting_modes:
+ reclass_files[weighting_mode] = gscript.tempfile()
+ r_file.write("tempdf <- data.frame(resultsdf$id, resultsdf$%s_%s)" % (output_classcol, weighting_mode))
+ r_file.write("\n")
+ r_file.write("reclass <- data.frame(out=apply(tempdf, 1, function(x) paste(x[1],'=', x[2])))")
+ r_file.write("\n")
+ r_file.write("write.table(reclass$out, '%s', col.names=FALSE, row.names=FALSE, quote=FALSE)" % reclass_files[weighting_mode])
+ r_file.write("\n")
+
+ if classification_results:
+ r_file.write("write.csv(resultsdf, '%s', row.names=FALSE, quote=FALSE)" % classification_results)
+ r_file.write("\n")
+ if accuracy_file:
+ r_file.write("df_means <- data.frame(method=names(resamps.cv$methods),accuracy=accuracy_means, kappa=kappa_means)")
+ r_file.write("\n")
+ r_file.write("write.csv(df_means, '%s', row.names=FALSE, quote=FALSE)" % accuracy_file)
+ r_file.write("\n")
+ if bw_plot_file:
+ r_file.write("png('%s.png')" % bw_plot_file)
+ r_file.write("\n")
+ r_file.write("print(bwplot(resamps.cv))")
+ r_file.write("\n")
+ r_file.write("dev.off()")
r_file.close()
- subprocess.call(['Rscript', r_commands])
+ if r_script_file:
+ shutil.copy(r_commands, r_script_file)
- f = open(model_output_desc, 'w')
- f.write('"Integer","Integer"\n')
- f.close()
+ subprocess.call(['Rscript', r_commands], stdout=open(os.devnull, 'wb'))
- if not flags['t']:
- grass.message("Loading results into attribute table")
- grass.run_command('db.in.ogr', input_=model_output, output=temptable,
- overwrite=True, quiet=True)
+ if allmap and not flags['f']:
+
+ model_output_desc = model_output + 't'
+ temptable = 'classif_tmp_table_%d' % os.getpid()
+
+ f = open(model_output_desc, 'w')
+ header_string = '"Integer"'
+ if flags['i']:
+ for model in classifiers:
+ header_string += ',"Integer"'
+ for weighting_mode in weighting_modes:
+ header_string += ',"Integer"'
+ header_string += ',"Real"'
+ f.write(header_string)
+ f.close()
+
+ gscript.message("Loading results into attribute table")
+ gscript.run_command('db.in.ogr',
+ input_=model_output,
+ output=temptable,
+ overwrite=True,
+ quiet=True)
index_creation = "CREATE INDEX idx_%s_cat" % temptable
- index_creation += " ON %s (cat_)" % temptable
- grass.run_command('db.execute', sql=index_creation)
- grass.run_command('v.db.join', map_=allfeatures, column='cat',
- otable=temptable, ocolumn='cat_',
- subset_columns=output_classcol, quiet=True)
+ index_creation += " ON %s (id)" % temptable
+ gscript.run_command('db.execute',
+ sql=index_creation,
+ quiet=True)
+ columns = gscript.read_command('db.columns',
+ table=temptable).splitlines()[1:]
+ gscript.run_command('v.db.join',
+ map_=allfeatures,
+ column='cat',
+ otable=temptable,
+ ocolumn='id',
+ subset_columns=columns,
+ quiet=True)
+ if classified_map:
+ for weighting_mode, reclass_file in reclass_files.iteritems():
+ output_map = classified_map + '_' + weighting_mode
+ gscript.run_command('r.reclass',
+ input=raster_segments_map,
+ output=output_map,
+ rules=reclass_file,
+ quiet=True)
+
+
+
if __name__ == "__main__":
- options, flags = grass.parser()
+ options, flags = gscript.parser()
atexit.register(cleanup)
main()
More information about the grass-commit
mailing list