当前位置:   article > 正文

Matlab实现Bi-Kmeans算法(每行代码标注详细注解)

bi-kmeans

逐行代码讲解Bi-Kmeans算法的原理及其实现,后续将更新该算法的进一步优化的代码的讲解

目录

一、什么是Kmeans++算法

二、bi-kmeans算法原理

三、bi-kmeans算法代码解析

四、总结


一、什么是Kmeans++算法

         K-means和bi-kmeans算法都是基于欧式距离进行聚类分析的方法,它们都试图最小化每个簇内数据点与其聚类中心之间距离之和。它们之间主要区别在于如何确定聚类个数k和如何选择初始聚类中心。K-means算法需要人为指定k值,并且随机选择初始聚类中心;而bi-kmeans算法可以根据数据集的特征自动确定k值,并且按照一定的规则选择初始聚类中心。因此,bi-kmeans算法相比K-means算法更加灵活和稳定,但是也更加耗时和复杂。

二、bi-kmeans算法原理

         bi-kmeans算法是一种改进的k-means聚类算法,它的目标是将数据集划分为k个互不相交的簇,使得每个簇内的数据点尽可能相似,而不同簇之间的数据点尽可能不同。bi-kmeans算法的基本步骤如下:

        1)将数据集看作一个整体簇,计算其误差平方和SSE(sum of squared error)。

        2)在当前所有簇中,选择SSE最大的一个簇进行划分,即用k-means算法将该簇分为两个子簇。

        3)计算划分后所有簇的SSE之和,并与划分前进行比较,如果SSE之和减小了,则保留划分结果,否则取消划分。

        4)重复步骤2和3,直到达到预设的簇个数k或者不能继续降低SSE为止。

        bi-kmeans算法的优点是可以自动确定最佳的簇个数k,而不需要事先指定;另外,bi-kmeans算法可以克服k-means算法对初始聚类中心选择敏感和容易陷入局部最优解的问题。bi-kmeans算法的缺点是计算复杂度较高,需要多次运行k-means算法,并且每次都需要比较SSE。

三、bi-kmeans算法代码解析

为了实现bi-kmeans算法,我们需要定义以下几个函数:

  • dist2:计算两个点之间的欧氏距离的平方。
  • mykmeans:实现k-means算法,返回聚类结果和SSE。
  • bikmeans:实现bi-kmeans算法,返回聚类结果。

