Skip to main content
edited tags
Source Link
PolyGeo
  • 65.4k
  • 29
  • 114
  • 345

I am doing a supervised classification using RF classifier in GEE. However, the accuracy that I am getting is not exceeding 0.67, even if I increase the training sample or no. of trees in my classifier. I would be grateful if

Can someone can have have a look and adviceadvise me of how can I can increase my accuracy (maybe till 80% would be enough) Thanks in advance and here?

Here is the link:   

https://code.earthengine.google.com/cf4f47bc398ff2b6cc45d54c7e32dc49

I am doing a supervised classification using RF classifier in GEE. However, the accuracy that I am getting is not exceeding 0.67, even if I increase the training sample or no. of trees in my classifier. I would be grateful if someone can have a look and advice me of how can I increase my accuracy (maybe till 80% would be enough) Thanks in advance and here is the link:  https://code.earthengine.google.com/cf4f47bc398ff2b6cc45d54c7e32dc49

I am doing a supervised classification using RF classifier in GEE. However, the accuracy that I am getting is not exceeding 0.67, even if I increase the training sample or no. of trees in my classifier.

Can someone have a look and advise me of how I can increase my accuracy (maybe till 80% would be enough)?

Here is the link: 

https://code.earthengine.google.com/cf4f47bc398ff2b6cc45d54c7e32dc49

added 889 characters in body
Source Link
ahmadhanb
  • 41.4k
  • 5
  • 54
  • 109

// Define a function that scales and masks Landsat 8 surface reflectance images. function prepSrL8(image) { // Develop masks for unwanted pixels (fill, cloud, cloud shadow). var qaMask = image.select('QA_PIXEL').bitwiseAnd(parseInt('11111', 2)).eq(0); var saturationMask = image.select('QA_RADSAT').eq(0);

// Apply the scaling factors to the appropriate bands. var getFactorImg = function(factorNames) { var factorList = image.toDictionary().select(factorNames).values(); return ee.Image.constant(factorList); }; var scaleImg = getFactorImg([ 'REFLECTANCE_MULT_BAND_.|TEMPERATURE_MULT_BAND_ST_B10']); var offsetImg = getFactorImg([ 'REFLECTANCE_ADD_BAND_.|TEMPERATURE_ADD_BAND_ST_B10']); var scaled = image.select('SR_B.|ST_B10').multiply(scaleImg).add(offsetImg);

// Replace original bands with scaled bands and apply masks. return image.addBands(scaled, null, true) .updateMask(qaMask).updateMask(saturationMask); }

// Make a cloud-free Landsat 8 surface reflectance composite. var dates = [ // ee.DateRange('2020-04-01', '2020-04-16'), ee.DateRange('2020-04-16', '2020-05-01'), ee.DateRange('2020-05-01', '2020-05-16'), ee.DateRange('2020-05-16', '2020-06-01'), ee.DateRange('2020-06-01', '2020-06-16'), ee.DateRange('2020-06-16', '2020-07-01'), ee.DateRange('2020-07-01', '2020-07-16'), ee.DateRange('2020-07-16', '2020-08-01'), ee.DateRange('2020-08-01', '2020-08-16'), ee.DateRange('2020-08-16', '2020-09-01'), ee.DateRange('2020-09-01', '2020-09-16'), ee.DateRange('2020-09-16', '2020-10-01'), //ee.DateRange('2020-10-01', '2020-10-16'),

] //var bands = ['SR_B2', 'SR_B3', 'SR_B4', 'SR_B5', // 'SR_B6', 'SR_B7']

var addNDVI = function(img) { var ndvi = img.normalizedDifference(['SR_B5','SR_B4']).rename('NDVI') return img.addBands(ndvi) }

var addNDWI = function(img) { var ndwi = img.normalizedDifference(['SR_B3', 'SR_B5']).rename('NDWI') return img.addBands(ndwi) }

// //EVI var addEVI= function(image){ var evi= image.expression( '2.5*(NIR-RED)/(NIR+6RED-7.5BLUE+10000)',{ NIR:image.select('SR_B5'), RED:image.select('SR_B4'), BLUE:image.select('SR_B2'), }).float().rename('EVI') return image.addBands(evi) }

var list = dates.map(function(range) { return ee.ImageCollection('LANDSAT/LC08/C02/T1_L2') .filterDate(ee.DateRange(range)) .filterBounds(ROI) .map(addNDVI) .map(addNDWI) .map(addEVI) .select(['SR_B2', 'SR_B3', 'SR_B4', 'SR_B5', 'SR_B6', 'SR_B7','NDVI', 'NDWI','EVI']) //.mean() .median() .rename(['SR_B2', 'SR_B3', 'SR_B4', 'SR_B5','SR_B6', 'SR_B7','NDVI', 'NDWI','EVI'])

});

// print(list) // Map.addLayer(ROI, {}, 'ROI', false)

