Пакет Classifier
обеспечивает контролируемую классификацию с использованием традиционных алгоритмов машинного обучения, работающих в Earth Engine. К таким классификаторам относятся CART, RandomForest, NaiveBayes и SVM. Общий рабочий процесс классификации следующий:
- Соберите обучающие данные. Соберите признаки, имеющие свойство, хранящее известную метку класса, и свойства, хранящие числовые значения предикторов.
- Создайте классификатор. При необходимости задайте его параметры.
- Обучить классификатор, используя обучающие данные.
- Классифицируйте изображение или коллекцию объектов.
- Оцените ошибку классификации с помощью независимых проверочных данных.
Обучающие данные представляют собой FeatureCollection
со свойством, хранящим метку класса, и свойствами, хранящими предикторные переменные. Метки классов должны быть последовательными целыми числами, начиная с 0. При необходимости используйте remap()
для преобразования значений класса в последовательные целые числа. Предикторы должны быть числовыми.
Данные для обучения и/или проверки могут поступать из различных источников. Для интерактивного сбора данных для обучения в Earth Engine можно использовать инструменты рисования геометрии (см. раздел «Инструменты для геометрии» на странице редактора кода ). Кроме того, можно импортировать предопределенные данные для обучения из табличного ресурса Earth Engine (подробнее см. на странице «Импорт табличных данных» ). Получите классификатор из одного из конструкторов в ee.Classifier
. Обучите классификатор с помощью classifier.train()
. Классифицируйте Image
или FeatureCollection
с помощью classify()
. В следующем примере классификатор CART (Classification and Regression Trees, CART) ( Breiman et al. 1984 ) используется для прогнозирования трех простых классов:
Редактор кода (JavaScript)
// Define a function that scales and masks Landsat 8 surface reflectance images. function prepSrL8(image) { // Develop masks for unwanted pixels (fill, cloud, cloud shadow). var qaMask = image.select('QA_PIXEL').bitwiseAnd(parseInt('11111', 2)).eq(0); var saturationMask = image.select('QA_RADSAT').eq(0); // Apply the scaling factors to the appropriate bands. var getFactorImg = function(factorNames) { var factorList = image.toDictionary().select(factorNames).values(); return ee.Image.constant(factorList); }; var scaleImg = getFactorImg([ 'REFLECTANCE_MULT_BAND_.|TEMPERATURE_MULT_BAND_ST_B10']); var offsetImg = getFactorImg([ 'REFLECTANCE_ADD_BAND_.|TEMPERATURE_ADD_BAND_ST_B10']); var scaled = image.select('SR_B.|ST_B10').multiply(scaleImg).add(offsetImg); // Replace original bands with scaled bands and apply masks. return image.addBands(scaled, null, true) .updateMask(qaMask).updateMask(saturationMask); } // Make a cloud-free Landsat 8 surface reflectance composite. var image = ee.ImageCollection('LANDSAT/LC08/C02/T1_L2') .filterDate('2021-03-01', '2021-07-01') .map(prepSrL8) .median(); // Use these bands for prediction. var bands = ['SR_B2', 'SR_B3', 'SR_B4', 'SR_B5', 'SR_B6', 'SR_B7', 'ST_B10']; // Load training points. The numeric property 'class' stores known labels. var points = ee.FeatureCollection('GOOGLE/EE/DEMOS/demo_landcover_labels'); // This property stores the land cover labels as consecutive // integers starting from zero. var label = 'landcover'; // Overlay the points on the imagery to get training. var training = image.select(bands).sampleRegions({ collection: points, properties: [label], scale: 30 }); // Train a CART classifier with default parameters. var trained = ee.Classifier.smileCart().train(training, label, bands); // Classify the image with the same bands used for training. var classified = image.select(bands).classify(trained); // Display the inputs and the results. Map.setCenter(-122.0877, 37.7880, 11); Map.addLayer(image, {bands: ['SR_B4', 'SR_B3', 'SR_B2'], min: 0, max: 0.25}, 'image'); Map.addLayer(classified, {min: 0, max: 2, palette: ['orange', 'green', 'blue']}, 'classification');
import ee import geemap.core as geemap
Colab (Python)
# Define a function that scales and masks Landsat 8 surface reflectance images. def prep_sr_l8(image): """Scales and masks Landsat 8 surface reflectance images.""" # Develop masks for unwanted pixels (fill, cloud, cloud shadow). qa_mask = image.select('QA_PIXEL').bitwiseAnd(0b11111).eq(0) saturation_mask = image.select('QA_RADSAT').eq(0) # Apply the scaling factors to the appropriate bands. def _get_factor_img(factor_names): factor_list = image.toDictionary().select(factor_names).values() return ee.Image.constant(factor_list) scale_img = _get_factor_img([ 'REFLECTANCE_MULT_BAND_.|TEMPERATURE_MULT_BAND_ST_B10']) offset_img = _get_factor_img([ 'REFLECTANCE_ADD_BAND_.|TEMPERATURE_ADD_BAND_ST_B10']) scaled = image.select('SR_B.|ST_B10').multiply(scale_img).add(offset_img) # Replace original bands with scaled bands and apply masks. return image.addBands(scaled, None, True).updateMask( qa_mask).updateMask(saturation_mask) # Make a cloud-free Landsat 8 surface reflectance composite. l8_image = ( ee.ImageCollection('LANDSAT/LC08/C02/T1_L2') .filterDate('2021-03-01', '2021-07-01') .map(prep_sr_l8) .median()) # Use these bands for prediction. bands = ['SR_B2', 'SR_B3', 'SR_B4', 'SR_B5', 'SR_B6', 'SR_B7', 'ST_B10'] # Load training points. The numeric property 'class' stores known labels. points = ee.FeatureCollection('GOOGLE/EE/DEMOS/demo_landcover_labels') # This property stores the land cover labels as consecutive # integers starting from zero. label = 'landcover' # Overlay the points on the imagery to get training. training = l8_image.select(bands).sampleRegions( collection=points, properties=[label], scale=30 ) # Train a CART classifier with default parameters. trained = ee.Classifier.smileCart().train(training, label, bands) # Classify the image with the same bands used for training. classified = l8_image.select(bands).classify(trained) # Display the inputs and the results. m = geemap.Map() m.set_center(-122.0877, 37.7880, 11) m.add_layer( l8_image, {'bands': ['SR_B4', 'SR_B3', 'SR_B2'], 'min': 0, 'max': 0.25}, 'image', ) m.add_layer( classified, {'min': 0, 'max': 2, 'palette': ['orange', 'green', 'blue']}, 'classification', ) m
В этом примере обучающие точки в таблице хранят только метку класса. Обратите внимание, что обучающее свойство ( 'landcover'
) хранит последовательные целые числа, начиная с 0 (при необходимости используйте remap()
для вашей таблицы, чтобы преобразовать метки классов в последовательные целые числа, начиная с нуля). Также обратите внимание на использование image.sampleRegions()
для добавления предикторов в таблицу и создания обучающего набора данных. Чтобы обучить классификатор, укажите имя свойства метки класса и список свойств в обучающей таблице, которые классификатор должен использовать для предикторов. Количество и порядок полос на классифицируемом изображении должны точно соответствовать порядку в списке свойств, предоставленном classifier.train()
. Используйте image.select()
чтобы убедиться, что схема классификатора соответствует изображению.
Если обучающие данные представляют собой полигоны, представляющие однородные области, каждый пиксель в каждом полигоне является обучающей точкой. Вы можете использовать полигоны для обучения, как показано в следующем примере:
Редактор кода (JavaScript)
// Define a function that scales and masks Landsat 8 surface reflectance images. function prepSrL8(image) { // Develop masks for unwanted pixels (fill, cloud, cloud shadow). var qaMask = image.select('QA_PIXEL').bitwiseAnd(parseInt('11111', 2)).eq(0); var saturationMask = image.select('QA_RADSAT').eq(0); // Apply the scaling factors to the appropriate bands. var getFactorImg = function(factorNames) { var factorList = image.toDictionary().select(factorNames).values(); return ee.Image.constant(factorList); }; var scaleImg = getFactorImg([ 'REFLECTANCE_MULT_BAND_.|TEMPERATURE_MULT_BAND_ST_B10']); var offsetImg = getFactorImg([ 'REFLECTANCE_ADD_BAND_.|TEMPERATURE_ADD_BAND_ST_B10']); var scaled = image.select('SR_B.|ST_B10').multiply(scaleImg).add(offsetImg); // Replace original bands with scaled bands and apply masks. return image.addBands(scaled, null, true) .updateMask(qaMask).updateMask(saturationMask); } // Make a cloud-free Landsat 8 surface reflectance composite. var image = ee.ImageCollection('LANDSAT/LC08/C02/T1_L2') .filterDate('2018-01-01', '2019-01-01') .map(prepSrL8) .median(); // Use these bands for prediction. var bands = ['SR_B2', 'SR_B3', 'SR_B4', 'SR_B5', 'SR_B6', 'SR_B7']; // Manually created polygons. var forest1 = ee.Geometry.Rectangle(-63.0187, -9.3958, -62.9793, -9.3443); var forest2 = ee.Geometry.Rectangle(-62.8145, -9.206, -62.7688, -9.1735); var nonForest1 = ee.Geometry.Rectangle(-62.8161, -9.5001, -62.7921, -9.4486); var nonForest2 = ee.Geometry.Rectangle(-62.6788, -9.044, -62.6459, -8.9986); // Make a FeatureCollection from the hand-made geometries. var polygons = ee.FeatureCollection([ ee.Feature(nonForest1, {'class': 0}), ee.Feature(nonForest2, {'class': 0}), ee.Feature(forest1, {'class': 1}), ee.Feature(forest2, {'class': 1}), ]); // Get the values for all pixels in each polygon in the training. var training = image.sampleRegions({ // Get the sample from the polygons FeatureCollection. collection: polygons, // Keep this list of properties from the polygons. properties: ['class'], // Set the scale to get Landsat pixels in the polygons. scale: 30 }); // Create an SVM classifier with custom parameters. var classifier = ee.Classifier.libsvm({ kernelType: 'RBF', gamma: 0.5, cost: 10 }); // Train the classifier. var trained = classifier.train(training, 'class', bands); // Classify the image. var classified = image.classify(trained); // Display the classification result and the input image. Map.setCenter(-62.836, -9.2399, 9); Map.addLayer(image, {bands: ['SR_B4', 'SR_B3', 'SR_B2'], min: 0, max: 0.25}, 'image'); Map.addLayer(polygons, {color: 'yellow'}, 'training polygons'); Map.addLayer(classified, {min: 0, max: 1, palette: ['orange', 'green']}, 'deforestation');
import ee import geemap.core as geemap
Colab (Python)
# Define a function that scales and masks Landsat 8 surface reflectance images. def prep_sr_l8(image): # Develop masks for unwanted pixels (fill, cloud, cloud shadow). qa_mask = image.select('QA_PIXEL').bitwiseAnd(0b11111).eq(0) saturation_mask = image.select('QA_RADSAT').eq(0) # Apply the scaling factors to the appropriate bands. def _get_factor_img(factor_names): factor_list = image.toDictionary().select(factor_names).values() return ee.Image.constant(factor_list) scale_img = _get_factor_img([ 'REFLECTANCE_MULT_BAND_.|TEMPERATURE_MULT_BAND_ST_B10']) offset_img = _get_factor_img([ 'REFLECTANCE_ADD_BAND_.|TEMPERATURE_ADD_BAND_ST_B10']) scaled = image.select('SR_B.|ST_B10').multiply(scale_img).add(offset_img) # Replace original bands with scaled bands and apply masks. return image.addBands(scaled, None, True).updateMask( qa_mask).updateMask(saturation_mask) # Make a cloud-free Landsat 8 surface reflectance composite. l8_image = ( ee.ImageCollection('LANDSAT/LC08/C02/T1_L2') .filterDate('2018-01-01', '2019-01-01') .map(prep_sr_l8) .median()) # Use these bands for prediction. bands = ['SR_B2', 'SR_B3', 'SR_B4', 'SR_B5', 'SR_B6', 'SR_B7'] # Manually created polygons. forest1 = ee.Geometry.Rectangle(-63.0187, -9.3958, -62.9793, -9.3443) forest2 = ee.Geometry.Rectangle(-62.8145, -9.206, -62.7688, -9.1735) non_forest1 = ee.Geometry.Rectangle(-62.8161, -9.5001, -62.7921, -9.4486) non_forest2 = ee.Geometry.Rectangle(-62.6788, -9.044, -62.6459, -8.9986) # Make a FeatureCollection from the hand-made geometries. polygons = ee.FeatureCollection([ ee.Feature(non_forest1, {'class': 0}), ee.Feature(non_forest1, {'class': 0}), ee.Feature(forest1, {'class': 1}), ee.Feature(forest2, {'class': 1}), ]) # Get the values for all pixels in each polygon in the training. training = l8_image.sampleRegions( # Get the sample from the polygons FeatureCollection. collection=polygons, # Keep this list of properties from the polygons. properties=['class'], # Set the scale to get Landsat pixels in the polygons. scale=30, ) # Create an SVM classifier with custom parameters. classifier = ee.Classifier.libsvm(kernelType='RBF', gamma=0.5, cost=10) # Train the classifier. trained = classifier.train(training, 'class', bands) # Classify the image. classified = l8_image.classify(trained) # Display the classification result and the input image. m = geemap.Map() m.set_center(-62.836, -9.2399, 9) m.add_layer( l8_image, {'bands': ['SR_B4', 'SR_B3', 'SR_B2'], 'min': 0, 'max': 0.25}, 'image', ) m.add_layer(polygons, {'color': 'yellow'}, 'training polygons') m.add_layer( classified, {'min': 0, 'max': 1, 'palette': ['orange', 'green']}, 'deforestation', ) m
В этом примере используется классификатор на основе опорных векторных машин (SVM) ( Burges, 1998 ). Обратите внимание, что SVM задаётся набором пользовательских параметров. Без априорной информации о физической природе задачи прогнозирования оптимальные параметры неизвестны. См. Hsu et al. (2003) для приблизительного руководства по выбору параметров SVM.
Режимы вывода классификатора
Метод ee.Classifier.setOutputMode()
управляет форматом результатов контролируемой классификации, позволяя структурировать выходные данные несколькими различными способами:
- КЛАССИФИКАЦИЯ (по умолчанию) : выходными данными является номер класса.
- РЕГРЕССИЯ : Выходные данные являются результатом стандартной регрессии.
- ВЕРОЯТНОСТЬ : Выходные данные представляют собой вероятность того, что классификация верна.
- МНОГОВЕРОЯТНОСТЬ : Выходные данные представляют собой массив вероятностей того, что каждый класс является правильным, упорядоченный по наблюдаемым классам.
- RAW : Выходной файл представляет собой массив внутреннего представления процесса классификации. Например, необработанные голоса в моделях многомерного дерева решений.
- RAW_REGRESSION : Выходной файл — массив внутреннего представления процесса регрессии. Например, необработанные прогнозы деревьев множественной регрессии.
Поддержка этих режимов вывода варьируется. В следующей таблице перечислены поддерживаемые режимы для каждого классификатора.
Классификатор | КЛАССИФИКАЦИЯ | РЕГРЕССИЯ | ВЕРОЯТНОСТЬ | МНОГОВЕРОЯТНОСТЬ | СЫРОЙ | RAW_REGRESSION |
---|---|---|---|---|---|---|
ee.Classifier.amnhMaxent | ||||||
ee.Classifier.minimumDistance | ||||||
ee.Classifier.smileCart | ||||||
ee.Classifier.smileGradientTreeBoost | ||||||
ee.Classifier.smileKNN | ||||||
ee.Classifier.smileNaiveBayes | ||||||
ee.Classifier.smileRandomForest | ||||||
ee.Classifier.libsvm C_SVC | ||||||
ee.Classifier.libsvm NU_SVC | ||||||
ee.Classifier.libsvm ONE_CLASS | ||||||
ee.Classifier.libsvm EPSILON_SVR | ||||||
ee.Classifier.libsvm NU_SVR |
Используйте setOutputMode()
перед обучением классификатора, чтобы определить формат выходных данных. Например, в предыдущем блоке кода можно настроить классификатор SVM на вывод вероятностей вместо меток классификации по умолчанию:
Редактор кода (JavaScript)
var classifier = ee.Classifier.libsvm({ kernelType: 'RBF', gamma: 0.5, cost: 10 }).setOutputMode('PROBABILITY'); var trained = classifier.train(training, 'class', bands);
import ee import geemap.core as geemap
Colab (Python)
classifier = ee.Classifier.libsvm( kernelType='RBF', gamma=0.5, cost=10 ).setOutputMode('PROBABILITY') trained = classifier.train(training, 'class', bands)
Оценка точности
Для оценки точности классификатора используется ConfusionMatrix
( Стехман, 1997 ). В следующем примере функция sample()
используется для генерации данных для обучения и проверки на основе эталонного изображения MODIS и сравниваются матрицы спутывания, отражающие точность обучения и проверки:
Редактор кода (JavaScript)
// Define a region of interest. var roi = ee.Geometry.BBox(-122.93, 36.99, -121.20, 38.16); // Define a function that scales and masks Landsat 8 surface reflectance images. function prepSrL8(image) { // Develop masks for unwanted pixels (fill, cloud, cloud shadow). var qaMask = image.select('QA_PIXEL').bitwiseAnd(parseInt('11111', 2)).eq(0); var saturationMask = image.select('QA_RADSAT').eq(0); // Apply the scaling factors to the appropriate bands. var getFactorImg = function(factorNames) { var factorList = image.toDictionary().select(factorNames).values(); return ee.Image.constant(factorList); }; var scaleImg = getFactorImg([ 'REFLECTANCE_MULT_BAND_.|TEMPERATURE_MULT_BAND_ST_B10']); var offsetImg = getFactorImg([ 'REFLECTANCE_ADD_BAND_.|TEMPERATURE_ADD_BAND_ST_B10']); var scaled = image.select('SR_B.|ST_B10').multiply(scaleImg).add(offsetImg); // Replace original bands with scaled bands and apply masks. return image.addBands(scaled, null, true) .updateMask(qaMask).updateMask(saturationMask); } // Make a cloud-free Landsat 8 surface reflectance composite. var input = ee.ImageCollection('LANDSAT/LC08/C02/T1_L2') .filterBounds(roi) .filterDate('2020-03-01', '2020-07-01') .map(prepSrL8) .median() .setDefaultProjection('EPSG:4326', null, 30) .select(['SR_B2', 'SR_B3', 'SR_B4', 'SR_B5', 'SR_B6', 'SR_B7']); // Use MODIS land cover, IGBP classification, for training. var modis = ee.Image('MODIS/006/MCD12Q1/2020_01_01') .select('LC_Type1'); // Sample the input imagery to get a FeatureCollection of training data. var training = input.addBands(modis).sample({ region: roi, numPixels: 5000, seed: 0 }); // Make a Random Forest classifier and train it. var classifier = ee.Classifier.smileRandomForest(10) .train({ features: training, classProperty: 'LC_Type1', inputProperties: ['SR_B2', 'SR_B3', 'SR_B4', 'SR_B5', 'SR_B6', 'SR_B7'] }); // Classify the input imagery. var classified = input.classify(classifier); // Get a confusion matrix representing resubstitution accuracy. var trainAccuracy = classifier.confusionMatrix(); print('Resubstitution error matrix: ', trainAccuracy); print('Training overall accuracy: ', trainAccuracy.accuracy()); // Sample the input with a different random seed to get validation data. var validation = input.addBands(modis).sample({ region: roi, numPixels: 5000, seed: 1 // Filter the result to get rid of any null pixels. }).filter(ee.Filter.notNull(input.bandNames())); // Classify the validation data. var validated = validation.classify(classifier); // Get a confusion matrix representing expected accuracy. var testAccuracy = validated.errorMatrix('LC_Type1', 'classification'); print('Validation error matrix: ', testAccuracy); print('Validation overall accuracy: ', testAccuracy.accuracy()); // Define a palette for the IGBP classification. var igbpPalette = [ 'aec3d4', // water '152106', '225129', '369b47', '30eb5b', '387242', // forest '6a2325', 'c3aa69', 'b76031', 'd9903d', '91af40', // shrub, grass '111149', // wetlands 'cdb33b', // croplands 'cc0013', // urban '33280d', // crop mosaic 'd7cdcc', // snow and ice 'f7e084', // barren '6f6f6f' // tundra ]; // Display the input and the classification. Map.centerObject(roi, 10); Map.addLayer(input.clip(roi), {bands: ['SR_B4', 'SR_B3', 'SR_B2'], min: 0, max: 0.25}, 'landsat'); Map.addLayer(classified.clip(roi), {palette: igbpPalette, min: 0, max: 17}, 'classification');
import ee import geemap.core as geemap
Colab (Python)
# Define a region of interest. roi = ee.Geometry.BBox(-122.93, 36.99, -121.20, 38.16) # Define a function that scales and masks Landsat 8 surface reflectance images. def prep_sr_l8(image): """Scales and masks Landsat 8 surface reflectance images.""" # Develop masks for unwanted pixels (fill, cloud, cloud shadow). qa_mask = image.select('QA_PIXEL').bitwiseAnd(0b1111).eq(0) saturation_mask = image.select('QA_RADSAT').eq(0) # Apply the scaling factors to the appropriate bands. def _get_factor_img(factor_names): factor_list = image.toDictionary().select(factor_names).values() return ee.Image.constant(factor_list) scale_img = _get_factor_img([ 'REFLECTANCE_MULT_BAND_.|TEMPERATURE_MULT_BAND_ST_B10']) offset_img = _get_factor_img([ 'REFLECTANCE_ADD_BAND_.|TEMPERATURE_ADD_BAND_ST_B10']) scaled = image.select('SR_B.|ST_B10').multiply(scale_img).add(offset_img) # Replace original bands with scaled bands and apply masks. return image.addBands(scaled, None, True).updateMask( qa_mask).updateMask(saturation_mask) # Make a cloud-free Landsat 8 surface reflectance composite. input_image = ( ee.ImageCollection('LANDSAT/LC08/C02/T1_L2') .filterBounds(roi) .filterDate('2020-03-01', '2020-07-01') .map(prep_sr_l8) .median() .setDefaultProjection('EPSG:4326', None, 30) .select(['SR_B2', 'SR_B3', 'SR_B4', 'SR_B5', 'SR_B6', 'SR_B7']) ) # Use MODIS land cover, IGBP classification, for training. modis = ee.Image('MODIS/006/MCD12Q1/2020_01_01').select('LC_Type1') # Sample the input imagery to get a FeatureCollection of training data. training = input_image.addBands(modis).sample( region=roi, numPixels=5000, seed=0 ) # Make a Random Forest classifier and train it. classifier = ee.Classifier.smileRandomForest(10).train( features=training, classProperty='LC_Type1', inputProperties=['SR_B2', 'SR_B3', 'SR_B4', 'SR_B5', 'SR_B6', 'SR_B7'], ) # Classify the input imagery. classified = input_image.classify(classifier) # Get a confusion matrix representing resubstitution accuracy. train_accuracy = classifier.confusionMatrix() display('Resubstitution error matrix:', train_accuracy) display('Training overall accuracy:', train_accuracy.accuracy()) # Sample the input with a different random seed to get validation data. validation = ( input_image.addBands(modis) .sample( region=roi, numPixels=5000, seed=1, # Filter the result to get rid of any null pixels. ) .filter(ee.Filter.notNull(input_image.bandNames())) ) # Classify the validation data. validated = validation.classify(classifier) # Get a confusion matrix representing expected accuracy. test_accuracy = validated.errorMatrix('LC_Type1', 'classification') display('Validation error matrix:', test_accuracy) display('Validation overall accuracy:', test_accuracy.accuracy()) # Define a palette for the IGBP classification. igbp_palette = [ 'aec3d4', # water '152106', '225129', '369b47', '30eb5b', '387242', # forest '6a2325', 'c3aa69', 'b76031', 'd9903d', '91af40', # shrub, grass '111149', # wetlands 'cdb33b', # croplands 'cc0013', # urban '33280d', # crop mosaic 'd7cdcc', # snow and ice 'f7e084', # barren '6f6f6f' # tundra ] # Display the input and the classification with geemap in a notebook. m = geemap.Map() m.center_object(roi, 10) m.add_layer( input_image.clip(roi), {'bands': ['SR_B4', 'SR_B3', 'SR_B2'], 'min': 0, 'max': 0.25}, 'landsat', ) m.add_layer( classified.clip(roi), {'palette': igbp_palette, 'min': 0, 'max': 17}, 'classification', ) m
В этом примере используется классификатор случайного леса ( Breiman 2001 ) с 10 деревьями для понижения разрешения данных MODIS до Landsat. Метод sample()
генерирует две случайные выборки из данных MODIS: одну для обучения и одну для проверки. Обучающая выборка используется для обучения классификатора. Точность повторной подстановки на обучающих данных можно получить с помощью classifier.confusionMatrix()
. Чтобы получить точность проверки, классифицируйте данные проверки. Это добавляет свойство classification
к проверочной FeatureCollection
. Вызовите errorMatrix()
для классифицированной FeatureCollection
, чтобы получить матрицу ошибок, представляющую ожидаемую точность проверки.
Проверьте выходные данные и убедитесь, что общая точность, рассчитанная по тренировочным данным, значительно выше, чем по проверочным. Оценка точности, рассчитанная по тренировочным данным, завышена, поскольку случайный лес «подогнан» под тренировочные данные. Ожидаемая точность на неизвестных данных ниже, о чём свидетельствует оценка по проверочным данным.
Вы также можете взять одну выборку и разбить её на наборы признаков с помощью метода randomColumn()
. Продолжим предыдущий пример:
Редактор кода (JavaScript)
var sample = input.addBands(modis).sample({ region: roi, numPixels: 5000, seed: 0 }); // The randomColumn() method will add a column of uniform random // numbers in a column named 'random' by default. sample = sample.randomColumn(); var split = 0.7; // Roughly 70% training, 30% testing. var training = sample.filter(ee.Filter.lt('random', split)); var validation = sample.filter(ee.Filter.gte('random', split));
import ee import geemap.core as geemap
Colab (Python)
sample = input_image.addBands(modis).sample(region=roi, numPixels=5000, seed=0) # The randomColumn() method will add a column of uniform random # numbers in a column named 'random' by default. sample = sample.randomColumn() split = 0.7 # Roughly 70% training, 30% testing. training = sample.filter(ee.Filter.lt('random', split)) validation = sample.filter(ee.Filter.gte('random', split))
Также может потребоваться убедиться, что обучающие выборки не коррелируют с оценочными. Это может быть результатом пространственной автокорреляции прогнозируемого явления. Один из способов исключить выборки, которые могут коррелировать таким образом, — это удалить выборки, находящиеся на некотором расстоянии от других выборок. Это можно сделать с помощью пространственного соединения:
Редактор кода (JavaScript)
// Sample the input imagery to get a FeatureCollection of training data. var sample = input.addBands(modis).sample({ region: roi, numPixels: 5000, seed: 0, geometries: true, tileScale: 16 }); // The randomColumn() method will add a column of uniform random // numbers in a column named 'random' by default. sample = sample.randomColumn(); var split = 0.7; // Roughly 70% training, 30% testing. var training = sample.filter(ee.Filter.lt('random', split)); print('Training size:', training.size()); var validation = sample.filter(ee.Filter.gte('random', split)); // Spatial join. var distFilter = ee.Filter.withinDistance({ distance: 1000, leftField: '.geo', rightField: '.geo', maxError: 10 }); var join = ee.Join.inverted(); // Apply the join. training = join.apply(training, validation, distFilter); print('Training size after spatial filtering:', training.size());
import ee import geemap.core as geemap
Colab (Python)
# Sample the input imagery to get a FeatureCollection of training data. sample = input_image.addBands(modis).sample( region=roi, numPixels=5000, seed=0, geometries=True, tileScale=16 ) # The randomColumn() method will add a column of uniform random # numbers in a column named 'random' by default. sample = sample.randomColumn() split = 0.7 # Roughly 70% training, 30% testing. training = sample.filter(ee.Filter.lt('random', split)) display('Training size:', training.size()) validation = sample.filter(ee.Filter.gte('random', split)) # Spatial join. dist_filter = ee.Filter.withinDistance( distance=1000, leftField='.geo', rightField='.geo', maxError=10 ) join = ee.Join.inverted() # Apply the join. training = join.apply(training, validation, dist_filter) display('Training size after spatial filtering:', training.size())
Обратите внимание, что в предыдущем фрагменте кода значение geometries
в sample()
равно true
. Это необходимо для сохранения пространственной информации о точках выборки, необходимой для пространственного объединения. Также обратите внимание, что значение tileScale
равно 16
Это необходимо для предотвращения ошибки «Превышен лимит пользовательской памяти».
Сохранение классификаторов
Обучение классификатора на большом объёме входных данных в интерактивном режиме может быть невозможным из-за слишком большого объёма входных данных (>99 МБ) или слишком длительного обучения (5 минут). Используйте Export.classifier.toAsset
для пакетного обучения классификатора, что позволит увеличить время обучения и использовать больше памяти. Классификаторы с высокой стоимостью обучения можно экспортировать и перезагружать, чтобы избежать необходимости повторного обучения.
Редактор кода (JavaScript)
// Using the random forest classifier defined earlier, export the random // forest classifier as an Earth Engine asset. var classifierAssetId = 'projects/<PROJECT-ID>/assets/upscaled_MCD12Q1_random_forest'; Export.classifier.toAsset( classifier, 'Saved-random-forest-IGBP-classification', classifierAssetId );
import ee import geemap.core as geemap
Colab (Python)
# Using the random forest classifier defined earlier, export the random # forest classifier as an Earth Engine asset. classifier_asset_id = ( 'projects/<PROJECT-ID>/assets/upscaled_MCD12Q1_random_forest' ) task = ee.batch.Export.classifier.toAsset( classifier, 'Saved-random-forest-IGBP-classification', classifier_asset_id ) task.start()
Чтобы загрузить сохраненный классификатор, используйте алгоритм ee.Classifier.load()
, укажите идентификатор экспортированного классификатора и используйте его так же, как любой другой обученный классификатор.
Редактор кода (JavaScript)
// Once the classifier export finishes, we can load our saved classifier. var savedClassifier = ee.Classifier.load(classifierAssetId); // We can perform classification just as before with the saved classifier now. var classified = input.classify(savedClassifier); Map.addLayer(classified.clip(roi), {palette: igbpPalette, min: 0, max: 17}, 'classification');
import ee import geemap.core as geemap
Colab (Python)
# Once the classifier export finishes, we can load our saved classifier. saved_classifier = ee.Classifier.load(classifier_asset_id) # We can perform classification just as before with the saved classifier now. classified = input_image.classify(saved_classifier) m = geemap.Map() m.center_object(roi, 10) m.add_layer( classified.clip(roi), {'palette': igbp_palette, 'min': 0, 'max': 17}, 'classification', ) m