K-Means算法问题一
对k个初始质心的选择比较敏感,容易陷入局部最小值。 例如,算法运行的时候,有可能会得到不 同的结果,如下面这两种情况。K-means也是收敛了, 只是收敛到了局部最小值
代码改善部分
# 设置k值
k = 4
min_loss = 10000
min_loss_centroids = np.array([])
min_loss_clusterData = np.array([])
for i in range(50):
# centroids 簇的中心点
# cluster Data样本的属性,第一列保存该样本属于哪个簇,第二列保存该样本跟它所属簇的误差
centroids, clusterData = kmeans(data, k)
loss = sum(clusterData[:,1])/data.shape[0]
if loss < min_loss:
min_loss = loss
min_loss_centroids = centroids
min_loss_clusterData = clusterData
# print('loss',min_loss)
print('cluster complete!')
centroids = min_loss_centroids
clusterData = min_loss_clusterData
# 显示结果
showCluster(data, k, centroids, clusterData)
K-Means算法问题二
k值的选择是用户指定的,不同的k得到的结果会有挺大的不同,如下图所示,左边是k=3的结果,蓝色的簇太稀疏了,蓝色的簇应该可以再划分成两个簇。右边 是k=5的结果,红色和蓝色的簇应该合并为一个簇
使用肘部法则来选取k值
代码优化
list_lost = []
for k in range(2,10):
min_loss = 10000
min_loss_centroids = np.array([])
min_loss_clusterData = np.array([])
for i in range(50):
# centroids 簇的中心点
# cluster Data样本的属性,第一列保存该样本属于哪个簇,第二列保存该样本跟它所属簇的误差
centroids, clusterData = kmeans(data, k)
loss = sum(clusterData[:,1])/data.shape[0]
if loss < min_loss:
min_loss = loss
min_loss_centroids = centroids
min_loss_clusterData = clusterData
list_lost.append(min_loss)
# print('loss',min_loss)
# print('cluster complete!')
# centroids = min_loss_centroids
# clusterData = min_loss_clusterData
# 显示结果
# showCluster(data, k, centroids, clusterData)
plt.plot(range(2,10),list_lost)
plt.xlabel('k')
plt.ylabel('loss')
plt.show()