You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

GEE环境下无监督聚类精度评估及轮廓分数报错解决

无监督NDVI聚类评估与报错解决

报错原因分析

silhouette_score要求输入的特征数据必须是2D数组(形状为(n_samples, n_features)),你传入的clustering.select("ndvi")大概率是1D数组(比如单波段NDVI的扁平化像素值)或未转换为numpy数组的影像对象,导致scikit-learn无法识别,抛出维度不匹配的错误。

解决报错并计算轮廓系数

根据你使用的影像处理环境,给出具体修正方案:

场景1:Google Earth Engine(GEE)环境

如果clustering是GEE的Image对象,需要先提取像素值并转换为符合要求的numpy数组:

import numpy as np
from sklearn.metrics import silhouette_score

# 替换成你的研究区域和影像分辨率
your_roi = ee.Geometry.Rectangle([xmin, ymin, xmax, ymax])
your_scale = 30

# 提取NDVI像素值并转为2D数组
ndvi_values = clustering.select("ndvi").sampleRegion(
    geometry=your_roi, scale=your_scale, geometries=False
).aggregate_array("ndvi").getInfo()
ndvi_array = np.array(ndvi_values).reshape(-1, 1)  # 关键:转为(n_samples, 1)的2D格式

# 提取聚类ID数组
cluster_ids = clustering.select("clusters").sampleRegion(
    geometry=your_roi, scale=your_scale, geometries=False
).aggregate_array("clusters").getInfo()
cluster_array = np.array(cluster_ids)

# 计算平均轮廓系数
silhouette_avg = silhouette_score(ndvi_array, cluster_array)
print(f"平均轮廓系数: {silhouette_avg}")

场景2:本地影像(如rasterio读取)

如果是本地存储的TIFF影像,需要读取后扁平化并调整维度:

import numpy as np
import rasterio
from sklearn.metrics import silhouette_score

# 读取NDVI聚类影像
with rasterio.open("ndvi_clustered.tif") as src:
    ndvi = src.read(1).flatten()  # 读取单波段并扁平化
    ndvi_array = ndvi.reshape(-1, 1)  # 转为2D数组
    nodata = src.nodata

# 读取聚类ID影像
with rasterio.open("clusters.tif") as src:
    clusters = src.read(1).flatten()

# 过滤无数据值(可选但推荐)
mask = (ndvi_array != nodata) & (clusters != nodata)
ndvi_filtered = ndvi_array[mask]
clusters_filtered = clusters[mask]

# 计算轮廓系数
silhouette_avg = silhouette_score(ndvi_filtered, clusters_filtered)
print(f"平均轮廓系数: {silhouette_avg}")

无监督聚类的其他评估指标

无真实标签时,除了轮廓系数,还可以用以下指标评估聚类效果:

  • Calinski-Harabasz指数:类间离散度与类内离散度的比值,值越大聚类效果越好
  • Davies-Bouldin指数:衡量类内相似度与类间距离的平衡,值越小聚类效果越好

示例代码:

from sklearn.metrics import calinski_harabasz_score, davies_bouldin_score

# 计算Calinski-Harabasz指数
ch_score = calinski_harabasz_score(ndvi_filtered, clusters_filtered)
print(f"Calinski-Harabasz指数: {ch_score}")

# 计算Davies-Bouldin指数
db_score = davies_bouldin_score(ndvi_filtered, clusters_filtered)
print(f"Davies-Bouldin指数: {db_score}")

注意事项

  • 轮廓系数取值范围为[-1,1]:接近1表示样本聚类合理,接近-1表示样本应该归为其他类,0表示样本处于聚类边界
  • 必须过滤无数据值(如NaN、影像nodata值),否则会干扰计算结果
  • 如果存在仅含单个样本的聚类,silhouette_score会报错,需提前过滤这类聚类

内容的提问来源于stack exchange,提问作者th145

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.07.19 05:07:44