Hi People,
I'm trying to model some soil parameters using random forest in google earth engine. However I am having a problem going past this error code in my work: Number (Error)
String: Unable to convert object to string. Predicted pH: Layer error: String: Unable to convert object to string.
Kindly assist.
This is my code:
// Define the study area boundary using your shapefile
var studyArea = ee.FeatureCollection('projects/ee-evanomondi/assets/Study_area');
// Load the pH and CaCO3 data from your shapefile
var soilData = ee.FeatureCollection('projects/ee-evanomondi/assets/Data_Points2');
// Load the Sentinel-1 SAR, Digital Elevation Model, and climatic data for 2018
var sentinel1 = ee.ImageCollection('COPERNICUS/S1_GRD_FLOAT')
.filterDate('2018-01-01', '2018-12-31')
.filter(ee.Filter.listContains('transmitterReceiverPolarisation', 'VV'))
.median();
// Load the Digital Elevation Model (DEM) data
var dem = ee.Image('USGS/SRTMGL1_003');
// Print the DEM image object
print('DEM:', dem);
// Visualize the DEM
var demVis = {
min: 0,
max: 4000,
palette: ['006633', 'E5FFCC', '662A00', 'D8D8D8', 'F5F5F5']
};
Map.addLayer(dem, demVis, 'DEM');
// Optional: Center the map on the DEM
Map.centerObject(dem, 10);
// Assign the DEM data to the 'dem' variable
var dem = ee.Image('CGIAR/SRTM90_V4');
// Define the date range for the CHIRPS data
var startDate = '2018-01-01';
var endDate = '2018-12-31';
// Load the CHIRPS precipitation data for the specified date range
var chirps = ee.ImageCollection('UCSB-CHG/CHIRPS/DAILY')
.filterDate(startDate, endDate)
.select('precipitation')
.sum();
// Print the CHIRPS image object
print('CHIRPS Data:', chirps);
// Visualize the precipitation
var precipitationVis = {
min: 0,
max: 200,
palette: ['white', 'lightblue', 'blue', 'purple', 'pink']
};
Map.addLayer(chirps, precipitationVis, 'Precipitation');
// Optional: Center the map on the CHIRPS data
Map.centerObject(chirps, 6);
// Assign the CHIRPS data to the climaticData variable and use the correct band name
var climaticData = chirps.select('precipitation');
// Prepare the training data by combining the soil data with the auxiliary variables
var trainingData = soilData.map(function(feature) {
var point = feature.geometry();
var pH = feature.getNumber('pH');
var CaCO3 = feature.getNumber('CaCO3');
var sentinel1Values = sentinel1.sampleRegions({
collection: ee.FeatureCollection(point),
scale: 10,
tileScale: 16
}).first();
var demValue = dem.reduceRegion({
reducer: ee.Reducer.first(),
geometry: point,
scale: 10,
maxPixels: 1e9
}).get('elevation');
var climaticDataValue = climaticData.reduceRegion({
reducer: ee.Reducer.first(),
geometry: point,
scale: 10,
maxPixels: 1e9
}).get('precipitation');
return ee.Feature(point, {
pH: pH,
CaCO3: CaCO3,
sentinel1: sentinel1Values,
dem: demValue,
climaticData: climaticDataValue
});
});
// Split the training data into training and validation sets
var split = 0.7; // Change this value to adjust the split ratio
var randomSeed = 123; // Change this value to set a specific random seed for reproducibility
var trainingSet = trainingData.randomColumn('random', randomSeed).filter(ee.Filter.lt('random', split));
var validationSet = trainingData.randomColumn('random', randomSeed).filter(ee.Filter.gte('random', split));
// Prepare the training features and target
var features = ee.List(['sentinel1', 'dem', 'climaticData']);
var target = 'pH'; // Change this to 'CaCO3' for modeling CaCO3
var trainingFeatures = trainingSet.map(function(feature) {
var values = ee.Image(feature.get('sentinel1')).sampleRegions({
collection: ee.FeatureCollection(feature.geometry()),
scale: 10,
tileScale: 16
});
return feature.set('sentinel1', values);
});
var trainingFeaturesArray = trainingFeatures.aggregate_array(features.slice(0, features.size()));
trainingFeaturesArray = ee.Array(trainingFeaturesArray).toList().map(function(row) {
return ee.Feature(null, ee.Dictionary.fromLists(features, row));
});
var trainingFeatures = ee.FeatureCollection(trainingFeaturesArray);
var trainingTarget = trainingSet.select(target);
// Prepare the validation features and target
var validationFeaturesList = validationSet.map(function(feature) {
var values = ee.Image(feature.get('sentinel1')).sampleRegions({
collection: ee.FeatureCollection(feature.geometry()),
scale: 10,
tileScale: 16
});
return feature.set('sentinel1', values);
});
var validationFeaturesArray = validationFeaturesList.aggregate_array(features.slice(0, features.size()));
validationFeaturesArray = ee.Array(validationFeaturesArray).toList().map(function(row) {
return ee.Feature(null, ee.Dictionary.fromLists(features, row));
});
var validationFeatures = ee.FeatureCollection(validationFeaturesArray);
var validationTarget = validationSet.select(target);
// Train the model using a Random Forest algorithm
var nTrees = 100; // Change this value to adjust the number of trees in the model
var rf = ee.Classifier.smileRandomForest({
numberOfTrees: nTrees,
variablesPerSplit: 0,
bagFraction: 0.5,
seed: randomSeed
}).train({
features: trainingFeatures,
classProperty: target,
inputProperties: features
});
// Make predictions on the validation set
var validationPredictions = validationFeatures.map(function(feature) {
var prediction = ee.Image(rf).classify(feature);
return feature.set('prediction', prediction);
});
// Compute the confusion matrix for the validation set
var validationAccuracy = ee.ConfusionMatrix(validationPredictions.aggregate_array(target), validationPredictions.aggregate_array('prediction'));
// Print the validation accuracy
print('Validation Accuracy:', validationAccuracy.accuracy());
// Visualize the predicted pH values
var pHVis = {
min: 0,
max: 14,
palette: ['red', 'yellow', 'green']
};
Map.addLayer(validationPredictions.select(['prediction']), pHVis, 'Predicted pH');
// Optional: Center the map on the study area
Map.centerObject(studyArea, 8);
// Define a function to export the pH prediction map
var exportMap = function() {
// Make predictions on the entire study area
var studyAreaFeatures = studyArea.map(function(feature) {
var values = ee.Image(sentinel1).sampleRegions({
collection: eeCollection(feature.geometry()),
scale: 10,
tileScale: 16
});
return feature.set('sentinel1', values);
});
var studyAreaFeaturesArray = studyAreaFeatures.aggregate_array(features.slice(0, features.size()));
studyAreaFeaturesArray = ee.Array(studyAreaFeaturesArray).toList().map(function(row) {
return ee.Feature(null, ee.Dictionary.fromLists(features, row));
});
studyAreaFeatures = ee.FeatureCollection(studyAreaFeaturesArray);
var predictionMap = studyAreaFeatures.map(function(feature) {
var prediction = ee.Image(rf).classify(feature);
return feature.geometry().set('prediction', prediction);
});
// Export the prediction map as a GeoTIFF file to your Google Drive
Export.image.toDrive({
image: predictionMap.select(['prediction']),
description: 'pH_prediction_map',
folder: 'GEE_Project',
scale: 10,
region: studyArea.geometry()
});
};