# Business Intelligence through Machine Learning from Satellite Remote Sensing Data
## 4 System Design and Implementation
### Data Preprocessing  
The preprocessing pipeline, depicted in Figure 1, consists of cloud masking, scaling the images retrieved via GEE, creating monthly image composites, and finally combing our retrieved time series into one single dataset, ready to be fed into the classifiers. **Cloud masking** is a vital preprocessing step in any geospatial analysis application ([[https://medium.com/google-earth/more-accurate-and-flexible-cloud-masking-for-sentinel-2-images-766897a9](https://medium.com/google-earth/more-accurate-and-flexible-cloud-masking-for-sentinel-2-images-766897a9) ba5f]([https://medium.com/google-earth/more-accurate-and-flexible-cloud-masking-for-sentinel-2-images-766897a9](https://medium.com/google-earth/more-accurate-and-flexible-cloud-masking-for-sentinel-2-images-766897a9) ba5f), accessed on 1 September 2023), since clouds captured in satellite imagery can interfere with the results of our analysis. To solve this problem, we chose the Sentinel-2 surface reflectance product, which offers information about the cloud probability within an image. It is a collection of cloud probability images, where for every image in the Sentinel-2 archive, a cloud probability per pixel at a 10 m scale is calculated through a joint effort between Sentinel Hub and Google. This provides a flexible method to mask cloudy pixels to create composites ready for classification tasks. While Sentinel-2 already offered the Quality Assurance band (QA60), a binary classifier for thick and cirrus clouds, the new algorithm called _s2 cloudless_ offers the ability to fine-tune the cloud masking procedure by choosing a probability threshold between 0 and 100.  
Figure 1: Machine learning pipeline diagram.  
To perform cloud masking for our Sentinel-2 images, we used the method provided by _cement_ ([[https://eemont.readthedocs.io/en/0.1.7/guide/maskingClouds.html](https://eemont.readthedocs.io/en/0.1.7/guide/maskingClouds.html)]([https://eemont.readthedocs.io/en/0.1.7/guide/maskingClouds.html](https://eemont.readthedocs.io/en/0.1.7/guide/maskingClouds.html)), accessed on 1 September 2023). We used the default option to filter all the images with more than 60% cloud probability, a moderate threshold that captures the majority of cloudy pixels while not removing clear pixels from the images.  
The second preprocessing step involves the **Scale and Offset** operations on the GEE images. Most images in Google Earth Engine are scaled to fit into the integer datatype. To obtain the original values, we multiplied them with the associated retrieved scalars. While the scaling procedure changes based on the bands and for the supported platforms (e.g., Landsat, Sentinel, etc.), the _eemont_ method automates the scaling for all supported bands ([[https://eemont.readthedocs.io/en/0.2.0/guide/imageScaling.html](https://eemont.readthedocs.io/en/0.2.0/guide/imageScaling.html)]([https://eemont.readthedocs.io/en/0.2.0/guide/imageScaling.html](https://eemont.readthedocs.io/en/0.2.0/guide/imageScaling.html)), accessed on 1 September 2023).  
Another important part of preprocessing is the **creation of monthly composites**. Sentinel-2 SR has a temporal resolution of 1 image every 5 days for the same region. On the other hand, VIIRS Monthly Composites are monthly average radiance composite images using nighttime data from the Visible Infrared Imaging Radiometer Suite (VIIRS) Day/Night Band (DNB).To be able to match these products, we used a library called _wxee_, which also extends GEE's capabilities. Specifically, we generate time series for our selected spectral indices by performing a temporal aggregation from almost daily to monthly frequencies.