数学建模模型6——Kmeans算法【数据型】

K-means算法简述

  1. K-means算法,也称为K-平均或者K-均值,一般作为掌握聚类算法的第一个算法。
  2. 这里的K为常数,需事先设定,通俗地说该算法是将没有标注的 M 个样本通过迭代的方式聚集成K个簇。
  3. 在对样本进行聚集的过程往往是以样本之间的距离作为指标来划分。
  • 简单Demo说明
    在这里插入图片描述
    如上图以 K 为2,样本集为M 来描述KMean算法,算法执行步骤如下:
  1. 选取K个点做为初始聚集的簇心(也可选择非样本点);
  2. 分别计算每个样本点到 K个簇核心的距离(这里的距离一般取欧氏距离或余弦距离),找到离该点最近的簇核心,将它归属到对应的簇;
  3. 所有点都归属到簇之后, M个点就分为了 K个簇。之后重新计算每个簇的重心(平均距离中心),将其定为新的“簇核心”;
  4. 反复迭代 2 - 3 步骤,直到达到某个中止条件。
  • 注:常用的中止条件有迭代次数、最小平方误差MSE、簇中心点变化率;

由上述Demo可知,对于KMean算法来说有三个比较重要的因素要考虑,分别如下所述;

K-means算法思考

K值的选择: k 值对最终结果的影响至关重要,而它却必须要预先给定。给定合适的 k 值,需要先验知识,凭空估计很困难,或者可能导致效果很差。

  • 异常点的存在:K-means算法在迭代的过程中使用所有点的均值作为新的质点(中心点),如果簇中存在异常点,将导致均值偏差比较严重。 比如一个簇中有2、4、6、8、100五个数据,那么新的质点为24,显然这个质点离绝大多数点都比较远;在当前情况下,使用中位数6可能比使用均值的想法更好,使用中位数的聚类方式叫做K-Mediods聚类(K中值聚类)。

  • 初值敏感:K-means算法是初值敏感的,选择不同的初始值可能导致不同的簇划分规则。为了避免这种敏感性导致的最终结果异常性,可以采用初始化多套初始节点构造不同的分类规则,然后选择最优的构造规则。针对这点后面因此衍生了:二分K-Means算法、K-Means++算法、K-Means||算法、Canopy算法等。

  • 常用的几种距离计算方法

    通常情况下,在聚类算法中,样本的属性主要由其在特征空间中的相对距离来表示。
    这就使得距离这个概念,对于聚类非常重要。以下是几种最常见的距离计算方法。

    • 欧式距离(又称 2-norm 距离)
      在欧几里德空间中,点 x=(x1,…,xn) 和 y=(y1,…,yn) 之间的欧氏距离为:
      在这里插入图片描述
      在欧几里德度量下,两点之间线段最短。

    • 余弦距离(又称余弦相似性)
      两个向量间的余弦值可以通过使用欧几里德点积公式求出:
      a⋅b=∥a∥∥b∥cosθ
      所以:
      在这里插入图片描述
      也就是说,给定两个属性向量 A 和 B,其余弦距离(也可以理解为两向量夹角的余弦)由点积和向量长度给出,如下所示:
      在这里插入图片描述
      这里的 Ai 和 Bi 分别代表向量 A 和 B 的各分量。

    • 曼哈顿距离(Manhattan Distance, 又称 1-norm 距离)
      曼哈顿距离的定义,来自于计算在规划为方型建筑区块的城市(如曼哈顿)中行车的最短路径。
      假设一个城市是完备的块状划分,从一点到达另一点必须要按照之间所隔着的区块的边缘走,没有其他捷径(如下图):
      在这里插入图片描述
      因此,曼哈顿距离就是:在直角坐标系中,两点所形成的线段对 x 和 y 轴投影的长度总和。
      从点 (x1,y1) 到点 (x2,y2),曼哈顿距离为:
      |x1−x2|+|y1−y2|

    KMean算法的算法优缺点与适用场景

    优点

    • 理解容易,聚类效果不错;
    • 处理大数据集的时候,该算法可以保证较好的伸缩性和高效率;
    • 当簇近似高斯分布的时候,效果非常不错。

    缺点

    • K值是用户给定的,在进行数据处理前,K值是未知的,给定合适的 k 值,需要先验知识,凭空估计很困难,或者可能导致效果很差。
    • 对初始簇中心点是敏感的。
    • 不适合发现非凸形状的簇或者大小差别较大的簇。
    • 特殊值(离群值或称为异常值)对模型的影响比较大。

    代码

    2D数据

    % 初始化工作空间
    clc;
    clear;
    
    % 载入数据
    load fisheriris
    
    % 二维数据
    % 花瓣长度和花瓣宽度散点图(真实标记)
    figure;
    speciesNum = grp2idx(species);
    gscatter(meas(:,3),meas(:,4),speciesNum,['r','g','b'])
    xlabel('花瓣长度')
    ylabel('花瓣宽度')
    title('真实标记')
    set(gca,'FontSize',12)
    set(gca,'FontWeight','bold')
    
    % 花瓣长度和花瓣宽度散点图(无标记)
    figure;
    scatter(meas(:,3),meas(:,4),150,'.')
    xlabel('花瓣长度')
    ylabel('花瓣宽度')
    title('无标记')
    set(gca,'FontSize',12)
    set(gca,'FontWeight','bold')
    
    % kmeans 聚类
    data=[meas(:,3), meas(:,4)];
    K=3;
    [idx,cen]=kmeans(data,K,'Distance','sqeuclidean','Replicates',5,'Display','Final');
    % 调整标号
    dist=sum(cen.^2,2);
    [dump,sortind]=sort(dist,'ascend');
    newidx=zeros(size(idx));
    for i =1:K
        newidx(idx==i)=find(sortind==i);
    end
    
    % 花瓣长度和花瓣宽度散点图(kmeans分类)
    figure;
    gscatter(data(:,1),data(:,2),newidx,['r','g','b'])
    hold on
    scatter(cen(:,1),cen(:,2),300,'m*')
    hold off
    xlabel('花瓣长度')
    ylabel('花瓣宽度')
    title('kmeans分类')
    set(gca,'FontSize',12)
    set(gca,'FontWeight','bold')
    
    % 花瓣长度和花瓣宽度散点图(真实标记:实心圆+kmeans分类:)
    figure;
    gscatter(meas(:,3),meas(:,4),speciesNum,['r','g','b'])
    hold on
    gscatter(data(:,1),data(:,2),newidx,['r','g','b'],'o',10)
    scatter(cen(:,1),cen(:,2),300,'m*')
    hold off
    xlabel('花瓣长度')
    ylabel('花瓣宽度')
    title('真实标记:实心圆+kmeans分类:圈')
    set(gca,'FontSize',12)
    set(gca,'FontWeight','bold')
    
    %{
    % 混淆矩阵 ConfusionMatrix
    confMat=confusionmat(speciesNum,newidx)
    error23=speciesNum==2&newidx==3;
    errDat23=data(error23,:)
    error32=speciesNum==3&newidx==2;
    errDat32=data(error32,:)
    %}
    

    3D数据

    % 初始化工作空间
    clc;
    clear;
    
    % 载入数据
    load fisheriris
    
    % 三维数据
    % 花瓣长度、花瓣宽度、花萼长度散点图(无标记)
    figure;
    speciesNum = grp2idx(species);
    plot3(meas(:,3),meas(:,4),meas(:,1),'.','MarkerSize',20)
    grid on
    view([60,24])
    xlabel('花瓣长度')
    ylabel('花瓣宽度')
    zlabel('萼片长度')
    title('无标记')
    set(gca,'FontSize',12)
    set(gca,'FontWeight','Bold')
    
    % 花瓣长度、花瓣宽度、花萼长度散点图(真实标记)
    figure;
    hold on
    colorArray=['r','g','b'];
    for  i= 1:3
        plotind=speciesNum==i;
        plot3(meas(plotind,3),meas(plotind,4),meas(plotind,1),'.','MarkerSize',20,'MarkerEdgeColor',colorArray(i))
    end
    hold off
    grid on
    view([60,24])
    xlabel('花瓣长度')
    ylabel('花瓣宽度')
    zlabel('萼片长度')
    title('真实标记')
    set(gca,'FontSize',12)
    set(gca,'FontWeight','Bold')
    
    
    % kmeans 聚类
    data2=[ meas(:,3), meas(:,4),meas(:,1)];
    K=3;
    [idx2,cen2]=kmeans(data2,K,'Distance','sqeuclidean','Replicates',5,'Display','Final');
    % 调整标号
    dist2=sum(cen2.^2,2);
    [dump2,sortind2]=sort(dist2,'ascend');
    newidx2=zeros(size(idx2));
    for i =1:K
        newidx2(idx2==i)=find(sortind2==i);
    end
    
    % 花瓣长度和花瓣宽度散点图(真实标记:实心圆+kmeans分类:)
    figure;
    hold on
    colorArray=['r','g','b'];
    for  i= 1:3
        plotind=speciesNum==i;
        plot3(meas(plotind,3),meas(plotind,4),meas(plotind,1),'.','MarkerSize',15,'MarkerEdgeColor',colorArray(i))
    end
    
    for  i= 1:3
        plotind=newidx2==i;
        plot3(meas(plotind,3),meas(plotind,4),meas(plotind,1),'o','MarkerSize',10,'MarkerEdgeColor',colorArray(i))
    end
    for i=1:3
        plot3(cen2(i,1),cen2(i,2),cen2(i,3),'*m')
    end
    
    hold off
    grid on
    view([60,24])
    xlabel('花瓣长度')  
    ylabel('花瓣宽度')
    zlabel('萼片长度')
    title('真实标记:实心圆+kmeans分类:圈')
    set(gca,'FontSize',12)
    set(gca,'FontWeight','Bold')
    
    %{
    % 混淆矩阵 ConfusionMatrix
    confMat=confusionmat(speciesNum,newidx2)
    error23=speciesNum==2&newidx2==3;
    errDat23=data2(error23,:)
    error32=speciesNum==3&newidx2==2;
    errDat32=data2(error32,:)
    [dump, errdatSort]=sort(errDat32(:,3));
    errDat32Sort=errDat32(errdatSort,:)
    %}
    

    代码参考:https://www.bilibili.com/video/av38476149?from=search&seid=3151051302140581746

  • 0
    点赞
  • 12
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值