k均值聚类算法简介
K均值聚类算法是一种迭代算法。每扫描一次就要重新计算每个聚类中心点的位置。当聚类中心点的位置变化在一定的阈值之内的时候停止变化时,最后就可以得到 K个类,并且类中每个样本数据点到本簇的中心的距离都小于到其它簇中心的距离。
k均值聚类算法主要过程
Step1: 随机生成k个初始点作为中心点。
Step2:将数据集中的数据按照距离中心点的远近,分配到各个类中。
Step3: 将各个类中的数据求平均值,作为新的中心点,重复上一步,直到所有的簇不再改变。
基于欧氏距离的k均值聚类算法matlab实现代码
function [label,U,R]=k_means(x,K)%label:每个个案的聚类编号,U:最终的聚类中心点,
%R:评判聚类的效果,x:n*p的数据,n为个案数,p为属性数,K为聚类数
[n,p]=size(x);
max_iter=10;%最大迭代次数
distance=0.2;%定义新类中心点的最大偏移量
%初始化中心点
s=randsample(1:n,K);
%从n个点中随机选择三个点作为中心点,由于初始类中心点是随机的,故每次运行答案会有偏差
U=x(s,:); %以这三个点为中心形成聚类
%开始聚类
label=zeros(n,1); %建立一个N行1列的零数组,用于存放每个个案的聚类编号
stop=true;
iter=0;
while stop
for i=1:n %从第1个个案一直到第n个个案
data=x(i,:); %读取第1个数据放到x里面
label_1=0; %初始化label为0,在聚类过程中暂时存放聚类编号
dist=0; %初始化为0,记为个案到类中心的距离
for j=1:K %计算到达每个中心点的距离,推断属于哪个簇类
now_dist=sum((data-U(j,:)).^2); %计算欧式距离,因比较大小,不用开根号也行
if label_1==0||now_dist<dist
%如果是第一次计算lable=0或者此时的距离小于上一次计算出的距离
label_1=j; %个案暂时属于第j个聚类
dist=now_dist; %距离更新为当前的更小值
end
end
label(i)=label_1; %将第i个个案分配给满足上面条件的类别
end
%更新类中心点
new_U=zeros(K,p); %初始化中心点,全部清零
label_counts= zeros(K, 1); %统计每个聚类包含的个案个数
for i=1:n %遍历所有个案
label_2=label(i); %提取出个案聚类编号
new_U(label_2,:)=new_U(label_2,:)+x(i,:); %计算每个聚类所含个案各属性数据的总和
label_counts(label_2)=label_counts(label_2)+1; %计算每个聚类中个案的数量
end
for i=1:K
new_U(i,:)=new_U(i,:)/label_counts(i);
%将每个聚类中所有个案取平均值,即为新的类中心点
end
U1=new_U; %新的类中心点U
%确定迭代停止的条件
for i=1:K
distance_1(i)=norm(U(i)-U1(i)); %计算新类中心点与上一个类中心点的距离
end
iter=iter+1;
if iter>max_iter-1||max(distance_1)<distance
%如果达到最大迭代次数或者最大偏移量小于要求的即停止迭代
stop=false;
end
U=U1; %如果继续迭代,用新类中心点参与聚类分析
end
%粗略评判聚类效果
R=0;
for i=1:n
label_3=label(i);
R=R+norm(x(i,:)-U(label_3,:)); %计算每个个案到所属聚类中心点的距离之和
end
R=R/n; %用各个案到所属聚类中心点距离的均值作为评判标准