我正在尝试使用 KMeans 质心来标记/聚集像素以进行土地覆盖分析。我希望仅使用 sklearn 和 matplotlib 来做到这一点。目前我的代码如下所示:
kmeans.fit(band_5)
centroids = kmeans.cluster_centers_
plt.scatter(centroids[:, 0], centroids[:, 1])
band_5 的形状是 (713, 1163),但从散点图中我可以看出质心坐标的值远远超过该形状。
根据我的理解,KMeans 提供的质心需要转换为正确的坐标,然后转换为 shapefile,然后在监督过程中使用该文件来标记/聚集像素。
如何将这些质心转换为正确的坐标,然后导出到 shapefile?另外,我需要创建一个 shapefile 吗?
我尝试采用这篇文章中的一些代码,但我无法让它工作。 http://scikit-learn.org/stable/auto_examples/cluster/plot_color_quantization.html#sphx-glr-auto-examples-cluster-plot-color-quantization-py
最佳答案
几点:
scikit-learn 需要列中的数据(想想电子表格中的表格),因此只需传入表示栅格波段的数组,实际上就会尝试对数据进行分类,就好像您有 1163 个样本点和 713 个值一样( strip )每个样本。相反,您需要 flatten如果您在 ArcGIS 之类的工具中查看栅格,并且质心位于带最小值到带最大值的范围内(不在像元坐标中),那么 kmeans 将返回的内容将相当于栅格的分位数分类。
看看您提供的示例,他们有一个三波段 jpeg,将其 reshape 为三个长列:
image_array = np.reshape(china, (w * h, d))
- 如果您需要空间受限的像素,那么您有两种选择:选择连接受限的聚类方法,例如 Agglomerative Clustering或Affinity Propagation ,然后查看将归一化的单元格坐标添加到您的样本集中,例如:
xs, ys = np.meshgrid(
np.linspace(0, 1, 1163), # x
np.linspace(0, 1, 713), # y
)
data_with_coordinates = np.column_stack([
band_5.flatten(),
xs.flatten(),
ys.flatten()
])
# And on with the clustering
- 使用 scikit-learn 完成聚类后,假设您使用
fit_predict
,您将按聚类获得每个值的标签,并且可以将其 reshape 回原始形状带绘制聚类结果。
labels = classifier.fit_predict(data_with_coordinates)
plt.imshow(labels.reshape(band_5.shape)
鉴于您有标记点,您实际上需要聚类质心吗?您在现实世界的空间坐标中需要它们吗?如果是,那么您需要查看 rasterio以及从 map 坐标转换为数组坐标的仿射方法,反之亦然。然后查看fiona将点写入形状文件。
关于Python:将 KMeans 质心转换为 Shapefile,以在土地覆盖分析中进行像素分类,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/40379074/