无监督学习-聚类
一、聚类,及常用的聚类统计量;
聚类:
聚类是针对给定的样本,根据据他们特征的相似度或者距离,将其归并到若干个"类"或"簇"的数据分析问题。一个类是样本的一个子集。直观上,相似的样本在相同的类,不相似的样本分散在不同的类。目的是通过得到的"类"或"簇",来发现数据的特点或者对数据进行处理,在数据挖掘、模式识别等领域有着广泛的应用。属于无监督学习,只是根据样本的相似度或者距离将其进行划分,而"类"或"簇"事先是不知道的。
常用的聚类统计量:
-
划分方法(原型方法):发现球形互斥的簇、基于距离、可以用均值或中心点等代表簇中心、对中小规模数据集有效;
-
层次方法:聚类是一个层次分解(多层)、不能纠正错误的合并或划分、可以集成其他技术如微聚类或考虑对象连接;
-
密度方法:可以发现任意形状的簇、簇是对象空间中被低密度区域分隔的稠密区域、簇密度每个点的邻域内必须具有最少个数的点、可能过滤离群点;
-
网格方法:使用一种多分辨率网格数据结构、快速处理(典型地,独立于数据对象数,但依赖于网格大小)。
二、k-均值与k-中心点方法的原理以及两种方法各自的优缺点;
k-均值:
原理:
样本集 D = { x 1 , x 2 … … x k } D = \{ x_{1},x_{2}\ldots\ldots\ x_{k}\} D={x1,x2…… xk};聚类簇数 K K K;
-
从D中随机的选择k个样本作为初始的均值向量 { u 1 , u 2 … … u k } \{ u_{1},u_{2}\ldots\ldots\ u_{k}\} {u1,u2…… uk};
-
开始迭代,为了避免运行时间过长,设置一个最大运行轮数或最小调整幅度阈值;
-
计算各样本与各均值向量的距离,将每个 x i x_{i} xi划分到与之最近的簇中;
-
根据新生成的簇计算出新的均值向量;
-
判断是否达到循环跳出条件,否则继续重复上述两步骤;
优点:
原理简单,实现容易,聚类效果中上(依赖K的选择)
缺点:
-
无法确定K的个数 (根据什么指标确定K)
-
对离群点敏感 (容易导致中心点偏移)
-
算法复杂度不易控制,迭代次数可能较(m可能会比较大);
-
局部最优解而不是全局优
-
结果不稳定
k-中心点:
原理:
-
首先随机选取一组聚类样本作为中心点集,每个中心点对应一个簇;
-
计算各样本点到各个中心点的距离(如欧几里德距离),将样本点放入离中心点最短的那个簇中根据新生成的簇计算出新的均值向量;
-
计算各簇中,距簇内各样本点距离的绝度误差最小的点,作为新的中心点
-
判断是否达到循环跳出条件,否则继续重复上述两步骤;
-
如果新的中心点集与原中心点集相同,算法终止;如果新的中心点集与原中心点集不完全相同,返回第二步骤)
优点:
相比较k-means方法k中心点正好可以解决k-means方法中噪声敏感的 问题;
缺点:
算法复杂度进一步提升;
三、k-means matlab实现;
源码:
clear
clc
%初始化初见
% 第一组数据
mu1=[0 0 ]; %均值
S1=[.1 0 ;0 .1]; %协方差
data1=mvnrnd(mu1,S1,100); %产生高斯分布数据
%第二组数据
mu2=[1.25 1.25 ];
S2=[.1 0 ;0 .1];
data2=mvnrnd(mu2,S2,100);
% 第三组数据
mu3=[-1.25 1.25 ];
S3=[.1 0 ;0 .1];
data3=mvnrnd(mu3,S3,100);
% 显示数据
plot(data1(:,1),data1(:,2),'b+');
hold on;
plot(data2(:,1),data2(:,2),'r+');
plot(data3(:,1),data3(:,2),'g+');
grid on;
title('理想的聚类效果')
% 三类数据合成
data=[data1;data2;data3];
N=3;%设置聚类数目
[m,n]=size(data);
pattern=zeros(m,n+1);
center=zeros(N,n);%初始化聚类中心
pattern(:,1:n)=data(:,:);
%第一次随机产生聚类中心
for x=1:N
center(x,:)=data( randi(300,1),:);
end
%进入迭代
while 1
distence=zeros(1,N);
num=zeros(1,N);
new_center=zeros(N,n);
for x=1:m
for y=1:N
distence(y)=norm(data(x,:)-center(y,:));%计算到每个类的距离
end
[~, temp]=min(distence);%求最小的距离
pattern(x,n+1)=temp;
end
k=0;
for y=1:N
for x=1:m
if pattern(x,n+1)==y
new_center(y,:)=new_center(y,:)+pattern(x,1:n);
num(y)=num(y)+1;
end
end
new_center(y,:)=new_center(y,:)/num(y);
if norm(new_center(y,:)-center(y,:))<0.1
k=k+1;
end
end
if k==N
break;
else
center=new_center;
end
end
[m, n]=size(pattern);
%最后显示聚类后的数据
figure;
hold on;
for i=1:m
if pattern(i,n)==1
plot(pattern(i,1),pattern(i,2),'r*');
plot(center(1,1),center(1,2),'ko');
elseif pattern(i,n)==2
plot(pattern(i,1),pattern(i,2),'g*');
plot(center(2,1),center(2,2),'ko');
elseif pattern(i,n)==3
plot(pattern(i,1),pattern(i,2),'b*');
plot(center(3,1),center(3,2),'ko');
end
end
title('k-means聚类算法的聚类结果')
grid on;
实验结果: