地球引擎示例
进行土地覆盖分类时的一个常见问题是采样数据中的空间自相关风险会扭曲预测结果或准确性评估。可以帮助解决此问题的一种方法是使用某种形式的缓冲确保训练和验证样本之间有足够的间隔。这个例子将演示一种方法来做到这一点。
使用缓冲区生成随机样本的一种蛮力方法可能是获取大量样本,并通过丢弃近邻将这些样本过滤到较小的数字。然而,选择从哪些点开始可能具有挑战性,并且计算点之间距离的叉积可能很昂贵,因此这种方法不太可能很好地扩展。Earth Engine 的一般规则是“在图像空间中可以完成的工作越多(使用图块和像素),解决方案的扩展性就越好。” 为此,本示例将通过生成指定大小的网格单元并从每个网格单元采样一个点来演示缓冲点。
生成基于栅格的网格单元非常简单;您只需使用 将任何图像重新投影到所需的投影+比例reproject()
。此示例最终将依赖于具有唯一整数值的相邻单元格,因此一个好的起点是重新投影由 生成的随机图像ee.Image.random()
。
阿尔伯斯投影中的 50 公里网格单元,随机着色。
下一步是在每个网格单元中随机选取一个点。这可以通过使用reduceConnectedComponents()
单元格结果加上第二个随机图像来完成(仍然在图像空间中),选择每个网格单元格中的最大随机值。该reduceConnectedComponents
函数random
对标签带 (the cells
) 中每个同质值补丁覆盖的值 (图像)应用一个归约器。此示例使用原始网格大小 1/16 的第二个随机图像的网格,这意味着在每个网格单元内生成了 256 个随机点。random == maximum
每个网格单元格中的位置被标记为 1 值,其余值被屏蔽。
50 公里的网格单元(随机着色),每个单元中有 1 个随机选择的点(白色)。平均而言,点间隔50km
开,但还不能保证最小间距。
这种配置并不能完全保证每个点distance
与最近的邻居相距几米,只是它们平均相距那么远。这是关于点间距的“松散”想法。如果需要“严格”遵守缓冲距离,那么网格中每隔一行和一列的单元格可以使用ee.Image.pixelCoordinates()
和一些数学运算来屏蔽掉。删除这些单元可以保证每个点distance
与其最近邻居的2*distance
平均距离最小。
具有偶数坐标的网格单元已被丢弃,从而保证每个单元中的随机点与其最近的邻居至少有给定的距离。平均而言,点的间距为 distance*2 。
可以使用 将点的最终结果提取到 FeatureCollection 中reduceToVectors
。下图显示了提取的点,并带有半径缓冲区,distance/2
用于可视化目的。请注意,在 50km 版本(左,橙色)中,图像的左下角和右上角有一些点几乎接触,但没有重叠。
使用 50 公里“严格”间距(左)和 5 公里“严格”间距(右)显示的带有用于可视化的缓冲区的最终随机点。
将所有内容内置到可调用函数中后,可以在https://goo.gle/3tsFpa7找到完整的脚本以及用于显示投影像素网格的实用程序。
显示投影的像素网格。
注意事项
- 使用
clip()
之前reproject()
,海岸线上的单个单元格不会被分成单独的部分(并成为多个点)。 - 在地图上显示结果时,使用重新投影通常会出现问题,因为它会覆盖地球引擎的正常缩放行为。如果您使用小尺寸
cellSize
然后缩小非常远,这将是本示例中的唯一问题。显示(或使用)最终的 FeatureCollection 应该没有问题,因为那时所有的重新投影都是与地图无关的。 - 我能够在代码编辑器中将其缩放到 >300,000 点。要使用更多点,您可能需要将其作为表导出运行,或使用多次传递。但在空间上分割事物;否则,点可能无法保持所需的间距。
- 您可以将带添加到同时进入
reduceToVectors
样本协变量的输入(first
在这种情况下使用减速器)。如果内存不足,请先尝试将点(无协变量)导出到表中。 - 要进行分层采样,您可以简单地替换
reduceToVectors
为stratifiedSample
,但是,您需要用points
图像屏蔽类带。 - 我选择使用 Albers 投影,因为墨卡托和板卡雷在远离原点时都会产生距离失真,因此在这些投影中使用固定大小的网格单元更难确保最小距离保证。注意:用于生成点的投影不必与用于对协变量进行采样的投影相匹配。
- 假设您已经有了点并且只想选择一个满足缓冲条件的子集。在这种情况下,您可以
reduceRegions
在random
图像上使用最大减速器,按图像分组cells
。该max
减速机可以让你指定额外的输入:它找到的任何沿最大(如协或像素坐标)来进行。 - 如果您要为例如:k 折交叉验证采集多个样本,则每次都应该偏移网格,这样就不会对每次折叠使用完全相同的采样网格。你可以这样做:
// 按投影单位中 0 到 1 之间的随机量平移投影。 var randomOffset = function(projection, seed) { var values = ee.FeatureCollection([ee.Feature(null, null)]) .randomColumn("x", seed) .randomColumn("y", seed) .first() return projection.translate(values.get("x"), values.get("y")) } proj = randomOffset(proj, seed)