K-means均值聚类 MATLAB

原理:

K-means算法的工作原理:首先随机从数据集中选取K个点,每个点初始地代表每个族的聚类中心,然后计算剩余各个样本到聚类中心的距离,将它赋给最近的簇,接着重新计算每一簇的平均值, 整个过程不断重复,如果相邻两次调整没有明显变化,说明数据聚类形成的簇已经收敛。

计算流程

X1=(0,1)

X2=(1,0)

X3=(3,2)

X4=(7,7)

X5=(8,7)

X6=(9,7)

 

步骤一:随机选取N个点作为初始聚类中心,本文以x1(0,1),x2(1,0)为初始聚类中心

步骤二:计算各点到聚类中心的距离

52de75dbf9d64a4d9136b37358438360.png

 

步骤三:根据各点到聚类中心的距离将x分为2簇

类别

集合

(0,1)

X1

(1,0)

X2,x3,x4,x5,x6

步骤四:计算每簇x的平均坐标值,生成新的聚类中心

9db4dcd7d29c4720bb1132c841168ed1.png

 

将新生成的聚类中心(0,1),(28/5,23/5)重复步骤一,知道新生成的聚类中心与上一步生成的聚类中心相同,则结束循环。

代码展示

%% K-means 均值聚类
x = [0 1;1 0;3 2;7 7;8 7;9 7]
z = zeros(2,2)
z1 = zeros(2,2)%设置两个聚类中心
z = x(1:2,1:2)
while 1%1是判断表达式,1显示永远为真,即永远循环,所以循环体中必须存在break
    count = zeros(2,1);
    allsum = zeros(2,2);
    for i = 1:6
        temp1 = sqrt((z(1,1)-x(i,1)).^2+(z(1,2)-x(i,2)).^2);%sqrt返还数组每一个元素的平方根,这里是计算x每一个坐标点与第一个坐标点的距离
        temp2 = sqrt((z(2,1)-x(i,1)).^2+(z(2,2)-x(i,2)).^2);%计算x每一个坐标点与第二个坐标点的距离
        if(temp1<temp2)%x中与第一个接近的坐标点计数、求和
            count(1) = count(1)+1;
            allsum(1,1) = allsum(1,1)+x(i,1);
            allsum(1,2) = allsum(1,2)+x(i,2);
            t(i,1) = x(i,1)
            t(i,2) = x(i,2)
        %x中与第一个接近的坐标点计数、求和
        else
            (temp2<temp1)
              count(2) = count(2)+1;
              allsum(2,1) = allsum(2,1)+x(i,1);
              allsum(2,2) = allsum(2,2)+x(i,2);
        end 
    end
        
    z1(1,1) = allsum(1,1)/count(1);%与第一个接近的坐标点的横坐标求平均数
    z1(1,2) = allsum(1,2)/count(1);%与第一个接近的坐标点的纵坐标求平均数
    z1(2,1) = allsum(2,1)/count(2);%与第二个接近的坐标点的横坐标求平均数
    z1(2,2) = allsum(2,2)/count(2);%与第二个接近的坐标点的横坐标求平均数
    if(z == z1)
      break
    else
        z = z1
    end
end

如何改变聚类中心数(以3为例)

%改变聚类中心数为3
x = [0 1;1 0;3 2;7 7;8 7;9 7]
z = zeros(3,2)
z1 = zeros(3,2)%设置两个聚类中心
z = x(1:3,1:2)
while 1%1是判断表达式,1显示永远为真,即永远循环,所以循环体中必须存在break
    count = zeros(3,1);
    allsum = zeros(3,2);
    for i = 1:6
        temp1 = sqrt((z(1,1)-x(i,1)).^2+(z(1,2)-x(i,2)).^2);%sqrt返还数组每一个元素的平方根,这里是计算x每一个坐标点与第一个坐标点的距离
        temp2 = sqrt((z(2,1)-x(i,1)).^2+(z(2,2)-x(i,2)).^2);%计算x每一个坐标点与第二个坐标点的距离
        temp3 = sqrt((z(3,1)-x(i,1)).^2+(z(3,2)-x(i,2)).^2);
        if(temp1<temp2)&&(temp1<temp3)%x中与第一个接近的坐标点计数、求和
            count(1) = count(1)+1;
            allsum(1,1) = allsum(1,1)+x(i,1);
            allsum(1,2) = allsum(1,2)+x(i,2);
        %x中与第一个接近的坐标点计数、求和
        elseif(temp2<temp1)&&(temp2<temp3)
              count(2) = count(2)+1;
              allsum(2,1) = allsum(2,1)+x(i,1);
              allsum(2,2) = allsum(2,2)+x(i,2);
        else
           count(3) = count(3)+1;
           allsum(3,1) = allsum(3,1)+x(i,1);
           allsum(3,2) = allsum(3,2)+x(i,2); 
        end
    end
    z1(1,1) = allsum(1,1)/count(1);%与第一个接近的坐标点的横坐标求平均数
    z1(1,2) = allsum(1,2)/count(1);%与第一个接近的坐标点的纵坐标求平均数
    z1(2,1) = allsum(2,1)/count(2);%与第二个接近的坐标点的横坐标求平均数
    z1(2,2) = allsum(2,2)/count(2);%与第二个接近的坐标点的横坐标求平均数
    z1(3,1) = allsum(3,1)/count(3);
    z1(3,2) = allsum(3,2)/count(3);
    if(z == z1)
        break
    else
        z = z1
    end
