【发布时间】:2023-04-09 05:43:02
【问题描述】:
所以我有一个奇怪的问题。我有一个包含 240 个点的数据集,我正在尝试使用 k-means 将其聚类为 100 个聚类。我正在使用 Matlab,但我无法访问统计工具箱,所以我不得不编写自己的 k-means 函数。这很简单,所以应该不会太难,对吧?好吧,我的代码似乎有问题:
function result=Kmeans(X,c)
[N,n]=size(X);
index=randperm(N);
ctrs = X(index(1:c),:);
old_label = zeros(1,N);
label = ones(1,N);
iter = 0;
while ~isequal(old_label, label)
old_label = label;
label = assign_labels(X, ctrs);
for i = 1:c
ctrs(i,:) = mean(X(label == i,:));
if sum(isnan(ctrs(i,:))) ~= 0
ctrs(i,:) = zeros(1,n);
end
end
iter = iter + 1;
end
result = ctrs;
function label = assign_labels(X, ctrs)
[N,~]=size(X);
[c,~]=size(ctrs);
dist = zeros(N,c);
for i = 1:c
dist(:,i) = sum((X - repmat(ctrs(i,:),[N,1])).^2,2);
end
[~,label] = min(dist,[],2);
似乎发生的情况是,当我去重新计算质心时,一些质心没有分配给它们的数据点,所以我不确定该怎么做。在对此进行了一些研究之后,我发现如果您提供任意初始质心,则可能会发生这种情况,但在这种情况下,初始质心是从数据点本身获取的,因此这没有任何意义。我尝试将这些质心重新分配给随机数据点,但这会导致代码不收敛(或者至少在让它运行一整夜之后,代码从未收敛)。基本上它们会被重新分配,但这会导致其他质心被边缘化并重复。我不太确定我的代码出了什么问题,但是我通过 R 的 k-means 函数运行了相同的数据集,k=100 进行了 1000 次迭代,并且它设法收敛。有谁知道我在这里搞砸了什么?谢谢。
【问题讨论】:
-
我很好奇,如果集群质心的任何维度为
NaN,为什么您将集群的中心设为全零。你有理由解释你为什么这样做吗?无论如何,我将检查您的代码并找出问题所在。 Kmeans 我非常了解。 -
NaN 只有在没有分配给质心的点时才会发生。当这种情况发生时,我真的不知道该怎么办。我尝试随机选择一个数据点并将质心移动到那里,但这最终会导致无限循环(移动的质心会导致其他质心没有任何数据点,然后重复)。我只是选择将质心全为零作为默认值,因为我不确定在这里做什么正确。
-
好的。我在帖子中写的确保所有集群质心都是唯一的建议应该有望解决您遇到的这个问题。试试看,看看效果如何!
标签: matlab machine-learning cluster-analysis k-means