下一章 上一章 目录 设置
7、七识 第1节:通 ...
-
第1节:通过混淆矩阵量化分类精度
我们测试了不同的分类器并对意大利米兰周边地区的陆地卫星图像进行了分类。我们将这个数据集命名为“data ”。该变量是一个特征集合,其特征包含四个土地覆盖/土地利用类别的“类”值(表 F2.2.1)和光谱信息:森林、发达、水和草本。我们还将定义一个变量,predictionBands,这是将用于预测(分类)的波段列表——数据变量中的光谱信息。
表 F2.2.1土地覆盖类别
班级等级值
森林0
发达1
水2
草本3
第一步是将已知值集划分为训练集和测试集,以便分类器能够预测之前未显示过的内容(测试集),模仿模型可能在训练集和测试集中看到的未见过的数据。未来。我们使用randomColumn方法将一列随机数添加到我们的FeatureCollection中。然后,我们使用ee将特征过滤为约80% 用于训练,20%用于测试。过滤。复制并粘贴以下代码以根据随机数对数据进行分区并过滤特征。
// Import the reference dataset.
var data=ee.FeatureCollection(
\'projects/gee-book/assets/F2-2/milan_data\');
// Define the prediction bands.
var predictionBands=[
\'SR_B1\', \'SR_B2\', \'SR_B3\', \'SR_B4\', \'SR_B5\', \'SR_B6\', \'SR_B7\',
\'ST_B10\',
\'ndvi\', \'ndwi\'
];
// Split the dataset into training and testing sets.
var trainingTesting=data.randomColumn();
var trainingSet=trainingTesting
.filter(ee.Filter.lessThan(\'random\', 0.8));
var testingSet=trainingTesting
.filter(ee.Filter.greaterThanOrEquals(\'random\', 0.8));
请注意,randomColumn 以确定性方式创建伪随机数。这使得通过定义种参数(Earth Engine 默认使用种子0)来生成可重现的伪随机序列成为可能。换句话说,给定起始值(即种子),randomColumn 将始终提供相同的伪随机数序列。
复制并粘贴以下代码,使用TrainingSet训练具有50个决策树的随机森林分类器。
// Train the Random Forest Classifier with the trainingSet.
var RFclassifier=ee.Classifier.smileRandomForest(50).train({
features: trainingSet,
classProperty: \'class\',
inputProperties: predictionBands
});
现在,我们来讨论一下什么是混淆矩阵。混淆矩阵通过将预测值与实际值进行比较来描述分类的质量。一个简单的例子是用于二元分类“阳性”和“阴性”的混淆矩阵,如表 F2.2.1 所示。
表 F2.2.1类别为“正”和“负”的二元分类的混淆矩阵
实际值
积极的 消极的
预测值积极的TP (真阳性)FP (误报)
消极的FN (假阴性)TN (真阴性)
在表F2.2.1中,列代表实际值(真相),而行代表预测(分类)。“真阳性”(TP)和“真阴性”(TN)意味着像素的分类与事实相符(例如,水像素被正确分类为水)。“假阳性”(FP)和“假阴性”(FN)意味着像素的分类与真实情况不匹配(例如,非水像素被错误地分类为水)。
?TP:分类为正类,实际类别为正类
?FP:分类为正类,实际类别为负类
?FN:分类为负类,实际类别为正类
?TN:分类为负数,实际类别为负数
我们可以从混淆矩阵中提取一些统计信息。让我们看一个例子来更清楚地说明这一点。表 F2.2.2是分类器 1,000个像素样本的混淆矩阵,用于识别像素是森林(正)还是非森林(负),即二元分类。
表 F2.2.2二元分类的混淆矩阵,其中类别为“正”(森林)和“负”(非森林)
实际值
积极的消极的
预测值积极的30718
消极的14661
在这种情况下,分类器正确识别了307个森林像素,错误地将18个非森林像素分类为森林,正确识别了661个非森林像素,错误地将14个森林像素分类为非森林。因此,分类器正确了968次,错误了32次。让我们计算一下这个例子的主要准确度指标。
总体准确度告诉我们参考数据被正确分类的比例,计算方法为正确识别的像素总数除以样本中的像素总数。
在本例中,使用(计算) 的总体准确率为 96.8%。
另外两个重要的准确度指标是生产者的准确度和用户的准确度,也分别称为“召回率”和“精确度”。重要的是,这些指标量化了每类准确性的各个方面。
制作者的精度是从地图制作者(“制作者”)的角度来看地图的精度,计算方法为给定类别的正确识别像素数除以该类别中实际的像素总数。生产者对给定类别的准确度告诉我们该类别中被正确分类的像素的比例。
在这种情况下,生产者对森林类别的准确度为95.6%(使用)计算。生产者对非森林类别的准确度为97.3%,根据) 计算。
用户准确度(也称为“消费者准确度”)是从地图用户的角度来看地图的准确度,计算公式为:正确识别给定类别的像素数除以所声明的像素总数在那个班级里。用户对给定类别的准确度告诉我们地图上识别为该类别的像素与地面上实际属于该类别的像素的比例。
在本例中,用户对森林类别的准确度为94.5%(使用)计算。用户对非森林类的准确度为97.9%,由)计算得出。
二元分类的混淆矩阵,其中类别为“正”(森林)和“负”(非森林),并具有准确度度量
在解决遥感分类精度问题时,经常谈论两种类型的错误:遗漏错误和委托错误。遗漏错误是指在分类图中被排除在正确类别之外的参考像素。在两级系统中,一类的遗漏错误将被视为另一类的犯错。遗漏错误是对生产者准确性的补充。
委员会错误是指地图中被错误分类的类像素,与用户的准确性相补充。
最后,另一个常用的精度指标是 kappa 系数,它评估分类与随机分类相比的表现如何。kappa 系数的值范围为-1 到 1:负值表示分类效果比随机分配类别差;值为 0 表示分类不比随机分类更好或更差;正值表示分类优于随机。
机会一致性计算为每个类的行和列总计的乘积之和,观察到的准确度是总体准确度。因此,对于我们的示例,kappa 系数为0.927。
现在,让我们回到脚本。在 Earth Engine 中,有用于这些操作的 API 调用。请注意,我们的混淆矩阵将是一个4 x 4表,因为我们有四个不同的类。
复制并粘贴以下代码以对测试集进行分类并使用errorMatrix 方法获取混淆矩阵。请注意,分类器会自动添加一个名为“分类”的属性,该属性与参考数据集的“类”属性进行比较。
// Now, to test the classification (verify model\'s accuracy),
// we classify the testingSet and get a confusion matrix.
var confusionMatrix=testingSet.classify(RFclassifier)
.errorMatrix({
actual: \'class\',
predicted: \'classification\'
});
复制并粘贴下面的代码以打印混淆矩阵和准确性指标。展开混淆矩阵对象来检查它。条目表示像素数。对角线上的项目代表正确的分类。对角线以外的项目是错误分类,其中第i行中的类别被分类为第j列(0 到3的值分别对应于我们的类别代码:森林、发达、水和草本植物)。还要扩展生产者准确率、用户准确率(消费者准确率)、kappa系数对象来考察。
// Print the results.
print(\'Confusion matrix:\', confusionMatrix);
print(\'Overall Accuracy:\', confusionMatrix.accuracy());
print(\'Producers Accuracy:\', confusionMatrix.producersAccuracy());
print(\'Consumers Accuracy:\', confusionMatrix.consumersAccuracy());
print(\'Kappa:\', confusionMatrix.kappa());
第 2节.超参数调整
我们还可以评估随机森林分类器中的树数量如何影响分类精度。复制并粘贴下面的代码以创建一个函数,该函数绘制总体精度与所用树木数量的关系图。该代码以5为增量测试5 到100棵树,生成
// Hyperparameter tuning.
var numTrees=ee.List.sequence(5, 100, 5);
var accuracies=numTrees.map(function(t){
var classifier=ee.Classifier.smileRandomForest(t)
.train({
features: trainingSet,
classProperty: \'class\',
inputProperties: predictionBands
});
return testingSet
.classify(classifier)
.errorMatrix(\'class\', \'classification\')
.accuracy();
});
print(ui.Chart.array.values({
array: ee.Array(accuracies),
axis: 0,
xLabels: numTrees
}).setOptions({
hAxis:{
title: \'Number of trees\'
},
vAxis:{
title: \'Accuracy\'
},
title: \'Accuracy per number of trees\'
}));
第 3 节空间自相关
我们可能还想确保训练集中的样本与测试集中的样本不相关。这可能是由所预测现象的空间自相关造成的。排除可能以这种方式相关的样本的一种方法是移除与任何其他样本在一定距离内的样本。在 Earth Engine 中,这可以通过空间连接来完成。
var trainingTesting = data.randomColumn();
var trainingSet = trainingTesting
.filter(ee.Filter.lessThan(\'random\', 0.8));
var testingSet = trainingTesting
.filter(ee.Filter.greaterThanOrEquals(\'random\', 0.8));
// Spatial join.
var distFilter = ee.Filter.withinDistance({
distance: 1000,
leftField: \'.geo\',
rightField: \'.geo\',
maxError: 10
});
var join = ee.Join.inverted();
var trainingSet = join.apply(trainingSet, testingSet, distFilter);
// Train the Random Forest Classifier with the trainingSet.
var RFclassifier = ee.Classifier.smileRandomForest(50).train({
features: trainingSet,
classProperty: \'class\',
inputProperties: predictionBands
});
// Now, to test the classification (verify model\'s accuracy),
// we classify the testingSet and get a confusion matrix.
var confusionMatrix = testingSet.classify(RFclassifier)
.errorMatrix({
actual: \'class\',
predicted: \'classification\'
});
// Print the results.
print(\'Confusion matrix:\', confusionMatrix);
print(\'Overall Accuracy:\', confusionMatrix.accuracy());
print(\'Producers Accuracy:\', confusionMatrix.producersAccuracy());
print(\'Consumers Accuracy:\', confusionMatrix.consumersAccuracy());
print(\'Kappa:\', confusionMatrix.kappa());