K-均值算法简介

article/2025/8/31 14:10:01

前段时间把en.wikipedia.org里关于K-means clustering算法的条目翻译了一下,搬到了zh.wikipedia.org里的条目“K-平均算法”下。

后来组内讨论的时候又重新整理了一下要用的内容,放到博客上来吧。
因为打算写一篇K-均值算法下自学习距离度量(distance metric)的文章,还需要有K-均值算法的内容作为铺垫。

本文名为K-均值算法简介,除包含算法内容以外,还包含了K-均值算法的来源、关于K-均值算法的不同视角,以及应用和优缺点方面的内容。

一、算法描述

已知观测集 这里写图片描述,其中每个观测都是一个这里写图片描述维实向量, 这里写图片描述-均值聚类要把这这里写图片描述个观测划分到这里写图片描述个集合中这里写图片描述,使得组内平方和(WCSS within-cluster sum of squares)最小。换句话说,它的目标是找到使得满足下式

这里写图片描述

其中 这里写图片描述这里写图片描述中所有点的均值。
注:这个 问题本身是NP-难的,所以出现了K-均值这样的启发式算法来求解。

1.1初始化
通常使用的初始化方法有Forgy随机划分(Random Partition)方法:
(1)Forgy方法随机地从数据集中选择 个观测点作为初始的均值点;
(2)随机划分方法则随机地为每一观测指定所属聚类,然后运行“更新(Update)”步骤,计算随机分配的各聚类的图心,作为初始的均值点。

特点:Forgy方法易于使得初始均值点散开,随机划分方法则把均值点都放到靠近数据集中心的地方。
适用性:随机划分方法一般更适用于K-调和均值和模糊K-均值算法;Forgy方法更适用于期望-最大化(EM)算法和标准K-均值算法。

K-均值是一个启发式算法,无法保证收敛到全局最优解,并且聚类的结果会依赖于初始的聚类。又因为算法的运行速度通常很快,所以一般都以不同的起始状态运行多次来得到更好的结果。

1.2运行时
已知初始的这里写图片描述个均值点这里写图片描述 ,算法的按照下面两个步骤交替进行:
分配(Assignment)
将每个观测分配到聚类中,使得组内平方和(WCSS)达到最小。

这里写图片描述

因为这一平方和就是平方后的欧氏距离,所以很把观测点分配到离它最近的均值点即可:
这里写图片描述

(数学上,这意味依照由这些均值点生成的Voronoi图来划分上述观测点)
其中每个 这里写图片描述都只被分配到一个确定的聚类 这里写图片描述中(在理论上它可能被分配到2个或者更多的聚类中)。

更新(Update)
计算上步得到的聚类中,每一聚类观测点的图心,作为新的均值点。

这里写图片描述

因为算术平均是最小平方估计,所以这一步同样减小了目标函数组内平方和(WCSS)的值。

这一算法将在对于观测的分配不再变化时收敛。由于交替进行的两个步骤都会减小目标函数WCSS的值,并且分配方案只有有限种,所以算法一定会收敛于某一(局部)最优解。
注意:使用这一算法无法保证得到全局最优解。

算法为把观测点分配到距离最近的聚类。
目标函数是组内平方和(WCSS),而且按照“最小平方和”来分配观测,确实是等价于按照最小欧氏距离来分配观测的。
如果使用不同的距离函数来代替(平方)欧氏距离,可能使得算法无法收敛。然而,使用不同的距离函数,也能得到K-均值聚类的其他变体,如球体K-均值算法和K-中心点算法。

二、算法思想[1]

算法的思想可以追溯到1957年,术语“K-均值”在1967年被首次使用。不过,标准算法其实是由Stuart Lloyd在1957年,作为一种脉冲编码调制技术提出的(但1982年才被AT&T实验室公开出版)。在1965年,E.W.Forgy发表了本质上相同的方法,所以这一算法有时被称为Lloyd-Forgy方法。

下面是问题原型:

脉冲编码调制就是把一个时间连续,取值连续的模拟信号变换成时间离散,取值离散的数字信号后在信道中传输。即对模拟信号先抽样,再对样值幅度量化,编码的过程。
给定一些要处理的信号,那些量化之后的值应该与……
It has long been realized that in pulse-code modulation(PCM), with a given ensemble of signals to handle, the quantum values should be spaced more closely in the voltage regions where the signal amplitude is more likely to fall.
也就是说,这其实是一个聚类问题:对于整个电压轴,需要找出这里写图片描述个离散的电压值,使得信号围绕这这里写图片描述个电压值的分布成为这里写图片描述个聚类。(原始文献中的讨论就视这里写图片描述为预先设定的值)

三、视角

3.1 可视为期望-最大化算法的特例
“分配”—即—“期望”
“更新”—即—“最大化”
可以看到,这一算法实际上是广义期望-最大化算法(GEM)的一个变体。

3.2 可视为空间划分的Voronoi图
链接到网页[3]。

3.3 与其它统计机器学习方法的关系

K-均值问题很容易就能一般化为高斯混合模型,另一个K-均值算法的推广则是K-SVD算法。后者把数据点视为“编码本向量”的稀疏线性组合,而K-均值对应于使用单编码本向量的特殊情形。

