K-means 聚类算法及其代码实现
【现场实战追-女教-程】【Q:1О⒈6.x.9⒌2б】 K-means算法是非监督学习(unsupervised learning)中最简单也是最常用的一种聚类算法,具有的特点是:
对初始化敏感。初始点选择的不同,可能会产生不同的聚类结果 最终会收敛。不管初始点如何选择,最终都会收敛。
本文章介绍K-means聚类算法的思想,同时给出在matlab环境中实现K-means算法的代码。代码使用向量化(vectorization1)来计算,可能不是很直观但是效率比使用循环算法高。
K-means算法
本节首先直观叙述要解决的问题,然后给出所要求解的数学模型,最后从EM2 算法的角度分析K-means算法的特点。
问题描述
首先我们有N个数据D={x1,x2.,xN}D={{x_1,x_2.,x_N}},我们想把这些数据分成K个类。首先我们没有任何的labellabel信息,所以这是一个unsupervied learning的问题。这个问题有一些难点,在于我们并不知道KK选择多大时分类是合适的,另外由于这个问题对初始点的选择是敏感的,我们也不好判断怎么样的初始点是好的。所以,我们定义一个距离的概念,这个距离可以是很多种,例如就用最简单的欧式距离∥?∥left | cdot right |来作为判断标准,又因为这里对每个点,使用距离或者是距离的平方,其实并没有什么影响,所以为了计算方便,我们就直接使用距离的平方∥?∥2|cdot|^2作为标准。我们想找到KK个中心,数据离哪
些中心近我们就将其定义为哪一类,同时我们的KK个中心能够使这个分类最合理也就是每个点到其中心的距离的和最小。用语言描述为
找KK个中心,数据属于距离其最近的中心一类,这KK个中心能使所有数据距离其中心的距离和最小。
为了更好的理解,我将在下节给出一些数学符号来定义清楚问题。 问题定义
上小节我们知道要把数据分成KK个类别,就是要找出KK个中心点,我们将这些KK个中心点定义为{μk}|Kk=1{mu_k}|_{k=1}^K. 同时,对于数据D={x1,x2,x3.,xN}D={x_1,x_2,x_3.,x_N},我们定义一个类别指示变量
(
set
of
binary
indicator
variables3
)
{rnk|rnk∈{0,1}}{r_{nk}|r_{nk}in{0,1}},表示xn(n∈(1,2.,N))x_n (nin(1,2.,N))是否属于第kk个中心点的类,属于就是1,不属于就是0。因为我们定义数据点属于离他最近的中心点的类,所以rnkr_{nk}的计算过程为:
rnk=?1,k=argminj||xn?μj||0,otherwise.(1) r_{nk}=left{begin{array}{ll} &1, k=argmin_j{||x_n-mu_j||} &0, otherwise.
end{array}right.tag{1}
我们的目标就是要得到KK个中心点,能够使每个数据点到其中心点的距离(距离的平方)和最短,也就是让目标函数
J=∑n=1N∑k=1Krnk||xn?μk||2(2)
begin{equation}
J=sum_{n=1}^Nsum_{k=1}^{K}r_{nk}||x_n-mu_k||^2tag{2} end{equation} 问题求解
这一部分将介绍使用EM算法4来求解K-means问题。关于EM算法求解总体分为两种步骤
E(expectation): 求期望最大。初始化时,随机生成KK个中心点{μk}|Kk=1{mu_k}|_{k=1}^K。然后使用公式(1)(1)决定数据的类别。
M(Maximization): 这里的极大化取决于你的问题,我们这里是要最优化目标函数。所以在这一步我们保持数据的类别不变,要使用公式(2)(2)更新中心点,也就是要求出
μk=argminukJ(3)
mu_k = argmin_{u_k}Jtag{3} 这个等式。
这里我们注意到,因为保持了类别不变,也就是说目标函数只有μkmu_k一个变量,等式(3)(3)变成了
μk=argminukJ(μk) mu_k=argmin_{u_k}J(mu_k)
式子。所以我们对目标函数求极值,也就对μkmu_k求导并令其为零,得到
2∑n=1Nrnk(xn?μk)=0
2sum_{n=1}^N{r_{nk}(x_n-mu_k)}=0
这样的式子。求解可以得到 μk=∑nrnkxn∑nrnk(4)
mu_k=frac{sum_n{r_{nk}x_n}}{sum_n{r_{nk}}}tag{4} 的表达式。
重复以上两步,直到收敛。
至此,我们就完成了对K-means方法的求解。接下来,我们将通过实例以及代码实现来理解K-means。
K-means实现
这一节主要通过实例和代码,来充分理解K-means算法,完成聚类分析,并在最后分析收敛效果。
实例分析 代码分析
都代码还是先整体再局部吧。我们先对代码整体设计如下 function [costDis] = runKMeans(K,fileString) X=load(fileString);
Ttermine and store data set information N=size(X,1); D=size(X,2);
%allocate space for the K mu vectors
Kmus=zeros(K,D); % not need to allocate it but it is still worthy %initialize cluster centers by randomly picking points from the data
rndinds=randperm(N); Kmus=X(rndinds(1:K),:);
%specify the maximum number of iterations to allow maxiters=1000; for iter=1:maxiters
%do this by first calculating a squared distance matrix where the n,k entry
%contains the squared distance from the nth data vector to the kth mu vector
%sqDmat will be an N-by-K matrix with the n,k entry as specfied above
sqDmat=calcSqDistances(X,Kmus);
%given the matrix of squared distances, determine the closest cluster
?nter for each data vector Rnk=determineRnk(sqDmat); KmusOld=Kmus;
plotCurrent(X,Rnk,Kmus); pause(1);
Kmus=recalcMus(X,Rnk);
%check to see if the cluster centers have converged. If so, break.
K - M e a n s 聚 类 算 法
![](/skin/haowen/images/icon_star.png)
![](/skin/haowen/images/icon_star.png)
![](/skin/haowen/images/icon_star.png)
![](/skin/haowen/images/icon_star.png)