4

I am building a classifier for Landsat7 by using MODIS land cover classification.

My goal is to split up my region of interest into 80% being training data and 20% being validation data (with a randomization).

However, I do not know how to implement this in my code. In my current code, only the number of pixels can be adjusted but it is not specified which ones.

Of the following code, this is:

// Make a training dataset by sampling the stacked images.
var training = modisLandcover.addBands(landsatComposite).sample({
    region: geometry,
    scale: 30,
    numPixels: 5000,
    seed: 0
});

var validation = modisLandcover.addBands(landsatComposite).sample({
    region: geometry,
    scale: 30,
    numPixels: 1000,
    seed: 1
}).filter(ee.Filter.neq('B1', null));

Full code:

// Upsample MODIS landcover classification (250m) to Landsat
// resolution (30m) using a supervised classifier.


// Use the MCD12 land-cover as training data.
var modisLandcover = ee.Image('MODIS/051/MCD12Q1/2011_01_01')
  .select('Land_Cover_Type_1');

// A pallete to use for visualizing landcover images.
var landcoverPalette = [
    'aec3d4', // water
    '152106', '225129', '369b47', '30eb5b', '387242', // forest
    '6a2325', 'c3aa69', 'b76031', 'd9903d', '91af40',  // shrub, grass, savanah
    '111149', // wetlands
    '8dc33b', // croplands
    'cc0013', // urban
    '6ca80d', // crop mosaic
    'd7cdcc', // snow and ice
    'f7e084', // barren
    '6f6f6f'  // tundra
];

// A set of visualization parameters using the landcover palette.
var landcoverVisualization = {palette: landcoverPalette, min: 0, max: 17, format: 'png'};
// Center over our region of interest.
Map.centerObject(geometry, 9);
// Draw the MODIS landcover image.
Map.addLayer(modisLandcover, landcoverVisualization, 'MODIS landcover');

// Load and filter Landsat data.
var l7 = ee.ImageCollection('LANDSAT/LE07/C01/T1')
    .filterBounds(geometry)
    .filterDate('2011-01-01', '2012-01-01')
    .sort('CLOUD_COVER', false);            //sort by cloud cover ('false' indivcates descending )

// Draw the Landsat composite, visualizing true color bands.
var landsatComposite = ee.Algorithms.Landsat.simpleComposite({
  collection: l7,
  asFloat: true
});
Map.addLayer(landsatComposite, {min: 0, max: 0.3, bands: ['B3','B2','B1']}, 'Landsat composite');

// Make a training dataset by sampling the stacked images.
var training = modisLandcover.addBands(landsatComposite).sample({
  region: geometry,
  scale: 30,
  numPixels: 5000,
  seed: 0
});


// Train a classifier using the training data. USING CART() classifier
//var classifier = ee.Classifier.cart().train({
var classifier = ee.Classifier.randomForest(100).train({
  features: training,
  classProperty: 'Land_Cover_Type_1',
});

// Apply the classifier to the original composite.
var upsampled = landsatComposite.classify(classifier);

// Draw the upsampled landcover image.
Map.addLayer(upsampled, landcoverVisualization, 'Classified Image');

// Show the training area.
Map.addLayer(ee.Image().paint(geometry, 1, 2), null, 'Training region');

// Get the confusion matrix from the TRAINING features
var trainAccuracy = classifier.confusionMatrix(); 
print('Resubstitution error matrix: ', trainAccuracy);
print('Training overall accuracy: ', trainAccuracy.accuracy());


// make a vlidation datast by using a different seed and filter for null pixels
var validation = modisLandcover.addBands(landsatComposite).sample({
  region: geometry,
  scale: 30,
  numPixels: 1000,
  seed: 1
}).filter(ee.Filter.neq('B1', null));

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

// Get a confusion matrix representing expected accuracy.
var testAccuracy = validated.errorMatrix('Land_Cover_Type_1', 'classification');
print('Validation error matrix: ', testAccuracy);
print('Validation overall accuracy: ', testAccuracy.accuracy());

1 Answer 1

3

Use randomColumn(columnName, seed), which adds a column of random values between 0 and 1 to the featurecollection. Then filter on <0.2 and >0.2 to get 20% for validation, 80% for testing.

// Make a training dataset by sampling the stacked images.
var feats = modisLandcover.addBands(landsatComposite).sample({
  region: geometry,
  scale: 30,
  numPixels: 5000,
  seed: 0
});

// add a random column (by default named 'random')
feats = feats.randomColumn();
// split in a training (80%) and validation (20%)
var training = feats.filter(ee.Filter.gt('random',0.2));
var validation = feats.filter(ee.Filter.lte('random',0.2));

print('validation', validation);
print('training', training);
1
  • Thank you very much, it works fine to split the data. However, if I run my code now, I get the error message: "List (Error) Classifier.train: InputProperties must be specified." How do I have to define the InputProperties then?
    – Simon
    Commented Dec 20, 2019 at 9:15

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.