在Matlab实现Kmeans算法(每行代码带注释)

2023-11-18

目录

一、前言

二、VQ概述

三、Kmeans算法

K-means 的算法步骤为:

 四、Matlab代码实现过程

五、 一点点可选改动(个人看法)

参考链接: 


一、前言

本人对机器学习、人工智能算法方面没什么研究,只是学习过程中恰好碰到了。

一开始看Kmeans算法只是为了图像(矩阵)的VQ(vector quantization),找了网上不少资料,跟VQ相关的比较多是LBG算法,单独找kmeans跟VQ联系不起来,后面研究了一下,得到这篇博客主要想表达的内容。

二、VQ概述

        VectorQuantization (VQ)是一种基于块编码规则的有损数据压缩方法。事实上,在 JPEG 和 MPEG-4 等多媒体压缩格式里都有 VQ 这一步。它的基本思想是:将若干个标量数据组构成一个矢量,然后在矢量空间给以整体量化,从而压缩了数据而不损失多少信息。

       在以前,VQ运用的一个难点在于它要要解决一个多维积分(multi-dimensional integration)的问题。后来,在1980年,Linde, Buzo和Gray(LBG,这个缩写也是LBG算法的命名)提出一种基于训练序列的VQ设计算法,对训练序列的运用绕开了多维积分的求解,使得世上又诞生了一种经典的被世人称为LBG-VQ的算法!它一直延绵至今,经典永不褪色。

三、Kmeans算法

K-means 有一个著名的解释:牧师—村民模型:

有四个牧师去郊区布道,一开始牧师们随意选了几个布道点,并且把这几个布道点的情况公告给了郊区所有的村民,于是每个村民到离自己家最近的布道点去听课。
听课之后,大家觉得距离太远了,于是每个牧师统计了一下自己的课上所有的村民的地址,搬到了所有地址的中心地带,并且在海报上更新了自己的布道点的位置。
牧师每一次移动不可能离所有人都更近,有的人发现A牧师移动以后自己还不如去B牧师处听课更近,于是每个村民又去了离自己最近的布道点……
就这样,牧师每个礼拜更新自己的位置,村民根据自己的情况选择布道点,最终稳定了下来。

K-means 的算法步骤为:

  1. 选择初始化的 k 个样本作为初始聚类中心 a=a1,a2,…ak ;
  2. 针对数据集中每个样本 xi 计算它到 k 个聚类中心的距离将其分到距离最小的聚类中心所对应的类中;
  3. 针对每个类别 aj ,重新计算它的聚类中心 aj=1|ci|∑x∈cix (即属于该类的所有样本的质心);
  4. 重复上面 2 3 两步操作,直到达到某个中止条件(迭代次数、最小误差变化等)。

 四、Matlab代码实现过程

(代码由参考文献中代码修改而来)

function [W, E_in, V] = KMeans(data, K)
%W是k个中心点;E_in是聚合效果,显示所有点的平均距离;V用中心点表示的新的数据
[N, d] = size(data);             %d个n维的点
% init W
sampleIds = randsample(d, K);    %从d个点中随机选择k个点作为中心点
W = data(:,sampleIds);                   %以这k个点为中心形成簇类
labels_u = zeros(1,d);                   %初始换建立一个1行d列的零数组
stop = true;  
while stop                                %把true复制给stop,需要一直循环
    stop = false;
    for i = 1:d                           %从第1个点一直到第d个点,得到每个点与对应最近中心
        x = data(:,i);                   %读取第1个数据放到X里面
        % check label        
        label = 0;                        %初始化label为0,代表是第几个簇类
        dist = 0;                         %初始化dist距离为0
        for j = 1:K                       %计算到达三个中心点的距离,依次推断属于哪个簇类
            tmp_dist = norm(x-W(:,j));        %计算欧式距离
            if label == 0 || tmp_dist < dist       %如果是第一次计算lable=0或者此时的距离小于上一次计算出的距离
                label = j;                         %当前的点暂时属于第j个聚类
                dist = tmp_dist;                   %欧式距离更新为当前的更小值
            end                                    
        end                                        %循环结束
        if labels_u(i) == label                    %如果第个i点不等于label
            stop = stop | false;                          %继续循环
        else
            stop = stop | true;
            labels_u(i) = label;                       %第个i点属于第label个簇类
        end
    end
    if stop == false                                %退出循环
        break;
    end
    %update W                                      %更新中心点
    new_W = zeros(N, K);                           %初始化中心点,并全部清零
    labels_count = zeros(1,K);                    %统计不同簇类的个数
    for i = 1:d                                    %遍历所有点
        label = labels_u(i);                       %提取出簇类标志
        new_W(:,label) = new_W(:,label) + data(:,i);    %相同簇类data数据之和
        labels_count(label) = labels_count(label) + 1;     %属于相同簇类的点的个数
    end
    for i = 1:K   %
        new_W(:,i) = new_W(:,i)/labels_count(i);        %初始化的中心点除以每个聚类里面总的个数,求出新质心
    end
    W = new_W;                         %用新的W来代替
end
E_in = 0;
V = zeros(N,d);
for i = 1:d                            %d个点需要重新遍历
    label = labels_u(i);               %将label标签提取出来
    V(:,i) = W(:,label);                 %用中心表示新数据
    E_in = E_in + norm(data(i)-W(:,label));     %每一个点跟对应中心的距离,所有的距离应该是欧式距离的和
end
E_in = E_in/d;                         %欧式距离的和除以d,每个点距离的均值,表示聚合的效果
end

输入参数:data 为原始数据,对应一列为“一点”,列数即为“点数”;k 表示需要的聚类中心个数

输出参数:W 为得到的聚类中心;E_in 所有点到对应中心距离的平均值,表示聚合效果;V 用对应聚类中心代替原有数据得到的新数据。

由VQ的相关概念可知,V可用 V = WH 进行表示,即用V近似表示原有数据data,或用W表示data达到数据降维的效果。系数H可在上面代码中倒数第五行加入 H(label,i) = 1 ,或得到输出结果后用 H = W\V 得到,表示原来第i个数据的聚类中心为第label个。

五、 一点点可选改动(个人看法)

上面代码中,聚类中心为 聚类中的所有点 求均值所得,但是所得 中心点 一般不在原数据中,可以进行计算,在最后分好对应聚类后(最后一次循环结束前),再计算一次距离,令离中心最近的原有的点 成为中心,这样更有利于VQ。

参考链接: 

(2条消息) Matlab实现Kmeans算法(每行代码标注详细注解)_高垚淼的博客-CSDN博客_matlab kmeans

【机器学习】K-means(非常详细) - 知乎 (zhihu.com)

(3条消息) 【机器学习】【数字信号处理】矢量量化(Vector Quantization)_Zhang_P_Y的博客-CSDN博客

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

