K-means算法

2023-05-16

算法描述:

1>    从N个数据中选出K个元素作为质心,即数据将被分成K簇

2>    依次计算剩下的每一个元素到K个元素的相异度,一般是计算距离,将这些元素分别划分到相异度最低的簇中去

3>    根据聚类结果分别重新计算k个簇各自的中心,计算方法是取簇中各维度的算术平均值。

4>    将D的全部元素按照新的中心重新聚类。

5>    重复第四步,直到聚类结果不再发生改变。

6>    将结果输出

算法的工作过程:

    首先从n个数据对象任意选择K个作为初始聚类中心,对于剩下的其它对象,则根据它们与这些聚类中心的相似度(距离),分别将它们分配到与其最相似的聚类中,然后再计算新的聚类的聚类质心,不断重复这个过程,直至标准测度函数收敛为止,一般采用均方差作为标准测度函数。

K-means算法的特点:

各簇之间的差异性较大,簇内的相似性较大

用数学表达式来说就是:

在聚类中的训练样本是{x(1),……x(m)},每个x(i)∈R(n)没有y


K-means算法就是将样本聚类冲K个簇

① 随机选取K个聚类质心点,分别为μ1,μ2,……,μk∈ Rn

②重复下面过程直到收敛

{

对于每一个样本计算它应该属于的簇(类)


对于每一个簇(类)重新计算质心


}

K是实现由用户给定的聚类数, 表示样例i与k个类中质心点距离最近的那个类,的值是1到K中的一个,质心 代表对属于同一个类的样本中心点的猜测。

K-means 算法可以说是一个不断迭代的问题,目的是为了求得每个样本点到质心的最小距离。公式描述如下:


J函数表示每个样本点到其质心的距离平方和。K-means算法是要将其调整到最小值,可以看出这个J函数最终是收敛的,因为不管是调整质心或是调整每个样例所属的类别,都可以让J逐渐变小,当J减到最小的时候,μ和c也就同时收敛。

这样可以得到K-means算法的时间复杂度和空间复杂度:

时间复杂度:O(tKmn),其中t为迭代次数,K为簇的数目,m为记录数目,n为维数

空间复杂度:O((m+K)*n),m为记录数目,K为簇的数目,n为维数

k-means算法的不足之处:

① K值是事先给定的,但是这个K的值不太好确定,事先不清楚到底分多少个类比较合适。

② 聚类质心不好选择,初始的聚类质心的值的选择对聚类结果具有较大的影响。由于K-means算法的聚类准则函数是常用的误差平

方和准则函数,是一个非凸函数,存在多个局部极小值,只有一个是全局最小的。加上K-means聚类算法随机选取的初始中心往往

会落入到非凸函数曲面的位置,从而导致与全局最优解的范围存在一定偏离,因此通过迭代技术往往使聚类准则函数达到局部最优

而非全局最优的解。

③ 算法的开支比较大,因为要不断地对样本进行分类调整,并需要不断地计算新的簇的质心,因此当数据量很大的时候,算法的时间开发就很大了。

 

K-means算法在人体运动编辑与合成方面的应用:

应用流形学习技术结合K-means算法对长运动序列进行聚类分析以达到动作分割目的


matlab源代码:

KMeans.m

%N是数据一共分多少类
%data是输入的不带分类标号的数据
%u是每一类的中心
%re是返回的带分类标号的数据
function [u re]=KMeans(data,N)   
    [m n]=size(data);   %m是数据个数,n是数据维数
    ma=zeros(n);        %每一维最大的数
    mi=zeros(n);        %每一维最小的数
    u=zeros(N,n);       %随机初始化,最终迭代到每一类的中心位置
    for i=1:n
       ma(i)=max(data(:,i));    %每一维最大的数
       mi(i)=min(data(:,i));    %每一维最小的数
       for j=1:N
            u(j,i)=ma(i)+(mi(i)-ma(i))*rand();  %随机初始化,不过还是在每一维[min max]中初始化好些
       end      
    end
    
    while 1
        pre_u=u;            %上一次求得的中心位置
        for i=1:N
            tmp{i}=[];      % 公式一中的x(i)-uj,为公式一实现做准备
            for j=1:m
                tmp{i}=[tmp{i};data(j,:)-u(i,:)];  %tmp存数的是每个数据减去每个聚类中心的结果,这是第i个聚类中心
            end
        end
        
        quan=zeros(m,N);
        for i=1:m        %公式一的实现
            c=[];
            for j=1:N
                c=[c norm(tmp{j}(i,:))];%返回二范数
            end
            [junk index]=min(c); %找每行得到的j个最小值的最终最小值,并返回其是那个聚类
            quan(i,index)=norm(tmp{index}(i,:));%得到当前行的对应最小二范数的值           
        end
        
        for i=1:N            %公式二的实现
           for j=1:n
                u(i,j)=sum(quan(:,i).*data(:,j))/sum(quan(:,i));%重新计算质心
           end           
        end
        
        if norm(pre_u-u)<0.1  %不断迭代直到位置不再变化
            break;
        end
    end
    
    re=[];
    %迭代不再发生变化,那就说明达到最后一步了,直接再计算一次二范数,去最小的那个,得到每一行所属的标签
    %可以看到与上面的步骤相同。
    for i=1:m
        tmp=[];
        for j=1:N
            tmp=[tmp norm(data(i,:)-u(j,:))];
        end
        [junk index]=min(tmp);
        re=[re;data(i,:) index];
    end
    
end


KMeansTset.m


clear all;
close all;
clc;

%第一类数据
mu1=[0 0 0];  %均值
S1=[0.3 0 0;0 0.35 0;0 0 0.3];  %协方差
data1=mvnrnd(mu1,S1,100);   %产生高斯分布数据

%%第二类数据
mu2=[1.25 1.25 1.25];
S2=[0.3 0 0;0 0.35 0;0 0 0.3];
data2=mvnrnd(mu2,S2,100);

%第三个类数据
mu3=[-1.25 1.25 -1.25];
S3=[0.3 0 0;0 0.35 0;0 0 0.3];
data3=mvnrnd(mu3,S3,100);

%显示数据
plot3(data1(:,1),data1(:,2),data1(:,3),'+');
hold on;
plot3(data2(:,1),data2(:,2),data2(:,3),'r+');
plot3(data3(:,1),data3(:,2),data3(:,3),'g+');
grid on;

%三类数据合成一个不带标号的数据类
data=[data1;data2;data3];   %这里的data是不带标号的

%k-means聚类
[u re]=KMeans(data,3);  %最后产生带标号的数据,标号在所有数据的最后,意思就是数据再加一维度
[m n]=size(re);

%最后显示聚类后的数据
figure;
for i=1:m 
    if re(i,4)==1   
         plot3(re(i,1),re(i,2),re(i,3),'ro'); 
         hold on;
    elseif re(i,4)==2
         plot3(re(i,1),re(i,2),re(i,3),'go'); 
         hold on;
    else 
         plot3(re(i,1),re(i,2),re(i,3),'bo'); 
         hold on;
    end
end
grid on;


最终结果:

聚类之前的数据:


聚类之后的数据:


本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

K-means算法 的相关文章

