Eigenanalyse

Die Transformation der Hauptkomponenten (PC) (auch Karhunen-Loeve-Transformation genannt) ist eine Spektraldrehung, bei der spektral korrelierte Bilddaten in nicht korrelierte Daten umgewandelt werden. Die PC-Transformation erreicht dies, indem die Korrelationsmatrix des Eingabebands durch Eigenanalyse diagonalisiert wird. Verwenden Sie dazu in Earth Engine einen Kovarianzreduzenten auf einem Array-Image und den Befehl eigen() auf dem resultierenden Kovarianz-Array. Betrachten Sie dazu die folgende Funktion. Ein Anwendungsbeispiel ist als Code-Editor-Script und als Colab-Notebook verfügbar.

var getPrincipalComponents = function(centered, scale, region) {
  // Collapse the bands of the image into a 1D array per pixel.
  var arrays = centered.toArray();

  // Compute the covariance of the bands within the region.
  var covar = arrays.reduceRegion({
    reducer: ee.Reducer.centeredCovariance(),
    geometry: region,
    scale: scale,
    maxPixels: 1e9
  });

  // Get the 'array' covariance result and cast to an array.
  // This represents the band-to-band covariance within the region.
  var covarArray = ee.Array(covar.get('array'));

  // Perform an eigen analysis and slice apart the values and vectors.
  var eigens = covarArray.eigen();

  // This is a P-length vector of Eigenvalues.
  var eigenValues = eigens.slice(1, 0, 1);
  // This is a PxP matrix with eigenvectors in rows.
  var eigenVectors = eigens.slice(1, 1);

  // Convert the array image to 2D arrays for matrix computations.
  var arrayImage = arrays.toArray(1);

  // Left multiply the image array by the matrix of eigenvectors.
  var principalComponents = ee.Image(eigenVectors).matrixMultiply(arrayImage);

  // Turn the square roots of the Eigenvalues into a P-band image.
  var sdImage = ee.Image(eigenValues.sqrt())
      .arrayProject([0]).arrayFlatten([getNewBandNames('sd')]);

  // Turn the PCs into a P-band image, normalized by SD.
  return principalComponents
      // Throw out an an unneeded dimension, [[]] -> [].
      .arrayProject([0])
      // Make the one band array image a multi-band image, [] -> image.
      .arrayFlatten([getNewBandNames('pc')])
      // Normalize the PCs by their SDs.
      .divide(sdImage);
};

Auf der Seite Python-Umgebung finden Sie Informationen zur Python API und zur Verwendung von geemap für die interaktive Entwicklung.

import ee
import geemap.core as geemap
def get_principal_components(centered, scale, region):
  # Collapse bands into 1D array
  arrays = centered.toArray()

  # Compute the covariance of the bands within the region.
  covar = arrays.reduceRegion(
      reducer=ee.Reducer.centeredCovariance(),
      geometry=region,
      scale=scale,
      maxPixels=1e9,
  )

  # Get the 'array' covariance result and cast to an array.
  # This represents the band-to-band covariance within the region.
  covar_array = ee.Array(covar.get('array'))

  # Perform an eigen analysis and slice apart the values and vectors.
  eigens = covar_array.eigen()

  # This is a P-length vector of Eigenvalues.
  eigen_values = eigens.slice(1, 0, 1)
  # This is a PxP matrix with eigenvectors in rows.
  eigen_vectors = eigens.slice(1, 1)

  # Convert the array image to 2D arrays for matrix computations.
  array_image = arrays.toArray(1)

  # Left multiply the image array by the matrix of eigenvectors.
  principal_components = ee.Image(eigen_vectors).matrixMultiply(array_image)

  # Turn the square roots of the Eigenvalues into a P-band image.
  sd_image = (
      ee.Image(eigen_values.sqrt())
      .arrayProject([0])
      .arrayFlatten([get_new_band_names('sd')])
  )

  # Turn the PCs into a P-band image, normalized by SD.
  return (
      # Throw out an an unneeded dimension, [[]] -> [].
      principal_components.arrayProject([0])
      # Make the one band array image a multi-band image, [] -> image.
      .arrayFlatten([get_new_band_names('pc')])
      # Normalize the PCs by their SDs.
      .divide(sd_image)
  )

Die Eingabe für die Funktion ist ein Bild mit Mittelung auf Null, ein Maßstab und ein Bereich, in dem die Analyse durchgeführt werden soll. Die Eingabebilder müssen zuerst in ein eindimensionales Arraybild umgewandelt und dann mit ee.Reducer.centeredCovariance() reduziert werden. Das Array, das durch diese Reduktion zurückgegeben wird, ist die symmetrische Varianz-Kovarianzmatrix der Eingabe. Verwenden Sie den Befehl eigen(), um die Eigenwerte und Eigenvektoren der Kovarianzmatrix abzurufen. Die von eigen() zurückgegebene Matrix enthält die Eigenwerte an der 0-ten Position der 1-Achse. Wie in der vorherigen Funktion gezeigt, verwenden Sie slice(), um die Eigenwerte und Eigenvektoren zu trennen. Jedes Element entlang der Nullachse der Eigenvektormatrix ist ein Eigenvektor. Führen Sie wie im Beispiel für die Kugelkalotte die Transformation durch Matrizenmultiplikation von arrayImage mit den Eigenvektoren aus. In diesem Beispiel führt jede Eigenvektormultiplikation zu einem PC.