end

对聚类中心的原始数据可视化

x = [0 1;1 0;3 2;7 7;8 7;9 7]
z = zeros(2,2)
z1 = zeros(2,2)%设置两个聚类中心
z = x(1:2,1:2)
while 1%1是判断表达式,1显示永远为真,即永远循环,所以循环体中必须存在break
    count = zeros(2,1);
    allsum = zeros(2,2);
    for i = 1:6
        temp1 = sqrt((z(1,1)-x(i,1)).^2+(z(1,2)-x(i,2)).^2);%sqrt返还数组每一个元素的平方根,这里是计算x每一个坐标点与第一个坐标点的距离
        temp2 = sqrt((z(2,1)-x(i,1)).^2+(z(2,2)-x(i,2)).^2);%计算x每一个坐标点与第二个坐标点的距离
        if(temp1<temp2)%x中与第一个接近的坐标点计数、求和
            count(1) = count(1)+1;
            allsum(1,1) = allsum(1,1)+x(i,1);
            allsum(1,2) = allsum(1,2)+x(i,2);
            t(i,1) = x(i,1)
            t(i,2) = x(i,2)
        %x中与第一个接近的坐标点计数、求和
        else
            (temp2<temp1)
              count(2) = count(2)+1;
              allsum(2,1) = allsum(2,1)+x(i,1);
              allsum(2,2) = allsum(2,2)+x(i,2);
        end 
    end
        
    z1(1,1) = allsum(1,1)/count(1);%与第一个接近的坐标点的横坐标求平均数
    z1(1,2) = allsum(1,2)/count(1);%与第一个接近的坐标点的纵坐标求平均数
    z1(2,1) = allsum(2,1)/count(2);%与第二个接近的坐标点的横坐标求平均数
    z1(2,2) = allsum(2,2)/count(2);%与第二个接近的坐标点的横坐标求平均数
    if(z == z1)
      break
    else
        z = z1
    end
end

plot(x(:,1),x(:,2),'k*',...
    'LineWidth',2,...
    'MarkerSize',10,...
    'MarkerEdgeColor','k',...
    'MarkerFaceColor',[0.5,0.5,0.5])
hold on
plot(z1(:,1),z1(:,2),'ko',...
    'LineWidth',2,...
    'MarkerSize',10,...
    'MarkerEdgeColor','k',...
    'MarkerFaceColor',[0.5,0.5,0.5])
set(gca,'LineWidth',2);
xlabel('特征1','fontsize',12)
ylabel('特征2','fontsize',12)
title('k-means分类图','fontsize',12)

cca88510ddfe47309fab99b536dd6324.png

 

对不同分类的簇可视化区分

x = [0 1;1 0;3 2;7 7;8 7;9 7]
z = zeros(2,2)
z1 = zeros(2,2)%设置两个聚类中心
z = x(1:2,1:2)
while 1%1是判断表达式,1显示永远为真,即永远循环,所以循环体中必须存在break
    count = zeros(2,1);
    allsum = zeros(2,2);
    for i = 1:6
        temp1 = sqrt((z(1,1)-x(i,1)).^2+(z(1,2)-x(i,2)).^2);%sqrt返还数组每一个元素的平方根,这里是计算x每一个坐标点与第一个坐标点的距离
        temp2 = sqrt((z(2,1)-x(i,1)).^2+(z(2,2)-x(i,2)).^2);%计算x每一个坐标点与第二个坐标点的距离
        if(temp1<temp2)%x中与第一个接近的坐标点计数、求和
            count(1) = count(1)+1;
            allsum(1,1) = allsum(1,1)+x(i,1);
            allsum(1,2) = allsum(1,2)+x(i,2);
            t(i,1) = x(i,1)
            t(i,2) = x(i,2)
        %x中与第一个接近的坐标点计数、求和
        else
            (temp2<temp1)
              count(2) = count(2)+1;
              allsum(2,1) = allsum(2,1)+x(i,1);
              allsum(2,2) = allsum(2,2)+x(i,2);
              t(i,3) = x(i,1)
              t(i,4) = x(i,2)
        end 
    end
        
    z1(1,1) = allsum(1,1)/count(1);%与第一个接近的坐标点的横坐标求平均数
    z1(1,2) = allsum(1,2)/count(1);%与第一个接近的坐标点的纵坐标求平均数
    z1(2,1) = allsum(2,1)/count(2);%与第二个接近的坐标点的横坐标求平均数
    z1(2,2) = allsum(2,2)/count(2);%与第二个接近的坐标点的横坐标求平均数
    if(z == z1)
      break
    else
        z = z1
    end
