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+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());