随机推荐

  • node.js及vue安装配置详解

    一 node js 安装配置 1 下载 首先先下载node js xff0c 通过以下链接进行选择下载 https nodejs org download release 选择自己想要的版本进行下载 2 安装 下载完成后双击node exe
  • BP神经网路详解(误差反向传播-链式求导法则)

    BP神经网络详解 简介 BP xff08 Back Propagation xff09 网络是1985年由Rumelhart和McCelland为首的科学家小组提出 xff0c 是一种按误差逆传播算法训练的多层前馈网络 xff0c 是目前应
  • OpenSSL: error:14077410:SSL routines:SSL23_GET_SERVER_HELLO:sslv3 alert handshake failur

    OpenSSL error 14077410 SSL routines SSL23 GET SERVER HELLO sslv3 alert handshake failure Unable to establish SSL connect
  • CV和NLP不分家

    嗯 xff0c 好久没有登陆csdn了 xff0c 看了一下 xff0c 距离上一篇文章发表已经过去了整整半年的时间了 xff0c 消息堆叠了将近100条 也没办法一一回复了 xff0c 因为这么长时间过去了 xff0c 不知道大家的问题都
  • 2022-09-14-openstack介绍

    1 云计算介绍 计算 xff08 CPU 内存 xff09 存储和网络是 IT 系统的三类资源 通过云计算平台 xff0c 这三类资源变成了三个资源池 当需要虚机的时候 xff0c 只需要向平台提供虚机的规格 平台会快速从三个资源池分配相应
  • docker debian中apt-get源替换为阿里源

    场景 docker容器内安装太慢 xff0c 实在受不了这速度了 解决方案 将默认的debian源替换为阿里源 cat命令 因为默认不带vim 查看源配置文件 xff1a span class token function cat span
  • Spring整合Junit

    原始Junit测试Spring的问题 在测试类中 xff0c 每个测试方法都有以下两行代码 xff1a ApplicationContext ac 61 new ClassPathXmlApplicationContext 34 bean
  • STM32驱动舵机(附例程)

    一 PWM Mode xff1a 当计数值小于CRR寄存器值时输出为有效电平 xff0c 而有效电平要根据OCXInit来设置 xff0c 设置的有效电平为高则当CNT值小于设置的CRR寄存器值时输出有效电平高电平 xff0c 当CNT值大
  • Win10下安装Anaconda后,conda不是内部或者外部命令

    今天在安装TAnaconda时 xff0c 在开始 gt 运行 gt cmd时输入如下命令 xff1a conda version 时显示出错 xff0c cuda不是内部或者外部命令 xff1b 第一直觉就是去检查环境变量 xff0c 你
  • VM16-ubuntu16桥接网络频繁掉线

    故障说明 旧电脑使用的vm15 ubuntu16 xff0c 通过移植安装到新电脑 xff0c 后又通过升级把虚拟机升级到vm16 xff0c 更改网络连接的NAT模式到桥接模式 xff0c 发现网络即使出现正常连接的图标和正确的IP地址但
  • IPTV机顶盒刷机过程--山东电信【天邑TY608】

    IPTV机顶盒刷机过程 山东电信 天邑TY608 准备工具拆机过程开始刷机 准备工具 双公头USB数据线 刷机小板 xff0c 我用的是淘宝买的USB转TTL的CH340G的小板 电烙铁 焊锡丝 焊锡膏 单排排针 拆机过程 这个型号的机顶盒
  • OpenStack Availability Zone和Aggregate Hosts理解

    1 availability zone az是在region范围内的再次切分 xff0c 只是工程上的独立 xff0c 例如可以把一个机架上的机器划分在一个az中 xff0c 划分az是为了提高容灾性和提供廉价的隔离服务 选择不同的regi
  • Mysql 根据月份分组并返回分组中的所有数据

    现有数据如下 xff1a 交易描述 金额 时间 交易A 1000 2021 01 28 交易B 2000 2021 01 30 交易C 3000 2021 02 03 交易D 4000 2021 02 04 交易E 5000 2021 02
  • 程序设计思维与实践 Week13 作业 (3/4/数据班)

    A TT 的神秘任务1 xff08 必做 xff09 这一天 xff0c TT 遇到了一个神秘人 神秘人给了两个数字 xff0c 分别表示 n 和 k xff0c 并要求 TT 给出 k 个奇偶性相同的正整数 xff0c 使得其和等于 n
  • 安装scikit-learn问题

    1 问题描述如下 xff1a pytorch root 64 cento conda install scikit learn Solving environment failed CondaHTTPError HTTP 000 CONNE
  • 火狐下setting a property that has only a getter 的错误, 真是诡异...

    刚刚遇到了个很诡异的问题 xff0c 有一段看似没有错误的js代码硬是在火狐下会报个 setting a property that has only a getter 错误 xff0c 而在其他浏览器下却可以正常运行 xff0c 代码大概
  • 最新社区版idea插件“intellij-spring-assistant”

    1 背景 idea社区版已经用了好长时间了 xff0c 其中丰富的插件库让社区版使用起来与专业版无差异 xff0c 完全能够满足当前工作需求 xff0c 但是随着版本的不断更新 xff0c 原作者已不再更新 xff0c 导致无法在新版本上使
  • VS2017/2019中默认编码问题,修改文本编码格式 为UTF-8

    1 修改VS中单个文本编码方式 VS2017 2019中默认格式为 GB2312 很多时候可能出现乱码情况 xff0c 就是编码问题 xff0c 接下来 xff0c 可以修改编码方式 xff1a 操作方法如下所示 xff1a 首先 xff0
  • 宏定义中的括号和自增自减运算(1)

    宏定义中容易引起许多运算优先级的问题 xff0c 需要用括号加以约束 例如 define abs x x gt 0 x x abs a b abs a 43 1 带入展开后 xff0c 结果如下 xff1a a b gt 0 a b a b
  • K-means算法

    算法描述 xff1a 1 gt 从N个数据中选出K个元素作为质心 xff0c 即数据将被分成K簇 2 gt 依次计算剩下的每一个元素到K个元素的相异度 xff0c 一般是计算距离 xff0c 将这些元素分别划分到相异度最低的簇中去 3 gt