【问题标题】:How to understand the Matlab build in function "kmeans"?如何理解 Matlab 内置函数“kmeans”?
【发布时间】:2015-08-05 22:50:34
【问题描述】:

假设我有一个矩阵A,其大小为2000*1000 double。然后我申请 Matlab 内置函数"kmeans"到矩阵A

k = 8;
[idx,C] = kmeans(A, k, 'Distance', 'cosine');

我得到C = 8*1000 double; idx = 2000*1 double,值从 1 到 8; 根据文档,C 返回k-by-p (8 by 1000) 矩阵中的 k 个簇质心位置。并且idx 返回一个n-by-1 vector,其中包含每个观察的集群索引。 我的问题是:

1) 我不知道如何理解C,即质心位置。位置应该表示为(x,y),对吗?如何正确理解矩阵C

2) c1, c2,...,ck 的最终中心是什么?它们只是价值还是位置?

3)对于每个簇,如果只想得到离这个簇中心最近的向量,如何计算得到呢?

谢谢!

【问题讨论】:

    标签: matlab machine-learning data-analysis


    【解决方案1】:

    在回答这三个部分之前,我将仅解释 MATLAB 解释 k-means (http://www.mathworks.com/help/stats/kmeans.html) 中使用的语法。

    • A 是您的数据矩阵(在链接中表示为 X)。有n 行(在本例中为 2000),它们表示您拥有的观察/数据点的数量。还有p 列(在本例中为 1000),表示每个数据点具有的“特征”数量。例如,如果您的数据由二维点组成,那么p 将等于 2。
    • k 是您要将数据分组到的集群数。根据您提供的C 的尺寸,k 必须为 8。

    现在我将回答三个部分:

    1. C 矩阵的维度为k x p。每行代表一个质​​心。质心位置根本不必是 (x, y)。质心位置的尺寸等于p。换句话说,如果您有 2D 点,则可以将质心绘制为 (x, y)。如果您有 3D 点,则可以将质心绘制为 (x, y, z)。由于A 中的每个数据点都有 1000 个特征,因此您的质心有 1000 个维度。
    2. 如果不知道您的数据到底是什么,这有点难以解释。质心当然不仅仅是值,它们不一定是位置。如果您的数据A 是坐标点,您当然可以将质心表示为位置。但是,我们可以更普遍地看待它。如果您有一个集群质心i 和与该质心分组的数据点v,则质心将表示与其集群中的数据点最相似的数据点。希望这是有道理的,如有必要,我可以给出更清晰的解释。
    3. k-means 方法实际上为我们提供了一个很好的方法来实现这一点。该函数实际上有 4 个可能的输出,但我将重点关注第 4 个,我将其称为D

      [idx,C,sumd,D] = kmeans(A, k, 'Distance', 'cosine');
      

      D 的维度为 n x k。对于数据点iD 矩阵中的行i 给出了从该点到每个质心的距离。因此,对于每个质心,您只需找到最接近此质心的数据点,并返回相应的数据点。如果您需要,我可以为此提供短代码。

    另外,只是一个提示。您可能应该使用 kmeans++ 方法来初始化质心。它更快,通常更好。你可以这样调用它:

    [idx,C,sumd,D] = kmeans(A, k, 'Distance', 'cosine', 'Start', 'plus');
    

    编辑:

    这是第 3 部分所需的代码:

    [~, min_idxs] = min(D, [], 1);
    closest_vecs = A(min_idxs, :);
    

    closest_vecs 的每一行i 是最接近质心i 的向量。

    【讨论】:

    • 非常好的答案。仅仅作为一名高中生就令人印象深刻。顺便说一句,欢迎来到 StackOverflow!
    • 另外,只要有时间,就到我们的 MATLAB 聊天室打个招呼:)。 chat.stackoverflow.com/rooms/81987/matlab-and-octave
    • @rayryeng 谢谢你:D。实际上,我现在正在一个研究营中使用 k-means 和空间金字塔池,所以这并不是非常困难。
    • K 均值是我最早学习的机器学习算法之一。确实很简单。不过,计算最接近对的算法......要使其高效实际上有点困难。蛮力一气呵成。希望你玩得开心!我也为你的帖子点赞。
    • @It'sMagic,您说“因此,对于每个质心,您只需找到最接近它的数据点,并返回相应的数据点。如果你需要它。”是的,我需要它,请提供短代码。
    【解决方案2】:

    好的,在我们真正深入细节之前,让我们先简要概述一下K 意味着什么是聚类。


    k-means clustering 的工作原理是,对于您拥有的某些数据,您希望将它们分组到 k 个组中。您最初在数据中选择 k 个随机点,这些点将具有来自 1,2,...,k 的标签。这些就是我们所说的质心。然后,您确定其余数据与这些点的接近程度。然后,您将这些点分组,以便无论哪个点最接近这些 k 点中的任何一个,您都将这些点分配给该特定组 (1,2,...,k)。之后,对于每个组的所有点,您更新 质心,它实际上被定义为每个组的代表点。对于每个组,您计算每个 k 组中所有点的平均值。这些成为下一次迭代的质心。在下一次迭代中,您将确定数据中的每个点与每个质心 的距离。您不断迭代并重复此行为,直到质心不再移动,或者它们移动很少。


    如何在 MATLAB 中使用 kmeans 函数是假设您有一个数据矩阵(在您的情况下为 A),它的排列方式是每行是一个样本,每列是一个特征/维度样本。例如,我们可以有 N x 2N x 3 笛卡尔坐标数组,无论是 2D 还是 3D。在彩色图像中,我们可以有N x 3 数组,其中每一列是图像中的一个颜色分量——红色、绿色或蓝色。

    在 MATLAB 中调用kmeans 的方式如下:

    [IDX, C] = kmeans(X, K);
    

    X 是我们谈到的数据矩阵,K 是您希望看到的集群/组的总数,输出 IDXC 分别是一个索引质心 矩阵。 IDX 是一个 N x 1 数组,其中 N 是您放入函数的样本总数。 IDX 中的每个值都会告诉您哪个质心X 中的样本/行与特定质心最匹配。您还可以覆盖用于测量点之间距离的距离测量。默认情况下,这是欧几里得距离,但您在调用中使用了余弦距离。

    CK 行,其中每一行都是一个质心。因此,对于笛卡尔坐标,这将是一个K x 2K x 3 数组。因此,您会将IDX 解释为在计算 k-means 时告诉该点最接近哪个组/质心。因此,如果我们得到一个点的值IDX=1,这意味着该点与第一个质心最匹配,即C 的第一行。同样,如果我们得到一个点的值IDX=1,这意味着该点与第三个质心最匹配,即C 的第三行。


    现在回答你的问题:

    1. 我们刚刚讨论了CIDX,所以这应该很清楚。
    2. 最终的中心存储在C。每行都会为您提供一个代表一个组的质心/中心。
    3. 除了实际的质心本身之外,您还想在数据中找到离每个集群最近的点。如果您使用knnsearch,这很容易做到,它通过给出一组点来执行K-最近邻搜索,并输出您的数据中最接近查询点的K 点。因此,您提供集群作为输入,您的数据作为输出,然后使用K=2 并跳过第一点。第一个点的距离为 0,因为这将等于质心本身,第二个点将为您提供最接近集群的最近点。

      假设您已经运行 kmeans,您可以通过以下方式做到这一点:

      out = knnsearch(A, C, 'k', 2);
      out = out(:,2);
      

      您运行knnsearch,然后抛出最近的点,因为它的距离基本上为 0。第二列是您所追求的,它为您提供了除实际质心之外的最接近集群的点。 out 将为您提供数据矩阵 A 中最接近每个质心的点。要获得实际分数,请执行以下操作:

      pts = A(out,:);
      

    希望这会有所帮助!

    【讨论】:

    • 其实对于第3部分,对于每个集群,我相信他想要的是离每个集群最近的数据点。考虑到 k-means 函数还给出了每个点到每个质心的距离,这应该非常容易做到。
    • @It'sMagic - 有道理。我会编辑我的帖子,但我也会等待确认。
    • @It'sMagic - 顺便说一句,您可以使用knnsearch 并指定k=2 并丢弃第一点。
    • @It'sMagic 是的,你是对的。对于每个簇,只保留最接近簇中心的向量。这就是我想要的。
    猜你喜欢
    • 2014-06-27
    • 2016-01-11
    • 2022-10-07
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2014-05-09
    • 2014-05-11
    • 2012-07-30
    相关资源
    最近更新 更多