LXX
读完需要
速读仅需 1 分钟
前言:
分类是地学和环境科学领域中的一个重要任务,它有助于我们理解和监测各类地物,如农业、林业、城市发展等方面。本文分享三种分类方法并对分类后的结果进行统计。
希望各位同学点个关注,点个小赞,这将是更新的动力,不胜感激❥(^_-)
1
1.1
决策树分类
CART 是一种决策树算法,可以用于分类和回归任务。CART 分类树的基本思想是通过递归地分割数据集,直到满足某些终止条件为止。具体包括:
(1)树的构建:
从根节点开始,选择一个特征及其分割点,将数据集分成两个子集。分割点的选择基于某种准则,如基尼指数(Gini Index)或信息增益(Information Gain),以最大化子集的纯度。对每个子集重复上述步骤,继续分割,直到达到停止条件,如最小节点大小或最大树深度。
(2)基尼指数:
基尼指数用于衡量节点的纯度,公式如下:
其中
(3)树的剪枝:
构建完树后,可能会产生过拟合,需要对树进行剪枝。剪枝通过删除某些不重要的节点,减少树的复杂度,提高模型的泛化能力。常见的剪枝方法包括预剪枝(pre-pruning)和后剪枝(post-pruning)。
(4)预测:
对于新的样本,从根节点开始,依次根据样本的特征值进行决策,直到到达叶节点。叶节点的类别标签作为最终的预测结果。
1.2
随机森林分类
随机森林(Random Forest)是一种集成学习方法,通过构建多个决策树并结合其预测结果来进行分类。具体包括:
(1)样本和特征随机化:
每棵树使用不同的训练样本,通过自助法(bootstrap)从原始数据集中有放回地抽样。在每个节点的分割过程中,随机选择特征的子集,以增加模型的多样性。
(2)树的构建:
构建每棵树时,使用与 CART 类似的方法,递归地分割数据集。不同于单一决策树,随机森林在每个节点上只考虑随机选择的特征子集。
(3)预测:
对于新的样本,随机森林中的每棵树都会给出一个预测结果。最终的预测结果通过所有树的投票(分类任务)或平均值(回归任务)来确定。优势:
通过集成多个模型,随机森林能够降低单一决策树的过拟合风险,提高预测的准确性和鲁棒性。它还提供了特征重要性评估的能力,帮助识别对预测最重要的特征。
1.3
支持向量机分类
支持向量机(Support Vector Machine,SVM)是一种常用的机器学习算法,主要用于分类和回归问题。SVM 的目标是找到一个最优的超平面,将不同类别的样本点分隔开来,使得两个类别的间隔最大化。具体来说,SVM 通过寻找支持向量(即距离超平面最近的样本点),确定决策边界,并根据支持向量的位置进行分类。
具体包括:数据准备,收集并准备用于训练的数据集,确保数据集包含标记好的样本点。特征选择,根据问题的特点选择合适的特征,并对特征进行预处理(如归一化、标准化等)。模型训练,利用训练数据集,通过优化算法找到最优的超平面,使得间隔最大化。模型评估,使用测试数据集评估模型的性能,通常使用准确率、精确率、召回率等指标进行评估。模型调优,根据评估结果,调整模型参数或选择合适的核函数,以提高模型的性能。模型应用,使用训练好的模型对新样本进行分类或回归预测。
2
// 加载数据
var forest = ee.Image("users/geestudy2/forest");
Map.centerObject(forest, 20);
// 计算植被指数并将其作为新波段添加到图像中
var NDVI = forest.normalizedDifference(['b4', 'b1']).rename('NDVI');
var ReCI = forest.expression('(NIR / RED) - 1', {
'NIR': forest.select('b4'),
'RED': forest.select('b1')
}).rename('ReCI');
var NDRE = forest.normalizedDifference(['b4', 'b5']).rename('NDRE');
var MSAVI = forest.expression(
'(2 * NIR + 1 - sqrt((2 * NIR + 1) ** 2 - 8 * (NIR - RED))) / 2', {
'NIR': forest.select('b4'),
'RED': forest.select('b1')
}).rename('MSAVI');
var GNDVI = forest.normalizedDifference(['b4', 'b2']).rename('GNDVI');
var SIPI = forest.expression(
'(NIR - BLUE) / (NIR - RED)', {
'NIR': forest.select('b4'),
'BLUE': forest.select('b3'),
'RED': forest.select('b1')
}).rename('SIPI');
// 创建用于分类的波段栈
var stack = forest.addBands([NDVI, ReCI, NDRE, MSAVI, GNDVI, SIPI]);
// 定义可视化的颜色调色板
var palette = ['blue', 'white', 'green', 'red', 'yellow', 'purple'];
// 显示RGB复合图像和指数
Map.addLayer(forest.select(['b1', 'b2', 'b3']), {min: 0, max: 0.3}, 'RGB');
var indicesLayers = {
'NDVI': NDVI,
'ReCI': ReCI,
'NDRE': NDRE,
'MSAVI': MSAVI,
'GNDVI': GNDVI,
'SIPI': SIPI
};
for (var index in indicesLayers) {
Map.addLayer(indicesLayers[index], {min: -1, max: 1, palette: palette}, index);
}
// 合并不同土地覆盖类型的样本点到一个 FeatureCollection
var samplePoints = Road.merge(Land).merge(Good_Forest)
.merge(Bad_Forest).merge(Glass).merge(Other);
// 将 'landcover' 从字符串转换为整数
var convertedSamplePoints = samplePoints.map(function(feature) {
// 获取 landcover 值
var landcover = feature.get('landcover');
// 检查 landcover 是否为非空字符串;如果不是,则设置为默认值(例如 null)
var landcoverNumber = ee.Algorithms.If(
ee.String(landcover).trim().length().gt(0),
ee.Number.parse(landcover),
null // 如果无效,则设置为 null
);
return feature.set('landcover', landcoverNumber);
});
// 在采样前过滤掉无效(null)的 landcover 值
var filteredSamplePoints = convertedSamplePoints.filter(ee.Filter.notNull(['landcover']));
// 使用过滤后的样本点对波段栈进行采样
var trainingRegions = stack.sampleRegions({
collection: filteredSamplePoints,
properties: ['landcover'],
});
// 随机化集合并分割为训练和验证数据集
trainingRegions = trainingRegions.randomColumn();
var training = trainingRegions.filter(ee.Filter.lt('random', 0.7));
var validation = trainingRegions.filter(ee.Filter.gte('random', 0.7));
// 训练 CART、随机森林和 SVM 分类器
var cartClassifier = ee.Classifier.smileCart().train({
features: training,
classProperty: 'landcover',
inputProperties: stack.bandNames()
});
var rfClassifier = ee.Classifier.smileRandomForest(40).train({
features: training,
classProperty: 'landcover',
inputProperties: stack.bandNames()
});
var svmClassifier = ee.Classifier.libsvm({
kernelType: 'RBF',
gamma: 0.5,
cost: 10
}).train({
features: training,
classProperty: 'landcover',
inputProperties: stack.bandNames()
});
// 使用训练好的分类器进行分类
var classifiedCart = stack.classify(cartClassifier);
var classifiedRf = stack.classify(rfClassifier);
var classifiedSvm = stack.classify(svmClassifier);
// 评估每个分类器的准确性
var validationClassifiedCart = validation.classify(cartClassifier);
var cartConfusionMatrix = validationClassifiedCart.errorMatrix('landcover', 'classification');
var cartAccuracy = cartConfusionMatrix.accuracy();
var validationClassifiedRF = validation.classify(rfClassifier);
var rfConfusionMatrix = validationClassifiedRF.errorMatrix('landcover', 'classification');
var rfAccuracy = rfConfusionMatrix.accuracy();
var validationClassifiedSVM = validation.classify(svmClassifier);
var svmConfusionMatrix = validationClassifiedSVM.errorMatrix('landcover', 'classification');
var svmAccuracy = svmConfusionMatrix.accuracy();
var cartKappa = cartConfusionMatrix.kappa();
var rfKappa = rfConfusionMatrix.kappa();
var svmKappa = svmConfusionMatrix.kappa();
// 打印 CART 分类器的准确性和 Kappa 系数
print('CART 混淆矩阵:', cartConfusionMatrix);
print('CART 准确性:', cartAccuracy);
print('CART Kappa 系数:', cartKappa);
print('随机森林 混淆矩阵:', rfConfusionMatrix);
print('随机森林 准确性:', rfAccuracy);
print('随机森林 Kappa 系数:', rfKappa);
print('SVM 混淆矩阵:', svmConfusionMatrix);
print('SVM 准确性:', svmAccuracy);
print('SVM Kappa 系数:', svmKappa);
// 显示分类结果
Map.addLayer(classifiedCart, {min: 0, max: 5, palette: palette}, 'CART 分类结果');
Map.addLayer(classifiedRf, {min: 0, max: 5, palette: palette}, '随机森林 分类结果');
Map.addLayer(classifiedSvm, {min: 0, max: 5, palette: palette}, 'SVM 分类结果');
print(classifiedSvm);
// 将地图缩放到森林对象
Map.centerObject(forest, 10);
// 导出 CART 分类结果
Export.image.toDrive({
image: classifiedCart,
description: 'CART_Classification',
scale: forest.projection().nominalScale(), // 假设 forest 是原始图像
region: forest.geometry(),
maxPixels: 1e13
});
// 类似地导出随机森林和 SVM 分类结果
// 计算面积并绘制图表
// 计算每个像素的面积
var classNames = ['Road', 'Land', 'Good_Forest', 'Bad_Forest', 'Glass', 'Other'];
var pixelArea = ee.Image.pixelArea();
// 计算每个类别的面积
var classValues = ee.List.sequence(0, 5); // 创建一个从 0 到 5 的列表,对应各个类别
var classAreas = ee.List(classValues.map(function(classValue) {
classValue = ee.Number(classValue); // 将类别值转换为数字
var masked = pixelArea.updateMask(classifiedSvm.eq(classValue)); // 将图像遮罩为该类别
return masked.reduceRegion({
reducer: ee.Reducer.sum(),
geometry: forest.geometry(),
scale: forest.projection().nominalScale(), // 假设 forest 是原始图像
maxPixels: 1e9
}).getNumber('area');
}));
// 将面积结果转换为 FeatureCollection 用于图表
var areasList = classAreas.zip(classNames).map(function(info) {
var infoList = ee.List(info);
var area = ee.Number(infoList.get(0));
var label = ee.String(infoList.get(1));
return ee.Feature(null, {'label': label, 'area': area});
});
// 转换为 FeatureCollection
var chartFeatures = ee.FeatureCollection(areasList);
// 创建图表
// 现在这个图表会使用从 classifiedSvm 自动计算得到的面积数据
// 创建条形图
var barChart = ui.Chart.feature.byFeature(chartFeatures, 'label', 'area')
.setChartType('ColumnChart')
.setOptions({
title: '各类别面积',
hAxis: {title: '类别'},
vAxis: {title: '面积(平方米)'},
legend: {position: 'none'},
bar: {groupWidth: '60%'}
});
// 创建饼状图
var pieChart = ui.Chart.feature.byFeature(chartFeatures, 'label', 'area')
.setChartType('PieChart')
.setOptions({
title: '各类别面积比例',
sliceVisibilityThreshold: 0 // 显示所有类别,即使面积非常小
});
// 显示图表
print(barChart);
print(pieChart);
3
后续开始补之前留下的ICESat-2水深反演......