[GRASS-SVN] r66802 - in grass-addons/grass7/vector: . v.class.mlR

svn_grass at osgeo.org svn_grass at osgeo.org
Wed Nov 11 09:26:14 PST 2015


Author: mlennert
Date: 2015-11-11 09:26:14 -0800 (Wed, 11 Nov 2015)
New Revision: 66802

Added:
   grass-addons/grass7/vector/v.class.mlR/
   grass-addons/grass7/vector/v.class.mlR/Makefile
   grass-addons/grass7/vector/v.class.mlR/v.class.mlR.html
   grass-addons/grass7/vector/v.class.mlR/v.class.mlR.py
Log:
A very simple module for classifying using machine learning routines from R. This is mainly for own classroom use. Do not add to Makefile at this stage.


Added: grass-addons/grass7/vector/v.class.mlR/Makefile
===================================================================
--- grass-addons/grass7/vector/v.class.mlR/Makefile	                        (rev 0)
+++ grass-addons/grass7/vector/v.class.mlR/Makefile	2015-11-11 17:26:14 UTC (rev 66802)
@@ -0,0 +1,7 @@
+MODULE_TOPDIR = ../..
+
+PGM = v.class.mlR
+
+include $(MODULE_TOPDIR)/include/Make/Script.make
+
+default: script

Added: grass-addons/grass7/vector/v.class.mlR/v.class.mlR.html
===================================================================
--- grass-addons/grass7/vector/v.class.mlR/v.class.mlR.html	                        (rev 0)
+++ grass-addons/grass7/vector/v.class.mlR/v.class.mlR.html	2015-11-11 17:26:14 UTC (rev 66802)
@@ -0,0 +1,51 @@
+<h2>DESCRIPTION</h2>
+
+<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.
+
+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.
+
+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 fix certain parameters so that they 
+will be excluded from tuning.
+
+<h2>NOTES</h2>
+
+The module automatically excludes columns that contain empty values in the map
+of all features.
+
+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>TODO</h2>
+
+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).
+
+Other classifiers should be included.
+
+<h2>EXAMPLE</h2>
+
+<div class="code"><pre>
+v.class.mlR segments training=basins_training2 classcol=classe outcol=classe_watershed
+</pre></div>
+
+<h2>SEE ALSO</h2>
+
+<em>
+<a href="i.segment.html">i.segment</a>,
+</em>
+
+<h2>AUTHOR</h2>
+Moritz Lennert
+
+<p><i>Last changed: $Date: 2015-06-05 14:55:16 +0200 (ven 05 jun 2015) $</i>