以下是这些函数的代码:

  1. % 计算两个点之间的欧氏距离的平方
  2. function d = dist2(x, y)
  3. d = sum((x - y) .^ 2);
  4. end
  5. % 实现k-means算法,返回聚类结果和SSE
  6. function [idx, C, SSE] = mykmeans(X, k)
  7. n = size(X, 1); % 数据集的大小
  8. idx = zeros(n, 1); % 初始化聚类标签
  9. C = X(randperm(n, k), :); % 随机选择k个数据点作为初始聚类中心
  10. SSE = 0; % 初始化SSE
  11. while true % 迭代直到收敛
  12. old_idx = idx; % 保存旧的聚类标签
  13. for i = 1 : n % 遍历每个数据点
  14. min_d = inf; % 初始化最小距离
  15. for j = 1 : k % 遍历每个聚类中心
  16. d = dist2(X(i, :), C(j, :)); % 计算距离
  17. if d < min_d % 如果距离更小
  18. min_d = d; % 更新最小距离
  19. idx(i) = j; % 更新聚类标签
  20. end
  21. end
  22. end
  23. for j = 1 : k % 遍历每个聚类中心
  24. C(j, :) = mean(X(idx == j, :)); % 更新聚类中心为均值
  25. end
  26. if isequal(old_idx, idx) % 如果聚类标签没有变化
  27. break; % 结束循环
  28. end
  29. end
  30. for i = 1 : n % 计算SSE
  31. SSE = SSE + dist2(X(i, :), C(idx(i), :));
  32. end
  33. end
  34. % 实现bi-kmeans算法,返回聚类结果
  35. function [idx, C] = bikmeans(X, k)
  36. n = size(X, 1); % 数据集的大小
  37. idx = ones(n, 1); % 初始化聚类标签为一个簇
  38. C = mean(X); % 初始化聚类中心为数据集的均值
  39. SSE = inf; % 初始化SSE为无穷大
  40. while size(C, 1) < k % 循环直到达到预设的簇个数
  41. minSSE = inf; % 初始化最小SSE为无穷大
  42. for i = 1 : size(C, 1) % 遍历每个簇
  43. Xi = X(idx == i, :); % 提取属于该簇的数据点
  44. [idxi, Ci, SSEi] = mykmeans(Xi, 2); % 用k-means算法将该簇分为两个子簇
  45. SSEj = SSE - sum(SSEi) + sum(SSEi); % 计算划分后的SSE之和
  46. if SSEj < minSSE % 如果SSE之和减小了
  47. minSSE = SSEj; % 更新最小SSE
  48. bestC = Ci; % 保存最佳划分的聚类中心
  49. bestIdx = idxi; % 保存最佳划分的聚类标签
  50. bestI = i; % 保存最佳划分的簇编号
  51. end
  52. end
  53. if minSSE < SSE % 如果最小SSE小于当前SSE
  54. SSE = minSSE; % 更新当前SSE
  55. C(bestI, :) = []; % 删除被划分的簇的聚类中心
  56. C = [C; bestC]; % 添加划分后的两个子簇的聚类中心
  57. idx(idx == bestI) = bestIdx + size(C, 1) - 2; % 更新被划分的簇的聚类标签
  58. else % 如果不能继续降低SSE
  59. break; % 结束循环
  60. end
  61. end
  62. end

        为了演示matlab实现bi-kmeans算法的效果,我们使用一个简单的二维数据集,其中包含四个不同的簇。我们先用散点图绘制出数据集,然后用我们定义的bikmeans函数进行聚类,并用不同的颜色和形状标记出聚类结果和聚类中心。以下是代码和结果:

  1. % 生成一个简单的二维数据集
  2. X = [randn(100, 2) + [0, 0]; randn(100, 2) + [5, 0]; randn(100, 2) + [0, 5]; randn(100, 2) + [5, 5]];
  3. % 绘制数据集
  4. figure;
  5. plot(X(:, 1), X(:, 2), 'k.');
  6. title('Data Set');
  7. xlabel('x1');
  8. ylabel('x2');
  9. % 聚类参数
  10. k = 4; % 聚类个数
  11. % 聚类
  12. [idx, C] = bikmeans(X, k);
  13. % 绘制聚类结果
  14. figure;
  15. gscatter(X(:, 1), X(:, 2), idx);
  16. hold on;
  17. plot(C(:, 1), C(:, 2), 'kx', 'MarkerSize', 10, 'LineWidth', 3);
  18. hold off;
  19. title('Clustering Result');
  20. xlabel('x1');
  21. ylabel('x2');
  22. legend('Cluster 1', 'Cluster 2', 'Cluster 3', 'Cluster 4', 'Centers');

四、总结

        又见面啦,本文介绍了如何用matlab实现bi-kmeans算法,并给出了一个简单的示例。bi-kmeans算法是一种改进的k-means聚类算法,它可以自动确定最佳的簇个数k,而不需要事先指定;另外,bi-kmeans算法可以克服k-means算法对初始聚类中心选择敏感和容易陷入局部最优解的问题。matlab实现bi-kmeans算法的关键是定义几个辅助函数,分别用于计算距离、进行k-means聚类和进行bi-kmeans聚类,快快点赞收藏学起来吧!后续将更新其他算法~

声明:本文内容由网友自发贡献,不代表【wpsshop博客】立场,版权归原作者所有,本站不承担相应法律责任。如您发现有侵权的内容,请联系我们。转载请注明出处:https://www.wpsshop.cn/w/笔触狂放9/article/detail/535523
推荐阅读
相关标签
  

闽ICP备14008679号