end
%% 用颜色分类可视化
t1 = t(1:count(1),1:2)
t2 = t(count(1)+1:6,3:4)%6为聚类元素的总数
plot(t1(:,1),t1(:,2),'k*',...
    'LineWidth',2,...
    'MarkerSize',10,...
    'MarkerEdgeColor','k',...
    'MarkerFaceColor',[0.5,0.5,0.5])
hold on
plot(t2(:,1),t2(:,2),'k*',...
    'LineWidth',2,...
    'MarkerSize',10,...
    'MarkerEdgeColor','g',...
    'MarkerFaceColor',[0.5,0.5,0.5])
set(gca,'LineWidth',2);
xlabel('特征1','fontsize',12)
ylabel('特征2','fontsize',12)
title('k-means分类图','fontsize',12)

090014a7b3dc4c6abdbe06331006daa8.png

一维数组聚类

x = [0 ;1 ;3 ;7 ;8 ;9]
z = zeros(2,1)
z1 = zeros(2,1)%设置两个聚类中心
z = x(1:2,1)
while 1%1是判断表达式,1显示永远为真,即永远循环,所以循环体中必须存在break
    count = zeros(2,1);
    allsum = zeros(2,1);
    for i = 1:6
        temp1 = sqrt(z(1,1)-x(i,1).^2);%sqrt返还数组每一个元素的平方根,这里是计算x每一个坐标点与第一个坐标点的距离
        temp2 = sqrt(z(2,1)-x(i,1).^2);%计算x每一个坐标点与第二个坐标点的距离
        if(temp1<temp2)%x中与第一个接近的坐标点计数、求和
            count(1) = count(1)+1;
            allsum(1,1) = allsum(1,1)+x(i,1);
            t(i,1) = x(i,1)
        %x中与第一个接近的坐标点计数、求和
        else
            (temp2<temp1)
              count(2) = count(2)+1;
              allsum(2,1) = allsum(2,1)+x(i,1);
              t(i,2) = x(i,1)
        end 
    end
        
    z1(1,1) = allsum(1,1)/count(1);%与第一个接近的坐标点的横坐标求平均数
    z1(2,1) = allsum(2,1)/count(2);%与第二个接近的坐标点的横坐标求平均数
    if(z == z1)
      break
    else
        z = z1
    end
end
t1 = t(1:count(1),1)%储存类别1的分类结果
t2 = t(count(1)+1:6,2)%储存类别2的分类结果

调用函数kmeans(),及可视化

x = [0 1;1 0;3 2;7 7;8 7;9 7]
k = kmeans(x,3)%x为待聚类数组,3为自定义聚类中心数
%可视化
num1 = length(find(k==1))
num2 = length(find(k==2))
num3 = length(find(k==3))

t1 = x(1:3,:)
t2 = x(4:5,:)
t3 = x(6,:)

plot(t1(:,1),t1(:,2),'k*',...
    'LineWidth',2,...
    'MarkerSize',10,...
    'MarkerEdgeColor','k',...
    'MarkerFaceColor',[0.5,0.5,0.5])
hold on
plot(t2(:,1),t2(:,2),'k*',...
    'LineWidth',2,...
    'MarkerSize',10,...
    'MarkerEdgeColor','g',...
    'MarkerFaceColor',[0.5,0.5,0.5])
hold on
plot(t3(:,1),t3(:,2),'k*',...
    'LineWidth',2,...
    'MarkerSize',10,...
    'MarkerEdgeColor','y',...
    'MarkerFaceColor',[0.5,0.5,0.5])

set(gca,'LineWidth',2);
xlabel('特征1','fontsize',12)
ylabel('特征2','fontsize',12)
title('k-means分类图','fontsize',12)

df96bcaf33de4adaab341c1a75f0e4c9.png

 绘制kmeans聚类结果相关程度图

x = [0 1;1 0;3 2;7 7;8 7;9 7]
d = pdist(x)%计算任意两行数据之间的距离
dd = squareform(d)%返还距离矩阵
figure
imagesc(dd)%将矩阵中元素按照大小值转成不同颜色
set(gca,'LineWidth',2);
xlabel('数据点','fontsize',12)
ylabel('数据点','fontsize',12)
title('k-means聚类结果相关程度图','fontsize',12)
ylabel(colorbar,['距离矩阵'])
axis square

