I am trying to run an unsupervised classification over a large area.

Here is my code:

var landsat_8 = ee.ImageCollection("LANDSAT/LC08/C02/T1_TOA")
                              .filterDate('2022-01-01', '2023-01-01')
                              .filterMetadata('CLOUD_COVER', 'less_than', 1)

// randomly generate training points
var training = landsat_8.sample({
  region: study_area,
  scale: 30,
  tileScale: 2,
  numPixels: 5000 // number of pixels to sample

var clusterer = ee.Clusterer.wekaKMeans(10).train(training);

var result_unsupervised = landsat_8.cluster(clusterer);

Map.addLayer(result_unsupervised.randomVisualizer(), {}, 'classification');

The result looks like this:

enter image description here

I just compared this to polygons of Landsat 8 scenes and it looks like the different parts coincide with the scene boundaries:

enter image description here

I assume the algorithm does not treat my image as a whole but actually loops through the original images and for each one calculates a classification.

The above code is similar to almost all examples and tutorials I found. The reason the results in the tutorials always look great is because they pick a small study area that falls exactly into one scene, I assume.

How do I go forward if I have a large study area?

1 Answer 1


The code is fine. The filter does this:

  • Preserve only images with almost no cloud (just a few during the year): this is too strict, and the images have little to non-variation.
  • Compute the mean: some zones have more images, hence more variability. Others have either only one image in summer or one image in winter, so the vegetation condition is quite different. Mean will capture this difference, you can use median instead.
  • Date range: based on previous points, you have a probability to mix two different seasons in the clustering process.
  • Using all bands: quality bands are messing your clustering. Use the bands you want for your purpose, but avoid QA bands.

So, taking these advices in account:

var landsat_8 = ee.ImageCollection("LANDSAT/LC08/C02/T1_TOA")
                              .filterDate('2022-04-01', '2023-07-01')
                              .filterMetadata('CLOUD_COVER', 'less_than', 30)

This is just a fast test, you can play and get the best settings:

enter image description here

  • 1
    This is the advice every tutorial is missing, wow! Especially taking into account seasonal differences and ignoring the QA bands makes a lot of sense. Thank you so much! Commented Feb 10, 2023 at 20:19

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.