Python中使用scipy的kmeans和kmeans2聚类遇到问题

4 投票
1 回答
6575 浏览
提问于 2025-04-18 17:15

我有个关于scipy的kmeanskmeans2的问题。我有一组1700个经纬度的数据点,想把它们分成100个区域。但是,当我使用kmeanskmeans2时,得到的结果差别很大。你能解释一下这是为什么吗?我的代码如下。

首先,我加载我的数据并绘制坐标,结果看起来都没问题。

import pandas as pd, numpy as np, matplotlib.pyplot as plt
from scipy.cluster.vq import kmeans, kmeans2, whiten

df = pd.read_csv('data.csv')
df.head()

coordinates = df.as_matrix(columns=['lon', 'lat'])
plt.figure(figsize=(10, 6), dpi=100)
plt.scatter(coordinates[:,0], coordinates[:,1], c='c', s=100)
plt.show()

截图

接下来,我对数据进行标准化处理,然后运行kmeans()kmeans2()。当我绘制kmeans()的中心点时,结果看起来差不多——大约有100个点,基本上代表了1700个数据点的位置。

N = len(coordinates)
w = whiten(coordinates)
k = 100
i = 20

cluster_centroids1, distortion = kmeans(w, k, iter=i)
cluster_centroids2, closest_centroids = kmeans2(w, k, iter=i)

plt.figure(figsize=(10, 6), dpi=100)
plt.scatter(cluster_centroids1[:,0], cluster_centroids1[:,1], c='r', s=100)
plt.show()

https://i.stack.imgur.com/WNi2L.png

但是,当我绘制kmeans2()的中心点时,结果看起来完全不对劲。我本以为kmeanskmeans2的结果应该差不多,但它们却完全不同。kmeans的结果似乎很好地代表了我的完整数据集,而kmeans2的结果看起来几乎是随机的。

plt.figure(figsize=(10, 6), dpi=100)
plt.scatter(cluster_centroids2[:,0], cluster_centroids2[:,1], c='r', s=100)
plt.show()

https://i.stack.imgur.com/AhgSU.png

以下是我设置的k和N的值,以及kmeans()kmeans2()得到的数组大小:

print 'k =', k
print 'N =', N
print len(cluster_centroids1)
print len(cluster_centroids2)
print len(closest_centroids)
print len(np.unique(closest_centroids))

输出:

k = 100
N = 1759
96
100
1759
17
  • 为什么len(cluster_centroids1)不等于k
  • len(closest_centroids)等于N,这看起来是对的。但为什么len(np.unique(closest_centroids))不等于k
  • len(cluster_centroids2)等于k,但当绘制时,cluster_centroids2似乎并没有像cluster_centroids1那样代表原始数据集。

最后,我绘制了完整的坐标数据集,并按区域上色。

plt.figure(figsize=(10, 6), dpi=100)
plt.scatter(coordinates[:,0], coordinates[:,1], c=closest_centroids, s=100)
plt.show()

你可以在这里看到:截图

1 个回答

1

感谢你提出这个好问题,并附上了示例代码和图片!这是一个很好的新手问题。

大部分奇怪的情况都可以通过仔细阅读文档来解决。这里有几点需要注意:

  • 在比较原始数据点和最终的聚类中心时,最好把它们放在同一个图上,并且使用相同的尺寸(也就是说,把w和结果放在一起比较)。比如,可以用大点表示聚类中心,然后在上面用小点表示原始数据。

  • kmeanskmeans2的起点不同。kmeans2是从随机分布的点开始的,而你的数据分布不均匀,所以kmeans2可能会得到不理想的结果。你可以试着加上关键词minit='points',看看结果是否会有所变化。

  • 由于初始选择的中心点不太好,100个初始中心点中只有17个实际上有数据点归属(这和图形的随机外观有很大关系)。

  • kmeans中,有些中心点可能会因为这样能减少失真而重合在一起。(这似乎没有在文档中说明。)所以你最终可能只会得到96个中心点。

撰写回答