0

I am training a random forest model in Google Earth Engine, and I want to output the confusion matrices so I know which classes are being confused for which.

By default, the confusion matrix is exported into a single cell in [[5, 0, 0], [0, 5, 0], [0, 0, 5]] format, which is inconvenient for downstream use. I want to use a function to place each value in (ideally) a named column, but I am not sure how to approach this as 1. functions can't be mapped to arrays, 2. arrays can't be placed in dictionaries, and 3. I am not sure if column names can even be created iteratively/from variables.

I know I could array.get() each individual value and place them in a dictionary, but I am hoping for something more generalizable for when I change the number of classes (varies from 4-8). array.get() is also sensitive to Out Of Bounds errors, which may crop up in certain edge cases where not all classes are present in the validation data, and I do not know how to handle this.

Here is an example script to show the type of data I am currently exporting.

0

1 Answer 1

1

You can turn the array into a list and map over that.

var a = ee.Array([[1,2,3],[4,5,6],[7,8,9]])

// Get the size and make arrays of row and column indices.
var size = a.length().get([0])
var r = ee.Array(ee.List.sequence(0, size.subtract(1))).repeat(1, size)
var c = r.transpose(0, 1)

// Combine, flatten to list, and map to make [name, value] pairs.
var data = ee.Array.cat([a, r, c], 2).toList().map(function(row) {
  row = ee.List(row)
  return row.map(function(elem) {
    elem = ee.List(elem)
    var name = elem.getNumber(1).format("t%d").cat(elem.getNumber(2).format("%d"))
    return [name, elem.get(0)]
  })
}).flatten()

print(ee.Dictionary(data))

https://code.earthengine.google.com/1bb4ded28318a2a910d4635a36e6f626

5
  • It does not like that in Row 12, 'elem' is already defined. Do I need to worry about that anywhere?
    – Matt
    Nov 29, 2023 at 17:58
  • Modified this as such: var tLength = a.length().get([0]) var r = ee.Array(ee.List.sequence(0, tLength.subtract(1))).repeat(1, tLength) var tHeight = a.length().get([1]) var c = ee.Array(ee.List.sequence(0, tHeight.subtract(1))).repeat(1, tHeight).transpose(0, 1) This will prevent it from throwing an error in a case where a class is absent from the validation data, but something is mistaken for that class anyway.
    – Matt
    Nov 29, 2023 at 18:27
  • 1
    confusionMatrix is always square, and always starts at 0. Nov 30, 2023 at 8:17
  • Oh, that makes sense thanks. I'm unsure if this follow-up needs to be asked separately. I am trying to export my f-scores this same way. As they are one-dimensional, I removed "var c," changed the "var data" axis to 1, and removed the "var name" .cat() step. The function fails due to float values. I do not understand what the issue is since the floating f-score values are not being called in "var name." How can I fix this?
    – Matt
    Dec 5, 2023 at 22:03
  • 1
    Yeah, start a new question with code showing the new issue. Dec 7, 2023 at 10:47

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.