Google Earth Engine(GEE)——机器学习土地分类中出现错误No valid training data were found.

我想使用 svm 算法对甘蔗进行分类。但是训练数据是错误的。

https://code.earthengine.google.com/5114e5fff3fd0d0294f6a3aef9c4037a

Test Accuracy:

Number (Error)

No valid training data were found.

函数:

ee.Classifier.libsvm(decisionProceduresvmTypekernelTypeshrinkingdegreegammacoef0costnuterminationEpsilonlossEpsilononeClass)

Creates an empty Support Vector Machine classifier.

Arguments:

decisionProcedure (String, default: "Voting"):

The decision procedure to use for classification. Either 'Voting' or 'Margin'. Not used for regression.

svmType (String, default: "C_SVC"):

The SVM type. One of C_SVCNU_SVCONE_CLASSEPSILON_SVR or NU_SVR.

kernelType (String, default: "LINEAR"):

The kernel type. One of LINEAR (u′×v), POLY ((γ×u′×v + coef₀)ᵈᵉᵍʳᵉᵉ), RBF (exp(-γ×|u-v|²)) or SIGMOID (tanh(γ×u′×v + coef₀)).

shrinking (Boolean, default: true):

Whether to use shrinking heuristics.

degree (Integer, default: null):

The degree of polynomial. Valid for POLY kernels.

gamma (Float, default: null):

The gamma value in the kernel function. Defaults to the reciprocal of the number of features. Valid for POLY, RBF and SIGMOID kernels.

coef0 (Float, default: null):

The coef₀ value in the kernel function. Defaults to 0. Valid for POLY and SIGMOID kernels.

cost (Float, default: null):

The cost (C) parameter. Defaults to 1. Only valid for C-SVC, epsilon-SVR, and nu-SVR.

nu (Float, default: null):

The nu parameter. Defaults to 0.5. Only valid for nu-SVC, one-class SVM, and nu-SVR.

terminationEpsilon (Float, default: null):

The termination criterion tolerance (e). Defaults to 0.001. Only valid for epsilon-SVR.

lossEpsilon (Float, default: null):

The epsilon in the loss function (p). Defaults to 0.1. Only valid for epsilon-SVR.

oneClass (Integer, default: null):

The class of the training data on which to train in a one-class SVM. Defaults to 0. Only valid for one-class SVM. Possible values are 0 and 1. The classifier output is binary (0/1) and will match this class value for the data determined to be in the class.

Returns: Classifier

主程序:

// Define the study area
var geometry = WilayahStudi; // Provide the coordinates of your study area

// Function to mask clouds and shadows in Sentinel-2 imagery
function maskS2clouds(image) {
  var qa = image.select('QA60');
  var cloudBitMask = 1 << 10;
  var cirrusBitMask = 1 << 11;
  var mask = qa.bitwiseAnd(cloudBitMask).eq(0)
      .and(qa.bitwiseAnd(cirrusBitMask).eq(0));
  return image.updateMask(mask).divide(10000); // Scale the image bands to the range [0, 1]
}

// Filter Sentinel-2 imagery
var S2A = ee.ImageCollection('COPERNICUS/S2_SR')
  .filterDate('2022-01-01', '2022-08-01')
  .filter(ee.Filter.lt('CLOUDY_PIXEL_PERCENTAGE', 5))
  .filterBounds(geometry)
  .map(maskS2clouds)
  .median()
  .clip(geometry);

// Display the RGB image
var RGBTrue = S2A.select(['B4', 'B3', 'B2']);
var RGBparam = { min: 0, max: 1, bands: ['B4', 'B3', 'B2'] };
Map.addLayer(RGBTrue, RGBparam, 'Sentinel RGB 432');

