Python 当超过 100 个样本时,K-means 无法拟合数据
Python K-means fails to fit data when over 100 samples
我对 sklearn
(总体上 python)还很陌生,但需要从事一些涉及 超过 10k 个样本的聚类 的项目。将以下代码与 k = 4 的少于 100 个样本的测试数据集一起使用,聚类按预期进行。然而,当我开始使用超过 100 个样本时,6/8 质心 似乎在原点 (0,0) 处 重复,即未能生成集群。对于可能出错的事情有什么建议吗?
截图:
86 Samples,
150 samples
代码:
data = pd.read_csv('parsed.txt', sep="\t", header=None)
data.columns = ["x", "y"]
kmeans = KMeans(algorithm='auto', copy_x=True, init='k-means++', max_iter=1000,
n_clusters=k, n_init=10, n_jobs=1, precompute_distances='auto',
random_state=None, tol=0.0001, verbose=0)
kmeans.fit(data)
labels = kmeans.predict(data)
centroids = kmeans.cluster_centers_
fig = plot.figure(figsize=(5, 5))
colmap = {(x+1): [(np.sin(0.3*x + 0)*127+128)/255,(np.sin(0.3*x + 2)*127+128)/255,(np.sin(0.3*x + 4)*127+128)/255] for x in range(k)} # making rainbow colormap
colors = map(lambda x: colmap[x+1], labels) #color for each label
plot.scatter(data['x'], data['y'], color=colors, alpha=0.5, edgecolor='k')
for idx, centroid in enumerate(centroids):
plot.scatter(*centroid, color=colmap[idx+1])
plot.xlim(0, 4000)
plot.ylim(0, 10000)
plot.show()
@150个样本,我打印的标签(几乎都是2s)和质心坐标(大部分在原点)如下所示:
[2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2
2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2
2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2
1 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2
2]
[[ 7.51619277e+09 7.51619277e+09]
[ 1.00000000e+27 1.00000000e+27]
[ 0.00000000e+00 0.00000000e+00]
[ 0.00000000e+00 0.00000000e+00]
[ 0.00000000e+00 0.00000000e+00]
[ 0.00000000e+00 0.00000000e+00]
[ 0.00000000e+00 0.00000000e+00]
[ 0.00000000e+00 0.00000000e+00]
[ 0.00000000e+00 0.00000000e+00]
[ 0.00000000e+00 0.00000000e+00]]
更多详情 (08/20/17)
这里的 GIF 显示了 k = 1 到 10 的簇,分别对应 86 和 150 个样本。如此处所示,86 组效果很好,但不适用于仅出现在原点的 150 组。请注意,在 k=4 帧处设置的 150 中的颜色变化是由我定义颜色图的方式引起的,因此不是问题的一部分。
,
您是否首先尝试检查您的数据中是否真的有您试图查找的那么多集群?简单地增加样本数量并不一定意味着集群的数量也会增加。如果不。您作为算法输入提供的集群数量大于实际数量。数据集中的簇数,则算法可能无法正确收敛,或者簇可能只是(完全)彼此重叠。
找到最优编号。对于您的数据集的聚类,我们使用一种称为肘法的技术。这种方法有不同的变体,但主要思想是对于不同的 K 值(簇数),您可以找到最适合您应用的成本函数(例如,a 中所有点的平方距离之和将 K 的所有值(例如 1 到 8 或任何其他 error/cost/variance 函数)聚类到它的质心。根据您选择的函数,您会发现在某个点之后,值的差异将可以忽略不计。这个想法是我们选择 'K' 的值,在该值处所选成本函数的值突然变化。
对于值 K=4,方差突然变化。所以K=4被选为一个合适的值。
图片来源:Wikipedia
集群验证还有其他几种方法。 R 中有几个专门用于此目的的包。
要从以下链接了解更多信息:
我对 sklearn
(总体上 python)还很陌生,但需要从事一些涉及 超过 10k 个样本的聚类 的项目。将以下代码与 k = 4 的少于 100 个样本的测试数据集一起使用,聚类按预期进行。然而,当我开始使用超过 100 个样本时,6/8 质心 似乎在原点 (0,0) 处 重复,即未能生成集群。对于可能出错的事情有什么建议吗?
截图: 86 Samples, 150 samples
代码:
data = pd.read_csv('parsed.txt', sep="\t", header=None)
data.columns = ["x", "y"]
kmeans = KMeans(algorithm='auto', copy_x=True, init='k-means++', max_iter=1000,
n_clusters=k, n_init=10, n_jobs=1, precompute_distances='auto',
random_state=None, tol=0.0001, verbose=0)
kmeans.fit(data)
labels = kmeans.predict(data)
centroids = kmeans.cluster_centers_
fig = plot.figure(figsize=(5, 5))
colmap = {(x+1): [(np.sin(0.3*x + 0)*127+128)/255,(np.sin(0.3*x + 2)*127+128)/255,(np.sin(0.3*x + 4)*127+128)/255] for x in range(k)} # making rainbow colormap
colors = map(lambda x: colmap[x+1], labels) #color for each label
plot.scatter(data['x'], data['y'], color=colors, alpha=0.5, edgecolor='k')
for idx, centroid in enumerate(centroids):
plot.scatter(*centroid, color=colmap[idx+1])
plot.xlim(0, 4000)
plot.ylim(0, 10000)
plot.show()
@150个样本,我打印的标签(几乎都是2s)和质心坐标(大部分在原点)如下所示:
[2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2
2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2
2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2
1 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2
2]
[[ 7.51619277e+09 7.51619277e+09]
[ 1.00000000e+27 1.00000000e+27]
[ 0.00000000e+00 0.00000000e+00]
[ 0.00000000e+00 0.00000000e+00]
[ 0.00000000e+00 0.00000000e+00]
[ 0.00000000e+00 0.00000000e+00]
[ 0.00000000e+00 0.00000000e+00]
[ 0.00000000e+00 0.00000000e+00]
[ 0.00000000e+00 0.00000000e+00]
[ 0.00000000e+00 0.00000000e+00]]
更多详情 (08/20/17)
这里的 GIF 显示了 k = 1 到 10 的簇,分别对应 86 和 150 个样本。如此处所示,86 组效果很好,但不适用于仅出现在原点的 150 组。请注意,在 k=4 帧处设置的 150 中的颜色变化是由我定义颜色图的方式引起的,因此不是问题的一部分。
您是否首先尝试检查您的数据中是否真的有您试图查找的那么多集群?简单地增加样本数量并不一定意味着集群的数量也会增加。如果不。您作为算法输入提供的集群数量大于实际数量。数据集中的簇数,则算法可能无法正确收敛,或者簇可能只是(完全)彼此重叠。
找到最优编号。对于您的数据集的聚类,我们使用一种称为肘法的技术。这种方法有不同的变体,但主要思想是对于不同的 K 值(簇数),您可以找到最适合您应用的成本函数(例如,a 中所有点的平方距离之和将 K 的所有值(例如 1 到 8 或任何其他 error/cost/variance 函数)聚类到它的质心。根据您选择的函数,您会发现在某个点之后,值的差异将可以忽略不计。这个想法是我们选择 'K' 的值,在该值处所选成本函数的值突然变化。
对于值 K=4,方差突然变化。所以K=4被选为一个合适的值。
图片来源:Wikipedia
集群验证还有其他几种方法。 R 中有几个专门用于此目的的包。
要从以下链接了解更多信息: