如何知道什么是最佳群集数量 - 有没有办法评估实际应该有多少群集?

时间:2017-12-02 02:00:59

标签: matlab k-means

我刚刚开始学习群集,并遇到了诸如groundtruth之类的术语,这是参考已知集的另一个名称,它将实际的聚类数据包含到正确的组中。出于教育目的,我创建了一个随机生成的数据集,并希望将其集群到7个集群。假设实际的簇应该是5,我如何使用这些信息来评估聚类的完成情况。有人可以帮忙吗?

K=3;

numObservarations = 100;
dimensions = 3;
data = rand([numObservarations dimensions]);

numObservarations = length(data);
%% cluster
opts = statset('MaxIter', 500, 'Display', 'iter');
[clustIDX, clusters, interClustSum, Dist] = kmeans(data, K, 'options',opts, ...
    'distance','sqEuclidean', 'EmptyAction','singleton', 'replicates',3);
%% plot data+clusters
figure, hold on
scatter3(data(:,1),data(:,2),data(:,3), 50, clustIDX, 'filled')
scatter3(clusters(:,1),clusters(:,2),clusters(:,3), 200, (1:K)', 'filled')
hold off, xlabel('x'), ylabel('y'), zlabel('z')

2 个答案:

答案 0 :(得分:2)

据我所知,衡量聚类与已知类比较好的最常用指标之一是purity

purity是群集质量的外部评估标准,表示正确分类的数据点的百分比,得分范围为01。为了计算purity,每个群集被分配到群集中最频繁的类,然后通过计算正确分配的元素的数量并将其除以数据的总数来测量该分配的准确性。分。

执行计算的第一步是创建confusion matrix。这可以通过循环遍历每个集群CR并计算每个类CS分类的对象数来实现:

     | CS_1 | CS_2 | CS_3 |
---------------------------
CR_1 |    4 |   28  |  10 |
CR_2 |   11 |    3  |  22 |
CR_3 |    8 |   14  |   0 |
CR_4 |    1 |    9  |   3 | 
CR_5 |    1 |    8  |   0 |

第二步是迭代遍历每个集群CR以找到最大行值:

CR_1 - 28
CR_2 - 22
CR_3 - 14
CR_4 - 9
CR_5 - 8

在最后一步中,必须汇总行的最大值,结果必须除以数据点的总数:

PURITY = (28 + 22 + 14 + 9 + 8) / 122 ~= 0,66

答案 1 :(得分:1)

这是生成测试集的一种方法:

K = 3;
numObservations = 100;
dimensions = 3;
data = cell(K,1);
for ii=1:K
   data{ii} = randn([numObservations,dimensions]) + 3 * randn([1,dimensions]);
end
data = cat(1,data{:});
labels = repmat(1:K,numObservations,1);
labels = labels(:); % This is the ground truth
scatter3(data(:,1),data(:,2),data(:,3), 50, labels, 'filled')

data是一个数据集,类似于您制作的数据集,但它有三个具有不同均值的集群。我使用3*randn生成随机方法,将群集充分分离,以便群集有一定的机会做正确的事情。 10*randn会造成一个微不足道的问题,1*randn会造成一个不可能的问题。

labels是每个数据点所属的群集ID。这是你的“基本事实”。

接下来,像以前一样,将k-means应用于数据集data,以获取clustIDX。现在,您可以将clustIDXlabels进行比较。因为k-means为每个集群分配一个随机ID(它无法知道您为每个集群分配了哪些ID),所以不要指望集群提供与您的基础事实相同的ID。正确分配的数据点可能包含label=2clustIDX=3。但正如Tommaso在另一个答案中解释的那样,混淆矩阵可以向您展示聚类的进展情况。计算方法如下:

C = zeros(K,K);
for ii=1:length(labels)
   C(labels(ii),clustIDX(ii)) = C(labels(ii),clustIDX(ii)) + 1;
end