// Function to add vegetation indices to the image
var addIndicesS2A = function(img) {
  var nir = S2A.select('B8');
  var red = S2A.select('B4');
  
  // Compute NDVI
  var NDVI = nir.subtract(red).divide(nir.add(red)).rename('NDVI');
  var NDVIparam = { min: -1, max: 1, palette: ['blue', 'white', 'green'] };
  Map.addLayer(NDVI, NDVIparam, 'NDVI');
  
  // Compute WDVI
  var WDVI = nir.subtract(red).divide(nir.add(red)).rename('WDVI');
  var WDVIparam = { min: -1, max: 1, palette: ['red', 'green', 'blue'] };
  Map.addLayer(WDVI, WDVIparam, 'WDVI');
  
  // Compute EVI
  var EVI = nir.subtract(red).multiply(2.5).divide(nir.add(red).add(6)).rename('EVI');
  var EVIparam = { min: -1, max: 1, palette: ['red', 'white', 'green'] };
  Map.addLayer(EVI, EVIparam, 'EVI');
  
  // Compute NDRE
  var NDRE = nir.subtract(S2A.select('B5')).divide(nir.add(S2A.select('B5'))).rename('NDRE');
  var NDREparam = { min: -1, max: 1, palette: ['black', 'white', 'blue'] };
  Map.addLayer(NDRE, NDREparam, 'NDRE');
  
  // Compute MSAVI
  var MSAVI = nir.subtract(red).multiply(2).add(1).subtract(nir.subtract(red).multiply(2).add(1)
    .pow(2).subtract(nir.subtract(red).multiply(8)).sqrt()).divide(2).rename('MSAVI');
  var MSAVIparam = { min: -1, max: 1, palette: ['black', 'white', 'blue'] };
  Map.addLayer(MSAVI, MSAVIparam, 'MSAVI');
  
  return img
    .addBands(NDVI)
    .addBands(WDVI)
    .addBands(EVI)
    .addBands(NDRE)
    .addBands(MSAVI);
};

// Add vegetation indices to the image
S2A = addIndicesS2A(S2A);

// Load training and testing samples
var classes = Tebu21.merge(NonTebu211);
var bands = ['B2', 'B3', 'B4', 'B5', 'B6', 'B7', 'NDVI', 'WDVI', 'EVI', 'NDRE', 'MSAVI'];

var samples = S2A.select(bands).sampleRegions({
  collection: classes,
  properties: ['landcover'],
  scale: 30,
});

// Split the data into training and testing datasets
var split = 0.8;
var training = samples.filter(ee.Filter.lt('random', split));
var testing = samples.filter(ee.Filter.gte('random', split));

// Train the Support Vector Machine (SVM) classifier
var classifier = ee.Classifier.libsvm().train({
  features: training,
  classProperty: 'landcover',
  inputProperties: bands,
});

// Perform classification on the testing dataset
var classified = testing.classify(classifier);

// Print the accuracy of the classifier
var testAccuracy = classified.errorMatrix('landcover', 'classification').accuracy();
print('Test Accuracy:', testAccuracy);

// Display the classified image
var classPalette = ['red', 'green']; // Define the class colors
Map.addLayer(classified, { min: 0, max: 1, palette: classPalette }, 'Land Cover Classification');

这里的主要问题不是在训练样本点,而是在于我们添加的给雷指数并没有通过函数正确的加载,当我们需要进行函数加载的时候,我们要用函数添加波段,并正确使用计算公式,从而作为一个波段添加到影像中。

最终结果:

Confusion Matrix 2022

JSON

[[0,17,0],[0,37,0],[0,7,0]]


JSON

kappa2022

0


JSON

Test Accuracy2022

0.6065573770491803


JSON

consumers Accuracy 2022

JSON

[[0,0.6065573770491803,0]]


JSON

producers Accuracy 2022

JSON

[[0],[1],[0]]

我提供一个代码案例:



function maskS2clouds(image) {
  var qa = image.select('QA60');

  // Bits 10 and 11 are clouds and cirrus, respectively.
  var cloudBitMask = 1 << 10;
  var cirrusBitMask = 1 << 11;

  // Both flags should be set to zero, indicating clear conditions.
  var mask = qa.bitwiseAnd(cloudBitMask).eq(0)
      .and(qa.bitwiseAnd(cirrusBitMask).eq(0));

  return image.updateMask(mask).divide(10000);
}

function maskCloudAndShadowsSR(image) {
  var cloudProb = image.select('MSK_CLDPRB');
  var snowProb = image.select('MSK_SNWPRB');
  var cloud = cloudProb.lt(60);
  var scl = image.select('SCL'); 
  var shadow = scl.eq(3); // 3 = cloud shadow
  var cirrus = scl.eq(10); // 10 = cirrus
  // 云层概率小于10%或云影分类
  var mask = cloud.and(cirrus.neq(1)).and(shadow.neq(1));
  return image.updateMask(mask)//.divide(10000)
    .copyProperties(image, ['system:time_start']);
}


