{ "cells": [ { "cell_type": "markdown", "id": "dd1b8a49-f8c0-4461-bbb6-1402dc3829fb", "metadata": {}, "source": [ "# SDM1 : Montane woodcreper - Random Forest Model using GRASS\n", "\n", "The [r.learn.ml](https://grass.osgeo.org/grass-devel/manuals/addons/r.learn.ml.html) add-on use the python scikit-learn package to train machine learning models and perform prediction on raster layer. \n", "\n", "Open the bash terminal, migrate in the directory, and open the jupter lab\n", "\n", " cd /media/sf_LVM_shared/my_SE_data/exercise\n", " wget https://raw.githubusercontent.com/selvaje/SE_data/master/exercise/SDM1_MWood_GRASSmodel.ipynb\n", " jupyter lab SDM1_MWood_GRASSmodel.ipynb\n", "\n", "\n", "Install [r.learn.ml](https://grass.osgeo.org/grass-devel/manuals/addons/r.learn.ml.html) add-on. \n", "\n", "## Preparation\n", "\n", " cd /home/user\n", " git clone https://github.com/OSGeo/grass-addons.git grass_addons\n", " sudo apt install subversion\n", " grass --text /home/user/my_SE_data/exercise/grassdb/south_america/PERMANENT --exec g.extension extension=r.learn.ml url=/home/user/grass_addons/src/raster/r.learn.ml\n" ] }, { "cell_type": "code", "execution_count": 11, "id": "fc49e8bb-72ac-447d-b1ac-c4e77ebf42d8", "metadata": { "scrolled": true }, "outputs": [ { "name": "stdout", "output_type": "stream", "text": [ "INTEGER|cat\n", "DOUBLE PRECISION|x\n", "DOUBLE PRECISION|y\n", "INTEGER|PA\n", "----------------------------------------------\n", "raster files available in mapset :\n", "SA_cos_aspect SA_meanannual SA_sin_aspect SA_tasmax_stdev SA_tree\n", "SA_elevation SA_pr_mean SA_slope SA_tasmin_mean SA_tri\n", "SA_intra SA_pr_stdev SA_tasmax_mean SA_tasmin_stdev aspect\n", "\n", "----------------------------------------------\n", "imagery group files available in mapset :\n", "group_rast\n", "\n", "group references the following raster maps\n", "-------------\n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", "-------------\n", "----------------------------------------------\n", "raster files available in mapset :\n", "SA_cos_aspect SA_pr_stdev SA_tasmin_mean rf_class_prob\n", "SA_elevation SA_sin_aspect SA_tasmin_stdev rf_class_prob_0\n", "SA_intra SA_slope SA_tree rf_class_prob_1\n", "SA_meanannual SA_tasmax_mean SA_tri rf_classification\n", "SA_pr_mean SA_tasmax_stdev aspect\n", "\n" ] }, { "name": "stderr", "output_type": "stream", "text": [ "Starting GRASS GIS...\n", "Creating new GRASS GIS location ...\n", "Cleaning up temporary files...\n", "\n", " __________ ___ __________ _______________\n", " / ____/ __ \\/ | / ___/ ___/ / ____/ _/ ___/\n", " / / __/ /_/ / /| | \\__ \\\\_ \\ / / __ / / \\__ \\\n", " / /_/ / _, _/ ___ |___/ /__/ / / /_/ // / ___/ /\n", " \\____/_/ |_/_/ |_/____/____/ \\____/___//____/\n", "\n", "Welcome to GRASS GIS 8.2.1\n", "GRASS GIS homepage: https://grass.osgeo.org\n", "This version running through: Bash Shell (/bin/bash)\n", "Help is available with the command: g.manual -i\n", "See the licence terms with: g.version -c\n", "See citation options with: g.version -x\n", "Start the GUI with: g.gui wxpython\n", "When ready to quit enter: exit\n", "\n", "Reading band 1 of 1...\n", "Link to raster map created.\n", "Default region for this location updated\n", "Region for the current mapset updated\n", "Reading band 1 of 1...\n", "Link to raster map created.\n", "Default region for this location updated\n", "Region for the current mapset updated\n", "Reading band 1 of 1...\n", "Link to raster map created.\n", "Default region for this location updated\n", "Region for the current mapset updated\n", "Reading band 1 of 1...\n", "Link to raster map created.\n", "Default region for this location updated\n", "Region for the current mapset updated\n", "Reading band 1 of 1...\n", "Link to raster map created.\n", "Default region for this location updated\n", "Region for the current mapset updated\n", "Reading band 1 of 1...\n", "Link to raster map created.\n", "Default region for this location updated\n", "Region for the current mapset updated\n", "Scanning input for column types...\n", "Number of columns: 3\n", "Number of data rows: 52255\n", "Importing points...\n", "\n", "Populating table...\n", "Building topology for vector map ...\n", "Registering primitives...\n", "Displaying column types/names for database connection of layer <1>:\n", "Adding raster map to group\n", "Adding raster map to group\n", "Adding raster map to group\n", "Adding raster map to group\n", "Adding raster map to group\n", "Adding raster map to group\n", "Adding raster map to group\n", "Adding raster map to group\n", "Adding raster map to group\n", "Adding raster map to group\n", "Adding raster map to group\n", "Adding raster map to group\n", "Adding raster map to group\n", "Adding raster map to group\n", "Group references the following raster maps:\n", "Extracting training data\n", "Removing samples with NaN values in the raster feature variables...\n", "\n", "Fitting model using RandomForestClassifier\n", "\n", "Cross validation global performance measures......:\n", "accuracy: 0.946 +/-SD 0.003\n", "precision: 0.947 +/-SD 0.005\n", "recall: 0.976 +/-SD 0.004\n", "f1: 0.961 +/-SD 0.002\n", "kappa: 0.877 +/-SD 0.008\n", "balanced_accuracy: 0.931 +/-SD 0.005\n", "roc_auc: 0.967 +/-SD 0.003\n", "matthews_corrcoef: 0.878 +/-SD 0.008\n", "\n", "Feature importances\n", "id Raster Importance\n", "0 SA_cos_aspect@PERMANENT 0.0004\n", "1 SA_elevation@PERMANENT 0.1231\n", "2 SA_intra@PERMANENT 0.0061\n", "3 SA_meanannual@PERMANENT 0.0301\n", "4 SA_pr_mean@PERMANENT 0.0288\n", "5 SA_pr_stdev@PERMANENT 0.001\n", "6 SA_sin_aspect@PERMANENT 0.0006\n", "7 SA_slope@PERMANENT 0.0008\n", "8 SA_tasmax_mean@PERMANENT 0.0366\n", "9 SA_tasmax_stdev@PERMANENT 0.0009\n", "10 SA_tasmin_mean@PERMANENT 0.0024\n", "11 SA_tasmin_stdev@PERMANENT 0.028\n", "12 SA_tree@PERMANENT 0.0322\n", "13 SA_tri@PERMANENT 0.0022\n", "\n", "Predicting classification/regression raster...\n", "Checking GDAL data type and nodata value...\n", "\n", "Using GDAL data type \n", "Exporting raster data to GTiff format...\n", "\n", "r.out.gdal complete. File\n", "\n", "created.\n", "Group references the following raster maps:\n", "Extracting training data\n", "Removing samples with NaN values in the raster feature variables...\n", "\n", "Fitting model using RandomForestClassifier\n", "\n", "Predicting classification/regression raster...\n", "Predicting class probabilities...\n", "Checking GDAL data type and nodata value...\n", "\n", "Using GDAL data type \n", "Exporting raster data to GTiff format...\n", "\n", "r.out.gdal complete. File\n", "\n", "created.\n", "Checking GDAL data type and nodata value...\n", "\n", "Using GDAL data type \n", "Exporting raster data to GTiff format...\n", "\n", "r.out.gdal complete. File\n", "\n", "created.\n", "Cleaning up default sqlite database ...\n", "Cleaning up temporary files...\n", "Done.\n", "\n", "Goodbye from GRASS GIS\n", "\n" ] } ], "source": [ "%%bash\n", "\n", "grass --text --tmp-location /media/sf_LVM_shared/my_SE_data/exercise/geodata//dem/SA_elevation_mn_GMTED2010_mn_crop_msk.tif --exec <<'EOF'\n", "\n", "# set g.region small for testing the script \n", "g.region n=0 s=-10 e=-60 w=-70\n", "\n", "\n", "r.external -e input=/media/sf_LVM_shared/my_SE_data/exercise/geodata/cloud/SA_meanannual_crop_msk.tif output=SA_meanannual --o --q\n", "r.external -e input=/media/sf_LVM_shared/my_SE_data/exercise/geodata/cloud/SA_intra_crop_msk.tif output=SA_intra --o --q\n", "\n", "for var in pr tasmin tasmax ; do\n", "for stat in stdev mean; do \n", "r.external -e input=/media/sf_LVM_shared/my_SE_data/exercise/geodata/climate/CHELSA_${var}_1981-2010_V.2.1_land_crop_${stat}_msk.tif output=SA_${var}_${stat}\n", "done\n", "done\n", "\n", "r.external -e input=/media/sf_LVM_shared/my_SE_data/exercise/geodata/dem/SA_elevation_mn_GMTED2010_mn_crop_msk.tif output=SA_elevation --o --q\n", "r.external -e input=/media/sf_LVM_shared/my_SE_data/exercise/geodata/dem/SA_elevation_mn_GMTED2010_mn_crop_tri_msk.tif output=SA_tri --o --q\n", "r.external -e input=/media/sf_LVM_shared/my_SE_data/exercise/geodata/dem/SA_elevation_mn_GMTED2010_mn_crop_aspect_msk.tif output=aspect --o --q\n", "r.mapcalc \"SA_cos_aspect = ( cos(aspect))\"\n", "r.mapcalc \"SA_sin_aspect = ( sin(aspect))\"\n", "\n", "r.external -e input=/media/sf_LVM_shared/my_SE_data/exercise/geodata/dem/SA_elevation_mn_GMTED2010_mn_crop_slope_msk.tif output=SA_slope --o --q\n", "\n", "r.external -e input=/media/sf_LVM_shared/my_SE_data/exercise/geodata/vegetation/SA_tree_mn_percentage_GFC2013_crop_msk.tif output=SA_tree --o --q\n", "\n", "v.in.ascii input=/media/sf_LVM_shared/my_SE_data/exercise/geodata/SDM/woodcreper_presence_absence.txt output=pres_abs format=point separator=\" \" x=1 y=2 skip=1 columns=\" x double precision, y double precision, PA integer\"\n", "v.info -c pres_abs\n", "\n", "i.group group=group_rast input=$(g.list type=raster pattern=\"SA_*\" separator=comma)\n", " \n", "g.list rast -p\n", "g.list group -p \n", "i.group group=group_rast -l \n", "\n", "r.learn.ml -f cv=10 group=group_rast trainingpoints=pres_abs field=PA output=rf_classification classifier=RandomForestClassifier n_estimators=400 n_jobs=2\n", "r.out.gdal --o -c -m -f createopt=\"COMPRESS=DEFLATE,ZLEVEL=9\" type=Byte format=GTiff nodata=255 input=rf_classification output=/media/sf_LVM_shared/my_SE_data/exercise/geodata/SDM/woodcreper_presence_absence.tif\n", "\n", "\n", "r.learn.ml -p group=group_rast trainingpoints=pres_abs field=PA output=rf_class_prob classifier=RandomForestClassifier n_estimators=200 n_jobs=2\n", "g.list rast -p\n", "r.out.gdal --o -c -m -f createopt=\"COMPRESS=DEFLATE,ZLEVEL=9\" type=Float32 format=GTiff nodata=-9999 input=rf_class_prob_0 output=/media/sf_LVM_shared/my_SE_data/exercise/geodata/SDM/woodcreper_prob_absence.tif\n", "r.out.gdal --o -c -m -f createopt=\"COMPRESS=DEFLATE,ZLEVEL=9\" type=Float32 format=GTiff nodata=-9999 input=rf_class_prob_1 output=/media/sf_LVM_shared/my_SE_data/exercise/geodata/SDM/woodcreper_prob_presence.tif\n", "\n", "\n", "\n", "EOF" ] }, { "cell_type": "code", "execution_count": null, "id": "cfcf2980-df3b-4fbf-8109-87d0e0dc3511", "metadata": {}, "outputs": [], "source": [] } ], "metadata": { "kernelspec": { "display_name": "Python 3 (ipykernel)", "language": "python", "name": "python3" }, "language_info": { "codemirror_mode": { "name": "ipython", "version": 3 }, "file_extension": ".py", "mimetype": "text/x-python", "name": "python", "nbconvert_exporter": "python", "pygments_lexer": "ipython3", "version": "3.10.12" } }, "nbformat": 4, "nbformat_minor": 5 }