在Matlab实现Kmeans算法(每行代码带注释) 的相关文章

  • 如何从绘图处理程序中绘图?

    我有绘图的处理程序或图形的处理程序 例子 h plot 1 0 2 10 xx get h xx DisplayName Annotation 1x1 handle Color 0 0 1 LineStyle LineWidth 0 500
  • 频域和空间域的汉明滤波器

    我想通过在 MATLAB 中应用汉明滤波器来消除一维信号中的吉布斯伪影 我所拥有的是k1这是频域中的信号 我可以通过应用 DFT 来获取时域信号k1 s1 ifft ifftshift k1 该信号具有吉布斯伪影 现在 我想通过 A 乘以汉
  • 在 MATLAB 中定义其他中缀运算符

    有没有办法在 MATLAB 中定义额外的中缀运算符 具体来说 我想定义两个中缀运算符 gt and lt gt 这些符号是理想的 但如果需要 它可以是单个字符 它调用函数implies and iff以同样的方式 calls and and
  • 作为动画的八度情节点

    我有以下八度脚本 TOTAL POINTS 100 figure 1 for i 1 TOTAL POINTS randX rand 1 randY rand 1 scatter randX randY hold on endfor 当我运
  • 为什么 MATLAB 在打印大量 (.png) 图形时速度会变慢?

    我正在将大量数字打印为 png 文件 每个图都是数据矩阵中的一列图 我获取 png 文件并将它们串在一起形成动画 我的问题是 前几百张图像打印得很快 但创建每个新图形的时间却迅速增加 从前几百个 png 文件的约 0 2 秒到第 800 个
  • R 中的聚类分析:确定最佳聚类数

    如何选择最佳的聚类数量来进行 k 均值分析 绘制以下数据的子集后 多少个簇比较合适 如何进行聚类树突分析 n 1000 kk 10 x1 runif kk y1 runif kk z1 runif kk x4 sample x1 lengt
  • 从 imread 返回的 ndims

    我正在从文件夹中选取图像 尺寸为128 128 为此 我使用以下代码行 FileName PathName uigetfile jpg Select the Cover Image file fullfile PathName FileNa
  • 在Matlab中选择图像上的像素时,索引指的是什么?

    当在Matlab中查看图像的单个像素时 该索引指的是什么 X Y 指的是像素的坐标 RGB 指的是颜色 但是关于索引是什么有什么想法吗 为了澄清一下 当我在 Matlab 中查看图形并使用数据光标选择一个点时 显示的三行是 X Y 指数 R
  • 如何获取MATLAB句柄对象的ID?

    当我尝试使用时出现问题MATLAB 句柄对象 http www mathworks com help techdoc ref handle html作为关键值MATLAB 容器 Map http www mathworks com help
  • 将数据提示堆栈放在轴标签顶部,并在轴位置发生更改后更新轴标签

    此问题仅适用于 unix matlab Windows 用户将无法重现该问题 我在尝试创建位于 y 轴标签顶部的数据提示时遇到问题 下图很能说明问题 正如您所看到的 在 ylabel 附近创建的数据提示将到达 ylabel 文本的底部 而期
  • 平衡两轮机器人而不使其向前/向后漂移

    我正在尝试设计一个控制器来平衡 2 轮机器人 约 13 公斤 并使其能够抵抗外力 例如 如果有人踢它 它不应该掉落 也不应该无限期地向前 向后漂移 我对大多数控制技术 LQR 滑模控制 PID 等 都很有经验 但我在网上看到大多数人使用 L
  • getappdata 在 MATLAB 中返回空矩阵

    我有一段代码 我在其中使用setappdata然后我使用以下方式调用数据getappdata即使它不为空 它也会返回一个空矩阵 我的一段简化代码如下 function edit1 Callback hObject eventdata han
  • 如何在Matlab中绘制网络?

    我有一个矩阵AMatlab中的维数mx2每行包含两个节点的标签 显示网络中的直接链接 例如 如果网络有4矩阵的节点A可能A 1 2 1 3 2 1 2 4 3 2 4 1 4 2 其中第一行表示有一个链接来自1 to 2 第二行表示有一个链
  • KMeans 对不平衡数据进行聚类

    我有一组包含 50 个特征 c1 c2 c3 的数据 行数超过 80k 每行包含标准化数值 范围 0 1 它实际上是一个标准化的虚拟变量 其中一些行只有很少的特征 3 4 即如果没有值则分配 0 大多数行大约有 10 20 个特征 我使用
  • 在matlab中,如何读取python pickle文件?

    在 python 中 我生成了一个 p 数据文件 pickle dump allData open myallData p wb 现在我想在Matlab中读取myallData p 我的Matlab安装在Windows 8下 其中没有Pyt
  • 将 Matlab 数组移植到 C/C++

    我正在将 matlab 程序移植到 C C 我有几个问题 但最重要的问题之一是 Matlab 将任何维度的数组都视为相同 假设我们有一个这样的函数 function result f A B C result A 2 B C A B and
  • 如何在 MATLAB 编译的应用程序中运行外部 .m 代码? [复制]

    这个问题在这里已经有答案了 我有一个 MATLAB 项目 我使用 MCC 对其进行编译以获得单个可执行文件 然后我想知道外部程序员是否可以在 exe 中执行他的一些 m 文件 而无需重新编译整个项目 重点是提供一个应用程序 其他开发人员可以
  • 通过多次合并相同的行向量来构建矩阵

    有没有一个matlab函数可以让我执行以下操作 x 1 2 2 3 然后基于x我想建立矩阵m 1 2 2 3 1 2 2 3 1 2 2 3 1 2 2 3 您正在寻找REPMAT http www mathworks com help t
  • 通过 cuFFT 进行逆 FFT 缩放

    每当我使用 cuFFT 绘制程序获得的值并将结果与 Matlab 的结果进行比较时 我都会得到相同形状的图形 并且最大值和最小值位于相同的点 然而 cuFFT 得到的值比 Matlab 得到的值大得多 Matlab代码是 fs 1000 s
  • 在 Matlab 中保存 Kinect 深度图像?

    通过使用 Kinect 我可以获得深度图像 其中每个深度图像像素存储相机和物体之间的距离 以毫米为单位 现在我想保存它们以便以后使用 最好的推荐是什么 我正在考虑将深度图像保存为图像 jpg png等 然而 该值通常是从50毫米到10000

