طبقه‌بندی تحت‌نظارت

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

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

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

داده‌های آموزشی و/یا اعتبارسنجی می‌تواند از منابع مختلفی به‌دست آید. برای جمع‌آوری تعاملی داده‌های آموزشی در Earth Engine، می‌توانید از ابزارهای رسم هندسی استفاده کنید (بخش ابزارهای هندسی صفحه «ویرایشگر کد» را ببینید). یا می‌توانید داده‌های آموزشی ازپیش تعریف‌شده را از دارایی جدول Earth Engine وارد کنید (برای جزئیات، صفحه وارد کردن داده‌های جدول را ببینید). طبقه‌بندی‌کننده‌ای را از یکی از سازنده‌ها در ee.Classifier دریافت کنید. آموزش دادن طبقه‌بندی‌کننده بااستفاده از classifier.train(). طبقه‌بندی Image یا FeatureCollection بااستفاده از classify(). مثال زیر از طبقه‌بندی‌کننده «درخت‌های طبقه‌بندی و رگرسیون» (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');

راه‌اندازی Python

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

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') اعداد صحیح متوالی را که از ۰ شروع می‌شوند ذخیره می‌کند (درصورت لزوم، از 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');

راه‌اندازی Python

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

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

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

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

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

راه‌اندازی Python

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

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 استفاده می‌کند و ماتریس‌های درهم‌ریختگی را که نشان‌دهنده دقت آموزش و اعتبارسنجی هستند مقایسه می‌کند:

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

// 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/061/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 = [
  '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
  'aec3d4'  // water
];

// 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: 1, max: 17},
             'classification');

راه‌اندازی Python

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

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/061/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 = [
    '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
    'aec3d4'   # water
]

# 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': 1, 'max': 17},
    'classification',
)
m

این نمونه از طبقه‌بندی‌کننده جنگل تصادفی (Breiman 2001) با ۱۰ درخت برای کاهش مقیاس داده‌های 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));

راه‌اندازی Python

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

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

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

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

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

راه‌اندازی Python

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

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 روی true در sample() تنظیم شده است. این کار برای حفظ اطلاعات فضایی نقاط نمونه موردنیاز برای پیوستن فضایی است. همچنین توجه داشته باشید که tileScale روی 16 تنظیم شده است. این کار برای جلوگیری از خطای «از حد مجاز حافظه کاربر بیشتر است» انجام می‌شود.

درحال ذخیره کردن طبقه‌بندی‌کننده‌ها

آموزش دادن طبقه‌بندی‌کننده روی مقدار زیادی داده ورودی ممکن است به‌صورت تعاملی امکان‌پذیر نباشد زیرا ورودی خیلی بزرگ است (بیش‌از ۹۹ مگابایت) یا آموزش دادن خیلی طول می‌کشد (۵ دقیقه). از 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
);

راه‌اندازی Python

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

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

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

// 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: 1, max: 17},
             'classification');

راه‌اندازی Python

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

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': 1, 'max': 17},
    'classification',
)
m