///create a stacked layer/// var stacked = ee.ImageCollection(list).toBands().clip(ROI); Map.addLayer(stacked, {bands: ["3_NDVI", "5_NDVI", "8_NDVI"]}, 'Stacked', false)

print(stacked,'stacked')

// // //Generate 4000 random pt sample var random1 = ee.FeatureCollection.randomPoints({ region: rice, points: 2000, seed: 0, maxError: 1 }) var random2 = ee.FeatureCollection.randomPoints({ region: maize, points: 2000, seed: 0, maxError: 1 })

var random3 = ee.FeatureCollection.randomPoints({ region: cotton, points: 3000, seed: 0, maxError: 1 })

var random4 = ee.FeatureCollection.randomPoints({ region: potato, points: 3000, seed: 0, maxError: 1 })

// Paint the reference data into an image so we can sample it. var referenceData = ee.Image().byte().paint(rice, 0).paint(maize, 1).paint(cotton,2).paint(potato,3).rename("class") //var merged_sample= random1.merge(random2,random3,random4); // Place the collections in a new collection. // var combined = ee.FeatureCollection([random1, random2,random3,random4]); var combined = ee.FeatureCollection([random1,random2,random3]);

// Flatten the collection to create a new collection with all the features. var flattened = combined.flatten();

///export the sample to assest to free some space and time for computation/// // Export.table.toAsset({ // collection: flattened, // description:'exportToTableAsset', // assetId: 'merged_sample', // });

// // // Get the values for all pixels in each polygon in the training. var training = stacked.addBands(referenceData).reduceRegions({ reducer: ee.Reducer.first(), // Get the sample from the polygons FeatureCollection. collection: flattened , // Set the scale to get Landsat pixels in the polygons. scale: 30, //crs: 'EPSG:32636',

tileScale: 2 });

// var training = stacked.addBands(referenceData).reduceRegion({ // reducer: ee.Reducer.frequencyHistogram(), // geometry:stacked.geometry(), // maxPixels: 1e14, // scale: 30

// });

//How balanced are the training data? print(training.reduceColumns(ee.Reducer.frequencyHistogram(), ["class"])) Map.addLayer(training,{},'training_sample')

// Filter out the null property values and try again. var trainingNoNulls = training.filter( ee.Filter.notNull(stacked.bandNames().add("class")) ) var sample=trainingNoNulls.randomColumn(); var split=0.7 var training_sample=sample.filter(ee.Filter.lt('random',split)); var validation_sample=sample.filter(ee.Filter.gte('random',split));

var classifier = ee.Classifier.smileRandomForest(150) .train({ features: training_sample, //.randomColumn().filter("random < 0.7"), classProperty: 'class', inputProperties: stacked.bandNames(),

})