随机推荐

  • pyltp的本地安装

    0 电脑配置 win 8 1 64位操作系统 python 2 7 1 使用pip安装pyltp 运行安装命令 pip install pyltp 第一次失败 缺少Visual C 9 0 参考资料 https blog csdn net
  • Android,页面3秒自东跳转和点击跳转显示

    先打开ADT程序创建 创建文件 如图 命名为Day01 注意大小写 注意改名字不要重复 在res layout中找到 下面第一个是视图 第二个是对视图进行编辑点击第二个进行编辑 把
  • 多线程面试总结

    总结 每个对象有一个监视器锁monitor 线程进入同步方法时尝试获取monitor的所有权 其他线程进入阻塞状态 该线程释放monitor的所有权后其他线程重新尝试获取monitor的所有权 只能有一个线程对同步监视器加锁 1 多线程的问
  • React报错误及其解决方案

    1 Import in body of module reorder to top import first 解决方案 import开头代码写在最前面
  • 微信支付之扫码支付相关代码(Java)(转载)

    最近开发网站过程 需要引入支付过程 第三方支付中最火的莫过于支付宝支付和微信支付 下边借助微信支付官网上的文档 写一下接入微信支付之扫码支付的流程 相对支付宝支付而言 微信支付的开发文档写的相当的low demo写的一点都不简洁 下边写一下
  • 如何创建http端口监听_比Minikube更快,使用Kind快速创建K8S学习环境

    简述 K8S 如火如荼的发展着 越来越多人想学习和了解 K8S 但是由于 K8S 的入门曲线较高很多人望而却步 然而随着 K8S 生态的蓬勃发展 社区也呈现了越来越多的部署方案 光针对生产可用的环境就有好几种部署方案 对于用来测试和学习环境
  • PHP秒杀系统 高并发 高性能的极致挑战 下载

    第1章 课程介绍 秒杀系统在各种网站和应用中经常会用到 本课程从基本的系统设计和基础功能开始教导大家用PHP来设计和实现秒杀系统 并且为海量并发提供更高级的技术方案和实现手段 第2章 系统技术选型分析 本章节需要大家掌握基础的LNMP平台的
  • RAC Failover三种方式

    1 Client Side Connect Time Failover 1 1 在用户端tnsname中配置了多个地址 用户发起连接请求时 会先尝试连接地址表中的第一个地址 如果这个连接尝试失败 则继续尝试使用第二个地址 直至连接成功或者遍
  • CSAPP——2.2整数表示

    两种整数 1 非负数 unsigned 2 负数 0 正数 T 补码 B 二进制 U 无符号数 1 整数数据类型 unsigned char short int long int32 t int64 t 2 无符号数的编码 假设位向量 x
  • 【Unity】2D太空登录小游戏开发入门教程(下)

    Unity 是一款非常流行且用途广泛的游戏引擎 拥有一长串受支持的平台和设备 3D 游戏可能是您谈到 Unity 时的第一个想法 该引擎甚至曾经被称为Unity 3D 但是 大部分移动 主机和桌面游戏都是以 2D 形式呈现的 因此了解 Un
  • 考研政治——选择题判断原则

    博主个人感觉政治的选择题答案真的不用背诵 而且付出与收获完全是绝对失衡的 大家做选择题时如果明确知道答案最好 但若不确定 这里博主分享一些个人总结的做题经验或可以说是筛选原则 练习时单选题尽量不要错 多选题保持在7个以内 文章目录 马原 毛
  • Inno Setup 系列之安装、卸载时调用bat

    需求 想在安装的时候调用install bat 在卸载的时候调用uninstall bat 解决 可以这样写 Inno Setup 的脚本 Setup NOTE The value of AppId uniquely identifies
  • Java中的OOP

    OOP Object Oriented Programming 是面向对象编程 OOP特征分别是封装 继承 多态 1 封装 保护内部的操作不被破坏 2 继承 在原本的基础之上继续进行扩充 3 多态 在一个指定的范围之内进行概念的转换 Jav
  • C++ 重载、覆盖、隐藏

    C 重载 覆盖 隐藏 重载 覆盖和隐藏是C 中容易混淆的概念 作为C 研发人员有必要了解其区别和实现 以下结合概念和源码加以说明 1 重载 重载指同一个类或者范围内 被声明的同名函数其参数数量或者类型不同 使用时根据函数参数列表确定调用哪个
  • 使用ifconfig结合awk提取主机的IP地址方法

    ifconfig是用来配置或者显示网卡信息的工具 可以提供与ip a类似的功能 在CentOS7以后的版本里 ifconfig是默认没有安装的 需要安装net tools工具 我们可以借助ifconfig工具 使用下面简单的脚本来完成主机I
  • 如何使用cd命令

    转自http jingyan baidu com article 8cdccae99f3d46315513cd47 html 以下适用于windows环境 cd就是change directory的缩写 即改变目录 讲cd命令之前 先来看看
  • 【Linux】Systemd+rc.local设置开机自启动

    1 问题描述 ubuntu18 04不再使用 inited 管理系统 改用 systemd 启动时 默认不再使用调用 etc rc local 如果想开机时调用 etc rc local 需要修改systemd的配置 2 解决方法 2 1
  • 任意进制之间的转换(C++实现)

    任意进制之间的转换 C 实现 题目描述 输入格式 第一行输入两个整数 n 和 m 2 lt n m lt 16 n 代表的是第二行输入的数的进制 m 代表的是输出的数字的进制 第二行输入一个x 如果有字母 输入大写字母 输出格式 输出一个
  • PCA主成分分析

    PCA主成分分析 优点 降低数据的复杂性 识别最重要的多个特征 缺点 不一定需要 且可能损失有用信息 适用数据类型 数值型数据 PCA背景知识 移动坐标轴 考虑上图中的大量数据点 如果要求我们画出一条直线 这条线要尽可能覆盖这些点 那么最长
  • 在Matlab实现Kmeans算法(每行代码带注释)

    目录 一 前言 二 VQ概述 三 Kmeans算法 K means 的算法步骤为 四 Matlab代码实现过程 五 一点点可选改动 个人看法 参考链接 一 前言 本人对机器学习 人工智能算法方面没什么研究 只是学习过程中恰好碰到了 一开始看