此外,K-均值算法还与下列方法有一定联系

(1)Mean Shift 聚类
基本的Mean Shift聚类要维护一个与输入数据集规模大小相同的数据点集。初始时,这一集合就是输入集的副本。然后对于每一个点,用一定距离范围内的所有点的均值来迭代地替换它。与之对比,K-均值把这样的迭代更新限制在(通常比输入数据集小得多的)K个点上,而更新这些点时,则利用了输入集中与之相近的所有点的均值。
还有一种与K-均值类似的Mean shift算法,即似然Mean shift,对于迭代变化的集合,用一定距离内在输入集中所有点的均值来更新集合里的点。

(2)主成分分析(PCA)
有研究表明,K-均值的放松形式解(由聚类指示向量表示),可由主成分分析中的主成分给出。
且主成分分析中,主方向张成的子空间与聚类图心空间是等价的。不过,主成分分析是K-均值聚类的有效放松形式并不是一个新的结果,并且还有研究结果直接给出了关于“聚类图心子空间是由主成分方向张成的”这一论述的反例。

(3)独立成分分析(ICA)
在稀疏假设下以及输入数据经过白化处理后,K-均值得到的解就是独立成分分析的解。这一结果对于解释K-均值在特征学习方面的成功应用很有帮助。

(4)双向过滤
K-均值算法隐含地假设输入数据的顺序不影响结果。双向过滤与K-均值算法和Mean shift算法类似之处在于它同样维护着一个迭代更新的数据集(亦是被均值更新)。
然而,双向过滤限制了均值的计算只包含了在输入数据中顺序相近的点,这使得双向过滤能够被应用在空间安排非常重要的图像去噪等问题中。

四、应用与优缺点

K-均值算法在向量量化、聚类分析、特征学习、计算机视觉等领域都有应用,也经常作为其他算法的预处理步骤使用。

使K-均值算法效率高的两个关键特点同时也常被视为它最大的缺陷:
(1)聚类数目k是一个输入参数。选择不恰当的k值可能会导致糟糕的聚类结果。这也是为什么要进行特征检查来决定数据集的聚类数目了。
(2)收敛到局部最优解,可能导致与直觉相反的错误结果。

K-均值算法的一个重要的局限性在于它的聚类模型:
这一模型的基本思想在于:得到相互分离的球状聚类,在这些聚类中,均值点趋向收敛于聚类中心。 一般会希望得到的聚类大小大致相当,这样把每个观测都分配到离它最近的均值点对应的聚类就是正确的分配方案。

五、其他[2]

  • K-均值算法的变体
  • 复杂度

参考文献
[1]STUART P. LLOYD.Least Squares Quantization in PCM[J].IEEE TRANSACTIONSON INFORMATION THEORY, 1982, IT-28(2):129-138.
[2]维基百科.K-平均算法[EB/OL].2015[2015-4-8].http://zh.wikipedia.org/zh/K%E5%B9%B3%E5%9D%87%E7%AE%97%E6%B3%95.
[3]VoronoiDiagram[EB/OL].[2015-4-8].
http://www.csie.ntnu.edu.tw/~u91029/VoronoiDiagram.html.


http://chatgpt.dhexx.cn/article/n8gQVMKK.shtml

相关文章

KMean算法精讲

本文目录 基本训练步骤关于KMeans的几个问题KMeans算法的目标函数是什么?KMeans算法是否一定会收敛?不同的初始化是否带来不⼀样的结果?K值如何进行选择? KMeansKMeans的优缺点个人有关KMeans的奇思妙想 KMeas算法是一种聚类算法&…

K-Means算法的并行和分布式写法

前段时间学习了并行与分布式技术,为了写了篇关于KMeans算法的并行和分布式的编程写法,上网找了挺久,没想到网上并没有很多资料,那今天就来说一下我是怎么写的吧。 首先来讲一下K-Means的思想原理吧! K-Means算法思想…

k-means算法、性能及优化

k-means算法、性能及优化 一、k-means算法简介 k-means是用来解决著名的聚类问题的最简单的非监督学习算法之一。 该过程遵循一个简易的方式,将一组数据划分为预先设定好的k个簇。其主要思想是为每个簇定义一个质心。设置这些质心需要一些技巧,因为不同的…

k均值聚类算法(K Means)及其实战案例

算法说明 K均值聚类算法其实就是根据距离来看属性,近朱者赤近墨者黑。其中K表示要聚类的数量,就是说样本要被划分成几个类别。而均值则是因为需要求得每个类别的中心点,比如一维样本的中心点一般就是求这些样本的算术平均数。 这里存在一个…

详解K-Means算法

一、引言 K-Means算法是机器学习中最简单、最常见的一种聚类算法。 1.什么是聚类? 通俗来讲,聚类就是将一堆没有标签的原始样本数据,按照某个标准让其中特征一致的样本自动聚成一堆儿,最后原始样本数据聚成了一堆儿一堆儿的。 …

weighted Kernel k-means 加权核k均值算法理解及其实现(一)