var classified = stacked.classify(classifier, 'Classified') Map.addLayer(classified,{ min: 0, max: 3, // palette: [ 'green','orange'] palette: ['yellow', 'green','orange','brown'] }, 'classification', true)

// Get a confusion matrix representing resubstitution accuracy. var trainAccuracy = classifier.confusionMatrix(); print('Resubstitution error matrix: ', trainAccuracy); print('Training overall accuracy: ', trainAccuracy.accuracy()); print('Training kappa accuracy: ', trainAccuracy.kappa());

////////////// validation sample//////

// Extract spectral data from the input image for validation points var validation = stacked.sampleRegions({ // Get the sample from the point FeatureCollection. collection: validation_sample, // We'll classify on 'Level_2" properties: ['class'], // Set the scale to get Sentinel-2 pixels at the points. scale: 30, tileScale: 2 })

// Classify the validation data. var validated = validation.classify(classifier);

// Get a confusion matrix representing expected accuracy. var testAccuracy = validated.errorMatrix('class', 'classification'); print('Test overall accuracy: ', testAccuracy.accuracy()); print('Test kappa accuracy: ', testAccuracy.kappa());

// Define a function that scales and masks Landsat 8 surface reflectance images.
function prepSrL8(image) {
  // Develop masks for unwanted pixels (fill, cloud, cloud shadow).
  var qaMask = image.select('QA_PIXEL').bitwiseAnd(parseInt('11111', 2)).eq(0);
  var saturationMask = image.select('QA_RADSAT').eq(0);

  // Apply the scaling factors to the appropriate bands.
  var getFactorImg = function(factorNames) {
    var factorList = image.toDictionary().select(factorNames).values();
    return ee.Image.constant(factorList);
  };
  var scaleImg = getFactorImg([
    'REFLECTANCE_MULT_BAND_.|TEMPERATURE_MULT_BAND_ST_B10']);
  var offsetImg = getFactorImg([
    'REFLECTANCE_ADD_BAND_.|TEMPERATURE_ADD_BAND_ST_B10']);
  var scaled = image.select('SR_B.|ST_B10').multiply(scaleImg).add(offsetImg);

  // Replace original bands with scaled bands and apply masks.
  return image.addBands(scaled, null, true)
    .updateMask(qaMask).updateMask(saturationMask);
}


// Make a cloud-free Landsat 8 surface reflectance composite.
var dates = [
 // ee.DateRange('2020-04-01', '2020-04-16'),
  ee.DateRange('2020-04-16', '2020-05-01'),
  ee.DateRange('2020-05-01', '2020-05-16'),
  ee.DateRange('2020-05-16', '2020-06-01'),
  ee.DateRange('2020-06-01', '2020-06-16'),
  ee.DateRange('2020-06-16', '2020-07-01'),
  ee.DateRange('2020-07-01', '2020-07-16'),
  ee.DateRange('2020-07-16', '2020-08-01'),
  ee.DateRange('2020-08-01', '2020-08-16'),
  ee.DateRange('2020-08-16', '2020-09-01'),
  ee.DateRange('2020-09-01', '2020-09-16'),
  ee.DateRange('2020-09-16', '2020-10-01'),
 //ee.DateRange('2020-10-01', '2020-10-16'),
  
]
//var bands = ['SR_B2', 'SR_B3', 'SR_B4', 'SR_B5',
            // 'SR_B6', 'SR_B7']
             
var addNDVI = function(img) {
  var ndvi = img.normalizedDifference(['SR_B5','SR_B4']).rename('NDVI')
  return img.addBands(ndvi)
}

var addNDWI = function(img) {
  var ndwi = img.normalizedDifference(['SR_B3', 'SR_B5']).rename('NDWI')
  return img.addBands(ndwi)
}

// //EVI
var addEVI= function(image){
  var evi= image.expression(
              '2.5*(NIR-RED)/(NIR+6*RED-7.5*BLUE+10000)',{
              NIR:image.select('SR_B5'),
              RED:image.select('SR_B4'),
              BLUE:image.select('SR_B2'),
            }).float().rename('EVI')
  return image.addBands(evi)
}

var list = dates.map(function(range) {
  return ee.ImageCollection('LANDSAT/LC08/C02/T1_L2')
      .filterDate(ee.DateRange(range))
      .filterBounds(ROI)
      .map(addNDVI)
      .map(addNDWI)
      .map(addEVI)
      .select(['SR_B2', 'SR_B3', 'SR_B4', 'SR_B5', 'SR_B6', 'SR_B7','NDVI', 'NDWI','EVI'])
      //.mean()
      .median()
      .rename(['SR_B2', 'SR_B3', 'SR_B4', 'SR_B5','SR_B6', 'SR_B7','NDVI', 'NDWI','EVI'])
      
});



// print(list)
// Map.addLayer(ROI, {}, 'ROI', false)


///create a stacked layer///
var stacked = ee.ImageCollection(list).toBands().clip(ROI);
Map.addLayer(stacked, {bands: ["3_NDVI", "5_NDVI", "8_NDVI"]}, 'Stacked', false)

print(stacked,'stacked')

// // //Generate 4000 random pt sample
var random1 = ee.FeatureCollection.randomPoints({
  region: rice,
  points: 2000,
  seed: 0,
  maxError: 1
})
var random2 = ee.FeatureCollection.randomPoints({
  region: maize,
  points: 2000,
  seed: 0,
  maxError: 1
})

var random3 = ee.FeatureCollection.randomPoints({
  region: cotton,
  points: 3000,
  seed: 0,
  maxError: 1
})

var random4 = ee.FeatureCollection.randomPoints({
  region: potato,
  points: 3000,
  seed: 0,
  maxError: 1
})

// Paint the reference data into an image so we can sample it.
var referenceData = ee.Image().byte().paint(rice, 0).paint(maize, 1).paint(cotton,2).paint(potato,3).rename("class")
//var merged_sample= random1.merge(random2,random3,random4);
// Place the collections in a new collection.
// var combined = ee.FeatureCollection([random1, random2,random3,random4]);
 var combined = ee.FeatureCollection([random1,random2,random3]);

// Flatten the collection to create a new collection with all the features.
var flattened = combined.flatten();




///export the sample to assest to free some space and time for computation///
// Export.table.toAsset({
//   collection: flattened,
//   description:'exportToTableAsset',
//   assetId: 'merged_sample',
// });

// // // Get the values for all pixels in each polygon in the training.
var training = stacked.addBands(referenceData).reduceRegions({
  reducer: ee.Reducer.first(),
  // Get the sample from the polygons FeatureCollection.
  collection: flattened
  ,
  // Set the scale to get Landsat pixels in the polygons.
scale: 30,
  //crs: 'EPSG:32636',
  
  tileScale: 2
});

// var training = stacked.addBands(referenceData).reduceRegion({
//     reducer: ee.Reducer.frequencyHistogram(),
//     geometry:stacked.geometry(),
//     maxPixels: 1e14,
//     scale: 30

//   });



//How balanced are the training data?
print(training.reduceColumns(ee.Reducer.frequencyHistogram(), ["class"]))
Map.addLayer(training,{},'training_sample')

// Filter out the null property values and try again.
var trainingNoNulls = training.filter(
  ee.Filter.notNull(stacked.bandNames().add("class"))
)
var sample=trainingNoNulls.randomColumn();
var split=0.7
var training_sample=sample.filter(ee.Filter.lt('random',split));
var validation_sample=sample.filter(ee.Filter.gte('random',split));


var classifier = ee.Classifier.smileRandomForest(150)
  .train({
    features: training_sample,
    //.randomColumn().filter("random < 0.7"),
    classProperty: 'class',
    inputProperties: stacked.bandNames(),
    
  })



var classified = stacked.classify(classifier, 'Classified')
Map.addLayer(classified,{
    min: 0,
    max: 3,
   // palette: [ 'green','orange']
    palette: ['yellow', 'green','orange','brown']
  },
  'classification', true)


// Get a confusion matrix representing resubstitution accuracy.
var trainAccuracy = classifier.confusionMatrix();
print('Resubstitution error matrix: ', trainAccuracy);
print('Training overall accuracy: ', trainAccuracy.accuracy());
print('Training kappa accuracy: ', trainAccuracy.kappa());

////////////// validation sample//////

// Extract spectral data from the input image for validation points
var validation = stacked.sampleRegions({
  // Get the sample from the point FeatureCollection.
  collection: validation_sample,
  // We'll classify on 'Level_2"
properties: ['class'],
  // Set the scale to get Sentinel-2 pixels at the points.
  scale: 30,
  tileScale: 2
})

// Classify the validation data.
var validated = validation.classify(classifier);

// Get a confusion matrix representing expected accuracy.
var testAccuracy = validated.errorMatrix('class', 'classification');
print('Test overall accuracy: ', testAccuracy.accuracy());
print('Test kappa accuracy: ', testAccuracy.kappa());

// Define a function that scales and masks Landsat 8 surface reflectance images. function prepSrL8(image) { // Develop masks for unwanted pixels (fill, cloud, cloud shadow). var qaMask = image.select('QA_PIXEL').bitwiseAnd(parseInt('11111', 2)).eq(0); var saturationMask = image.select('QA_RADSAT').eq(0);

// Apply the scaling factors to the appropriate bands. var getFactorImg = function(factorNames) { var factorList = image.toDictionary().select(factorNames).values(); return ee.Image.constant(factorList); }; var scaleImg = getFactorImg([ 'REFLECTANCE_MULT_BAND_.|TEMPERATURE_MULT_BAND_ST_B10']); var offsetImg = getFactorImg([ 'REFLECTANCE_ADD_BAND_.|TEMPERATURE_ADD_BAND_ST_B10']); var scaled = image.select('SR_B.|ST_B10').multiply(scaleImg).add(offsetImg);

// Replace original bands with scaled bands and apply masks. return image.addBands(scaled, null, true) .updateMask(qaMask).updateMask(saturationMask); }

// Make a cloud-free Landsat 8 surface reflectance composite. var dates = [ // ee.DateRange('2020-04-01', '2020-04-16'), ee.DateRange('2020-04-16', '2020-05-01'), ee.DateRange('2020-05-01', '2020-05-16'), ee.DateRange('2020-05-16', '2020-06-01'), ee.DateRange('2020-06-01', '2020-06-16'), ee.DateRange('2020-06-16', '2020-07-01'), ee.DateRange('2020-07-01', '2020-07-16'), ee.DateRange('2020-07-16', '2020-08-01'), ee.DateRange('2020-08-01', '2020-08-16'), ee.DateRange('2020-08-16', '2020-09-01'), ee.DateRange('2020-09-01', '2020-09-16'), ee.DateRange('2020-09-16', '2020-10-01'), //ee.DateRange('2020-10-01', '2020-10-16'),

] //var bands = ['SR_B2', 'SR_B3', 'SR_B4', 'SR_B5', // 'SR_B6', 'SR_B7']

var addNDVI = function(img) { var ndvi = img.normalizedDifference(['SR_B5','SR_B4']).rename('NDVI') return img.addBands(ndvi) }

var addNDWI = function(img) { var ndwi = img.normalizedDifference(['SR_B3', 'SR_B5']).rename('NDWI') return img.addBands(ndwi) }

// //EVI var addEVI= function(image){ var evi= image.expression( '2.5*(NIR-RED)/(NIR+6RED-7.5BLUE+10000)',{ NIR:image.select('SR_B5'), RED:image.select('SR_B4'), BLUE:image.select('SR_B2'), }).float().rename('EVI') return image.addBands(evi) }

var list = dates.map(function(range) { return ee.ImageCollection('LANDSAT/LC08/C02/T1_L2') .filterDate(ee.DateRange(range)) .filterBounds(ROI) .map(addNDVI) .map(addNDWI) .map(addEVI) .select(['SR_B2', 'SR_B3', 'SR_B4', 'SR_B5', 'SR_B6', 'SR_B7','NDVI', 'NDWI','EVI']) //.mean() .median() .rename(['SR_B2', 'SR_B3', 'SR_B4', 'SR_B5','SR_B6', 'SR_B7','NDVI', 'NDWI','EVI'])

});

// print(list) // Map.addLayer(ROI, {}, 'ROI', false)

///create a stacked layer/// var stacked = ee.ImageCollection(list).toBands().clip(ROI); Map.addLayer(stacked, {bands: ["3_NDVI", "5_NDVI", "8_NDVI"]}, 'Stacked', false)

print(stacked,'stacked')

// // //Generate 4000 random pt sample var random1 = ee.FeatureCollection.randomPoints({ region: rice, points: 2000, seed: 0, maxError: 1 }) var random2 = ee.FeatureCollection.randomPoints({ region: maize, points: 2000, seed: 0, maxError: 1 })

var random3 = ee.FeatureCollection.randomPoints({ region: cotton, points: 3000, seed: 0, maxError: 1 })

var random4 = ee.FeatureCollection.randomPoints({ region: potato, points: 3000, seed: 0, maxError: 1 })

// Paint the reference data into an image so we can sample it. var referenceData = ee.Image().byte().paint(rice, 0).paint(maize, 1).paint(cotton,2).paint(potato,3).rename("class") //var merged_sample= random1.merge(random2,random3,random4); // Place the collections in a new collection. // var combined = ee.FeatureCollection([random1, random2,random3,random4]); var combined = ee.FeatureCollection([random1,random2,random3]);

// Flatten the collection to create a new collection with all the features. var flattened = combined.flatten();

///export the sample to assest to free some space and time for computation/// // Export.table.toAsset({ // collection: flattened, // description:'exportToTableAsset', // assetId: 'merged_sample', // });

// // // Get the values for all pixels in each polygon in the training. var training = stacked.addBands(referenceData).reduceRegions({ reducer: ee.Reducer.first(), // Get the sample from the polygons FeatureCollection. collection: flattened , // Set the scale to get Landsat pixels in the polygons. scale: 30, //crs: 'EPSG:32636',

tileScale: 2 });

