【问题标题】:Why Matlab K-means does not find the best centroids while Excel Solver does?为什么 Matlab K-means 找不到最佳质心而 Excel Solver 找到?
【发布时间】:2014-10-26 22:26:44
【问题描述】:

我有一个数据集如下:

数据 = [4 12; 5 10; 8 7; 5 3; 5 4; 2 11; 5 4; 3 8; 6 2; 7 4; 10 8; 8 9; 10 9; 10 12]

然后我继续:

[idx,ctrs, sumD] = kmeans(Data,3)

它给了我质心和 sumD(簇内点到质心距离的总和),例如:

ctrs = [5.6000 3.4000; 3.5000 10.2500; 9.2000 9.0000]

sumD = [6.4000; 13.7500; 18.8000]

而根据 Excel Solver(来自已发表的文章),ctrssumD 对于 k=3 如下:

ctrs = [5.21815716 3.66736761; 3.615385665 10.461533; 9.47841197 8.75055345]

sumD = [5.151897802; 7.285383286; 8.573829765]

(注意:在那篇文章中,作者通过图中的视觉决策为每个集群提供了一个初始(种子)质心,例如 [4 4; 5 12; 10 6]。)

显然,Excel 会找到更准确的 ctrs 值,从而找到更小的 sumD 值。我无法用 Matlab 实现这一点。这就是我使用kmeans函数的其他参数的原因。我使用了“replicates”和“options”(MaxIter)以及“start”参数——即使是 3D 数组种子——也无济于事。我什至采用了文章中相同的初始种子到 Matlab。以下是我尝试过但失败的方法:

第一:

opts = statset('MaxIter',100);
Seed = [4 4; 5 12; 10 6];
[idx,ctrs] = kmeans(Data,3,'Replicates',50,'options',opts,'start',Seed)

这给出了一个错误:'Start' 数组的第三个维度必须与 'replicates' 参数值匹配。

第二:

我创建了一个包含 50 页的 3D 数组,其中第一页是上面相同的初始种子,其余 49 页是随机的。我将随机页面创建为:

T = rand(3,2,49); 

之后,我创建了这样的 50 页 3D 数组:

Seed2 = cat(3,Seed,T);

然后用kmeans:

[idx,ctrs] = kmeans(Data,3,'Replicates',50,'options',opts,'start',Seed2)

但是,Matlab 发出警告,表明第一次复制后的所有复制都因迭代 1 中创建的空集群而终止。此外,获得的 idx、ctrs 和 sumD 值仍然与以前相同 - 就好像我运行了我的上面的第一个函数(即[idx,ctrs, sumD] = kmeans(Data,3))。

我被困住了。我正在尝试使用 Matlab 验证文章中发布的 Excel 求解器的结果,因为那时我会将应用于文章中 14 个观察值的相同算法应用于包含 900 多个观察值的更大数据集。

我做错了什么?我应该在我的编码中更正什么以获得与 Excel Solver 相同或非常相似的结果?

【问题讨论】:

    标签: matlab statistics k-means solver centroid


    【解决方案1】:

    您如何确定 excel 值是正确的,而 MATLAB kmeans 给出的结果并不那么准确。

    使用下面的快速 MATLAB 脚本,我绘制了质心,至少在视觉上看起来是正确的

    Data = [4 12; 5 10; 8 7; 5 3; 5 4; 2 11; 5 4; 3 8; 6 2; 7 4; 10 8; 8 9; 10 9; 10 12];
    
    plot(Data(:,1), Data(:,2),'ob','markersize', 10);
    axis([min(Data(:,1))-2, max(Data(:,1))+2, min(Data(:,2))-2, max(Data(:,2))+2]);
    hold on;
    
    [idx,ctrs, sumD] = kmeans(Data,3);
    plot(ctrs(:,1), ctrs(:,2), '*r', 'markersize', 10);
    

    如果这还不够准确,我们可以定义我们的 kmean 函数,而不是尝试自定义 MATLAB 的 kmeans。我前段时间实现了 kmeans,让 matlab 微调参数似乎更容易。

    【讨论】:

    • 我猜 OP 得到了一个 sumD 明显更小的解决方案,现在想知道为什么 Matlab 没有找到它。例如,较低的红星可能在右侧和下方更多。 (只是我的眼睛判断)
    • 嗨 Anoop 和 Trilarion。谢谢您的回答。是的,ctr 的位置在视觉上看起来很相似。 Matlab 的聚类与 Excel Solver 相同。然而,正如 Trilarion 所提到的,ctrs Matlab 的发现不如 Solver 准确,因为 Solver 的 sumD 值比 Matlab 更小(这意味着更好)。但是,我需要准确的 ctrs,因为当我将此算法反映到我的 900 多个数据集时,会有很多我无法直观检测到的偏差,因为我的数据集很大并且彼此非常接近。所以,聚类是错误的。文章链接为:bit.ly/1CmNzBn
    【解决方案2】:

    区别似乎在于所用距离度量的选择,而不是编码。在这种情况下,定义“距离”的方法不止一种。

    MATLAB 默认使用squared Euclidean distance。通过使用 MATLAB 结果手动计算,我可以复制您获得的sumD 结果。但是,使用平方欧几里得距离度量和您从论文中给出的结果给出了更高的值sumD

    如果我使用普通(非平方)欧几里得距离,sumD 的结果与论文相同。使用此度量,MATLAB 结果为sumD 返回更高的值。

    所以这两个结果本身都不是错误的,它们只是以不同的方式衡量“正确性”。

    【讨论】:

      猜你喜欢
      • 2017-03-10
      • 2021-02-08
      • 2023-04-09
      • 2020-02-21
      • 1970-01-01
      • 2012-04-13
      • 2019-08-29
      • 2018-03-17
      • 1970-01-01
      相关资源
      最近更新 更多