在matlab上使用kmeans进行Kmeans聚类

Kaw*_*mad 1 matlab cluster-analysis matrix k-means

我有这个矩阵:

x=[ 2+2*i 2-2*i -2+2*i -2-2*i];
Run Code Online (Sandbox Code Playgroud)

我想模拟传输它并为其添加噪声.我代表复数的组成部分如下:

A=randn(150,2)+2*ones(150,2); C=randn(150,2)-2*ones(150,2);
Run Code Online (Sandbox Code Playgroud)

在接收器处,我收到了下面的向量,其中组件根据我最初发送的内容( x)的组件进行排序.

X = [A A A C C A C C];
Run Code Online (Sandbox Code Playgroud)

现在我想应用kmeans(X)有4个集群,所以kmeans(X,4).我遇到以下问题:

  1. 我不确定我是否可以代表X上面显示的复数.
  2. 我无法绘制kmeans显示聚类的结果.
  3. 我无法理解群集质心结果.
  4. 如何找到最佳错误率,如果这个例子是代表通信系统而在接收器上,k-means则使用聚类来决定传输信号是什么?

ray*_*ica 7

如果您不"理解"群集质心结果,那么您不了解k-means的工作原理.我将在这里提供一个小摘要.

如何ķ -means工作原理是,对于一些数据,你有,你想将它们归入ķ组.您最初在数据中选择k个随机点,这些点将包含标签1,2,...,k.这就是我们所说的质心.然后,确定其余数据与这些点之间的接近程度.然后,您将这些点分组,以便无论哪个点最接近这些k点中的任何一个,都可以将这些点分配为属于该特定组(1,2,...,k).之后,对于每个组的所有点,您更新质心,实际上这些质心被定义为每个组的代表点.对于每个组,您计算每个k组中所有点的平均值.这些成为下一次迭代的质心.在下一次迭代中,您可以确定数据中每个点与每个质心的接近程度.你继续迭代并重复这种行为,直到质心不再移动,或者它们移动很少.


现在,让我们一个一个地回答你的问题.

1.复数表示

kMATLAB中的-means没有定义复杂数据的处理方式.人们处理复杂数字数据的常用方法是将实部和虚部分割成单独的维度.k对于复杂的有价数据,这是一种非常有效的方法.means.

有关详细信息,请参阅MathWorks MATLAB论坛上的这篇文章:https://www.mathworks.com/matlabcentral/newsreader/view_thread/78306

2.绘制结果

您没有X正确构建矩阵.注意,AC均为150×2矩阵.您需要构造X使每都是一个点,每列都是一个变量.因此,您需要连接您的AC .因此:

X = [A; A; A; C; C; A; C; C];
Run Code Online (Sandbox Code Playgroud)

请注意,您有重复的点.这实际上是不比做不同X = [A; C];尽可能kmeans关注.也许您应该生成X,然后添加噪声而不是采取AC添加噪声,然后构建您的信号.

现在,如果你要绘制的结果以及质心,你需要做的是使用两个输出版本kmeans,像这样:

[idx, centroids] = kmeans(X, 4);
Run Code Online (Sandbox Code Playgroud)

idx将包含每个点X所属的簇编号,并且centroids将是一个4 x 2矩阵,其中每行告诉您在数据中找到的每个簇的平均值.如果要绘制数据以及集群,只需执行以下操作即可.我将循环遍历每个集群成员资格并在结果上绘制结果.我还将着色每个群集的平均值所在的位置:

x = X(:,1);
y = X(:,2);
figure;
hold on;
colors = 'rgbk';
for num = 1 : 4
    plot(x(idx == num), y(idx == num), [colors(num) '.']);
end

plot(centroids(:,1), centroids(:,2), 'c.', 'MarkerSize', 14);
grid;
Run Code Online (Sandbox Code Playgroud)

上面的代码遍历每个聚类,用不同的颜色绘制它们,然后将青色的质心绘制成稍大的厚度,这样你就可以看到图形的样子.

这就是我得到的:

在此输入图像描述

3.了解质心结果

这可能是因为你没有X正确构建.这就是我的质心所得到的:

centroids =

   -1.9176   -2.0759
    1.5980    2.8071
    2.7486    1.6147
    0.8202    0.8025
Run Code Online (Sandbox Code Playgroud)

这是非常不言自明的,我谈到了如何更早地构建它.

4.信号的最佳表示

您可以做的是多次重复聚类,然后算法将决定这些时间内最佳聚类是什么.您只需使用该Replicates标志并表示您希望此次运行的次数.显然,运行此次的次数越多,结果就越好.因此,做一些事情:

[idx, centroids] = kmeans(X, 4, 'Replicates', 5);
Run Code Online (Sandbox Code Playgroud)

这将运行kmeans5次,并为您提供这5次最好的质心.

现在,如果你想确定传输的最佳序列,你必须将X每行分成150行(因为你的随机序列是150个元素),然后kmeans在每个子集上单独运行.您可以尝试通过每次使用Replicates标志来找到序列的每个部分的最佳表示....所以您可以执行以下操作:

for num = 1 : 8
    %// Look at 150 points at a time
    [idx, centroids] = kmeans(X((num-1)*150 + 1 : num*150, :), 4, 'Replicates', 5);

    %// Do your analysis
    %//...
    %//...
end
Run Code Online (Sandbox Code Playgroud)

idx并且centroids将是您传输信号的每个部分的结果.您可能希望查看centroids每次迭代以确定在特定时间传输的符号.


如果你想绘制决策区域,那么你可能正在寻找Voronoi图.您所做的只是给出了一组在问题域内定义的点,您只需要确定每个点属于哪个簇.鉴于我们的数据跨越-5 <= (x,y) <= 5,我们遍历网格中的每个点并确定每个点属于哪个集群.然后,我们根据它所属的群集为相应的点着色.

就像是:

colors = 'rgbk';
[X,Y] = meshgrid(-5:0.05:5, -5:0.05:5);
X = X(:);
Y = Y(:);
figure;
hold on;
for idx = 1 : numel(X)
    [~,ind] = min(sum(bsxfun(@minus, [X(idx) Y(idx)], centroids).^2, 2));
    plot(X(idx), Y(idx), [colors(ind), '.']);
end
plot(centroids(:,1), centroids(:,2), 'c.', 'MarkerSize', 14);
Run Code Online (Sandbox Code Playgroud)

上面的代码将绘制特定配置的决策区域/ Voronoi图,以及集群中心所在的位置.请注意,代码是相当未优化的,并且图形生成需要一段时间,但我想快速编写一些内容来说明我的观点.

以下是决策区域的外观:

在此输入图像描述


希望这可以帮助!祝好运!