共计 2432 个字符,预计需要花费 7 分钟才能阅读完成。
为什么选择随机森林?
随机森林在 GIS 中的魅力在于它能同时处理分类和回归任务,尤其擅长:

- 土地利用 / 覆被分类(LULC)
- 地质灾害风险预测
- 城市扩张模拟
- 植被类型识别
我最近用随机森林做了个县城尺度的柑橘园识别项目,OOB 误差控制在 0.1 以下,比 SVM 快 3 倍。
三种实现方式对比
方案 1:Spatial Analyst 工具箱(最快捷)
适合快速验证想法,但灵活性最低:
- 在 Geoprocessing 搜索栏输入 ”Train Random Trees Classifier”
- 设置输入栅格和训练样本
- 调整关键参数(建议初始值):
- Number Of Trees: 100
- Max Depth: 20
- Minimum Samples Per Leaf: 5
方案 2:scikit-learn + ArcPy(最灵活)
需要先安装 conda 环境:
import arcpy
from sklearn.ensemble import RandomForestClassifier
import numpy as np
# 读取训练数据
train_points = "C:/data/samples.shp"
arr = arcpy.da.FeatureClassToNumPyArray(
train_points,
["NDVI", "Elevation", "ClassValue"]
)
# 拆分特征和标签
X = np.array([arr["NDVI"], arr["Elevation"]]).T
y = arr["ClassValue"]
# 训练模型(重点参数调优)clf = RandomForestClassifier(
n_estimators=200,
max_depth=15,
class_weight="balanced", # 处理样本不均衡
n_jobs=-1 # 启用所有 CPU 核心
)
clf.fit(X, y)
方案 3:Python 工具箱开发(最专业)
创建自定义工具的关键步骤:
- 在 Catalog 面板右键 → New → Python Toolbox
- 继承 arcpy.toolbox 类
- 实现 execute 方法:
def execute(self, parameters, messages):
# 获取用户输入
in_raster = parameters[0].valueAsText
samples = parameters[1].valueAsText
# 转换训练样本为栅格
temp_raster = "in_memory/temp_samples"
arcpy.sa.ExtractValuesToPoints(samples, in_raster, temp_raster)
# 执行随机森林分类
out_classifier = arcpy.sa.RandomForestClassifier(
temp_raster,
numberOfTrees=parameters[2].value,
maxDepth=parameters[3].value
)
# 保存模型
out_classifier.save(parameters[4].valueAsText)
避坑实战经验
样本失衡解决方案
遇到柑橘园(目标类)只占 5% 的情况时:
- 在 scikit-learn 中设置
class_weight='balanced' - 对多数类进行下采样
- 使用 SMOTE 过采样(需安装 imbalanced-learn)
坐标系问题
上周刚踩的坑:训练数据用 WGS84,而 DEM 用 UTM,导致特征提取错位。务必在预处理时:
arcpy.Project_management(
"input_samples.shp",
"projected_samples.shp",
arcpy.SpatialReference(32650) # UTM Zone 50N
)
内存优化技巧
处理全省数据时:
- 使用
arcpy.env.compression = "LZ77"压缩临时文件 - 分块处理:
for x in range(0, width, 1024):
for y in range(0, height, 1024):
window = arcpy.Window(x, y, 1024, 1024)
tile = arcpy.sa.ExtractByRectangle(raster, window)
# 处理分块...
性能调优实测
在 i7-11800H + 32GB 内存设备上的测试数据:
| 树数量 | 训练时间(s) | 内存峰值(GB) |
|---|---|---|
| 50 | 23.4 | 2.1 |
| 100 | 41.7 | 3.8 |
| 200 | 89.2 | 6.5 |
推荐设置:
# 启用并行处理(占用 80% 内存)arcpy.env.parallelProcessingFactor = "80%"
结果可视化技巧
特征重要性图表
import matplotlib.pyplot as plt
# 获取特征重要性
importance = clf.feature_importances_
features = ["NDVI", "Slope", "Population"]
# 创建水平条形图
plt.barh(features, importance)
plt.title("Feature Importance")
plt.savefig("importance.png", dpi=300, bbox_inches='tight')
# 在 ArcGIS Pro 中显示
aprx = arcpy.mp.ArcGISProject("CURRENT")
layout = aprx.listLayouts()[0]
layout.insertElement(1, "importance.png", "GRAPHIC_ELEMENT")
进阶思考题
- 当遇到训练准确率高但验证集效果差时,除了增加样本量,还有哪些调整策略?
- 如何利用 ArcGIS Pro 的 Image Analyst 扩展改进多光谱数据分类?
- 在部署 Web 应用时,怎样将训练好的随机森林模型集成到 ArcGIS Enterprise?
随机森林就像 GIS 分析中的瑞士军刀,掌握好参数调优和性能平衡,就能让它在你的项目中大放异彩。最近我在尝试结合 Sentinel- 2 时序数据做动态分类,有兴趣可以一起探讨!
正文完
发表至: 地理信息系统
近一天内