Added: grass-addons/grass7/vector/v.class.mlR/v.class.mlR.py
===================================================================
--- grass-addons/grass7/vector/v.class.mlR/v.class.mlR.py	                        (rev 0)
+++ grass-addons/grass7/vector/v.class.mlR/v.class.mlR.py	2015-11-11 17:26:14 UTC (rev 66802)
@@ -0,0 +1,226 @@
+#!/usr/bin/env python
+############################################################################
+#
+# MODULE:       v.class.Re1071svm.py
+# AUTHOR:       Moritz Lennert
+# PURPOSE:      Provides supervised machine learning based classification
+#               (using support vector machine from R package e1071)
+#
+# COPYRIGHT:    (c) 2015 Moritz Lennert, and the GRASS Development Team
+#               This program is free software under the GNU General Public
+#               License (>=v2). Read the file COPYING that comes with GRASS
+#               for details.
+#
+#############################################################################
+
+#%module
+#% description: Provides supervised support vector machine classification
+#% keyword: classification
+#% keyword: machine learning
+#% keyword: R
+#% keyword: svm
+#%end
+#%option G_OPT_V_MAP
+#% label: Vector map with areas to be classified
+#% description: Vector map containing all areas and relevant attributes
+#% required: yes
+#%end
+#%option G_OPT_V_INPUT
+#% key: training
+#% label: Vector map with training areas
+#% description: Vector map with training areas and relevant attributes
+#% required: yes
+#%end
+#%option
+#% key: class_column
+#% type: string
+#% description: Name of attribute column containing training classification
+#% required: yes
+#%end
+#%option
+#% key: output_column
+#% type: string
+#% description: Name of column to create with final classification
+#% required: yes
+#%end
+#%option
+#% key: kernel
+#% type: string
+#% description: Kernel to use
+#% required: yes
+#% options: linear,polynomial,radial,sigmoid
+#% answer: linear
+#%end
+#%option
+#% key: cost
+#% type: double
+#% description: cost value
+#% required: no
+#%end
+#%option
+#% key: degree
+#% type: double
+#% description: degree value (for polynomial kernel)
+#% required: no
+#%end
+#%option
+#% key: gamma
+#% type: double
+#% description: gamma value (for all kernels except linear)
+#% required: no
+#%end
+#%option
+#% key: coeff0
+#% type: double
+#% description: coeff0 value (for polynomial and sigmoid kernels)
+#% required: no
+#%end
+
+import atexit
+import subprocess
+import os
+import grass.script as grass
+
+def cleanup():
+
+    os.remove(feature_vars)
+    os.remove(training_vars)
+    os.remove(model_output)
+    os.remove(model_output_desc)
+    os.remove(r_commands)
+    grass.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']
+    kernel = options['kernel']
+    cost = options['cost']
+    gamma = options['gamma']
+    degree = options['degree']
+    coeff0 = options['coeff0']
+
+    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()
+
+    feature_vars_file = open(feature_vars, 'w')
+    training_vars_file = open(training_vars, 'w')
+
+    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)
+
+    feature_vars_file.close()
+    training_vars_file.close()
+
+    r_commands = grass.tempfile()
+
+    r_file = open(r_commands, 'w')
+
+    install = "if(!is.element('e1071', installed.packages()[,1])) "
+    install += "{install.packages('e1071', "
+    install += "repos='https://mirror.ibcp.fr/pub/CRAN/')}"
+    r_file.write(install)
+    r_file.write("\n")
+    r_file.write('library(e1071)')
+    r_file.write("\n")
+    r_file.write('features<-read.csv("%s", sep="|", header=TRUE)' % feature_vars)
+    r_file.write("\n")
+    r_file.write("features<-features[sapply(features, function(x) !any(is.na(x)))]") 
+    r_file.write("\n")
+    r_file.write('training<-read.csv("%s", sep="|", header=TRUE)' % training_vars)
+    r_file.write("\n")
+    r_file.write("training = data.frame(training[names(features)], classe=training$%s)" % classcol)
+    r_file.write("\n")
+    r_file.write("training$%s <- as.factor(training$%s)" % (classcol, classcol))
+    r_file.write("\n")
+    model_string = "model=tune(svm, %s~., data=training[-1], " % classcol
+    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:
+            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:
+            if first:
+                model_string += "degree=seq(2,4,1)"
+                first = False
+            else:
+                model_string += ", degree=seq(2,4,1)"
+
+        if not coeff0:
+            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("\n")
+    r_file.write("cat('\nSample classification error: ')")
+    r_file.write("\n")
+    r_file.write("cat(model$best.performance)")
+    r_file.write("\n")
+    r_file.write("cat('\n\nSpecification of best model:')")
+    r_file.write("\n")
+    r_file.write("print(model$best.model)")
+    r_file.write("\n")
+    r_file.write("%s=predict(model$best.model, features[-1])" % output_classcol)
+    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("\n")
+    r_file.close()
+
+    grass.message('Running R to tune and apply "best" model')
+    subprocess.call(['Rscript', r_commands])
+
+    f = open(model_output_desc, 'w')
+    f.write('"Integer","Integer"\n')
+    f.close()
+
+    grass.message("Loading results into attribute table")
+    grass.run_command('db.in.ogr', input_=model_output, output=temptable,
+            overwrite=True, quiet=True)
+    grass.run_command('v.db.join', map_=allfeatures, column='cat',
+                        otable=temptable, ocolumn='cat_', 
+                        subset_columns=output_classcol, quiet=True)
+
+
+if __name__ == "__main__":
+    options, flags = grass.parser()
+    atexit.register(cleanup)
+    main()


Property changes on: grass-addons/grass7/vector/v.class.mlR/v.class.mlR.py
___________________________________________________________________
Added: svn:executable
   + *



More information about the grass-commit mailing list