// var training = stacked.addBands(referenceData).reduceRegion({ // reducer: ee.Reducer.frequencyHistogram(), // geometry:stacked.geometry(), // maxPixels: 1e14, // scale: 30

// });

//How balanced are the training data? print(training.reduceColumns(ee.Reducer.frequencyHistogram(), ["class"])) Map.addLayer(training,{},'training_sample')

// Filter out the null property values and try again. var trainingNoNulls = training.filter( ee.Filter.notNull(stacked.bandNames().add("class")) ) var sample=trainingNoNulls.randomColumn(); var split=0.7 var training_sample=sample.filter(ee.Filter.lt('random',split)); var validation_sample=sample.filter(ee.Filter.gte('random',split));

var classifier = ee.Classifier.smileRandomForest(150) .train({ features: training_sample, //.randomColumn().filter("random < 0.7"), classProperty: 'class', inputProperties: stacked.bandNames(),

})

var classified = stacked.classify(classifier, 'Classified') Map.addLayer(classified,{ min: 0, max: 3, // palette: [ 'green','orange'] palette: ['yellow', 'green','orange','brown'] }, 'classification', true)

// Get a confusion matrix representing resubstitution accuracy. var trainAccuracy = classifier.confusionMatrix(); print('Resubstitution error matrix: ', trainAccuracy); print('Training overall accuracy: ', trainAccuracy.accuracy()); print('Training kappa accuracy: ', trainAccuracy.kappa());

////////////// validation sample//////

// Extract spectral data from the input image for validation points var validation = stacked.sampleRegions({ // Get the sample from the point FeatureCollection. collection: validation_sample, // We'll classify on 'Level_2" properties: ['class'], // Set the scale to get Sentinel-2 pixels at the points. scale: 30, tileScale: 2 })

// Classify the validation data. var validated = validation.classify(classifier);

// Get a confusion matrix representing expected accuracy. var testAccuracy = validated.errorMatrix('class', 'classification'); print('Test overall accuracy: ', testAccuracy.accuracy()); print('Test kappa accuracy: ', testAccuracy.kappa());

// Define a function that scales and masks Landsat 8 surface reflectance images.
function prepSrL8(image) {
  // Develop masks for unwanted pixels (fill, cloud, cloud shadow).
  var qaMask = image.select('QA_PIXEL').bitwiseAnd(parseInt('11111', 2)).eq(0);
  var saturationMask = image.select('QA_RADSAT').eq(0);

  // Apply the scaling factors to the appropriate bands.
  var getFactorImg = function(factorNames) {
    var factorList = image.toDictionary().select(factorNames).values();
    return ee.Image.constant(factorList);
  };
  var scaleImg = getFactorImg([
    'REFLECTANCE_MULT_BAND_.|TEMPERATURE_MULT_BAND_ST_B10']);
  var offsetImg = getFactorImg([
    'REFLECTANCE_ADD_BAND_.|TEMPERATURE_ADD_BAND_ST_B10']);
  var scaled = image.select('SR_B.|ST_B10').multiply(scaleImg).add(offsetImg);

  // Replace original bands with scaled bands and apply masks.
  return image.addBands(scaled, null, true)
    .updateMask(qaMask).updateMask(saturationMask);
}


// Make a cloud-free Landsat 8 surface reflectance composite.
var dates = [
 // ee.DateRange('2020-04-01', '2020-04-16'),
  ee.DateRange('2020-04-16', '2020-05-01'),
  ee.DateRange('2020-05-01', '2020-05-16'),
  ee.DateRange('2020-05-16', '2020-06-01'),
  ee.DateRange('2020-06-01', '2020-06-16'),
  ee.DateRange('2020-06-16', '2020-07-01'),
  ee.DateRange('2020-07-01', '2020-07-16'),
  ee.DateRange('2020-07-16', '2020-08-01'),
  ee.DateRange('2020-08-01', '2020-08-16'),
  ee.DateRange('2020-08-16', '2020-09-01'),
  ee.DateRange('2020-09-01', '2020-09-16'),
  ee.DateRange('2020-09-16', '2020-10-01'),
 //ee.DateRange('2020-10-01', '2020-10-16'),
  
]
//var bands = ['SR_B2', 'SR_B3', 'SR_B4', 'SR_B5',
            // 'SR_B6', 'SR_B7']
             
var addNDVI = function(img) {
  var ndvi = img.normalizedDifference(['SR_B5','SR_B4']).rename('NDVI')
  return img.addBands(ndvi)
}

var addNDWI = function(img) {
  var ndwi = img.normalizedDifference(['SR_B3', 'SR_B5']).rename('NDWI')
  return img.addBands(ndwi)
}

// //EVI
var addEVI= function(image){
  var evi= image.expression(
              '2.5*(NIR-RED)/(NIR+6*RED-7.5*BLUE+10000)',{
              NIR:image.select('SR_B5'),
              RED:image.select('SR_B4'),
              BLUE:image.select('SR_B2'),
            }).float().rename('EVI')
  return image.addBands(evi)
}

var list = dates.map(function(range) {
  return ee.ImageCollection('LANDSAT/LC08/C02/T1_L2')
      .filterDate(ee.DateRange(range))
      .filterBounds(ROI)
      .map(addNDVI)
      .map(addNDWI)
      .map(addEVI)
      .select(['SR_B2', 'SR_B3', 'SR_B4', 'SR_B5', 'SR_B6', 'SR_B7','NDVI', 'NDWI','EVI'])
      //.mean()
      .median()
      .rename(['SR_B2', 'SR_B3', 'SR_B4', 'SR_B5','SR_B6', 'SR_B7','NDVI', 'NDWI','EVI'])
      
});



// print(list)
// Map.addLayer(ROI, {}, 'ROI', false)


///create a stacked layer///
var stacked = ee.ImageCollection(list).toBands().clip(ROI);
Map.addLayer(stacked, {bands: ["3_NDVI", "5_NDVI", "8_NDVI"]}, 'Stacked', false)

print(stacked,'stacked')

// // //Generate 4000 random pt sample
var random1 = ee.FeatureCollection.randomPoints({
  region: rice,
  points: 2000,
  seed: 0,
  maxError: 1
})
var random2 = ee.FeatureCollection.randomPoints({
  region: maize,
  points: 2000,
  seed: 0,
  maxError: 1
})

var random3 = ee.FeatureCollection.randomPoints({
  region: cotton,
  points: 3000,
  seed: 0,
  maxError: 1
})

var random4 = ee.FeatureCollection.randomPoints({
  region: potato,
  points: 3000,
  seed: 0,
  maxError: 1
})

// Paint the reference data into an image so we can sample it.
var referenceData = ee.Image().byte().paint(rice, 0).paint(maize, 1).paint(cotton,2).paint(potato,3).rename("class")
//var merged_sample= random1.merge(random2,random3,random4);
// Place the collections in a new collection.
// var combined = ee.FeatureCollection([random1, random2,random3,random4]);
 var combined = ee.FeatureCollection([random1,random2,random3]);

// Flatten the collection to create a new collection with all the features.
var flattened = combined.flatten();




///export the sample to assest to free some space and time for computation///
// Export.table.toAsset({
//   collection: flattened,
//   description:'exportToTableAsset',
//   assetId: 'merged_sample',
// });

// // // Get the values for all pixels in each polygon in the training.
var training = stacked.addBands(referenceData).reduceRegions({
  reducer: ee.Reducer.first(),
  // Get the sample from the polygons FeatureCollection.
  collection: flattened
  ,
  // Set the scale to get Landsat pixels in the polygons.
scale: 30,
  //crs: 'EPSG:32636',
  
  tileScale: 2
});

// var training = stacked.addBands(referenceData).reduceRegion({
//     reducer: ee.Reducer.frequencyHistogram(),
//     geometry:stacked.geometry(),
//     maxPixels: 1e14,
//     scale: 30

//   });



//How balanced are the training data?
print(training.reduceColumns(ee.Reducer.frequencyHistogram(), ["class"]))
Map.addLayer(training,{},'training_sample')

// Filter out the null property values and try again.
var trainingNoNulls = training.filter(
  ee.Filter.notNull(stacked.bandNames().add("class"))
)
var sample=trainingNoNulls.randomColumn();
var split=0.7
var training_sample=sample.filter(ee.Filter.lt('random',split));
var validation_sample=sample.filter(ee.Filter.gte('random',split));


var classifier = ee.Classifier.smileRandomForest(150)
  .train({
    features: training_sample,
    //.randomColumn().filter("random < 0.7"),
    classProperty: 'class',
    inputProperties: stacked.bandNames(),
    
  })



var classified = stacked.classify(classifier, 'Classified')
Map.addLayer(classified,{
    min: 0,
    max: 3,
   // palette: [ 'green','orange']
    palette: ['yellow', 'green','orange','brown']
  },
  'classification', true)


// Get a confusion matrix representing resubstitution accuracy.
var trainAccuracy = classifier.confusionMatrix();
print('Resubstitution error matrix: ', trainAccuracy);
print('Training overall accuracy: ', trainAccuracy.accuracy());
print('Training kappa accuracy: ', trainAccuracy.kappa());

////////////// validation sample//////

// Extract spectral data from the input image for validation points
var validation = stacked.sampleRegions({
  // Get the sample from the point FeatureCollection.
  collection: validation_sample,
  // We'll classify on 'Level_2"
properties: ['class'],
  // Set the scale to get Sentinel-2 pixels at the points.
  scale: 30,
  tileScale: 2
})

// Classify the validation data.
var validated = validation.classify(classifier);

// Get a confusion matrix representing expected accuracy.
var testAccuracy = validated.errorMatrix('class', 'classification');
print('Test overall accuracy: ', testAccuracy.accuracy());
print('Test kappa accuracy: ', testAccuracy.kappa());
Source Link

Increasing accuracy with RF classifier in GEE

I am doing a supervised classification using RF classifier in GEE. However, the accuracy that I am getting is not exceeding 0.67, even if I increase the training sample or no. of trees in my classifier. I would be grateful if someone can have a look and advice me of how can I increase my accuracy (maybe till 80% would be enough) Thanks in advance and here is the link:https://code.earthengine.google.com/cf4f47bc398ff2b6cc45d54c7e32dc49

// Define a function that scales and masks Landsat 8 surface reflectance images. function prepSrL8(image) { // Develop masks for unwanted pixels (fill, cloud, cloud shadow). var qaMask = image.select('QA_PIXEL').bitwiseAnd(parseInt('11111', 2)).eq(0); var saturationMask = image.select('QA_RADSAT').eq(0);

// Apply the scaling factors to the appropriate bands. var getFactorImg = function(factorNames) { var factorList = image.toDictionary().select(factorNames).values(); return ee.Image.constant(factorList); }; var scaleImg = getFactorImg([ 'REFLECTANCE_MULT_BAND_.|TEMPERATURE_MULT_BAND_ST_B10']); var offsetImg = getFactorImg([ 'REFLECTANCE_ADD_BAND_.|TEMPERATURE_ADD_BAND_ST_B10']); var scaled = image.select('SR_B.|ST_B10').multiply(scaleImg).add(offsetImg);

// Replace original bands with scaled bands and apply masks. return image.addBands(scaled, null, true) .updateMask(qaMask).updateMask(saturationMask); }

// Make a cloud-free Landsat 8 surface reflectance composite. var dates = [ // ee.DateRange('2020-04-01', '2020-04-16'), ee.DateRange('2020-04-16', '2020-05-01'), ee.DateRange('2020-05-01', '2020-05-16'), ee.DateRange('2020-05-16', '2020-06-01'), ee.DateRange('2020-06-01', '2020-06-16'), ee.DateRange('2020-06-16', '2020-07-01'), ee.DateRange('2020-07-01', '2020-07-16'), ee.DateRange('2020-07-16', '2020-08-01'), ee.DateRange('2020-08-01', '2020-08-16'), ee.DateRange('2020-08-16', '2020-09-01'), ee.DateRange('2020-09-01', '2020-09-16'), ee.DateRange('2020-09-16', '2020-10-01'), //ee.DateRange('2020-10-01', '2020-10-16'),

] //var bands = ['SR_B2', 'SR_B3', 'SR_B4', 'SR_B5', // 'SR_B6', 'SR_B7']

var addNDVI = function(img) { var ndvi = img.normalizedDifference(['SR_B5','SR_B4']).rename('NDVI') return img.addBands(ndvi) }

var addNDWI = function(img) { var ndwi = img.normalizedDifference(['SR_B3', 'SR_B5']).rename('NDWI') return img.addBands(ndwi) }

// //EVI var addEVI= function(image){ var evi= image.expression( '2.5*(NIR-RED)/(NIR+6RED-7.5BLUE+10000)',{ NIR:image.select('SR_B5'), RED:image.select('SR_B4'), BLUE:image.select('SR_B2'), }).float().rename('EVI') return image.addBands(evi) }

var list = dates.map(function(range) { return ee.ImageCollection('LANDSAT/LC08/C02/T1_L2') .filterDate(ee.DateRange(range)) .filterBounds(ROI) .map(addNDVI) .map(addNDWI) .map(addEVI) .select(['SR_B2', 'SR_B3', 'SR_B4', 'SR_B5', 'SR_B6', 'SR_B7','NDVI', 'NDWI','EVI']) //.mean() .median() .rename(['SR_B2', 'SR_B3', 'SR_B4', 'SR_B5','SR_B6', 'SR_B7','NDVI', 'NDWI','EVI'])

});

// print(list) // Map.addLayer(ROI, {}, 'ROI', false)

///create a stacked layer/// var stacked = ee.ImageCollection(list).toBands().clip(ROI); Map.addLayer(stacked, {bands: ["3_NDVI", "5_NDVI", "8_NDVI"]}, 'Stacked', false)

print(stacked,'stacked')

// // //Generate 4000 random pt sample var random1 = ee.FeatureCollection.randomPoints({ region: rice, points: 2000, seed: 0, maxError: 1 }) var random2 = ee.FeatureCollection.randomPoints({ region: maize, points: 2000, seed: 0, maxError: 1 })

var random3 = ee.FeatureCollection.randomPoints({ region: cotton, points: 3000, seed: 0, maxError: 1 })

var random4 = ee.FeatureCollection.randomPoints({ region: potato, points: 3000, seed: 0, maxError: 1 })

// Paint the reference data into an image so we can sample it. var referenceData = ee.Image().byte().paint(rice, 0).paint(maize, 1).paint(cotton,2).paint(potato,3).rename("class") //var merged_sample= random1.merge(random2,random3,random4); // Place the collections in a new collection. // var combined = ee.FeatureCollection([random1, random2,random3,random4]); var combined = ee.FeatureCollection([random1,random2,random3]);

// Flatten the collection to create a new collection with all the features. var flattened = combined.flatten();

///export the sample to assest to free some space and time for computation/// // Export.table.toAsset({ // collection: flattened, // description:'exportToTableAsset', // assetId: 'merged_sample', // });

// // // Get the values for all pixels in each polygon in the training. var training = stacked.addBands(referenceData).reduceRegions({ reducer: ee.Reducer.first(), // Get the sample from the polygons FeatureCollection. collection: flattened , // Set the scale to get Landsat pixels in the polygons. scale: 30, //crs: 'EPSG:32636',

tileScale: 2 });

// var training = stacked.addBands(referenceData).reduceRegion({ // reducer: ee.Reducer.frequencyHistogram(), // geometry:stacked.geometry(), // maxPixels: 1e14, // scale: 30

// });

//How balanced are the training data? print(training.reduceColumns(ee.Reducer.frequencyHistogram(), ["class"])) Map.addLayer(training,{},'training_sample')

// Filter out the null property values and try again. var trainingNoNulls = training.filter( ee.Filter.notNull(stacked.bandNames().add("class")) ) var sample=trainingNoNulls.randomColumn(); var split=0.7 var training_sample=sample.filter(ee.Filter.lt('random',split)); var validation_sample=sample.filter(ee.Filter.gte('random',split));

var classifier = ee.Classifier.smileRandomForest(150) .train({ features: training_sample, //.randomColumn().filter("random < 0.7"), classProperty: 'class', inputProperties: stacked.bandNames(),

})

var classified = stacked.classify(classifier, 'Classified') Map.addLayer(classified,{ min: 0, max: 3, // palette: [ 'green','orange'] palette: ['yellow', 'green','orange','brown'] }, 'classification', true)

// Get a confusion matrix representing resubstitution accuracy. var trainAccuracy = classifier.confusionMatrix(); print('Resubstitution error matrix: ', trainAccuracy); print('Training overall accuracy: ', trainAccuracy.accuracy()); print('Training kappa accuracy: ', trainAccuracy.kappa());

////////////// validation sample//////

// Extract spectral data from the input image for validation points var validation = stacked.sampleRegions({ // Get the sample from the point FeatureCollection. collection: validation_sample, // We'll classify on 'Level_2" properties: ['class'], // Set the scale to get Sentinel-2 pixels at the points. scale: 30, tileScale: 2 })

// Classify the validation data. var validated = validation.classify(classifier);

// Get a confusion matrix representing expected accuracy. var testAccuracy = validated.errorMatrix('class', 'classification'); print('Test overall accuracy: ', testAccuracy.accuracy()); print('Test kappa accuracy: ', testAccuracy.kappa());