如何理解Matlab内置函数"kmeans"?
How to understand the Matlab build in function "kmeans"?
假设我有一个矩阵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
returns k-by-p (8 by 1000)
矩阵中的 k 个聚类质心位置。并且 idx
returns 一个 n-by-1 vector
包含每个观察的聚类索引。
我的问题是:
1) 我不知道如何理解 C
的质心位置。位置应该表示为 (x,y)
,对吗?如何正确理解矩阵C
?
2) 最后的中心是什么c1, c2,...,ck
?它们只是值还是位置?
3) 对于每一个cluster,如果我只想得到最接近这个cluster中心的vector,如何计算得到呢?
谢谢!
好的,在我们真正深入细节之前,让我们先简要概述一下K——聚类是什么意思。
k-means clustering 的工作原理是,对于您拥有的某些数据,您想将它们分组到 k 组中。您最初在数据中选择 k 运行dom 点,这些点将具有来自 1,2,...,k
的标签。这些就是我们所说的 质心 。然后,您确定其余数据与每个点的接近程度。然后,您将这些点分组,以便无论哪个点最接近这些 k 点中的任何一个,您都将这些点分配给属于该特定组 (1,2,...,k
)。之后,对于每个组的所有点,更新 centroids,它实际上被定义为每个组的代表点。对于每个组,您计算每个 k 组中所有点的平均值。这些成为下一次迭代的 new 质心。在下一次迭代中,您确定数据中的每个点与 每个质心 的接近程度。您不断迭代并重复此行为,直到质心不再移动,或者它们移动得很少。
如何在 MATLAB 中使用 kmeans
函数,假设您有一个数据矩阵(A
在您的情况下),它是 ar运行ged 这样每一行都是一个样本,每一列都是样本的一个特征/维度。例如,我们可以有 N x 2
或 N x 3
笛卡尔坐标数组,无论是 2D 还是 3D。在彩色图像中,我们可以有 N x 3
个数组,其中每一列都是图像中的一个颜色分量 - 红色、绿色或蓝色。
如何在 MATLAB 中调用 kmeans
的方式如下:
[IDX, C] = kmeans(X, K);
X
是我们谈到的数据矩阵,K
是您希望看到的簇/组的总数以及输出 IDX
和 C
分别是 index 和 centroid 矩阵。 IDX
是一个 N x 1
数组,其中 N
是您放入函数中的样本总数。 IDX
中的每个值都会告诉您 哪个质心 X
中的样本/行与特定质心最匹配。您还可以覆盖用于测量点之间距离的距离度量。默认情况下,这是欧氏距离,但您在调用中使用了余弦距离。
C
有 K
行,其中每行都是一个质心。因此,对于笛卡尔坐标,这将是一个 K x 2
或 K x 3
数组。因此,在计算 k-means 时,您会将 IDX
解释为告诉该点最接近哪个组/质心。因此,如果我们得到一个点的值 IDX=1
,这意味着该点与第一个质心最匹配,即 C
的第一行。同样,如果我们得到一个点的值 IDX=1
,这意味着该点与第三个质心最匹配,即 C
的第三行。
现在回答你的问题:
- 我们刚刚谈到了
C
和 IDX
所以这应该很清楚了。
- 最终的中心存储在
C
中。每行给你一个代表一组的质心/中心。
听起来你想在数据中找到离每个聚类最近的点,除了实际的质心本身。如果您使用 knnsearch
通过给出一组点执行 K 最近邻搜索并输出数据中接近查询点的 K
最近点,这很容易做到。因此,您提供集群作为输入,您的数据作为输出,然后使用 K=2
并跳过第一点。第一个点的距离为 0,因为这将等于质心本身,第二个点将为您提供距离集群最近的最近点。
假设您已经运行kmeans
:
,您可以通过以下方式做到这一点
out = knnsearch(A, C, 'k', 2);
out = out(:,2);
你 运行 knnsearch
,然后抛出最近的点,因为它的距离基本上为 0。第二列是你所追求的,它给你最近的点到不包括实际质心的集群。 out
将为您提供数据矩阵 A
中最接近每个质心的点。要获得实际分数,请执行以下操作:
pts = A(out,:);
希望对您有所帮助!
在回答这三个部分之前,我将只解释一下 MATLAB 解释 k-means (http://www.mathworks.com/help/stats/kmeans.html) 时使用的语法。
A
是您的数据矩阵(在 link 中表示为 X
)。有 n
行(在本例中为 2000),代表您拥有的 observations/data 点数。还有 p
列(在本例中为 1000),表示每个数据点具有的 "features" 个数。例如,如果您的数据由二维点组成,那么 p
将等于 2.
k
是您要将数据分组到的聚类数。根据您提供的 C
的维度,k
必须是 8。
现在我分三部分回答:
C
矩阵的维度为 k x p
。每行代表一个质心。质心位置根本不必是 (x, y)。质心位置的尺寸等于 p
。换句话说,如果您有 2D 点,则可以将质心绘制为 (x, y)。如果您有 3D 点,则可以将质心绘制为 (x, y, z)。由于 A
中的每个数据点都有 1000 个特征,因此您的质心有 1000 个维度。
- 如果不知道您的数据到底是什么,这有点难以解释。质心当然不仅仅是值,也不一定是位置。如果您的数据
A
是坐标点,您当然可以将质心表示为位置。但是,我们可以更普遍地看待它。如果您有一个聚类质心 i
和与该质心分组的数据点 v
,则质心将代表与其聚类中的数据点最相似的数据点。希望这是有道理的,如有必要,我可以给出更清楚的解释。
k-means方法实际上给了我们一个很好的方法来完成这个。该函数实际上有 4 个可能的输出,但我将重点关注第 4 个,我将其称为 D
:
[idx,C,sumd,D] = kmeans(A, k, 'Distance', 'cosine');
D
的维度为 n x k
。对于数据点 i
,D
矩阵中的行 i
给出了从该点到每个质心的距离。因此,对于每个质心,您只需找到最接近它的数据点,然后 return 对应的数据点。如果您需要,我可以提供短代码。
此外,只是一个小费。您可能应该使用 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
的向量。
假设我有一个矩阵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
returns k-by-p (8 by 1000)
矩阵中的 k 个聚类质心位置。并且 idx
returns 一个 n-by-1 vector
包含每个观察的聚类索引。
我的问题是:
1) 我不知道如何理解 C
的质心位置。位置应该表示为 (x,y)
,对吗?如何正确理解矩阵C
?
2) 最后的中心是什么c1, c2,...,ck
?它们只是值还是位置?
3) 对于每一个cluster,如果我只想得到最接近这个cluster中心的vector,如何计算得到呢?
谢谢!
好的,在我们真正深入细节之前,让我们先简要概述一下K——聚类是什么意思。
k-means clustering 的工作原理是,对于您拥有的某些数据,您想将它们分组到 k 组中。您最初在数据中选择 k 运行dom 点,这些点将具有来自 1,2,...,k
的标签。这些就是我们所说的 质心 。然后,您确定其余数据与每个点的接近程度。然后,您将这些点分组,以便无论哪个点最接近这些 k 点中的任何一个,您都将这些点分配给属于该特定组 (1,2,...,k
)。之后,对于每个组的所有点,更新 centroids,它实际上被定义为每个组的代表点。对于每个组,您计算每个 k 组中所有点的平均值。这些成为下一次迭代的 new 质心。在下一次迭代中,您确定数据中的每个点与 每个质心 的接近程度。您不断迭代并重复此行为,直到质心不再移动,或者它们移动得很少。
如何在 MATLAB 中使用 kmeans
函数,假设您有一个数据矩阵(A
在您的情况下),它是 ar运行ged 这样每一行都是一个样本,每一列都是样本的一个特征/维度。例如,我们可以有 N x 2
或 N x 3
笛卡尔坐标数组,无论是 2D 还是 3D。在彩色图像中,我们可以有 N x 3
个数组,其中每一列都是图像中的一个颜色分量 - 红色、绿色或蓝色。
如何在 MATLAB 中调用 kmeans
的方式如下:
[IDX, C] = kmeans(X, K);
X
是我们谈到的数据矩阵,K
是您希望看到的簇/组的总数以及输出 IDX
和 C
分别是 index 和 centroid 矩阵。 IDX
是一个 N x 1
数组,其中 N
是您放入函数中的样本总数。 IDX
中的每个值都会告诉您 哪个质心 X
中的样本/行与特定质心最匹配。您还可以覆盖用于测量点之间距离的距离度量。默认情况下,这是欧氏距离,但您在调用中使用了余弦距离。
C
有 K
行,其中每行都是一个质心。因此,对于笛卡尔坐标,这将是一个 K x 2
或 K x 3
数组。因此,在计算 k-means 时,您会将 IDX
解释为告诉该点最接近哪个组/质心。因此,如果我们得到一个点的值 IDX=1
,这意味着该点与第一个质心最匹配,即 C
的第一行。同样,如果我们得到一个点的值 IDX=1
,这意味着该点与第三个质心最匹配,即 C
的第三行。
现在回答你的问题:
- 我们刚刚谈到了
C
和IDX
所以这应该很清楚了。 - 最终的中心存储在
C
中。每行给你一个代表一组的质心/中心。 听起来你想在数据中找到离每个聚类最近的点,除了实际的质心本身。如果您使用
knnsearch
通过给出一组点执行 K 最近邻搜索并输出数据中接近查询点的K
最近点,这很容易做到。因此,您提供集群作为输入,您的数据作为输出,然后使用K=2
并跳过第一点。第一个点的距离为 0,因为这将等于质心本身,第二个点将为您提供距离集群最近的最近点。假设您已经运行
,您可以通过以下方式做到这一点kmeans
:out = knnsearch(A, C, 'k', 2); out = out(:,2);
你 运行
knnsearch
,然后抛出最近的点,因为它的距离基本上为 0。第二列是你所追求的,它给你最近的点到不包括实际质心的集群。out
将为您提供数据矩阵A
中最接近每个质心的点。要获得实际分数,请执行以下操作:pts = A(out,:);
希望对您有所帮助!
在回答这三个部分之前,我将只解释一下 MATLAB 解释 k-means (http://www.mathworks.com/help/stats/kmeans.html) 时使用的语法。
A
是您的数据矩阵(在 link 中表示为X
)。有n
行(在本例中为 2000),代表您拥有的 observations/data 点数。还有p
列(在本例中为 1000),表示每个数据点具有的 "features" 个数。例如,如果您的数据由二维点组成,那么p
将等于 2.k
是您要将数据分组到的聚类数。根据您提供的C
的维度,k
必须是 8。
现在我分三部分回答:
C
矩阵的维度为k x p
。每行代表一个质心。质心位置根本不必是 (x, y)。质心位置的尺寸等于p
。换句话说,如果您有 2D 点,则可以将质心绘制为 (x, y)。如果您有 3D 点,则可以将质心绘制为 (x, y, z)。由于A
中的每个数据点都有 1000 个特征,因此您的质心有 1000 个维度。- 如果不知道您的数据到底是什么,这有点难以解释。质心当然不仅仅是值,也不一定是位置。如果您的数据
A
是坐标点,您当然可以将质心表示为位置。但是,我们可以更普遍地看待它。如果您有一个聚类质心i
和与该质心分组的数据点v
,则质心将代表与其聚类中的数据点最相似的数据点。希望这是有道理的,如有必要,我可以给出更清楚的解释。 k-means方法实际上给了我们一个很好的方法来完成这个。该函数实际上有 4 个可能的输出,但我将重点关注第 4 个,我将其称为
D
:[idx,C,sumd,D] = kmeans(A, k, 'Distance', 'cosine');
D
的维度为n x k
。对于数据点i
,D
矩阵中的行i
给出了从该点到每个质心的距离。因此,对于每个质心,您只需找到最接近它的数据点,然后 return 对应的数据点。如果您需要,我可以提供短代码。
此外,只是一个小费。您可能应该使用 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
的向量。