【大数据分析与挖掘算法】matlab实现——k-means聚类算法
k-means聚类算法的简单实现
·
实验三 :k-means聚类方法
一、实验目的
掌握有关k-means聚类方法的理论知识,通过反复迭代改变分组的重定位,让同一个簇当中的对象尽可能“相似”,不同簇中的对象尽可能“相异”。
二、实验任务
对k-means聚类方法进行编码计算,实例如下:
三、实验过程
1.k-means算法模型介绍:
四、实验结果
实现平台:Matlab 2022A
实验代码:
clc; clear; close all;
% 初始化数据
%书上数据
data(:,1) = [1, 5, 10, 9, 26, 32, 16, 21, 14];
data(:,2) = [0, 0, 0, 0, 0, 0, 0, 0, 0];
%随机大量二维数据
%data(:,1) = randi([0, 100], 100, 1);
%data(:,2) = randi([0, 100], 100, 1);
% 绘制原始数据散点图
figure(1)
scatter(data(:,1),data(:,2),'LineWidth',2)
title("原始数据散点图")
% 设置聚类数
cluster_num = 3;
% 调用K-Means算法进行聚类
[index_cluster, cluster, E] = kmeans_func(data, cluster_num);
% 绘制聚类效果图
figure(2)
a = unique(index_cluster); % 找出分类出的个数
C = cell(1,length(a));
for i = 1:length(a)
C{1,i} = find(index_cluster == a(i)); % 将相同簇的索引存储在C中
end
for j = 1:cluster_num
data_get = data(C{1,j},:);
if j == 1
scatter(data_get(:,1),data_get(:,2),100,'o','filled','MarkerFaceAlpha',.6,'MarkerEdgeAlpha',.9);
elseif j == 2
scatter(data_get(:,1),data_get(:,2),100,'s','filled','MarkerFaceAlpha',.6,'MarkerEdgeAlpha',.9);
elseif j == 3
scatter(data_get(:,1),data_get(:,2),100,'^','filled','MarkerFaceAlpha',.6,'MarkerEdgeAlpha',.9);
end
hold on
end
% 绘制聚类中心
plot(cluster(:,1),cluster(:,2),'ks','LineWidth',2);
hold on
% 计算并显示轮廓系数
sc_t = mean(silhouette(data, index_cluster'));
title_str = ['原理推导K均值聚类', ' 聚类数为:', num2str(cluster_num), ' SC轮廓系数:', num2str(sc_t), ' 准则函数E:', num2str(E)];
title(title_str)
% K-Means算法实现
function [index_cluster, cluster, E] = kmeans_func(data, cluster_num)
% 原理推导Kmeans聚类算法
[m, n] = size(data); % 获取数据的行数和列数
cluster = data(randperm(m, cluster_num), :); % 从m个点中随机选择cluster_num个点作为初始聚类中心点
epoch_max = 1000; % 最大迭代次数
therad_lim = 0.001; % 中心变化阈值
epoch_num = 0; % 迭代次数初始化
E = inf; % 初始化准则函数E
while (epoch_num < epoch_max)
epoch_num = epoch_num + 1; % 迭代次数加1
% distance1存储每个点到各聚类中心的欧氏距离
for i = 1:cluster_num
distance = (data - repmat(cluster(i,:), m, 1)).^2;
distance1(:, i) = sqrt(sum(distance, 2));
end
[~, index_cluster] = min(distance1, [], 2); % 找到每个点距离最近的聚类中心
% cluster_new存储新的聚类中心
for j = 1:cluster_num
cluster_new(j, :) = mean(data(find(index_cluster == j), :)); % 计算新的聚类中心
end
% 计算当前聚类结果的准则函数E
E_new = 0;
for j = 1:cluster_num
E_new = E_new + sum(sum((data(find(index_cluster == j), :) - cluster(j, :)).^2));
end
% 如果新的聚类中心和上一轮的聚类中心距离和大于阈值,更新聚类中心,否则算法结束
if (sqrt(sum((cluster_new - cluster).^2, 'all')) > therad_lim)
cluster = cluster_new; % 更新聚类中心
E = E_new; % 更新准则函数E
else
break; % 跳出循环,算法结束
end
end
end
实验结果:
①基本结果
运行书上实例
②额外结果
计算数据量更大的二维数据实例
开放原子开发者工作坊旨在鼓励更多人参与开源活动,与志同道合的开发者们相互交流开发经验、分享开发心得、获取前沿技术趋势。工作坊有多种形式的开发者活动,如meetup、训练营等,主打技术交流,干货满满,真诚地邀请各位开发者共同参与!
更多推荐
已为社区贡献8条内容
所有评论(0)