Classifier
软件包通过在 Earth Engine 中运行的传统机器学习算法处理监督分类。这些分类器包括 CART、RandomForest、NaiveBayes 和 SVM。分类的一般工作流程如下:
- 收集训练数据。组装具有以下属性的特征:一个用于存储已知类标签的属性,以及用于存储预测器的数值的属性。
- 实例化分类器。根据需要设置其参数。
- 使用训练数据训练分类器。
- 对图片或地图项集合进行分类。
- 使用独立验证数据估算分类错误。
训练数据是一个 FeatureCollection
,其中包含一个用于存储类标签的属性和用于存储预测变量的属性。类标签应为从 0 开始的连续整数。如有必要,请使用 remap()
将类值转换为连续的整数。预测因子应为数字。
训练和/或验证数据可以来自各种来源。如需在 Earth Engine 中以交互方式收集训练数据,您可以使用几何图形绘制工具(请参阅“代码编辑器”页面的“几何图形工具”部分)。
或者,您也可以从 Earth Engine 表资产导入预定义的训练数据(如需了解详情,请参阅“导入表格数据”页面)。从 ee.Classifier
中的某个构造函数获取分类器。使用 classifier.train()
训练分类器。使用 classify()
对 Image
或 FeatureCollection
进行分类。以下示例使用分类和回归树 (CART) 分类器 (Breiman 等人,1984) 预测三个简单的类:
Code Editor (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()
确保分类器架构与图片相匹配。
如果训练数据是表示均匀区域的多边形,则每个多边形中的每个像素都是训练点。您可以使用多边形进行训练,如以下示例所示:
Code Editor (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 是使用一组自定义参数指定的。如果没有关于预测问题物理性质的先验信息,则无法确定最佳参数。如需有关为 SVM 选择参数的大致指南,请参阅 Hsu et al. (2003)。
分类器输出模式
ee.Classifier.setOutputMode()
方法用于控制监督式分类结果的格式,可让输出以多种不同的方式进行结构化:
- 分类(默认):输出为类别编号。
- 回归:输出是标准回归的结果。
- PROBABILITY:输出是分类正确的概率。
- MULTIPROBABILITY:输出是一个数组,其中包含每个类正确的概率,按看到的类排序。
- RAW:输出是分类过程的内部表示的数组。例如,多决策树模型中的原始投票结果。
- RAW_REGRESSION:输出是回归过程的内部表示法的数组。例如,多个回归树的原始预测结果。
对这些输出模式的支持因设备而异。下表汇总了每种分类器支持的模式。
分类器 | 分类 | 退化 | 概率 | MULTIPROBABILITY | RAW | 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 分类器配置为输出概率,而不是默认的分类标签:
Code Editor (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
(Stehman 1997)。以下示例使用 sample()
从 MODIS 参照图像生成训练和验证数据,并比较表示训练和验证准确度的混淆矩阵:
Code Editor (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
此示例使用包含 10 个树的随机森林 (Breiman 2001) 分类器将 MODIS 数据下采样为 Landsat 分辨率。sample()
方法会从 MODIS 数据生成两个随机样本:一个用于训练,一个用于验证。训练样本用于训练分类器。
您可以从 classifier.confusionMatrix()
获取训练数据的重新替换准确率。如需获取验证准确性,请对验证数据进行分类。这会向验证 FeatureCollection
添加 classification
属性。对分类后的 FeatureCollection
调用 errorMatrix()
,以获取表示验证(预期)准确性的混淆矩阵。
检查输出,您会发现根据训练数据估算的总体准确性远高于验证数据。从训练数据估算的准确度是过高估计的,因为随机森林会“拟合”训练数据。验证数据的估算结果表明,未知数据的预期准确率较低。
您还可以对地图项集使用 randomColumn()
方法获取单个样本并对其进行分区。继续上例:
Code Editor (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))
您可能还需要确保训练样本与评估样本不相关。这可能是因为所预测现象的空间自相关性。 排除可能以这种方式相关联的样本的一种方法是,移除与任何其他样本相距不远的样本。这可以通过空间联接来实现:
Code Editor (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())
请注意,在上面的代码段中,sample()
中的 geometries
设置为 true
。这是为了保留空间连接所需的样本点的空间信息。另请注意,tileScale
设置为 16
。
这是为了避免出现“用户内存用量超限”错误。
保存分类器
由于输入数据过大(大于 99 MB)或训练时间过长(5 分钟),因此可能无法对大量输入数据交互式地训练分类器。
使用 Export.classifier.toAsset
将分类器训练作为批处理作业运行,这样它就可以使用更多内存,并运行更长时间。您可以导出训练成本较高的分类器并重新加载,以免重新训练。
Code Editor (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`,指定导出的分类器 ID,然后像使用任何其他训练分类器一样使用它。
Code Editor (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