Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

String: Unable to convert object to string. Predicted pH: Layer error: String: Unable to convert object to string. #16

Open
safariant opened this issue Jun 24, 2023 · 0 comments

Comments

@safariant
Copy link

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()
});
};

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

1 participant