1. GEE机器学习遥感分类实战:从数据到结果全流程解析
在遥感影像分析领域,Google Earth Engine(GEE)平台的出现彻底改变了传统工作模式。这个基于云计算的平台不仅提供了海量的遥感数据资源,更集成了强大的机器学习算法,让全球范围内的地物分类研究变得前所未有的高效。今天我将以水体/植被识别为例,带大家走通从数据准备到结果导出的完整流程,涵盖随机森林、SVM、CART、GTB等主流算法的实际应用。
2. 环境准备与数据加载
2.1 GEE平台初始化
首先需要完成GEE的账号注册和API授权。Python环境下推荐使用geemap库进行交互开发:
import ee import geemap # 初始化GEE ee.Initialize()2.2 研究区与数据选择
以Landsat 8地表反射率数据为例,我们需要先定义研究区域和日期范围:
# 定义研究区(以旧金山湾区为例) roi = ee.Geometry.Rectangle([-122.5, 37.7, -122.3, 37.9]) # 加载Landsat 8数据 landsat = ee.ImageCollection('LANDSAT/LC08/C02/T1_L2') \ .filterBounds(roi) \ .filterDate('2020-01-01', '2020-12-31') \ .sort('CLOUD_COVER')2.3 数据预处理
关键预处理步骤包括辐射定标、云掩膜和合成:
def preprocess(image): # 云掩膜 qa = image.select('QA_PIXEL') cloud_mask = qa.bitwiseAnd(1 << 3).eq(0) # 云标志位 shadow_mask = qa.bitwiseAnd(1 << 4).eq(0) # 云阴影标志位 # 辐射定标 optical_bands = image.select('SR_B.').multiply(0.0000275).add(-0.2) thermal_band = image.select('ST_B10').multiply(0.00341802).add(149.0) return image.addBands(optical_bands, None, True) \ .addBands(thermal_band, None, True) \ .updateMask(cloud_mask.And(shadow_mask)) # 应用预处理并生成中值合成影像 composite = landsat.map(preprocess).median()3. 训练样本准备
3.1 样本采集策略
训练样本质量直接影响分类结果。推荐采用以下策略:
- 每个类别至少采集50-100个样本点
- 均匀分布在整个研究区
- 避免边缘混合像元
3.2 样本标注方法
GEE支持多种样本采集方式:
# 方法1:直接在代码中定义样本点 water_samples = ee.FeatureCollection([ ee.Feature(ee.Geometry.Point([-122.45, 37.75]), {'class': 0}), ee.Feature(ee.Geometry.Point([-122.40, 37.78]), {'class': 0}) ]) vegetation_samples = ee.FeatureCollection([ ee.Feature(ee.Geometry.Point([-122.35, 37.72]), {'class': 1}), ee.Feature(ee.Geometry.Point([-122.38, 37.80]), {'class': 1}) ]) # 合并样本集 samples = water_samples.merge(vegetation_samples)3.3 样本特征提取
从影像中提取样本点的光谱特征:
# 选择特征波段 bands = ['SR_B2', 'SR_B3', 'SR_B4', 'SR_B5', 'SR_B6', 'SR_B7'] # 提取训练数据 training_data = composite.select(bands).sampleRegions( collection=samples, properties=['class'], scale=30 )4. 机器学习模型构建与训练
4.1 随机森林模型
随机森林因其出色的表现成为遥感分类的首选:
# 训练随机森林分类器 rf_classifier = ee.Classifier.smileRandomForest( numberOfTrees=100, # 树的数量 variablesPerSplit=3, # 每棵树的特征数 minLeafPopulation=1, # 叶节点最小样本数 bagFraction=0.5 # 样本采样比例 ).train( features=training_data, classProperty='class', inputProperties=bands )4.2 支持向量机(SVM)
SVM适合小样本情况下的分类:
svm_classifier = ee.Classifier.libsvm( kernelType='RBF', # 径向基核函数 gamma=0.5, # 核函数参数 cost=10 # 惩罚系数 ).train( features=training_data, classProperty='class', inputProperties=bands )4.3 决策树(CART)
CART模型简单直观,适合快速验证:
cart_classifier = ee.Classifier.smileCart().train( features=training_data, classProperty='class', inputProperties=bands )4.4 梯度提升树(GTB)
GTB适合处理复杂的非线性关系:
gtb_classifier = ee.Classifier.smileGradientTreeBoost( numberOfTrees=50, shrinkage=0.1, samplingRate=0.7 ).train( features=training_data, classProperty='class', inputProperties=bands )5. 分类实施与结果可视化
5.1 影像分类
应用训练好的模型进行分类:
# 使用随机森林分类 classified = composite.classify(rf_classifier) # 定义可视化参数 vis_params = { 'min': 0, 'max': 1, 'palette': ['blue', 'green'] } # 在地图上显示结果 Map = geemap.Map() Map.centerObject(roi, 10) Map.addLayer(classified, vis_params, 'Classification') Map5.2 分类后处理
常见后处理操作包括:
- 小斑块去除
- 边缘平滑
- 分类结果矢量化
# 小斑块去除示例(最小面积1公顷) area_pixels = 10000 / (30*30) # Landsat分辨率30m classified = classified.connectedPixelCount(area_pixels, True)6. 精度验证
6.1 混淆矩阵计算
将样本集分为训练集和验证集:
# 添加随机列用于分割 sample = training_data.randomColumn() # 70%训练,30%验证 train_sample = sample.filter(ee.Filter.lt('random', 0.7)) valid_sample = sample.filter(ee.Filter.gte('random', 0.3)) # 重新训练分类器 rf_classifier = rf_classifier.train( features=train_sample, classProperty='class', inputProperties=bands ) # 验证集分类 validated = valid_sample.classify(rf_classifier) # 计算混淆矩阵 confusion_matrix = validated.errorMatrix('class', 'classification') print('总体精度:', confusion_matrix.accuracy()) print('Kappa系数:', confusion_matrix.kappa())6.2 精度指标解读
关键精度指标包括:
- 总体精度(OA):正确分类的样本比例
- Kappa系数:考虑随机因素的分类一致性
- 生产者精度:各类别的漏分误差
- 用户精度:各类别的错分误差
7. 结果导出
7.1 分类结果导出
将分类结果导出到Google Drive:
# 配置导出任务 task = ee.batch.Export.image.toDrive( image=classified, description='LandCover_Export', folder='GEE_Exports', fileNamePrefix='landcover_map', scale=30, region=roi, maxPixels=1e13 ) # 启动导出任务 task.start()7.2 分类器保存
保存训练好的模型供后续使用:
# 导出分类器 classifier_asset = 'projects/your-project/assets/rf_classifier' task = ee.batch.Export.classifier.toAsset( classifier=rf_classifier, description='RF_Classifier_Export', assetId=classifier_asset ) task.start() # 后续使用时加载 saved_classifier = ee.Classifier.load(classifier_asset)8. 实战经验与技巧
8.1 特征工程建议
- 加入NDVI等植被指数提升植被识别精度:
ndvi = composite.normalizedDifference(['SR_B5', 'SR_B4']).rename('NDVI') composite = composite.addBands(ndvi) - 考虑纹理特征(如GLCM)用于城市区域识别
- 时序特征对农作物分类特别有效
8.2 样本均衡技巧
当各类别样本不均衡时:
- 采用分层抽样
- 调整类别权重
- 使用过采样/欠采样技术
8.3 常见问题排查
分类结果出现"椒盐"噪声:
- 增加minLeafPopulation参数
- 应用形态学滤波后处理
模型过拟合:
- 减少树的数量或深度
- 增加bagFraction参数
内存不足错误:
- 减小研究区范围
- 降低输出分辨率
- 使用tileScale参数分块处理
9. 不同模型对比分析
通过系统测试四种模型在相同数据集上的表现:
| 模型 | 总体精度 | Kappa系数 | 训练时间 | 适用场景 |
|---|---|---|---|---|
| 随机森林 | 0.92 | 0.89 | 中等 | 通用场景,特征重要性分析 |
| SVM | 0.88 | 0.84 | 快 | 小样本,高维特征 |
| CART | 0.85 | 0.80 | 快 | 快速验证,规则提取 |
| GTB | 0.91 | 0.88 | 慢 | 复杂非线性关系 |
实际项目中,我通常会先用CART快速验证特征有效性,再用随机森林进行正式分类。当样本量特别少时(<100个样本),SVM往往表现更好。