它只是告诉您在分配-重新计算迭代期间,一个集群变成了空的(丢失了所有分配的点)。这通常是由于集群初始化不充分,或者数据具有的固有集群少于您指定的数量。
尝试使用start 选项更改初始化方法。 Kmeans 提供了四种可能的技术来初始化集群:
- sample:从数据中随机抽取 K 个点作为初始聚类(默认)
- uniform:在数据范围内均匀选择 K 个点
- 集群:对一个小子集执行初步集群
- 手动:手动指定初始集群
您还可以尝试emptyaction 选项的不同值,它会告诉 MATLAB 在集群变为空时要做什么。
最终,我认为您需要减少集群的数量,即尝试K=2集群。
我尝试将您的数据可视化以感受一下:
load matlab_X.mat
figure('renderer','zbuffer')
line(XX(:,1), XX(:,2), XX(:,3), ...
'LineStyle','none', 'Marker','.', 'MarkerSize',1)
axis vis3d; view(3); grid on
经过一些手动缩放/平移后,它看起来像一个人的剪影:
可以看到307200个点的数据确实密集紧凑,印证了我的猜想;数据没有那么多簇。
这是我试过的代码:
>> [IDX,C] = kmeans(XX, 3, 'start','uniform', 'emptyaction','singleton');
>> tabulate(IDX)
Value Count Percent
1 18023 5.87%
2 264690 86.16%
3 24487 7.97%
更重要的是,簇2中的整个点都是重复点([0 0 0]):
>> unique(XX(IDX==2,:),'rows')
ans =
0 0 0
另外两个集群看起来像:
clr = lines(max(IDX));
for i=1:max(IDX)
line(XX(IDX==i,1), XX(IDX==i,2), XX(IDX==i,3), ...
'Color',clr(i,:), 'LineStyle','none', 'Marker','.', 'MarkerSize',1)
end
因此,如果您首先删除重复点,您可能会得到更好的聚类...
此外,您还有一些异常值可能会影响聚类结果。从视觉上看,我将数据范围缩小到包含大部分数据的以下区间:
>> xlim([-500 100])
>> ylim([-500 100])
>> zlim([900 1500])
这是删除重复点(超过 250K 点)和异常值(大约 250 个数据点)并使用 K=3 聚类后的结果(使用 replicates 选项运行 5 次中最好的):
XX = unique(XX,'rows');
XX(XX(:,1) < -500 | XX(:,1) > 100, :) = [];
XX(XX(:,2) < -500 | XX(:,2) > 100, :) = [];
XX(XX(:,3) < 900 | XX(:,3) > 1500, :) = [];
[IDX,C] = kmeans(XX, 3, 'replicates',5);
三个集群几乎相等:
>> tabulate(IDX)
Value Count Percent
1 15605 36.92%
2 15048 35.60%
3 11613 27.48%
回想一下,默认距离函数是欧几里得距离,它解释了形成的簇的形状。