طبقه بندی نظارت شده

بسته Classifier طبقه‌بندی نظارت شده توسط الگوریتم‌های سنتی ML را که در Earth Engine اجرا می‌شوند، کنترل می‌کند. این طبقه‌بندی‌کننده‌ها عبارتند از CART، RandomForest، NaiveBayes و SVM. گردش کار کلی برای طبقه بندی به شرح زیر است:

  1. جمع آوری داده های آموزشی ویژگی هایی را جمع آوری کنید که دارای یک ویژگی هستند که برچسب کلاس شناخته شده را ذخیره می کند و ویژگی هایی که مقادیر عددی را برای پیش بینی کننده ها ذخیره می کند.
  2. نمونه سازی یک طبقه بندی کننده در صورت لزوم پارامترهای آن را تنظیم کنید.
  3. با استفاده از داده های آموزشی، طبقه بندی کننده را آموزش دهید.
  4. دسته بندی یک تصویر یا مجموعه ویژگی
  5. خطای طبقه بندی را با داده های اعتبارسنجی مستقل تخمین بزنید.

داده های آموزشی یک FeatureCollection است که دارای یک ویژگی است که برچسب کلاس را ذخیره می کند و خصوصیات متغیرهای پیش بینی کننده را ذخیره می کند. برچسب های کلاس باید متوالی باشند، اعداد صحیح از 0 شروع می شوند. در صورت لزوم، از remap() برای تبدیل مقادیر کلاس به اعداد صحیح متوالی استفاده کنید. پیش بینی کننده ها باید عددی باشند.

داده‌های آموزشی و/یا اعتبارسنجی می‌توانند از منابع مختلفی به دست آیند. برای جمع‌آوری داده‌های آموزشی به صورت تعاملی در Earth Engine، می‌توانید از ابزارهای ترسیم هندسه استفاده کنید ( به بخش ابزارهای هندسه صفحه ویرایش کد مراجعه کنید). همچنین، می‌توانید داده‌های آموزشی از پیش تعریف‌شده را از دارایی جدول Earth Engine وارد کنید (برای جزئیات به صفحه وارد کردن داده‌های جدول مراجعه کنید). یک طبقه بندی کننده از یکی از سازنده های ee.Classifier دریافت کنید. با استفاده از classifier.train() طبقه بندی کننده را آموزش دهید. با استفاده از classify() یک Image یا FeatureCollection را طبقه بندی کنید. مثال زیر از طبقه‌بندی‌کننده درختان طبقه‌بندی و رگرسیون (CART) ( Breiman et al. 1984 ) برای پیش‌بینی سه کلاس ساده استفاده می‌کند:

ویرایشگر کد (جاوا اسکریپت)

// 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');

راه اندازی پایتون

برای اطلاعات در مورد API پایتون و استفاده از geemap برای توسعه تعاملی به صفحه محیط پایتون مراجعه کنید.

import ee
import geemap.core as geemap

کولب (پایتون)

# 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() استفاده کنید تا مطمئن شوید که طرح طبقه بندی کننده با تصویر مطابقت دارد.

اگر داده های آموزشی چند ضلعی هستند که مناطق همگن را نشان می دهند، هر پیکسل در هر چند ضلعی یک نقطه آموزشی است. همانطور که در مثال زیر نشان داده شده است می توانید از چند ضلعی برای آموزش استفاده کنید:

ویرایشگر کد (جاوا اسکریپت)

// 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');

راه اندازی پایتون

برای اطلاعات در مورد API پایتون و استفاده از geemap برای توسعه تعاملی به صفحه محیط پایتون مراجعه کنید.

import ee
import geemap.core as geemap

کولب (پایتون)

# 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 را در بلوک کد قبلی برای خروجی احتمالی به جای برچسب‌های طبقه‌بندی پیش‌فرض پیکربندی کنید:

ویرایشگر کد (جاوا اسکریپت)

var classifier = ee.Classifier.libsvm({
  kernelType: 'RBF',
  gamma: 0.5,
  cost: 10
}).setOutputMode('PROBABILITY');

var trained = classifier.train(training, 'class', bands);

راه اندازی پایتون

برای اطلاعات در مورد API پایتون و استفاده از geemap برای توسعه تعاملی به صفحه محیط پایتون مراجعه کنید.

import ee
import geemap.core as geemap

کولب (پایتون)

classifier = ee.Classifier.libsvm(
    kernelType='RBF', gamma=0.5, cost=10
).setOutputMode('PROBABILITY')

trained = classifier.train(training, 'class', bands)

ارزیابی دقت

برای ارزیابی دقت طبقه‌بندی‌کننده، از ConfusionMatrix استفاده کنید ( Stehman 1997 ). مثال زیر از sample() برای تولید داده‌های آموزشی و اعتبارسنجی از تصویر مرجع MODIS استفاده می‌کند و ماتریس‌های سردرگمی را که نشان‌دهنده دقت آموزشی و اعتبارسنجی هستند، مقایسه می‌کند:

ویرایشگر کد (جاوا اسکریپت)

// 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');

راه اندازی پایتون

برای اطلاعات در مورد API پایتون و استفاده از geemap برای توسعه تعاملی به صفحه محیط پایتون مراجعه کنید.

import ee
import geemap.core as geemap

کولب (پایتون)

# 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() در مجموعه‌های ویژگی پارتیشن بندی کنید. ادامه مثال قبل:

ویرایشگر کد (جاوا اسکریپت)

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

راه اندازی پایتون

برای اطلاعات در مورد API پایتون و استفاده از geemap برای توسعه تعاملی به صفحه محیط پایتون مراجعه کنید.

import ee
import geemap.core as geemap

کولب (پایتون)

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))

همچنین ممکن است بخواهید اطمینان حاصل کنید که نمونه های آموزشی با نمونه های ارزیابی ارتباطی ندارند. این ممکن است ناشی از خودهمبستگی فضایی پدیده پیش‌بینی‌شده باشد. یکی از راه‌های حذف نمونه‌هایی که ممکن است به این روش همبستگی داشته باشند، حذف نمونه‌هایی است که در فاصله‌ای با هر نمونه (های) دیگری هستند. این را می توان با اتصال فضایی انجام داد:

ویرایشگر کد (جاوا اسکریپت)

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

راه اندازی پایتون

برای اطلاعات در مورد API پایتون و استفاده از geemap برای توسعه تعاملی به صفحه محیط پایتون مراجعه کنید.

import ee
import geemap.core as geemap

کولب (پایتون)

# 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 برای اجرای آموزش طبقه بندی کننده به عنوان یک کار دسته ای استفاده کنید، جایی که می تواند برای مدت طولانی تری با حافظه بیشتر اجرا شود. طبقه‌بندی‌کننده‌های گران قیمت را می‌توان صادر کرد و مجدداً بارگیری کرد تا از نیاز به آموزش مجدد جلوگیری شود.

ویرایشگر کد (جاوا اسکریپت)

// 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
);

راه اندازی پایتون

برای اطلاعات در مورد API پایتون و استفاده از geemap برای توسعه تعاملی به صفحه محیط پایتون مراجعه کنید.

import ee
import geemap.core as geemap

کولب (پایتون)

# 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» استفاده کنید، شناسه طبقه‌بندی‌کننده صادر شده را مشخص کنید و از آن مانند هر طبقه‌بندی‌کننده آموزش‌دیده دیگری استفاده کنید.

ویرایشگر کد (جاوا اسکریپت)

// 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');

راه اندازی پایتون

برای اطلاعات در مورد API پایتون و استفاده از geemap برای توسعه تعاملی به صفحه محیط پایتون مراجعه کنید.

import ee
import geemap.core as geemap

کولب (پایتون)

# 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