我知道有很多这样的问题和一些解决方案,但我希望还有另一种方法。
目标:最终目标是在给定图像的情况下对颜色进行聚类,然后允许用户更改这些颜色。用户不需要输入任何k。该算法确定 K 。
方法:目前,我使用了轮廓得分指标(http://scikit-learn.sourceforge.net/dev/modules/generated/sklearn.metrics.silhouette_score.html#sklearn.metrics.silhouette_score)。我使用MiniBatchKMeans对图像进行聚类,然后计算k(4-8)范围内的silhouette_score。代码是:
# silhouetteCoeff determination
def silhouetteCoeff(z):
max_silhouette = 0
max_k = 0
for i in range(4, 17):
clt = MiniBatchKMeans(n_clusters = i, random_state = 42)
clt.fit(z)
silhouette_avg = silhouette_score(z, clt.labels_, sample_size = 250, random_state = 42)
print("k: ", i, " silhouette avg: ", silhouette_avg)
if (silhouette_avg == 1.0):
max_k = i
break
elif (silhouette_avg > max_silhouette):
max_silhouette = silhouette_avg
max_k = i
print("Max silhouette: ", max_silhouette)
print("Max k: ", max_k)
return int(max_k)
即使我预先对图像进行颜色量化(16种颜色),该功能仍需要6-8秒才能运行(假设图像尺寸为400x400)。
我的问题是,有没有更好或更快的方法来找到k?我也尝试过 Elbow方法,但还是要在那里计算SSE。通过对某些图像的测试,我发现了一个很好的平均k = 8.但是在色彩更浓的图像上,算法会丢失一些颜色。
答案 0 :(得分:0)
衡量你的瓶颈!
剪影在O(n²)中,所以很可能它会成为你的方法的瓶颈。此外,有更快的k-means变体比sklearn更快...因此有很多可能使事情变得更快。
Minibatch kmeans甚至不会收敛,但只是接近结果。只有我无法承担将所有数据保存在内存中的意义,这才有意义。
将调色板减少到只有16种颜色据说完全没有帮助。