Skip to article frontmatterSkip to article content
Site not loading correctly?

This may be due to an incorrect BASE_URL configuration. See the MyST Documentation for reference.

Image classification with GEE and scikit-learn

So far, we have come a long way. We have learned to work with both, vector and raster data. We have used this knowledge to e.g., extract for specific geo-locations raster-values, to use these data for parameterizing a machine-learning classifier, and to do a subsequent prediction. Now, what this small tutorial does is show you how to do these steps using a combination of functions from the packages scikit-learn and geemap. We will exemplify this on a - admittedly not great - example. Specifically, we will collect some training data from an existing land cover dataset, and predict the same land cover categories on spectra-temporal metrics (STM). Obviously, one would expect the results to be similar, but for the sake of this tutorial, we keep it this way.

We now go step by step over the process with some example code. First, we load some packages and initialize GEE

Load vector data

Open them using the ogr library

First, we will load two vector files, both are located on my personal drive:

  1. One file does only contain one feature, with a squared geometry. This will be our region of interest (ROI), i.e., the boundaries of our classification

  2. A set of points that will serve as our training locations. This is not an uncommon scenario: often you have/receive some shapefiles in the form of points, which you use for your work.

POLYGON ((13.2134494446947 52.4151979479578,13.2134494446947 52.4873242002239,13.3018503384978 52.4873242002239,13.3018503384978 52.4151979479578,13.2134494446947 52.4151979479578))
1000

Convert items into ee.Geometry() and ee.FeatureCollection()

Next, we will convert these items into GEE-Objects. The ROI we convert it into an ee.Geometry(), the points into an ee.FeatureCollection(). Both items we have already learned how to do (check the intro chapter on GEE of this course

Loading...
Loading...
Loading...

Prepare STM

From our chapters on image classifications and image workflows in GEE we learned what STMs are and how we can use them. Here, we repeat many of these steps, while at the same time providing some smaller functions that you can incorporate in your library.

Specifically, we take all Landsat 8 and Landsat 9 imagery of the year 2023 with less than 70% cloud cover. We merge the images of these two satellites into one collection, mask and scale the data, and calculate basic STMs.

We can check the outcome by having a quick look at the band names. I do that here by getting the band names for all metrics calculated for the blue band:

['SR_B2_mean', 'SR_B2_stdDev', 'SR_B2_p10', 'SR_B2_p25', 'SR_B2_p50', 'SR_B2_p75', 'SR_B2_p90']

Prepare Land Cover variables

That seemed to have worked well. In essence, we have now our independent variables prepared. As dependent variable - again: thematically not the most suitable case - we extract the label of the ESA World Cover, and add it as an additional band to the SMT image:

Extract values at the point locations

Now that we have everything ready, we can extract the data for our point locations and store them on our computers. We use the function.sampleRegions() to do that. This function works well over smaller areas; for larger areas we need some workaround (see next chapter).

the code box below then allows you to convert the json dictionary into a pandas data frame. It is probably not the smartest option/solution, but it does the job. Feel free to write us with a better option:

Loading...

Parameterization in scikit-learn and conversion into GEE-classifier

The data are ready. We can now move on with the parameterization and the prediction. We will use some pretty cool tools from the geemap, including the upload of trained trees beack into GEE. We use a random forest classifier to parameterize a model, similar to what we did in the machine learning session session.

D:\miniforge3\envs\py310\lib\site-packages\sklearn\model_selection\_split.py:725: UserWarning: The least populated class in y has only 2 members, which is less than n_splits=3.
  warnings.warn(

Now, we apply a pretty cool part, implemented in the geemap package. What the two functions below are doing is that they (1) convert the random forest model into strings (i.e., the trees), (2) convert it into a feature collection, before (3) converting it into a ee.Classifer. For very large models with very long variable names the maximum size of 10MB per model might not be sufficient, but for the problem here it is fine.

Loading...

Prediction in GEE and export

Now we have (1) the STM sitting in form of a container in GEE and (2) a model which we have trained. All what is needed is to bring these two together through a prediction. This is very easily done through one line of code. Remember, that until you hit getInfo() or export the dataset to your drive or into an asset, GEE does not a tiny thing of work. Some examples for exporting data were already provided in the GEE raster chapter, so we only repeat the code here without muhc explanation.

Loading...

And that is it. We essentially have used GEE as a pure processing and data engine. The advantages of this approach are manyfold:

  1. We can have now basically a classification as a pre-processing step before doing some more advanced techniques offline which we cannot in GEE, such as image segmentation. Think about, for example, a probability image [of a class] which you want to segment using a random walker segmentation. In GEE alone you cannot do this, but you also don’t want to (a) download all the images, (b) run the pre-processing, and (c) calculate the probabilities before running the segmentation.

  2. You can also think about everything else until the model prediction - so, harvesting GEE for its data to run all sorts of tests (e.g., different STMs, different images included in a growing season, etc.

  3. Sometimes you want to keep you workflow, and maybe even dynamically adjust your training sample, e.g., by using different buffer sizes. You can do all the vector-based manipulation offline and only use GEE for the bits of data extraction and processing.

Further reading

  1. Local Random Forest Training

  2. Classification notebook in EEwPython