c86b898030e64b36b9a0f71f6c03c1bb.png

 

 

  • 3
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论
### 回答1: 分簇算法是一种常用的数据挖掘算法,可以根据数据的似性将其分为不同的Matlab是一个强大的科学计算软件,对于编写分簇算法的代码也提供了丰富的函数库和工具。 要编写一个分簇算法Matlab代码,可以按照以下步骤进行: 1. 导入数据:首先,需要导入待处理的数据。可以使用Matlab中的读取文件函数,如csvread()、xlsread()等,将数据加载到Matlab的工作环境中。 2. 数据预处理:根据实际需求,对数据进行必要的预处理。这包括数据清洗、数据缺失值处理、数据归一化等。 3. 选择合适的算法:根据具体问题选择适合的分簇算法。常见的分簇算法包括K均值聚类、层次聚类、DBSCAN等。在Matlab中,可以使用关的函数实现这些算法,如kmeans()、linkage()、dbscan()等。 4. 运行算法:根据选择的算法,调用应的函数进行分簇计算。比如,如果选择的是K均值聚类算法,可以使用kmeans()函数。该函数需要输入待处理的数据、的个数和其他可选参数,然后返回每个数据点所属的标签。 5. 结果分析与可视化:对算法的输出结果进行分析和可视化。可以使用Matlab中的函数,如clustergram()、scatter()等,来展示不同的分布情况。 最后,根据实际需求,可以对代码进行优化和扩展,以提高分簇算法的性能和准确性。这些包括对参数的调优、通过交叉验证等手段评估算法的性能,以及使用特征选择等方法提高数据的表征能力等。 综上所述,分簇算法Matlab代码编写需要涉及数据导入、预处理、选择算法、运行算法和结果分析等步骤。通过这些步骤,可以将原始数据按照似性划分成不同的,并从中获取有价值的信息。 ### 回答2: 分簇算法是一种常用的聚类分析方法,主要用于将数据集分为不同的,每个包含似的数据点。以下是一个使用Matlab编写的分簇算法的示例代码。 ```matlab % 读取数据集 data = csvread('data.csv'); % 设置聚类数量 k = 3; % 初始化质心 centroids = data(randperm(size(data, 1), k), :); while true % 计算每个数据点到质心的距离 distances = pdist2(data, centroids); % 将每个数据点分配到距离最近的质心中 [~, clusters] = min(distances, [], 2); % 保存上一次的质心 oldCentroids = centroids; % 更新质心为每个均值 for i = 1:k centroids(i, :) = mean(data(clusters == i, :)); end % 如果质心不再变化,则退出循环 if isequal(oldCentroids, centroids) break; end end % 打印每个的数据点 for i = 1:k clusterData = data(clusters == i, :); fprintf('Cluster %d: %d data points\n', i, size(clusterData, 1)); disp(clusterData); end ``` 以上代码的思路是不断迭代直到质心不再变化。首先根据给定的数据集和聚类数量,随机初始化质心。然后计算所有数据点到质心的距离,并根据距离将每个数据点分配到距离最近的质心所属的。接下来,更新每个质心中所有数据点的均值。重复这个过程直到质心不再变化。 最后,打印每个的数据点。可以根据实际需求对结果进行更多的处理和分析,例如可视化的结果或计算的评估指标等。 ### 回答3: 分簇算法是一种常用的数据挖掘算法,用于将数据集划分成若干个不同的以下是一个基于K-means算法分簇算法MATLAB代码: ```matlab % 读取数据 data = load('data.txt'); [n, m] = size(data); % n为数据样本数,m为特征数 % 定义参数 k = 3; % 的个数 max_iter = 100; % 最大迭代次数 % 初始化中心 centers = data(randperm(n, k), :); % 迭代更新中心 for iter = 1:max_iter % 计算每个样本与各个中心的距离 distances = pdist2(data, centers); % 对每个样本进行分配 [~, assignments] = min(distances, [], 2); % 更新中心 for i = 1:k cluster = data(assignments == i, :); if isempty(cluster) continue; end centers(i, :) = mean(cluster); end end % 可视化结果 gscatter(data(:, 1), data(:, 2), assignments); hold on; plot(centers(:, 1), centers(:, 2), 'kx', 'MarkerSize', 10, 'LineWidth', 2); legend('Cluster 1', 'Cluster 2', 'Cluster 3', 'Centers'); title('K-means Clustering'); ``` 这段代码使用了K-means算法进行分簇,首先读取数据,然后定义了个数k和最大迭代次数max_iter。代码进行初始化中心,然后进行迭代更新中心,直到达到最大迭代次数或者中心变化很小。最后,将分簇结果进行可视化展示。 注意:上述代码只适用于二维数据,并且需要将数据保存在名为"data.txt"的文件中,每行表示一个样本点,其中每个样本的特征值以空格或制表符分隔。实际使用时,需要根据具体问题进行修改和优化。

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

江希垣

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值