8

I create a RF module in GEE like this:

//Random Forest Result Function Module

exports.getRfResults = function(image, title, bands, trainPoint, testPoint, area, label) {
  
  //Create Sample Points for Training
  var sampleTraining = image.select(bands).sampleRegions({
    collection: trainPoint,
    properties: label,
    scale: 10
  });
  var sampleTrainingTitle = 'sample traingin for ' + title + ' : ';
  print(sampleTrainingTitle, sampleTraining.first());

  //Create Sample Points for Testing
  var sampleTesting = image.select(bands).sampleRegions({
    collection: testPoint,
    properties: label,
    scale: 10
  });
  var sampleTestingTitle = 'sample testing for ' + title + ' : ';
  print(sampleTestingTitle, sampleTesting.first());

  // Classifier for 500 trees
  var classifier = ee.Classifier.smileRandomForest(500,2).setOutputMode('PROBABILITY').train({
    features: sampleTraining,
    classProperty: label[0],
    inputProperties: bands
  });
  var dict = classifier.explain();
  var explainTitle = 'Explain ' + title + ' :';
  print(explainTitle, dict);

  //Variable Importance of RF Classifier
  var variable_importance = ee.Feature(null, ee.Dictionary(dict).get('importance'));

  // Chart of Variable Importance of RF Classifier
  var chartTitle = 'Random Forest Variable Importance for trees for ' + title;
  var chart =
    ui.Chart.feature.byProperty(variable_importance)
      .setChartType('ColumnChart')
      .setOptions({
        title: chartTitle,
        legend: {position: 'none'},
        hAxis: {title: 'Bands'},
        vAxis: {title: 'Importance'}
      });
  print(chart);

  //RF Classifier's Confusion Matrix and Some Values
  var confMatrix = classifier.confusionMatrix();
  var confMatrixTitle = 'Confusion Matrix for '+ title + ' : ';
  print(confMatrixTitle, confMatrix);

  var oaTitle = 'Overall Accuracy for ' + title + ' : ';
  var kappaTitle = 'Kappa for ' + title + ' : ';
  var orderTitle = 'Order for ' + title + ' : ';
  var caTitle = 'Consumers Accuracy for ' + title + ' : ';
  var paTitle = 'Producers Accuracy for ' + title + ' : ';

  print(oaTitle, confMatrix.accuracy());
  print(caTitle, confMatrix.consumersAccuracy());
  print(kappaTitle, confMatrix.kappa());
  print(orderTitle, confMatrix.order());
  print(paTitle, confMatrix.producersAccuracy());

  //var classified = image.classify(classifier);
  //Map.addLayer(classified, {min:0, max:1, palette: ['red', 'green']}, 'classification');

  //RF Classifier's Validation Error Matrix and Some Values
  var tested = sampleTesting.classify(classifier);

  var testErrorMatrix = tested.errorMatrix('isTea', 'classification');
  var vemTitle = 'Validation Error Matrix for ' + title +' : ';
  print(vemTitle, testErrorMatrix);

  var voaTitle = 'Validation Overall Accuracy for ' + title + ' : ';
  var vkappaTitle = 'Validation Kappa for ' + title + ' : ';
  var vorderTitle = 'Validation Order for ' + title + ' : ';
  var vcaTitle = 'Validation Consumers Accuracy for ' + title + ' : ';
  var vpaTitle = 'Validation Producers Accuracy for ' + title + ' : ';

  print(voaTitle, testErrorMatrix.accuracy());
  print(vcaTitle, testErrorMatrix.consumersAccuracy());
  print(vkappaTitle, testErrorMatrix.kappa());
  print(vorderTitle, testErrorMatrix.order());
  print(vpaTitle, testErrorMatrix.producersAccuracy());

  //Classified Image
  var classified = image.classify(classifier);
  Map.addLayer(classified, {min:0, max:1, palette: ['red', 'green']}, 'classification');

  //Pixels Numbers of Classes
  var teaMask = classified.select('classification').eq(1);
  var nonTeaMask = classified.select('classification').eq(0);

  var teaPxNum = ee.Array(classified.updateMask(teaMask).reduceRegion(ee.Reducer.toList(), area, 10).get('classification')).length();
  print('tea Classified PxNum',teaPxNum);

  var nonTeaPxNum = ee.Array(classified.updateMask(nonTeaMask).reduceRegion(ee.Reducer.toList(), area, 10).get('classification')).length();
  print('nonTea Classified PxNum',nonTeaPxNum);

};

But the problem is, which features contribute most to the change between classes? When I explain the classifier with ee.Classifier.explain() method, the output is like this for Sentinel-2;

importance: Object (4 properties)

B2: 17086.790105776927

B3: 17961.828026936393

B4: 17386.157666003204

B8: 20509.20284219093

numberOfTrees: 500

outOfBagErrorEstimate: 0.2574935769340565

trees: List (149 elements)

How do I calculate the importance value and by which method? Because most values I have seen are normalized difference values in the range of 0 to 1. So what is the meaning of these values?

The application for sentinel-2: https://code.earthengine.google.com/79c90e29348b698bae8d094a026584fd

1 Answer 1

1

It is the sum of decrease in Gini impurity index over all trees in the forest. From the comments in the code:

 /**
 * Variable importance. Every time a split of a node is made on variable
 * the (GINI, information gain, etc.) impurity criterion for the two
 * descendent nodes is less than the parent node. Adding up the decreases
 * for each individual variable over all trees in the forest gives a fast
 * variable importance that is often very consistent with the permutation
 * importance measure.
 */
1
  • I would check that this is, in fact, really the case. This is not the commonly used measure of importance because it is not permutated (as a function of the mtry parameter). It is not at all true that the gini index is consistent the permutated measure. Commented Nov 1, 2020 at 1:52

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.