那就从k-means开始吧 对于机器学习的新手小白来说,k-means算法应该都会接触到吧。传统的k-means算法是一个硬聚类(因为要指定k这个参数啦)算法。这里利用百度的解释 它是数据点到原型的某种距离作为优化的目标函数,利用函数求极值的方法得到迭代运算的调整规则。K-means算…

K-均值算法的原理与实战

K-均值(K-means)算法是一种常用的聚类算法。 当我们需要对未标记的数据划分类别时,往往用到的算法是聚类(clustering)。聚类是一种无监督的学习,它试图将数据集中的样本划分为若干个通常是不相交的子集&…

十分钟快速讲明白K均值聚类算法

K均值聚类算法 无监督学习 在一个典型的监督学习中,我们有一个有标签的训练集,我们的目标是找到能够区分正样本和负样本的决策边界,在这里的监督学习中,我们有一系列标签,我们需要据此拟合一个假设函数。 与此不同的…

深入浅出聚类算法之k-means算法

k-means是一个十分简单的聚类算法,它的思路非常简明清晰,所以经常拿来当做教学。下面就来讲述一下这个模型的细节操作。 内容 模型原理模型收敛过程模型聚类个数模型局限 1. 模型原理 将某一些数据分为不同的类别,在相同的类别中数据之间的…

c++函数调用

一个函数就是完成一项任务的独立代码块,它以名字作为整个代码块的代表 函数完成任务后,如果有数值需要返回,则在声明函数时,在函数名前写好返回值类型 如果不需要返回任何值,则在函数名前写 void 有时,一个…

c语言中函数调用的过程

一.程序在内存中的占用。 要学习C语言中函数调用的过程,必须要知道程序在内存中各个区域的分布。 C语言的函数调用的过程主要分布在栈中,所以我们今天主要研究栈。 二.几个基本的汇编指令。 call:1.将当前指令的下一条指令的地址保存到栈中…

函数定义和调用

<1>定义函数 定义函数的格式如下&#xff1a; def 函数名(): 代码 demo: 定义一个函数&#xff0c;能够完成打印信息的功能 def printInfo(): print(’------------------------------------’) print(’ 人生苦短&#xff0c;我用Python’) print(’----------------…

Shell函数调用

文章目录 一.函数基本格式二.函数调用2.1函数中调用2.2函数调用函数2.3外部调用2.4案例 三.总结 在shell脚本中&#xff0c;有些命令或者某些操作需要频繁的使用时&#xff0c;每次都重新写太过繁琐&#xff0c;这时我们就可以使用函数&#xff0c;当需要使用时&#xff0c;直接…

类的函数调用

父类和子类的函数调用 1.用指针&#xff08;引用&#xff09;调用函数的时候&#xff0c;被调用的函数取决于指针&#xff08;引用&#xff09;的类型&#xff1b; 2.涉及多态性时&#xff0c;采用虚函数和动态绑定&#xff0c;函数调用在运行时绑定&#xff0c;而非在编译时…

函数调用栈分析

进程在虚拟地址空间的布局 操作系统把磁盘上可执行文件加载到内存运行之前, 需要做很多工作, 其中很重要的一件事就是把可执行文件中的代码, 数据存放到内存 中合适的位置, 并分配和初始化程序运行过程中必须的堆栈, 所有准备工作完成之后操作系统才会调度程序起来运行. 进程…

C语言的函数调用过程

C语言的函数调用过程 先上一段代码 #include<stdio.h> int Add(int x, int y) {int z 0;z x y;return z; } #include <stdio.h> int main() {int a 10;int b 20;int c Add(a, b);return 0; } 123456789101112131415 这个函数计算两个数的值。接下来我们通…

C--函数调用

C函数的调用约定 编译器实现函数调用时所遵循的一系列规则称为函数的“调用约定&#xff08;Calling Convention&#xff09;” 对于C语言来说&#xff0c;运行在X86-64平台上的编译器基本都会根据操作系统的不同选择使用几种常见的调用约定。例如&#xff0c;在wiindows下通常…

C语言 函数调用的过程

例题&#xff1a;求两个整数中的较小者&#xff0c;用函数调用实现。 【代码实现】 int Min(int x, int y) {if (x < y){return x;}elsereturn y; } int main() {int Min(int x, int y);int a, b, c;printf("输入两个要比较的整数&#xff1a;\n");scanf("%…

函数调用的过程分析

一、函数调用机制 局部变量占用的内存是在程序执行过程中”动态”地建立和释放的。这种”动态”是通过栈由系统自动管理进行的。当任何一个函数调用发生时,系统都要作以下工作: 1)建立栈帧空间;2)保护现场: 主调函数运行状态和返回地址入栈&#xff1b;3)为被调函数传递数据(…

C/C++ 函数调用是如何实现的?

一、写在前面的话 C/C 函数调用方式与栈原理是 C/C 开发必须要掌握的基础知识&#xff0c;也是高级技术岗位面试中高频题。我真的真的真的建议无论是使用 C/C 的学生还是广大 C/C 开发者&#xff0c;都该掌握此回答中所介绍的知识。 如果你看不懂接下来第二部分在说什么&#…