function renameS2_SR(img) {
  return img.select(
		["B2",  "B3",  "B4",  "B8",  "B11",  "B12",'QA60'],
		['Blue', 'Green', 'Red', 'NIR', 'SWIR1', 'SWIR2', 'QA_PIXEL']);
}


function calVI(img) {
  var ndvi = img.normalizedDifference(['NIR', 'Red']).rename('NDVI');
  
//Mcfeeters 1996
  var ndwi=img.normalizedDifference(["Green", "NIR"]).rename("NDWI");
  
var ndbi=img.normalizedDifference(["SWIR1", "NIR"]).rename("NDBI");

  var rvi = img.expression(  'NIR / RED ', 
  {  
      'NIR': img.select("NIR"),  
      'RED': img.select("Red")
  }).rename('RVI'); 
  
  
  var dvi = img.expression(  'NIR - RED ', 
  {  
      'NIR': img.select('NIR'),  
      'RED': img.select('Red')
  }).rename('DVI');  

            
  return img.addBands(ndvi).addBands(ndwi).addBands(ndbi).addBands(rvi).addBands(dvi);
}

function performClassification(image, gcp, year) {
//获取随机森林列表
  var gcp = gcp.randomColumn();
//获取训练样本和验证样本
  var trainingGcp = gcp.filter(ee.Filter.lt('random', 0.7));
  var validationGcp = gcp.filter(ee.Filter.gte('random', 0.7));
  
  // 将点叠加在图像上得到训练数据
  var training = image.sampleRegions({
    collection: trainingGcp,
    properties: ['landcover'], //训练属性名称
    scale: 30,
    tileScale: 1 //聚合方式
  });
  
  // 训练分类器,将随机森林样本选择为50
  var classifier = ee.Classifier.libsvm()
  .train({
    features: training,  
    classProperty: 'landcover',
    inputProperties: image.bandNames() //输入的属性
  });
  
  // 对图像进行分类,应用训练分类的结果
  var classified = image.classify(classifier);
  var palette = ["#059c31","#070bff","#ecff46","#07ff94","#ff0d0d","#ff8d00","#060300"]
// 加载影像分了结果
  Map.addLayer(classified, {min: 0, max: 6, palette: palette}, year.toString());
  
  Export.image.toAsset({
		image:classified,
	description:year+"classified",
//	assetId:,
//	pyramidingPolicy:,
//	dimensions:,
//	region:,
	scale:100,
//	crs:,
//	crsTransform:,
	maxPixels:1e13,
//	shardSize:,
})
  
// 使用分类图,使用上面创建的整个训练集的验证分数来评估准确性。
  var test = classified.sampleRegions({
    collection: validationGcp, //验证进行评估
    properties: ['landcover'],
    tileScale: 1,
    scale: 30,
  });
  
// 进行混淆矩阵进行分析
  var testConfusionMatrix = test.errorMatrix('landcover', 'classification')
// 混淆矩阵的打印可能会超时。或者,您可以将其导出为 CSV
  print('Confusion Matrix ' + year, testConfusionMatrix);
  print('kappa' + year, testConfusionMatrix.kappa());
  print('Test Accuracy' + year, testConfusionMatrix.accuracy());
//  print('Returns the name and order of the rows and columns of the matrix: order() ' + year, testConfusionMatrix.order());
  print('consumers Accuracy ' + year, testConfusionMatrix.consumersAccuracy());
  print('producers Accuracy ' + year, testConfusionMatrix.producersAccuracy());
  }


var S2A = ee.ImageCollection('COPERNICUS/S2_SR')
                  .filterDate('2022-06-01', '2022-08-31')
                  .filterBounds(roi1)
                  .filter(ee.Filter.lt('CLOUDY_PIXEL_PERCENTAGE',20))
                  .map(maskS2clouds).map(renameS2_SR).map(calVI).median().clip(roi1);

// Load training and testing samples
var training = Tebu21.merge(NonTebu211).merge(NonTebu21);
//var bands = ['B2', 'B3', 'B4', 'B5', 'B6', 'B7', 'NDVI', 'WDVI', 'EVI', 'NDRE', 'MSAVI'];


performClassification(S2A, training, 2022)

猜你喜欢

转载自blog.csdn.net/qq_31988139/article/details/131011915
今日推荐